Mercurial > ecos-v2_0-branch
annotate packages/kernel/current/src/sched/mlqueue.cxx @ 46:797268ecc331 ecos-sw-1999-10-19
Merge from eCos master repository on 1999-10-19-18:55:31-BST
| author | jlarmour |
|---|---|
| date | Tue, 19 Oct 1999 19:19:52 +0000 |
| parents | 443894e2e912 |
| children | c38311975d4f |
| rev | line source |
|---|---|
| 0 | 1 //========================================================================== |
| 2 // | |
| 2 | 3 // sched/mlqueue.cxx |
| 0 | 4 // |
| 2 | 5 // Multi-level queue scheduler class implementation |
| 0 | 6 // |
| 7 //========================================================================== | |
| 8 //####COPYRIGHTBEGIN#### | |
| 9 // | |
| 10 // ------------------------------------------- | |
| 11 // The contents of this file are subject to the Cygnus eCos Public License | |
| 12 // Version 1.0 (the "License"); you may not use this file except in | |
| 13 // compliance with the License. You may obtain a copy of the License at | |
| 14 // http://sourceware.cygnus.com/ecos | |
| 15 // | |
| 16 // Software distributed under the License is distributed on an "AS IS" | |
| 17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 18 // License for the specific language governing rights and limitations under | |
| 19 // the License. | |
| 20 // | |
| 21 // The Original Code is eCos - Embedded Cygnus Operating System, released | |
| 22 // September 30, 1998. | |
| 23 // | |
| 24 // The Initial Developer of the Original Code is Cygnus. Portions created | |
| 2 | 25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. |
| 0 | 26 // ------------------------------------------- |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //========================================================================== | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 2 | 32 // Author(s): nickg |
| 33 // Contributors: nickg, jlarmour | |
| 34 // Date: 1999-02-17 | |
| 35 // Purpose: Multilevel queue scheduler class implementation | |
| 36 // Description: This file contains the implementations of | |
| 37 // Cyg_Scheduler_Implementation and | |
| 38 // Cyg_SchedThread_Implementation. | |
| 0 | 39 // |
| 40 // | |
| 41 //####DESCRIPTIONEND#### | |
| 42 // | |
| 43 //========================================================================== | |
| 44 | |
| 45 #include <pkgconf/kernel.h> | |
| 46 | |
| 47 #include <cyg/kernel/ktypes.h> // base kernel types | |
| 48 #include <cyg/infra/cyg_trac.h> // tracing macros | |
| 49 #include <cyg/infra/cyg_ass.h> // assertion macros | |
| 50 | |
| 51 #include <cyg/kernel/sched.hxx> // our header | |
| 52 | |
| 53 #include <cyg/hal/hal_arch.h> // Architecture specific definitions | |
| 54 | |
| 55 #include <cyg/kernel/thread.inl> // thread inlines | |
| 56 #include <cyg/kernel/sched.inl> // scheduler inlines | |
| 57 | |
| 58 #ifdef CYGSEM_KERNEL_SCHED_MLQUEUE | |
| 59 | |
| 60 //------------------------------------------------------------------------- | |
| 61 // Some local tracing control - a default. | |
| 62 #ifdef CYGDBG_USE_TRACING | |
| 63 # if !defined( CYGDBG_INFRA_DEBUG_TRACE_ASSERT_SIMPLE ) && \ | |
| 64 !defined( CYGDBG_INFRA_DEBUG_TRACE_ASSERT_FANCY ) | |
| 65 // ie. not a tracing implementation that takes a long time to output | |
| 66 | |
| 67 # ifndef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 68 # define CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 69 # endif // control not already defined | |
| 70 | |
| 71 # endif // trace implementation not ..._SIMPLE && not ..._FANCY | |
| 72 #endif // CYGDBG_USE_TRACING | |
| 73 | |
| 74 //========================================================================== | |
| 75 // Cyg_Scheduler_Implementation class static members | |
| 76 | |
| 77 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
| 78 | |
| 79 cyg_ucount32 Cyg_Scheduler_Implementation::timeslice_count = | |
| 80 CYGNUM_KERNEL_SCHED_TIMESLICE_TICKS; | |
| 81 | |
| 82 #endif | |
| 83 | |
| 84 | |
| 85 //========================================================================== | |
| 86 // Cyg_Scheduler_Implementation class members | |
| 87 | |
| 88 // ------------------------------------------------------------------------- | |
| 89 // Constructor. | |
| 90 | |
| 91 Cyg_Scheduler_Implementation::Cyg_Scheduler_Implementation() | |
| 92 { | |
| 93 CYG_REPORT_FUNCTION(); | |
| 94 | |
| 95 queue_map = 0; | |
| 2 | 96 |
| 97 CYG_REPORT_RETURN(); | |
| 0 | 98 } |
| 99 | |
| 100 // ------------------------------------------------------------------------- | |
| 101 // Choose the best thread to run next | |
| 102 | |
| 2 | 103 Cyg_Thread * |
| 104 Cyg_Scheduler_Implementation::schedule(void) | |
| 0 | 105 { |
| 2 | 106 CYG_REPORT_FUNCTYPE("returning thread %08x"); |
| 0 | 107 |
| 108 // The run queue may _never_ be empty, there is always | |
| 109 // an idle thread at the lowest priority. | |
| 110 | |
| 111 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 112 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 113 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 114 | |
| 115 register cyg_uint32 index; | |
| 116 | |
| 117 HAL_LSBIT_INDEX(index, queue_map); | |
| 118 | |
| 119 Cyg_Thread *thread = run_queue[index].highpri(); | |
| 120 | |
| 121 CYG_ASSERT( thread != NULL , "No threads in run queue"); | |
| 122 | |
| 2 | 123 CYG_REPORT_RETVAL(thread); |
| 124 | |
| 0 | 125 return thread; |
| 126 } | |
| 127 | |
| 128 // ------------------------------------------------------------------------- | |
| 129 | |
| 2 | 130 void |
| 131 Cyg_Scheduler_Implementation::add_thread(Cyg_Thread *thread) | |
| 0 | 132 { |
| 133 CYG_REPORT_FUNCTION(); | |
| 2 | 134 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 135 |
| 136 cyg_priority pri = thread->priority; | |
| 137 Cyg_ThreadQueue_Implementation *queue = &run_queue[pri]; | |
| 138 | |
|
46
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
139 CYG_ASSERT((CYG_THREAD_MIN_PRIORITY >= pri) |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
140 && (CYG_THREAD_MAX_PRIORITY <= pri), |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
141 "Priority out of range!"); |
|
797268ecc331
Merge from eCos master repository on 1999-10-19-18:55:31-BST
jlarmour
parents:
2
diff
changeset
|
142 |
| 0 | 143 // If the thread is on some other queue, remove it |
| 144 // here. | |
| 145 if( thread->queue != NULL ) | |
| 146 { | |
| 147 thread->queue->remove(thread); | |
| 148 thread->queue = NULL; | |
| 149 } | |
| 150 | |
| 151 if( queue->empty() ) | |
| 152 { | |
| 153 // set the map bit and ask for a reschedule if this is a | |
| 154 // new highest priority thread. | |
| 155 | |
| 156 queue_map |= (1<<pri); | |
| 157 | |
| 158 // If the new thread is higher priority than the | |
| 159 // current thread, request a reschedule. | |
| 160 | |
| 161 if( pri < Cyg_Scheduler::get_current_thread()->priority ) | |
| 162 need_reschedule = true; | |
| 163 | |
| 164 } | |
| 165 // else the queue already has an occupant, queue behind him | |
| 166 | |
| 167 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 168 CYG_ASSERT( queue_map & (1<<pri), "Queue map bit not set for pri"); | |
| 169 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 170 // CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 171 | |
| 2 | 172 queue->enqueue(thread); |
| 173 | |
| 174 CYG_REPORT_RETURN(); | |
| 0 | 175 } |
| 176 | |
| 177 // ------------------------------------------------------------------------- | |
| 178 | |
| 2 | 179 void |
| 180 Cyg_Scheduler_Implementation::rem_thread(Cyg_Thread *thread) | |
| 0 | 181 { |
| 182 CYG_REPORT_FUNCTION(); | |
| 2 | 183 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 184 |
| 185 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 186 | |
| 187 cyg_priority pri = thread->priority; | |
| 188 Cyg_ThreadQueue_Implementation *queue = &run_queue[pri]; | |
| 189 | |
| 190 CYG_ASSERT( pri != CYG_THREAD_MIN_PRIORITY, "Idle thread trying to sleep!"); | |
| 191 CYG_ASSERT( queue_map & (1<<pri), "Queue map bit not set for pri"); | |
| 192 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 193 | |
| 194 // remove thread from queue | |
| 195 queue->remove(thread); | |
| 196 | |
| 197 if( queue->empty() ) | |
| 198 { | |
| 199 // If this was only thread in | |
| 200 // queue, clear map. | |
| 201 | |
| 202 queue_map &= ~(1<<pri); | |
| 203 } | |
| 204 | |
| 205 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 206 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 207 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 2 | 208 |
| 209 CYG_REPORT_RETURN(); | |
| 0 | 210 } |
| 211 | |
| 212 // ------------------------------------------------------------------------- | |
| 213 // register thread with scheduler | |
| 214 | |
| 2 | 215 void |
| 216 Cyg_Scheduler_Implementation::register_thread(Cyg_Thread *thread) | |
| 0 | 217 { |
| 218 CYG_REPORT_FUNCTION(); | |
| 2 | 219 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 220 // No registration necessary in this scheduler |
| 2 | 221 CYG_REPORT_RETURN(); |
| 0 | 222 } |
| 223 | |
| 224 // ------------------------------------------------------------------------- | |
| 225 | |
| 226 // deregister thread | |
| 2 | 227 void |
| 228 Cyg_Scheduler_Implementation::deregister_thread(Cyg_Thread *thread) | |
| 0 | 229 { |
| 230 CYG_REPORT_FUNCTION(); | |
| 2 | 231 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 232 // No registration necessary in this scheduler |
| 2 | 233 CYG_REPORT_RETURN(); |
| 0 | 234 } |
| 235 | |
| 236 // ------------------------------------------------------------------------- | |
| 237 // Test the given priority for uniqueness | |
| 238 | |
| 2 | 239 cyg_bool |
| 240 Cyg_Scheduler_Implementation::unique( cyg_priority priority) | |
| 0 | 241 { |
| 2 | 242 CYG_REPORT_FUNCTYPE("returning %d"); |
| 243 CYG_REPORT_FUNCARG1("priority=%d", priority); | |
| 0 | 244 // Priorities are not unique |
| 2 | 245 CYG_REPORT_RETVAL(true); |
| 0 | 246 return true; |
| 247 } | |
| 248 | |
| 249 //========================================================================== | |
| 250 // Support for timeslicing option | |
| 251 | |
| 252 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
| 253 | |
| 2 | 254 void |
| 255 Cyg_Scheduler_Implementation::timeslice(void) | |
| 0 | 256 { |
| 257 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 258 CYG_REPORT_FUNCTION(); | |
| 259 #endif | |
| 260 CYG_ASSERT( queue_map != 0, "Run queue empty"); | |
| 261 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 262 | |
| 263 if( --timeslice_count == 0 ) | |
| 264 { | |
| 265 CYG_INSTRUMENT_SCHED(TIMESLICE,0,0); | |
| 266 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 267 CYG_TRACE0( true, "quantum consumed, time to reschedule" ); | |
| 268 #endif | |
| 269 // And force the current thread to yield. | |
| 270 current_thread->yield(); | |
| 271 } | |
| 272 | |
| 273 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); | |
| 274 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); | |
| 275 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE | |
| 276 CYG_REPORT_RETURN(); | |
| 277 #endif | |
| 278 } | |
| 279 | |
| 280 #endif | |
| 281 | |
| 282 //========================================================================== | |
| 283 // Cyg_Cyg_SchedThread_Implementation class members | |
| 284 | |
| 285 Cyg_SchedThread_Implementation::Cyg_SchedThread_Implementation | |
| 286 ( | |
| 287 CYG_ADDRWORD sched_info | |
| 288 ) | |
| 289 { | |
| 290 CYG_REPORT_FUNCTION(); | |
| 2 | 291 CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info); |
| 0 | 292 |
| 293 // Create all threads at maximum priority | |
| 294 priority = (cyg_priority)sched_info; | |
| 295 | |
| 296 // point the next and prev field at this thread. | |
| 297 | |
| 298 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 299 Cyg_SchedThread_Implementation, | |
| 300 this); | |
| 2 | 301 CYG_REPORT_RETURN(); |
| 0 | 302 } |
| 303 | |
| 304 // ------------------------------------------------------------------------- | |
| 305 // Insert thread in front of this | |
| 306 | |
| 2 | 307 void |
| 308 Cyg_SchedThread_Implementation::insert( Cyg_Thread *thread) | |
| 0 | 309 { |
| 310 CYG_REPORT_FUNCTION(); | |
| 2 | 311 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 312 |
| 313 thread->next = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 314 Cyg_SchedThread_Implementation, | |
| 315 this); | |
| 316 thread->prev = prev; | |
| 317 prev->next = thread; | |
| 318 prev = thread; | |
| 2 | 319 |
| 320 CYG_REPORT_RETURN(); | |
| 0 | 321 } |
| 322 | |
| 323 // ------------------------------------------------------------------------- | |
| 324 // remove this from queue | |
| 325 | |
| 2 | 326 void |
| 327 Cyg_SchedThread_Implementation::remove(void) | |
| 0 | 328 { |
| 329 CYG_REPORT_FUNCTION(); | |
| 330 | |
| 331 next->prev = prev; | |
| 332 prev->next = next; | |
| 333 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 334 Cyg_SchedThread_Implementation, | |
| 335 this); | |
| 2 | 336 CYG_REPORT_RETURN(); |
| 0 | 337 } |
| 338 | |
| 339 // ------------------------------------------------------------------------- | |
| 340 // Yield the processor to another thread | |
| 341 | |
| 2 | 342 void |
| 343 Cyg_SchedThread_Implementation::yield(void) | |
| 0 | 344 { |
| 345 CYG_REPORT_FUNCTION(); | |
| 346 | |
| 347 // Prevent preemption | |
| 348 Cyg_Scheduler::lock(); | |
| 349 | |
| 350 Cyg_Thread *thread = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 351 Cyg_SchedThread_Implementation, | |
| 352 this); | |
| 353 | |
| 354 // Only do this if this thread is running. If it is not, there | |
| 355 // is no point. | |
| 356 | |
| 357 if( thread->get_state() == Cyg_Thread::RUNNING ) | |
| 358 { | |
| 359 // To yield we simply rotate the appropriate | |
| 360 // run queue to the next thread and reschedule. | |
| 361 | |
| 362 CYG_ASSERTCLASS( thread, "Bad current thread"); | |
| 363 | |
| 364 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; | |
| 365 | |
| 366 CYG_ASSERTCLASS( sched, "Bad scheduler"); | |
| 367 | |
| 368 cyg_priority pri = thread->priority; | |
| 369 Cyg_ThreadQueue_Implementation *queue = &sched->run_queue[pri]; | |
| 370 | |
| 371 queue->rotate(); | |
| 372 | |
| 373 if( queue->highpri() != thread ) | |
| 374 sched->need_reschedule = true; | |
| 375 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE | |
| 376 // Reset the timeslice counter so that this thread gets a full | |
| 377 // quantum. | |
| 378 else Cyg_Scheduler::reset_timeslice_count(); | |
| 379 #endif | |
| 380 } | |
| 381 | |
| 382 // Unlock the scheduler and switch threads | |
| 383 Cyg_Scheduler::unlock(); | |
| 384 | |
| 2 | 385 CYG_REPORT_RETURN(); |
| 0 | 386 } |
| 387 | |
| 388 // ------------------------------------------------------------------------- | |
| 389 // Rotate the run queue at a specified priority. | |
| 390 // (pri is the decider, no this, so the routine is static) | |
| 391 | |
| 392 void | |
| 393 Cyg_SchedThread_Implementation::rotate_queue( cyg_priority pri ) | |
| 394 { | |
| 395 CYG_REPORT_FUNCTION(); | |
| 2 | 396 CYG_REPORT_FUNCARG1("priority=%d", pri); |
| 0 | 397 |
| 398 // Prevent preemption | |
| 399 Cyg_Scheduler::lock(); | |
| 400 | |
| 401 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; | |
| 402 | |
| 403 CYG_ASSERTCLASS( sched, "Bad scheduler"); | |
| 404 | |
| 405 Cyg_ThreadQueue_Implementation *queue = &sched->run_queue[pri]; | |
| 406 | |
| 407 if ( !queue->empty() ) { | |
| 408 queue->rotate(); | |
| 409 sched->need_reschedule = true; | |
| 410 } | |
| 411 | |
| 412 // Unlock the scheduler and switch threads | |
| 413 Cyg_Scheduler::unlock(); | |
| 414 | |
| 2 | 415 CYG_REPORT_RETURN(); |
| 416 } | |
| 417 | |
| 418 // ------------------------------------------------------------------------- | |
| 419 // Move this thread to the head of its queue | |
| 420 // (not necessarily a scheduler queue) | |
| 421 | |
| 422 void | |
| 423 Cyg_SchedThread_Implementation::to_queue_head( void ) | |
| 424 { | |
| 425 CYG_REPORT_FUNCTION(); | |
| 426 | |
| 427 // Prevent preemption | |
| 428 Cyg_Scheduler::lock(); | |
| 429 | |
| 430 Cyg_Thread *thread = CYG_CLASSFROMBASE(Cyg_Thread, | |
| 431 Cyg_SchedThread_Implementation, | |
| 432 this); | |
| 433 | |
| 434 CYG_ASSERTCLASS( thread, "Bad current thread"); | |
| 435 | |
| 436 Cyg_ThreadQueue *q = thread->get_current_queue(); | |
| 437 q->to_head( thread ); | |
| 438 | |
| 439 // Unlock the scheduler and switch threads | |
| 440 Cyg_Scheduler::unlock(); | |
| 441 | |
| 442 CYG_REPORT_RETURN(); | |
| 0 | 443 } |
| 444 | |
| 445 //========================================================================== | |
| 446 // Cyg_ThreadQueue_Implementation class members | |
| 447 | |
| 448 Cyg_ThreadQueue_Implementation::Cyg_ThreadQueue_Implementation() | |
| 449 { | |
| 450 CYG_REPORT_FUNCTION(); | |
| 451 | |
| 452 queue = NULL; // empty queue | |
| 2 | 453 |
| 454 CYG_REPORT_RETURN(); | |
| 0 | 455 } |
| 456 | |
| 457 | |
| 458 | |
| 2 | 459 void |
| 460 Cyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread) | |
| 0 | 461 { |
| 462 CYG_REPORT_FUNCTION(); | |
| 2 | 463 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 464 |
| 465 if( queue == NULL ) queue = thread; | |
| 466 else queue->insert(thread); | |
| 467 | |
| 468 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue, | |
| 469 Cyg_ThreadQueue_Implementation, | |
| 470 this); | |
| 2 | 471 CYG_REPORT_RETURN(); |
| 0 | 472 } |
| 473 | |
| 474 // ------------------------------------------------------------------------- | |
| 475 | |
| 2 | 476 Cyg_Thread * |
| 477 Cyg_ThreadQueue_Implementation::dequeue(void) | |
| 0 | 478 { |
| 2 | 479 CYG_REPORT_FUNCTYPE("returning thread %08x"); |
| 0 | 480 |
| 2 | 481 if( queue == NULL ) { |
| 482 CYG_REPORT_RETVAL(NULL); | |
| 483 return NULL; | |
| 484 } | |
| 0 | 485 |
| 486 Cyg_Thread *thread = queue; | |
| 487 | |
| 488 if( thread->next == thread ) | |
| 489 { | |
| 490 // sole thread on list, NULL out ptr | |
| 491 queue = NULL; | |
| 492 } | |
| 493 else | |
| 494 { | |
| 495 // advance to next and remove thread | |
| 496 queue = thread->next; | |
| 497 thread->remove(); | |
| 498 } | |
| 499 | |
| 500 thread->queue = NULL; | |
| 501 | |
| 2 | 502 CYG_REPORT_RETVAL(thread); |
| 0 | 503 return thread; |
| 504 } | |
| 505 | |
| 506 // ------------------------------------------------------------------------- | |
| 507 | |
| 2 | 508 Cyg_Thread * |
| 509 Cyg_ThreadQueue_Implementation::highpri(void) | |
| 0 | 510 { |
| 2 | 511 CYG_REPORT_FUNCTYPE("returning thread %08x"); |
| 512 CYG_REPORT_RETVAL(queue); | |
| 0 | 513 return queue; |
| 514 } | |
| 515 | |
| 516 // ------------------------------------------------------------------------- | |
| 517 | |
| 2 | 518 void |
| 519 Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread) | |
| 0 | 520 { |
| 521 CYG_REPORT_FUNCTION(); | |
| 2 | 522 CYG_REPORT_FUNCARG1("thread=%08x", thread); |
| 0 | 523 |
| 524 // If the thread we want it the at the head | |
| 525 // of the list, and is on its own, clear the | |
| 526 // list and return. Otherwise advance to the | |
| 527 // next thread and remove ours. If the thread | |
| 528 // is not at the head of the list, just dequeue | |
| 529 // it. | |
| 530 | |
| 531 thread->queue = NULL; | |
| 532 | |
| 533 if( queue == thread ) | |
| 534 { | |
| 535 if( thread->next == thread ) | |
| 536 { | |
| 537 queue = NULL; | |
| 538 return; | |
| 539 } | |
| 540 else queue = thread->next; | |
| 541 } | |
| 542 | |
| 543 thread->Cyg_SchedThread_Implementation::remove(); | |
| 544 | |
| 2 | 545 CYG_REPORT_RETURN(); |
| 0 | 546 } |
| 547 | |
| 548 // ------------------------------------------------------------------------- | |
| 549 // Rotate the front thread on the queue to the back. | |
| 550 | |
| 2 | 551 void |
| 552 Cyg_ThreadQueue_Implementation::rotate(void) | |
| 0 | 553 { |
| 554 CYG_REPORT_FUNCTION(); | |
| 555 | |
| 556 queue = queue->next; | |
| 2 | 557 |
| 558 CYG_REPORT_RETURN(); | |
| 559 } | |
| 560 | |
| 561 // ------------------------------------------------------------------------- | |
| 562 // Rotate or move the thread quoted to the front. | |
| 563 | |
| 564 void | |
| 565 Cyg_ThreadQueue_Implementation::to_head(Cyg_Thread *thread) | |
| 566 { | |
| 567 CYG_REPORT_FUNCTION(); | |
| 568 | |
| 569 queue = thread; | |
| 570 | |
| 571 CYG_REPORT_RETURN(); | |
| 0 | 572 } |
| 573 | |
| 574 // ------------------------------------------------------------------------- | |
| 575 | |
| 576 #endif | |
| 577 | |
| 578 // ------------------------------------------------------------------------- | |
| 579 // EOF sched/mlqueue.cxx |
