comparison packages/kernel/current/src/sched/mlqueue.cxx @ 2:443894e2e912 ecos-v1_2_1-release

Block commit of eCos version 1.2.1
author jlarmour
date Tue, 11 May 1999 12:24:34 +0000
parents 3111d98ba7b3
children 797268ecc331
comparison
equal deleted inserted replaced
1:72f549f0d891 2:443894e2e912
1 //========================================================================== 1 //==========================================================================
2 // 2 //
3 // sched/mlqueue.cxx 3 // sched/mlqueue.cxx
4 // 4 //
5 // Multi-level queue scheduler class implementation 5 // Multi-level queue scheduler class implementation
6 // 6 //
7 //========================================================================== 7 //==========================================================================
8 //####COPYRIGHTBEGIN#### 8 //####COPYRIGHTBEGIN####
9 // 9 //
10 // ------------------------------------------- 10 // -------------------------------------------
20 // 20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released 21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998. 22 // September 30, 1998.
23 // 23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created 24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. 25 // by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved.
26 // ------------------------------------------- 26 // -------------------------------------------
27 // 27 //
28 //####COPYRIGHTEND#### 28 //####COPYRIGHTEND####
29 //========================================================================== 29 //==========================================================================
30 //#####DESCRIPTIONBEGIN#### 30 //#####DESCRIPTIONBEGIN####
31 // 31 //
32 // Author(s): nickg 32 // Author(s): nickg
33 // Contributors: nickg 33 // Contributors: nickg, jlarmour
34 // Date: 1997-09-16 34 // Date: 1999-02-17
35 // Purpose: Multilevel queue scheduler class implementation 35 // Purpose: Multilevel queue scheduler class implementation
36 // Description: This file contains the implementations of 36 // Description: This file contains the implementations of
37 // Cyg_Scheduler_Implementation and Cyg_SchedThread_Implementation. 37 // Cyg_Scheduler_Implementation and
38 // Cyg_SchedThread_Implementation.
38 // 39 //
39 // 40 //
40 //####DESCRIPTIONEND#### 41 //####DESCRIPTIONEND####
41 // 42 //
42 //========================================================================== 43 //==========================================================================
90 Cyg_Scheduler_Implementation::Cyg_Scheduler_Implementation() 91 Cyg_Scheduler_Implementation::Cyg_Scheduler_Implementation()
91 { 92 {
92 CYG_REPORT_FUNCTION(); 93 CYG_REPORT_FUNCTION();
93 94
94 queue_map = 0; 95 queue_map = 0;
96
97 CYG_REPORT_RETURN();
95 } 98 }
96 99
97 // ------------------------------------------------------------------------- 100 // -------------------------------------------------------------------------
98 // Choose the best thread to run next 101 // Choose the best thread to run next
99 102
100 Cyg_Thread *Cyg_Scheduler_Implementation::schedule() 103 Cyg_Thread *
101 { 104 Cyg_Scheduler_Implementation::schedule(void)
102 CYG_REPORT_FUNCTION(); 105 {
106 CYG_REPORT_FUNCTYPE("returning thread %08x");
103 107
104 // The run queue may _never_ be empty, there is always 108 // The run queue may _never_ be empty, there is always
105 // an idle thread at the lowest priority. 109 // an idle thread at the lowest priority.
106 110
107 CYG_ASSERT( queue_map != 0, "Run queue empty"); 111 CYG_ASSERT( queue_map != 0, "Run queue empty");
114 118
115 Cyg_Thread *thread = run_queue[index].highpri(); 119 Cyg_Thread *thread = run_queue[index].highpri();
116 120
117 CYG_ASSERT( thread != NULL , "No threads in run queue"); 121 CYG_ASSERT( thread != NULL , "No threads in run queue");
118 122
123 CYG_REPORT_RETVAL(thread);
124
119 return thread; 125 return thread;
120 } 126 }
121 127
122 // ------------------------------------------------------------------------- 128 // -------------------------------------------------------------------------
123 129
124 void Cyg_Scheduler_Implementation::add_thread(Cyg_Thread *thread) 130 void
125 { 131 Cyg_Scheduler_Implementation::add_thread(Cyg_Thread *thread)
126 CYG_REPORT_FUNCTION(); 132 {
133 CYG_REPORT_FUNCTION();
134 CYG_REPORT_FUNCARG1("thread=%08x", thread);
127 135
128 cyg_priority pri = thread->priority; 136 cyg_priority pri = thread->priority;
129 Cyg_ThreadQueue_Implementation *queue = &run_queue[pri]; 137 Cyg_ThreadQueue_Implementation *queue = &run_queue[pri];
130 138
131 // If the thread is on some other queue, remove it 139 // If the thread is on some other queue, remove it
155 CYG_ASSERT( queue_map != 0, "Run queue empty"); 163 CYG_ASSERT( queue_map != 0, "Run queue empty");
156 CYG_ASSERT( queue_map & (1<<pri), "Queue map bit not set for pri"); 164 CYG_ASSERT( queue_map & (1<<pri), "Queue map bit not set for pri");
157 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); 165 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!");
158 // CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); 166 // CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!");
159 167
160 queue->enqueue(thread); 168 queue->enqueue(thread);
161 } 169
162 170 CYG_REPORT_RETURN();
163 // ------------------------------------------------------------------------- 171 }
164 172
165 void Cyg_Scheduler_Implementation::rem_thread(Cyg_Thread *thread) 173 // -------------------------------------------------------------------------
166 { 174
167 CYG_REPORT_FUNCTION(); 175 void
176 Cyg_Scheduler_Implementation::rem_thread(Cyg_Thread *thread)
177 {
178 CYG_REPORT_FUNCTION();
179 CYG_REPORT_FUNCARG1("thread=%08x", thread);
168 180
169 CYG_ASSERT( queue_map != 0, "Run queue empty"); 181 CYG_ASSERT( queue_map != 0, "Run queue empty");
170 182
171 cyg_priority pri = thread->priority; 183 cyg_priority pri = thread->priority;
172 Cyg_ThreadQueue_Implementation *queue = &run_queue[pri]; 184 Cyg_ThreadQueue_Implementation *queue = &run_queue[pri];
187 } 199 }
188 200
189 CYG_ASSERT( queue_map != 0, "Run queue empty"); 201 CYG_ASSERT( queue_map != 0, "Run queue empty");
190 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!"); 202 CYG_ASSERT( queue_map & (1<<CYG_THREAD_MIN_PRIORITY), "Idle thread vanished!!!");
191 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!"); 203 CYG_ASSERT( !run_queue[CYG_THREAD_MIN_PRIORITY].empty(), "Idle thread vanished!!!");
204
205 CYG_REPORT_RETURN();
192 } 206 }
193 207
194 // ------------------------------------------------------------------------- 208 // -------------------------------------------------------------------------
195 // register thread with scheduler 209 // register thread with scheduler
196 210
197 void Cyg_Scheduler_Implementation::register_thread(Cyg_Thread *thread) 211 void
198 { 212 Cyg_Scheduler_Implementation::register_thread(Cyg_Thread *thread)
199 CYG_REPORT_FUNCTION(); 213 {
200 214 CYG_REPORT_FUNCTION();
215 CYG_REPORT_FUNCARG1("thread=%08x", thread);
201 // No registration necessary in this scheduler 216 // No registration necessary in this scheduler
217 CYG_REPORT_RETURN();
202 } 218 }
203 219
204 // ------------------------------------------------------------------------- 220 // -------------------------------------------------------------------------
205 221
206 // deregister thread 222 // deregister thread
207 void Cyg_Scheduler_Implementation::deregister_thread(Cyg_Thread *thread) 223 void
208 { 224 Cyg_Scheduler_Implementation::deregister_thread(Cyg_Thread *thread)
209 CYG_REPORT_FUNCTION(); 225 {
210 226 CYG_REPORT_FUNCTION();
227 CYG_REPORT_FUNCARG1("thread=%08x", thread);
211 // No registration necessary in this scheduler 228 // No registration necessary in this scheduler
229 CYG_REPORT_RETURN();
212 } 230 }
213 231
214 // ------------------------------------------------------------------------- 232 // -------------------------------------------------------------------------
215 // Test the given priority for uniqueness 233 // Test the given priority for uniqueness
216 234
217 cyg_bool Cyg_Scheduler_Implementation::unique( cyg_priority priority) 235 cyg_bool
218 { 236 Cyg_Scheduler_Implementation::unique( cyg_priority priority)
219 CYG_REPORT_FUNCTION(); 237 {
220 238 CYG_REPORT_FUNCTYPE("returning %d");
239 CYG_REPORT_FUNCARG1("priority=%d", priority);
221 // Priorities are not unique 240 // Priorities are not unique
241 CYG_REPORT_RETVAL(true);
222 return true; 242 return true;
223 } 243 }
224 244
225 //========================================================================== 245 //==========================================================================
226 // Support for timeslicing option 246 // Support for timeslicing option
227 247
228 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE 248 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
229 249
230 void Cyg_Scheduler_Implementation::timeslice() 250 void
251 Cyg_Scheduler_Implementation::timeslice(void)
231 { 252 {
232 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE 253 #ifdef CYGDBG_KERNEL_TRACE_TIMESLICE
233 CYG_REPORT_FUNCTION(); 254 CYG_REPORT_FUNCTION();
234 #endif 255 #endif
235 CYG_ASSERT( queue_map != 0, "Run queue empty"); 256 CYG_ASSERT( queue_map != 0, "Run queue empty");
261 ( 282 (
262 CYG_ADDRWORD sched_info 283 CYG_ADDRWORD sched_info
263 ) 284 )
264 { 285 {
265 CYG_REPORT_FUNCTION(); 286 CYG_REPORT_FUNCTION();
287 CYG_REPORT_FUNCARG1("sched_info=%08x", sched_info);
266 288
267 // Create all threads at maximum priority 289 // Create all threads at maximum priority
268 priority = (cyg_priority)sched_info; 290 priority = (cyg_priority)sched_info;
269 291
270 // point the next and prev field at this thread. 292 // point the next and prev field at this thread.
271 293
272 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, 294 next = prev = CYG_CLASSFROMBASE(Cyg_Thread,
273 Cyg_SchedThread_Implementation, 295 Cyg_SchedThread_Implementation,
274 this); 296 this);
297 CYG_REPORT_RETURN();
275 } 298 }
276 299
277 // ------------------------------------------------------------------------- 300 // -------------------------------------------------------------------------
278 // Insert thread in front of this 301 // Insert thread in front of this
279 302
280 void Cyg_SchedThread_Implementation::insert( Cyg_Thread *thread) 303 void
281 { 304 Cyg_SchedThread_Implementation::insert( Cyg_Thread *thread)
282 CYG_REPORT_FUNCTION(); 305 {
306 CYG_REPORT_FUNCTION();
307 CYG_REPORT_FUNCARG1("thread=%08x", thread);
283 308
284 thread->next = CYG_CLASSFROMBASE(Cyg_Thread, 309 thread->next = CYG_CLASSFROMBASE(Cyg_Thread,
285 Cyg_SchedThread_Implementation, 310 Cyg_SchedThread_Implementation,
286 this); 311 this);
287 thread->prev = prev; 312 thread->prev = prev;
288 prev->next = thread; 313 prev->next = thread;
289 prev = thread; 314 prev = thread;
315
316 CYG_REPORT_RETURN();
290 } 317 }
291 318
292 // ------------------------------------------------------------------------- 319 // -------------------------------------------------------------------------
293 // remove this from queue 320 // remove this from queue
294 321
295 void Cyg_SchedThread_Implementation::remove() 322 void
323 Cyg_SchedThread_Implementation::remove(void)
296 { 324 {
297 CYG_REPORT_FUNCTION(); 325 CYG_REPORT_FUNCTION();
298 326
299 next->prev = prev; 327 next->prev = prev;
300 prev->next = next; 328 prev->next = next;
301 next = prev = CYG_CLASSFROMBASE(Cyg_Thread, 329 next = prev = CYG_CLASSFROMBASE(Cyg_Thread,
302 Cyg_SchedThread_Implementation, 330 Cyg_SchedThread_Implementation,
303 this); 331 this);
332 CYG_REPORT_RETURN();
304 } 333 }
305 334
306 // ------------------------------------------------------------------------- 335 // -------------------------------------------------------------------------
307 // Yield the processor to another thread 336 // Yield the processor to another thread
308 337
309 void Cyg_SchedThread_Implementation::yield() 338 void
339 Cyg_SchedThread_Implementation::yield(void)
310 { 340 {
311 CYG_REPORT_FUNCTION(); 341 CYG_REPORT_FUNCTION();
312 342
313 // Prevent preemption 343 // Prevent preemption
314 Cyg_Scheduler::lock(); 344 Cyg_Scheduler::lock();
346 } 376 }
347 377
348 // Unlock the scheduler and switch threads 378 // Unlock the scheduler and switch threads
349 Cyg_Scheduler::unlock(); 379 Cyg_Scheduler::unlock();
350 380
381 CYG_REPORT_RETURN();
351 } 382 }
352 383
353 // ------------------------------------------------------------------------- 384 // -------------------------------------------------------------------------
354 // Rotate the run queue at a specified priority. 385 // Rotate the run queue at a specified priority.
355 // (pri is the decider, no this, so the routine is static) 386 // (pri is the decider, no this, so the routine is static)
356 387
357 void 388 void
358 Cyg_SchedThread_Implementation::rotate_queue( cyg_priority pri ) 389 Cyg_SchedThread_Implementation::rotate_queue( cyg_priority pri )
359 { 390 {
360 CYG_REPORT_FUNCTION(); 391 CYG_REPORT_FUNCTION();
392 CYG_REPORT_FUNCARG1("priority=%d", pri);
361 393
362 // Prevent preemption 394 // Prevent preemption
363 Cyg_Scheduler::lock(); 395 Cyg_Scheduler::lock();
364 396
365 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler; 397 Cyg_Scheduler *sched = &Cyg_Scheduler::scheduler;
374 } 406 }
375 407
376 // Unlock the scheduler and switch threads 408 // Unlock the scheduler and switch threads
377 Cyg_Scheduler::unlock(); 409 Cyg_Scheduler::unlock();
378 410
411 CYG_REPORT_RETURN();
412 }
413
414 // -------------------------------------------------------------------------
415 // Move this thread to the head of its queue
416 // (not necessarily a scheduler queue)
417
418 void
419 Cyg_SchedThread_Implementation::to_queue_head( void )
420 {
421 CYG_REPORT_FUNCTION();
422
423 // Prevent preemption
424 Cyg_Scheduler::lock();
425
426 Cyg_Thread *thread = CYG_CLASSFROMBASE(Cyg_Thread,
427 Cyg_SchedThread_Implementation,
428 this);
429
430 CYG_ASSERTCLASS( thread, "Bad current thread");
431
432 Cyg_ThreadQueue *q = thread->get_current_queue();
433 q->to_head( thread );
434
435 // Unlock the scheduler and switch threads
436 Cyg_Scheduler::unlock();
437
438 CYG_REPORT_RETURN();
379 } 439 }
380 440
381 //========================================================================== 441 //==========================================================================
382 // Cyg_ThreadQueue_Implementation class members 442 // Cyg_ThreadQueue_Implementation class members
383 443
384 Cyg_ThreadQueue_Implementation::Cyg_ThreadQueue_Implementation() 444 Cyg_ThreadQueue_Implementation::Cyg_ThreadQueue_Implementation()
385 { 445 {
386 CYG_REPORT_FUNCTION(); 446 CYG_REPORT_FUNCTION();
387 447
388 queue = NULL; // empty queue 448 queue = NULL; // empty queue
389 } 449
390 450 CYG_REPORT_RETURN();
391 451 }
392 452
393 void Cyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread) 453
394 { 454
395 CYG_REPORT_FUNCTION(); 455 void
456 Cyg_ThreadQueue_Implementation::enqueue(Cyg_Thread *thread)
457 {
458 CYG_REPORT_FUNCTION();
459 CYG_REPORT_FUNCARG1("thread=%08x", thread);
396 460
397 if( queue == NULL ) queue = thread; 461 if( queue == NULL ) queue = thread;
398 else queue->insert(thread); 462 else queue->insert(thread);
399 463
400 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue, 464 thread->queue = CYG_CLASSFROMBASE(Cyg_ThreadQueue,
401 Cyg_ThreadQueue_Implementation, 465 Cyg_ThreadQueue_Implementation,
402 this); 466 this);
403 467 CYG_REPORT_RETURN();
404 } 468 }
405 469
406 // ------------------------------------------------------------------------- 470 // -------------------------------------------------------------------------
407 471
408 Cyg_Thread *Cyg_ThreadQueue_Implementation::dequeue() 472 Cyg_Thread *
409 { 473 Cyg_ThreadQueue_Implementation::dequeue(void)
410 CYG_REPORT_FUNCTION(); 474 {
411 475 CYG_REPORT_FUNCTYPE("returning thread %08x");
412 if( queue == NULL ) return NULL; 476
477 if( queue == NULL ) {
478 CYG_REPORT_RETVAL(NULL);
479 return NULL;
480 }
413 481
414 Cyg_Thread *thread = queue; 482 Cyg_Thread *thread = queue;
415 483
416 if( thread->next == thread ) 484 if( thread->next == thread )
417 { 485 {
425 thread->remove(); 493 thread->remove();
426 } 494 }
427 495
428 thread->queue = NULL; 496 thread->queue = NULL;
429 497
498 CYG_REPORT_RETVAL(thread);
430 return thread; 499 return thread;
431 } 500 }
432 501
433 // ------------------------------------------------------------------------- 502 // -------------------------------------------------------------------------
434 503
435 Cyg_Thread *Cyg_ThreadQueue_Implementation::highpri() 504 Cyg_Thread *
436 { 505 Cyg_ThreadQueue_Implementation::highpri(void)
437 CYG_REPORT_FUNCTION(); 506 {
438 507 CYG_REPORT_FUNCTYPE("returning thread %08x");
508 CYG_REPORT_RETVAL(queue);
439 return queue; 509 return queue;
440 } 510 }
441 511
442 // ------------------------------------------------------------------------- 512 // -------------------------------------------------------------------------
443 513
444 void Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread) 514 void
445 { 515 Cyg_ThreadQueue_Implementation::remove(Cyg_Thread *thread)
446 CYG_REPORT_FUNCTION(); 516 {
517 CYG_REPORT_FUNCTION();
518 CYG_REPORT_FUNCARG1("thread=%08x", thread);
447 519
448 // If the thread we want it the at the head 520 // If the thread we want it the at the head
449 // of the list, and is on its own, clear the 521 // of the list, and is on its own, clear the
450 // list and return. Otherwise advance to the 522 // list and return. Otherwise advance to the
451 // next thread and remove ours. If the thread 523 // next thread and remove ours. If the thread
464 else queue = thread->next; 536 else queue = thread->next;
465 } 537 }
466 538
467 thread->Cyg_SchedThread_Implementation::remove(); 539 thread->Cyg_SchedThread_Implementation::remove();
468 540
541 CYG_REPORT_RETURN();
469 } 542 }
470 543
471 // ------------------------------------------------------------------------- 544 // -------------------------------------------------------------------------
472 // Rotate the front thread on the queue to the back. 545 // Rotate the front thread on the queue to the back.
473 546
474 void Cyg_ThreadQueue_Implementation::rotate() 547 void
548 Cyg_ThreadQueue_Implementation::rotate(void)
475 { 549 {
476 CYG_REPORT_FUNCTION(); 550 CYG_REPORT_FUNCTION();
477 551
478 queue = queue->next; 552 queue = queue->next;
553
554 CYG_REPORT_RETURN();
555 }
556
557 // -------------------------------------------------------------------------
558 // Rotate or move the thread quoted to the front.
559
560 void
561 Cyg_ThreadQueue_Implementation::to_head(Cyg_Thread *thread)
562 {
563 CYG_REPORT_FUNCTION();
564
565 queue = thread;
566
567 CYG_REPORT_RETURN();
479 } 568 }
480 569
481 // ------------------------------------------------------------------------- 570 // -------------------------------------------------------------------------
482 571
483 #endif 572 #endif