comparison 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
comparison
equal deleted inserted replaced
114:5ad2b71d525e 115:6ed91473a1cd
30 //####COPYRIGHTEND#### 30 //####COPYRIGHTEND####
31 //========================================================================== 31 //==========================================================================
32 //#####DESCRIPTIONBEGIN#### 32 //#####DESCRIPTIONBEGIN####
33 // 33 //
34 // Author(s): nickg 34 // Author(s): nickg
35 // Contributors: nickg, jlarmour 35 // Contributors: jlarmour
36 // Date: 1999-02-17 36 // Date: 1999-02-17
37 // Purpose: Multilevel queue scheduler class implementation 37 // Purpose: Multilevel queue scheduler class implementation
38 // Description: This file contains the implementations of 38 // Description: This file contains the implementations of
39 // Cyg_Scheduler_Implementation and 39 // Cyg_Scheduler_Implementation and
40 // Cyg_SchedThread_Implementation. 40 // Cyg_SchedThread_Implementation.
259 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE 259 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE
260 CYG_REPORT_FUNCTION(); 260 CYG_REPORT_FUNCTION();
261 #endif 261 #endif
262 CYG_ASSERT( queue_map != 0, "Run queue empty"); 262 CYG_ASSERT( queue_map != 0, "Run queue empty");
263 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); 263 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!");
264 264
265 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
266 if( current_thread->timeslice_enabled && --timeslice_count == 0 )
267 #else
265 if( --timeslice_count == 0 ) 268 if( --timeslice_count == 0 )
269 #endif
266 { 270 {
267 CYG_INSTRUMENT_SCHED(TIMESLICE,0,0); 271 CYG_INSTRUMENT_SCHED(TIMESLICE,0,0);
268 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE 272 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE
269 CYG_TRACE0( true, "quantum consumed, time to reschedule" ); 273 CYG_TRACE0( true, "quantum consumed, time to reschedule" );
270 #endif 274 #endif
271 // And force the current thread to yield. 275 // And force the current thread to yield.
272 current_thread->yield(); 276 current_thread->yield();
273 } 277 }
274 278
279
275 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); 280 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!");
276 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); 281 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!");
277 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE 282 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE
278 CYG_REPORT_RETURN(); 283 CYG_REPORT_RETURN();
279 #endif 284 #endif
280 } 285 }
281 286
282 #endif 287 #endif
283 288
284 //========================================================================== 289 //==========================================================================
285 // Cyg_Cyg_SchedThread_Implementation class members 290 // Cyg_SchedThread_Implementation class members
286 291
287 Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation 292 Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation
288 ( 293 (
289 CYG_ADDRWORD sched_info 294 CYG_ADDRWORD sched_info
290 ) 295 )
291 { 296 {
292 CYG_REPORT_FUNCTION(); 297 CYG_REPORT_FUNCTION();
293 CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info); 298 CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info);
294 299
295 // Create all threads at maximum priority 300 // Set priority to the supplied value.
296 priority = (cyg_priority)sched_info; 301 priority = (cyg_priority)sched_info;
297 302
303 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE
304 // If timeslice_enabled exists, set it true by default
305 timeslice_enabled = true;
306 #endif
307
298 // point the next and prev field at this thread. 308 // point the next and prev field at this thread.
299 309
300 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, 310 next = prev = CYG_CLASSFROMBASE(Cyg_Thread,
301 Cyg_SchedThread_Implementation, 311 Cyg_SchedThread_Implementation,
302 this); 312 this);
463 { 473 {
464 CYG_REPORT_FUNCTION(); 474 CYG_REPORT_FUNCTION();
465 CYG_REPORT_FUNCARG1("thread=%08x", thread); 475 CYG_REPORT_FUNCARG1("thread=%08x", thread);
466 476
467 if( queue == NULL ) queue = thread; 477 if( queue == NULL ) queue = thread;
468 else queue->insert(thread); 478 else {
479 #ifdef CYGIMP_KERNEL_SCHED_SORTED_QUEUES
480
481 // Insert the thread into the queue in priority order.
482
483 if( queue == queue->next )
484 {
485 // There is only one other thread in the queue, join it
486 // and adjust the queue pointer to point to the highest
487 // priority of the two. If they are the same priority,
488 // leave the pointer pointing to the oldest.
489
490 queue->insert( thread );
491
492 if( thread->priority < queue->priority )
493 queue = thread;
494 }
495 else
496 {
497 // There is more than one thread in the queue. First check
498 // whether we are of higher priority than the head and if
499 // so just jump in at the front. Also check whether we are
500 // lower priority than the tail and jump onto the end.
501 // Otherwise we really have to search the queue to find
502 // our place.
503
504 if( thread->priority < queue->priority )
505 {
506 queue->insert( thread );
507 queue = thread;
508 }
509 else if( thread->priority > queue->prev->priority )
510 {
511 // We are lower priority than any thread in the queue,
512 // go in at the end.
513
514 queue->prev->insert( thread );
515 }
516 else
517 {
518 // Search the queue. We do this backwards so that we
519 // always add new threads after any that have the same
520 // priority.
521
522 // Because of the previous tests we know that this
523 // search will terminate before we hit the head of the
524 // queue, hence we do not need to check for that
525 // condition.
526
527 Cyg_Thread *qtmp = queue->prev;
528
529 // Scan the queue until we find a higher or equal
530 // priority thread.
531
532 while( thread->priority > qtmp->priority )
533 qtmp = qtmp->prev;
534
535 // Insert ourself after the node pointed to by qtmp.
536 // We do this by inserting before the next node since
537 // that is the operation we have.
538
539 qtmp->next->insert( thread );
540 }
541
542 }
543 #else
544 queue->prev->insert(thread);
545 #endif
546 }
469 547
470 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue, 548 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue,
471 Cyg_ThreadQueue_Implementation, 549 Cyg_ThreadQueue_Implementation,
472 this); 550 this);
473 CYG_REPORT_RETURN(); 551 CYG_REPORT_RETURN();
521 Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread) 599 Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread)
522 { 600 {
523 CYG_REPORT_FUNCTION(); 601 CYG_REPORT_FUNCTION();
524 CYG_REPORT_FUNCARG1("thread=%08x", thread); 602 CYG_REPORT_FUNCARG1("thread=%08x", thread);
525 603
526 // If the thread we want it the at the head 604 // If the thread we want is the at the head
527 // of the list, and is on its own, clear the 605 // of the list, and is on its own, clear the
528 // list and return. Otherwise advance to the 606 // list and return. Otherwise advance to the
529 // next thread and remove ours. If the thread 607 // next thread and remove ours. If the thread
530 // is not at the head of the list, just dequeue 608 // is not at the head of the list, just dequeue
531 // it. 609 // it.
573 CYG_REPORT_RETURN(); 651 CYG_REPORT_RETURN();
574 } 652 }
575 653
576 // ------------------------------------------------------------------------- 654 // -------------------------------------------------------------------------
577 655
656 inline void
657 Cyg_ThreadQueue_Implementation::set_thread_queue(Cyg_Thread *thread,
658 Cyg_ThreadQueue *tq )
659
660 {
661 thread->queue = tq;
662 }
663
664 // -------------------------------------------------------------------------
665
666 void
667 Cyg_SchedulerThreadQueue_Implementation::enqueue(Cyg_Thread *thread)
668 {
669 CYG_REPORT_FUNCTION();
670 CYG_REPORT_FUNCARG1("thread=%08x", thread);
671
672 if( queue == NULL ) queue = thread;
673 else queue->prev->insert(thread);
674
675 set_thread_queue( thread, CYG_CLASSFROMBASE(Cyg_ThreadQueue,
676 Cyg_SchedulerThreadQueue_Implementation,
677 this));
678 CYG_REPORT_RETURN();
679 }
680
681 // -------------------------------------------------------------------------
682
578 #endif 683 #endif
579 684
580 // ------------------------------------------------------------------------- 685 // -------------------------------------------------------------------------
581 // EOF sched/mlqueue.cxx 686 // EOF sched/mlqueue.cxx