Mercurial > ecos
diff packages/kernel/current/src/sched/mlqueue.cxx @ 115:6ed91473a1cd ecos-sw-2000-08-21
Merge from eCos master repository on 2000-08-21-22:40:54-BST
| author | jlarmour |
|---|---|
| date | Fri, 25 Aug 2000 17:32:38 +0000 |
| parents | bf00f99aec69 |
| children | 0ec04793409a |
line wrap: on
line diff
--- a/packages/kernel/current/src/sched/mlqueue.cxx +++ b/packages/kernel/current/src/sched/mlqueue.cxx @@ -32,7 +32,7 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): nickg -// Contributors: nickg, jlarmour +// Contributors: jlarmour // Date: 1999-02-17 // Purpose: Multilevel queue scheduler class implementation // Description: This file contains the implementations of @@ -261,8 +261,12 @@ Cyg_Scheduler_Implementation::timeslice( #endif CYG_ASSERT( queue_map != 0, "Run queue empty"); CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); - + +#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE + if( current_thread->timeslice_enabled && --timeslice_count == 0 ) +#else if( --timeslice_count == 0 ) +#endif { CYG_INSTRUMENT_SCHED(TIMESLICE,0,0); #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE @@ -272,6 +276,7 @@ Cyg_Scheduler_Implementation::timeslice( current_thread->yield(); } + CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE @@ -282,7 +287,7 @@ Cyg_Scheduler_Implementation::timeslice( #endif //========================================================================== -// Cyg_Cyg_SchedThread_Implementation class members +// Cyg_SchedThread_Implementation class members Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation ( @@ -292,9 +297,14 @@ Cyg_SchedThread_Implementation::Cyg_Sche CYG_REPORT_FUNCTION(); CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info); - // Create all threads at maximum priority + // Set priority to the supplied value. priority = (cyg_priority)sched_info; +#ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE + // If timeslice_enabled exists, set it true by default + timeslice_enabled = true; +#endif + // point the next and prev field at this thread. next = prev = CYG_CLASSFROMBASE(Cyg_Thread, @@ -465,7 +475,75 @@ Cyg_ThreadQueue_Implementation::enqueue( CYG_REPORT_FUNCARG1("thread=%08x", thread); if( queue == NULL ) queue = thread; - else queue->insert(thread); + else { +#ifdef CYGIMP_KERNEL_SCHED_SORTED_QUEUES + + // Insert the thread into the queue in priority order. + + if( queue == queue->next ) + { + // There is only one other thread in the queue, join it + // and adjust the queue pointer to point to the highest + // priority of the two. If they are the same priority, + // leave the pointer pointing to the oldest. + + queue->insert( thread ); + + if( thread->priority < queue->priority ) + queue = thread; + } + else + { + // There is more than one thread in the queue. First check + // whether we are of higher priority than the head and if + // so just jump in at the front. Also check whether we are + // lower priority than the tail and jump onto the end. + // Otherwise we really have to search the queue to find + // our place. + + if( thread->priority < queue->priority ) + { + queue->insert( thread ); + queue = thread; + } + else if( thread->priority > queue->prev->priority ) + { + // We are lower priority than any thread in the queue, + // go in at the end. + + queue->prev->insert( thread ); + } + else + { + // Search the queue. We do this backwards so that we + // always add new threads after any that have the same + // priority. + + // Because of the previous tests we know that this + // search will terminate before we hit the head of the + // queue, hence we do not need to check for that + // condition. + + Cyg_Thread *qtmp = queue->prev; + + // Scan the queue until we find a higher or equal + // priority thread. + + while( thread->priority > qtmp->priority ) + qtmp = qtmp->prev; + + // Insert ourself after the node pointed to by qtmp. + // We do this by inserting before the next node since + // that is the operation we have. + + qtmp->next->insert( thread ); + } + + } +#else + queue->prev->insert(thread); +#endif + } thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue, Cyg_ThreadQueue_Implementation, @@ -523,7 +601,7 @@ Cyg_ThreadQueue_Implementation::remove(C CYG_REPORT_FUNCTION(); CYG_REPORT_FUNCARG1("thread=%08x", thread); - // If the thread we want it the at the head + // If the thread we want is the at the head // of the list, and is on its own, clear the // list and return. Otherwise advance to the // next thread and remove ours. If the thread @@ -575,6 +653,33 @@ Cyg_ThreadQueue_Implementation::to_head( // ------------------------------------------------------------------------- +inline void +Cyg_ThreadQueue_Implementation::set_thread_queue(Cyg_Thread *thread, + Cyg_ThreadQueue *tq ) + +{ + thread->queue = tq; +} + +// ------------------------------------------------------------------------- + +void +Cyg_SchedulerThreadQueue_Implementation::enqueue(Cyg_Thread *thread) +{ + CYG_REPORT_FUNCTION(); + CYG_REPORT_FUNCARG1("thread=%08x", thread); + + if( queue == NULL ) queue = thread; + else queue->prev->insert(thread); + + set_thread_queue( thread, CYG_CLASSFROMBASE(Cyg_ThreadQueue, + Cyg_SchedulerThreadQueue_Implementation, + this)); + CYG_REPORT_RETURN(); +} + +// ------------------------------------------------------------------------- + #endif // -------------------------------------------------------------------------
