Mercurial > ecos
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 |
