]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/kernel/v2_0/src/common/thread.cxx
7888c663070ab11417af9014b7fb795ed4174e65
[karo-tx-redboot.git] / packages / kernel / v2_0 / src / common / thread.cxx
1 //==========================================================================
2 //
3 //      common/thread.cxx
4 //
5 //      Thread class implementations
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   nickg
44 // Contributors:        nickg
45 // Date:        1997-09-15
46 // Purpose:     Thread class implementation
47 // Description: This file contains the definitions of the thread class
48 //              member functions that are common to all thread implementations.
49 //
50 //####DESCRIPTIONEND####
51 //
52 //==========================================================================
53
54 #include <pkgconf/kernel.h>             // kernel configuration file
55
56 #include <cyg/hal/hal_arch.h>           // HAL_REORDER_BARRIER &
57                                         // CYGNUM_HAL_STACK_SIZE_TYPICAL
58
59 #include <cyg/kernel/ktypes.h>          // base kernel types
60 #include <cyg/infra/cyg_trac.h>         // tracing macros
61 #include <cyg/infra/cyg_ass.h>          // assertion macros
62 #include <cyg/kernel/instrmnt.h>        // instrumentation
63
64 #include <cyg/kernel/thread.hxx>        // our header
65
66 #include <cyg/kernel/intr.hxx>          // Interrupt support
67
68 #include <cyg/kernel/thread.inl>        // thread inlines
69 #include <cyg/kernel/sched.inl>         // scheduler inlines
70 #include <cyg/kernel/clock.inl>         // clock inlines
71
72 #ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT
73 #include <cyg/infra/diag.h>
74 #endif
75
76 // =========================================================================
77 // Cyg_HardwareThread members
78
79 // -------------------------------------------------------------------------
80 // Thread entry point.
81 // This is inserted as the PC value in all initial thread contexts.
82 // It does some housekeeping and then calls the real entry point.
83
84 void
85 Cyg_HardwareThread::thread_entry( Cyg_Thread *thread )
86 {
87     CYG_REPORT_FUNCTION();
88
89     Cyg_Scheduler::scheduler.clear_need_reschedule(); // finished rescheduling
90     Cyg_Scheduler::scheduler.set_current_thread(thread); // restore current thread pointer
91
92     CYG_INSTRUMENT_THREAD(ENTER,thread,0);
93     
94 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
95     // Reset the timeslice counter so that this thread gets a full
96     // quantum. 
97     Cyg_Scheduler::reset_timeslice_count();
98 #endif
99     
100     // Zero the lock
101     HAL_REORDER_BARRIER ();            // Prevent the compiler from moving
102     Cyg_Scheduler::zero_sched_lock();     // the assignment into the code above.
103     HAL_REORDER_BARRIER();
104
105     // Call entry point in a loop.
106
107     for(;;)
108     {
109         thread->entry_point(thread->entry_data);
110         thread->exit();
111     }
112 }
113
114 // =========================================================================
115 // Cyg_Thread members
116
117 // -------------------------------------------------------------------------
118 // Statics and thread list functions
119
120 #ifdef CYGVAR_KERNEL_THREADS_LIST
121
122 // List of all extant threads
123 Cyg_Thread *Cyg_Thread::thread_list = 0;
124
125 inline void
126 Cyg_Thread::add_to_list( void )
127 {
128     // Add thread to housekeeping list
129     Cyg_Scheduler::lock();
130
131     if( thread_list == 0 )
132         list_next = this;
133     else {
134         Cyg_Thread *prev = thread_list;
135         do {
136             if ( this == prev )
137                 break; // found it already!
138             prev = prev->list_next;
139         } while ( prev != thread_list );
140         if ( this != prev ) {
141             // insert it in the list:
142             list_next = thread_list->list_next;
143             thread_list->list_next = this;
144         }
145     }
146     thread_list = this;
147
148     Cyg_Scheduler::unlock();
149 }
150
151 inline void
152 Cyg_Thread::remove_from_list( void )
153 {
154     // remove thread from housekeeping list
155     Cyg_Scheduler::lock();
156
157     Cyg_Thread *prev = thread_list;
158
159     do {
160         if( prev->list_next == this ) {
161             prev->list_next = list_next;
162             if( thread_list == this )
163                 thread_list = list_next;
164             break;
165         }
166         prev = prev->list_next;
167     } while ( prev != thread_list );
168     
169     Cyg_Scheduler::unlock();
170 }
171
172 #endif
173
174 static cyg_uint16 next_unique_id = 1;
175
176 // -------------------------------------------------------------------------
177 // Magic new operator to allow the thread constructor to be
178 // recalled.
179
180 inline void *
181 operator new(size_t size, Cyg_Thread *ptr)
182 { return (void *)ptr; };
183
184 // Constructor
185
186 Cyg_Thread::Cyg_Thread(
187         CYG_ADDRWORD            sched_info,     // Scheduling parameter(s)
188         cyg_thread_entry        *entry,         // entry point function
189         CYG_ADDRWORD            entry_data,     // entry data
190         char                    *name_arg,      // thread name cookie
191         CYG_ADDRESS             stack_base,     // stack base, NULL = allocate
192         cyg_ucount32            stack_size      // stack size, 0 = use default
193         )
194 :   Cyg_HardwareThread(entry, entry_data, stack_size, stack_base),
195     Cyg_SchedThread(this, sched_info)
196 #ifdef CYGFUN_KERNEL_THREADS_TIMER
197     ,timer(this)
198 #endif
199 {
200     CYG_REPORT_FUNCTION();
201
202     CYG_INSTRUMENT_THREAD(CREATE,this,0);
203     
204     // Start the thread in suspended state.
205     state               = SUSPENDED;
206     suspend_count       = 1;
207     wakeup_count        = 0;
208
209     // Initialize sleep_reason which is used by kill, release
210     sleep_reason        = NONE;
211     wake_reason         = NONE;
212
213     // Assign a 16 bit id to the thread.
214     unique_id           = next_unique_id++;
215
216 #ifdef CYGVAR_KERNEL_THREADS_DATA
217     // Zero all per-thread data entries.
218     for( int i = 0; i < CYGNUM_KERNEL_THREADS_DATA_MAX; i++ )
219         thread_data[i] = 0;
220 #endif
221 #ifdef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
222     for (int j=0; j<CYGNUM_KERNEL_THREADS_DESTRUCTORS; j++) {
223         destructors[j].fn = NULL;
224     }
225 #endif
226 #ifdef CYGVAR_KERNEL_THREADS_NAME
227     name = name_arg;
228 #endif
229 #ifdef CYGVAR_KERNEL_THREADS_LIST
230     // Add thread to housekeeping list
231     add_to_list();
232 #endif    
233     
234     Cyg_Scheduler::scheduler.register_thread(this);
235     
236     init_context(this);
237
238     CYG_REPORT_RETURN();
239 }
240
241
242 // -------------------------------------------------------------------------
243 // Re-initialize this thread.
244 // We do this by re-invoking the constructor with the original
245 // arguments, which are still available in the object.
246
247 void
248 Cyg_Thread::reinitialize()
249 {
250     CYG_REPORT_FUNCTION();
251
252     CYG_ASSERTCLASS( this, "Bad thread");
253     CYG_ASSERT( this != Cyg_Scheduler::get_current_thread(),
254                 "Attempt to reinitialize current thread");
255     CYG_ASSERT( get_current_queue() == NULL , "Thread is still on a queue");
256
257 #ifdef CYGFUN_KERNEL_THREADS_TIMER
258     // Clear the timeout. It is irrelevant whether there was
259     // actually a timeout pending.
260     timer.disable();
261 #endif
262
263     // Ensure the scheduler has let go of us.
264     Cyg_Scheduler::scheduler.deregister_thread(this);
265
266     cyg_priority pri = get_priority();
267 #ifdef CYGVAR_KERNEL_THREADS_NAME
268     char * name_arg = name;
269 #else
270     char * name_arg = NULL;
271 #endif
272     
273     new(this) Cyg_Thread( pri,
274                           entry_point, entry_data,
275                           name_arg,
276                           get_stack_base(), get_stack_size() );
277     // the constructor re-registers the thread with the scheduler.
278
279     CYG_ASSERTCLASS( this, "Thread corrupted by reinitialize");    
280
281     CYG_REPORT_RETURN();
282 }
283
284 // -------------------------------------------------------------------------
285 // Destructor.
286
287 Cyg_Thread::~Cyg_Thread()
288 {
289     CYG_REPORT_FUNCTION();
290
291     Cyg_Scheduler::scheduler.deregister_thread(this);
292
293 #ifdef CYGVAR_KERNEL_THREADS_LIST
294     // Remove thread from housekeeping list.
295     remove_from_list();
296 #endif 
297     
298     // Zero the unique_id to render this thread inconsistent.
299     unique_id = 0;
300     
301     CYG_REPORT_RETURN();
302 }
303
304 // -------------------------------------------------------------------------
305 // Thread consistency checker.
306
307 #ifdef CYGDBG_USE_ASSERTS
308
309 cyg_bool
310 Cyg_Thread::check_this( cyg_assert_class_zeal zeal) const
311 {
312 //    CYG_REPORT_FUNCTION();
313
314     // check that we have a non-NULL pointer first
315     if( this == NULL ) return false;
316     
317     switch( zeal )
318     {
319     case cyg_system_test:
320     case cyg_extreme:
321     case cyg_thorough:
322         if( (state & SUSPENDED) && (suspend_count == 0) ) return false;
323     case cyg_quick:
324         // Check that the stackpointer is within its limits.
325         // Note: This does not check the current stackpointer value
326         // of the executing thread.
327         if( (stack_ptr > (stack_base + stack_size)) ||
328             (stack_ptr < stack_base) ) return false;
329 #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
330         if( stack_ptr < stack_limit ) return false;
331 #endif
332     case cyg_trivial:
333     case cyg_none:
334     default:
335         break;
336     };
337
338     return true;
339 }
340
341 #endif
342
343 // -------------------------------------------------------------------------
344 // Put the thread to sleep.
345 // This can only be called by the current thread on itself, hence
346 // it is a static function.
347
348 void
349 Cyg_Thread::sleep()
350 {
351     CYG_REPORT_FUNCTION();
352
353     Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
354
355     CYG_ASSERTCLASS( current, "Bad current thread" );
356     
357     CYG_INSTRUMENT_THREAD(SLEEP,current,0);
358     
359     // Prevent preemption
360     Cyg_Scheduler::lock();
361
362     // If running, remove from run qs
363     if ( current->state == RUNNING )
364         Cyg_Scheduler::scheduler.rem_thread(current);
365
366     // Set the state
367     current->state |= SLEEPING;
368
369     // Unlock the scheduler and switch threads
370     Cyg_Scheduler::unlock();
371
372     CYG_REPORT_RETURN();
373 }
374
375 // -------------------------------------------------------------------------
376 // Awaken the thread from sleep.
377
378 void
379 Cyg_Thread::wake()
380 {
381     CYG_REPORT_FUNCTION();
382
383     CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
384     
385     // Prevent preemption
386     Cyg_Scheduler::lock();
387
388     if( 0 != (state & SLEEPSET) )
389     {
390         // Set the state
391         state &= ~SLEEPSET;
392
393         // remove from any queue we were on
394         remove();
395
396         // If the thread is now runnable, return it to run queue
397         if( state == RUNNING )
398             Cyg_Scheduler::scheduler.add_thread(this);
399
400     }
401     
402     // Unlock the scheduler and maybe switch threads
403     Cyg_Scheduler::unlock();
404
405     CYG_REPORT_RETURN();
406 }
407
408 // -------------------------------------------------------------------------
409 // Put the thread to sleep, with wakeup count.
410 // This can only be called by the current thread on itself, hence
411 // it is a static function.
412
413 void
414 Cyg_Thread::counted_sleep()
415 {
416     CYG_REPORT_FUNCTION();
417
418     Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
419
420     CYG_ASSERTCLASS( current, "Bad current thread" );
421     
422     CYG_INSTRUMENT_THREAD(SLEEP,current,0);
423     
424     // Prevent preemption
425     Cyg_Scheduler::lock();
426
427     if ( 0 == current->wakeup_count ) {
428         set_sleep_reason( Cyg_Thread::WAIT );
429         current->sleep();               // prepare to sleep
430         current->state |= COUNTSLEEP;   // Set the state
431     }
432     else
433         // there is a queued wakeup, do not sleep
434         current->wakeup_count--;
435
436     // Unlock the scheduler and switch threads
437     Cyg_Scheduler::unlock();
438
439     // and deal with anything we must do when we return
440     switch( current->wake_reason ) {
441     case DESTRUCT:
442     case EXIT:            
443         current->exit();
444         break;
445         
446     default:
447         break;
448     }
449
450     CYG_REPORT_RETURN();
451 }
452
453 // -------------------------------------------------------------------------
454 // Put the thread to sleep for a delay, with wakeup count.
455 // This can only be called by the current thread on itself, hence
456 // it is a static function.
457
458 #ifdef CYGFUN_KERNEL_THREADS_TIMER
459 void
460 Cyg_Thread::counted_sleep( cyg_tick_count delay )
461 {
462     CYG_REPORT_FUNCTION();
463
464     Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
465
466     CYG_ASSERTCLASS( current, "Bad current thread" );
467     
468     CYG_INSTRUMENT_THREAD(SLEEP,current,0);
469     
470     // Prevent preemption
471     Cyg_Scheduler::lock();
472
473     if ( 0 == current->wakeup_count ) {
474
475         // Set the timer (once outside any waiting loop.)
476         set_timer( Cyg_Clock::real_time_clock->current_value()+delay,
477                          Cyg_Thread::TIMEOUT  );
478
479         // If the timeout is in the past, the wake reason will have been
480         // set to something other than NONE already.
481     
482         if( current->get_wake_reason() == Cyg_Thread::NONE )
483         {
484             set_sleep_reason( Cyg_Thread::TIMEOUT );
485             current->sleep();               // prepare to sleep
486             current->state |= COUNTSLEEP;   // Set the state
487
488             Cyg_Scheduler::reschedule();
489     
490             // clear the timer; if it actually fired, no worries.
491             clear_timer();
492         }
493     }
494     else
495         // there is a queued wakeup, do not sleep
496         current->wakeup_count--;
497
498     // Unlock the scheduler and switch threads
499     Cyg_Scheduler::unlock();
500
501     // and deal with anything we must do when we return
502     switch( current->wake_reason ) {
503     case DESTRUCT:
504     case EXIT:            
505         current->exit();
506         break;
507         
508     default:
509         break;
510     }
511
512     CYG_REPORT_RETURN();
513 }
514 #endif
515
516 // -------------------------------------------------------------------------
517 // Awaken the thread from sleep.
518
519 void
520 Cyg_Thread::counted_wake()
521 {
522     CYG_REPORT_FUNCTION();
523
524     CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
525     
526     // Prevent preemption
527     Cyg_Scheduler::lock();
528
529     if ( 0 == (state & COUNTSLEEP) )    // already awake, or waiting:
530         wakeup_count++;                 // not in a counted sleep anyway.
531     else {
532         sleep_reason = NONE;
533         wake_reason = DONE;
534         wake();                         // and awaken the thread
535     }
536
537 #ifdef CYGNUM_KERNEL_MAX_COUNTED_WAKE_COUNT_ASSERT
538     CYG_ASSERT( CYGNUM_KERNEL_MAX_COUNTED_WAKE_COUNT_ASSERT > wakeup_count,
539                 "wakeup_count overflow" );
540 #endif
541
542     // Unlock the scheduler and maybe switch threads
543     Cyg_Scheduler::unlock();
544
545     CYG_REPORT_RETURN();
546 }
547
548 // -------------------------------------------------------------------------
549 // Cancel wakeups for this thread and return how many were pending
550 cyg_uint32
551 Cyg_Thread::cancel_counted_wake()
552 {
553     CYG_REPORT_FUNCTION();
554
555     CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
556     
557     // Prevent preemption
558     Cyg_Scheduler::lock();
559
560     cyg_uint32 result = wakeup_count;
561     wakeup_count = 0;
562
563     // Unlock the scheduler
564     Cyg_Scheduler::unlock();
565
566     CYG_REPORT_RETVAL( result );
567     return result;
568 }
569
570 // -------------------------------------------------------------------------
571 // Suspend thread. Increment suspend count and deschedule thread
572 // if still running.
573
574 void
575 Cyg_Thread::suspend()
576 {
577     CYG_REPORT_FUNCTION();
578
579     CYG_INSTRUMENT_THREAD(SUSPEND,this,Cyg_Scheduler::current_thread);
580     
581     // Prevent preemption
582     Cyg_Scheduler::lock();
583
584     suspend_count++;
585     
586 #ifdef CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT
587     CYG_ASSERT( CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT > suspend_count,
588                 "suspend_count overflow" );
589 #endif
590
591     // If running, remove from run qs
592     if( state == RUNNING )
593         Cyg_Scheduler::scheduler.rem_thread(this);
594
595     // Set the state
596     state |= SUSPENDED;
597     
598     // Unlock the scheduler and maybe switch threads
599     Cyg_Scheduler::unlock();
600
601     CYG_REPORT_RETURN();
602 }
603
604 // -------------------------------------------------------------------------
605 // Resume thread. Decrement suspend count and reschedule if it
606 // is zero.
607
608 void
609 Cyg_Thread::resume()
610 {
611     CYG_REPORT_FUNCTION();
612
613     CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread);
614  
615     // Prevent preemption
616     Cyg_Scheduler::lock();
617
618     // If we are about to zero the count, clear the state bit and
619     // reschedule the thread if possible.
620     
621     if( suspend_count == 1 )
622     {
623         suspend_count = 0;
624
625         CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
626         
627         // Set the state
628         state &= ~SUSPENDED;
629
630         // Return thread to scheduler if runnable
631         if( state == RUNNING )
632             Cyg_Scheduler::scheduler.add_thread(this);
633     }
634     else
635         if( suspend_count > 0 )
636             suspend_count--;
637     // else ignore attempt to resume
638
639     // Unlock the scheduler and maybe switch threads
640     Cyg_Scheduler::unlock();
641
642     CYG_REPORT_RETURN();
643 }
644
645 // -------------------------------------------------------------------------
646 // Forced Resume thread.  Zero suspend count and reschedule...
647
648 void
649 Cyg_Thread::force_resume()
650 {
651     CYG_REPORT_FUNCTION();
652
653     CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread);
654             
655     // Prevent preemption
656     Cyg_Scheduler::lock();
657
658     // If we are about to zero the count, clear the state bit and
659     // reschedule the thread if possible.
660     
661     if ( 0 < suspend_count ) {
662         suspend_count = 0;
663
664         CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
665         
666         // Set the state
667         state &= ~SUSPENDED;
668
669         // Return thread to scheduler if runnable
670         if( state == RUNNING )
671             Cyg_Scheduler::scheduler.add_thread(this);
672     }
673
674     // Unlock the scheduler and maybe switch threads
675     Cyg_Scheduler::unlock();
676     CYG_REPORT_RETURN();
677 }
678
679 // -------------------------------------------------------------------------
680 // Force thread to wake up from a sleep with a wake_reason of
681 // BREAK. It is the responsibility of the woken thread to detect
682 // the release() and do the right thing.
683
684 void
685 Cyg_Thread::release()
686 {
687     CYG_REPORT_FUNCTION();
688     // Prevent preemption
689     Cyg_Scheduler::lock();
690
691     // If the thread is in any of the sleep states, set the
692     // wake reason and wake it up.
693
694     switch( sleep_reason )
695     {
696
697     case NONE:
698         // The thread is not sleeping for any reason, do nothing.
699         // drop through...
700         
701     case DESTRUCT:
702     case BREAK:
703     case EXIT:
704     case DONE:
705         // Do nothing in any of these cases. They are here to
706         // keep the compiler happy.
707         
708         Cyg_Scheduler::unlock();
709         CYG_REPORT_RETURN();
710         return;
711
712     case WAIT:
713         // The thread was waiting for some sync object to do
714         // something.
715         // drop through...
716         
717     case TIMEOUT:
718         // The thread was waiting on a sync object with a timeout.
719         // drop through...
720         
721     case DELAY:
722         // The thread was simply delaying, unless it has been
723         // woken up for some other reason, wake it now.
724         sleep_reason = NONE;
725         wake_reason = BREAK;
726         break;
727     }
728
729     wake();
730     
731     // Allow preemption
732     Cyg_Scheduler::unlock();
733
734     CYG_REPORT_RETURN();
735 }
736
737 // -------------------------------------------------------------------------
738 // Exit thread. This puts the thread into EXITED state.
739
740 #ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
741 #ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
742 Cyg_Thread::Cyg_Destructor_Entry
743 Cyg_Thread::destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ];
744 #endif
745 #endif
746
747 void
748 Cyg_Thread::exit()
749 {
750     CYG_REPORT_FUNCTION();
751     
752     // The thread should never return from this function.
753
754     Cyg_Thread *self = Cyg_Thread::self();
755
756 #ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
757     cyg_ucount16 i;
758     for (i=0; i<CYGNUM_KERNEL_THREADS_DESTRUCTORS; i++) {
759         if (NULL != self->destructors[i].fn) {
760             destructor_fn fn = self->destructors[i].fn;
761             CYG_ADDRWORD data = self->destructors[i].data;
762             fn(data);
763         }        
764     }
765 #endif
766 #ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT
767     diag_printf( "Stack usage for thread %08x: %d\n", self,
768                  self->measure_stack_usage() );
769 #endif
770
771     Cyg_Scheduler::lock();
772
773     // clear the timer; if there was none, no worries.
774     clear_timer();
775
776     // It is possible that we have already been killed by another
777     // thread, in which case we do not want to try and take ourself
778     // out of the scheduler again.
779     if( self->state != EXITED )
780     {
781         self->state = EXITED;
782
783         Cyg_Scheduler::scheduler.rem_thread(self);
784     }
785
786     Cyg_Scheduler::reschedule();
787 }
788
789 // -------------------------------------------------------------------------
790 // Kill thread. Force the thread into EXITED state externally, or
791 // make it wake up and call exit().
792
793 void
794 Cyg_Thread::kill()
795 {
796     CYG_REPORT_FUNCTION();
797     // If this is called by the current thread on itself,
798     // just call exit(), which is what he should have done
799     // in the first place.
800     if( this == Cyg_Scheduler::get_current_thread() )
801         exit();
802
803     // Prevent preemption
804     Cyg_Scheduler::lock();
805
806     // We are killing someone else. Find out what state he is
807     // in and force him to wakeup and call exit().
808
809     force_resume();                     // this is necessary for when
810                                         // he is asleep AND suspended.
811 #ifdef CYGFUN_KERNEL_THREADS_TIMER
812     timer.disable();                    // and make sure the timer
813                                         // does not persist.
814 #endif
815
816     if ( EXIT != wake_reason ) switch( sleep_reason ) {
817         // Only do any of this if the thread is not in pending death already:
818
819     case NONE:
820         // The thread is not sleeping for any reason, it must be
821         // on a run queue.
822         // We can safely deschedule and set its state.
823         if( state == RUNNING ) Cyg_Scheduler::scheduler.rem_thread(this);
824         state = EXITED;
825         break;
826         
827     case DESTRUCT:
828     case BREAK:
829     case EXIT:
830     case DONE:
831         // Do nothing in any of these cases. They are here to
832         // keep the compiler happy.
833         
834         Cyg_Scheduler::unlock();
835         CYG_REPORT_RETURN();
836         return;
837
838     case WAIT:
839         // The thread was waiting for some sync object to do
840         // something.
841         // drop through...
842         
843     case TIMEOUT:
844         // The thread was waiting on a sync object with a timeout.
845         // drop through...
846         
847     case DELAY:
848         // The thread was simply delaying, unless it has been
849         // woken up for some other reason, wake it now.
850         sleep_reason = NONE;
851         wake_reason = EXIT;
852         break;
853     }
854
855     wake();
856
857     // Allow preemption
858     Cyg_Scheduler::unlock();
859     CYG_REPORT_RETURN();
860 }
861
862 // -------------------------------------------------------------------------
863 // Set thread priority
864
865 #ifdef CYGIMP_THREAD_PRIORITY
866
867 void
868 Cyg_Thread::set_priority( cyg_priority new_priority )
869 {
870     CYG_REPORT_FUNCTION();
871
872 //    CYG_ASSERT( new_priority >=  CYG_THREAD_MAX_PRIORITY, "Priority out of range");
873 //    CYG_ASSERT( new_priority <=  CYG_THREAD_MIN_PRIORITY, "Priority out of range");
874     
875     CYG_INSTRUMENT_THREAD(PRIORITY,this,new_priority);
876         
877     // Prevent preemption
878     Cyg_Scheduler::lock();
879
880     Cyg_ThreadQueue *queue = NULL;
881     
882     // If running, remove from run qs
883     if( state == RUNNING )
884         Cyg_Scheduler::scheduler.rem_thread(this);
885     else if( state & SLEEPING )
886     {
887         // Remove thread from current queue.
888         queue = get_current_queue();
889         // if indeed we are on a queue
890         if ( NULL != queue ) {
891             CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");        
892             remove();
893         }
894     }
895
896     Cyg_Scheduler::scheduler.deregister_thread(this);
897     
898 #if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
899
900     // Check that there are no other threads at this priority.
901     // If so, leave is as it is.
902
903     CYG_ASSERT( Cyg_Scheduler::scheduler.unique(new_priority), "Priority not unique");
904     
905     if( Cyg_Scheduler::scheduler.unique(new_priority) )
906         priority = new_priority;
907
908 #else // !CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
909
910 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_SIMPLE
911
912     // When we have priority inheritance, we must update the original
913     // priority and not the inherited one.  If the new priority is
914     // better than the current inherited one, then use that
915     // immediately. We remain in inherited state to avoid problems
916     // with multiple mutex inheritances.
917     
918     if( priority_inherited )
919     {
920         original_priority = new_priority;
921         if( priority > new_priority ) priority = new_priority;
922     }
923     else priority = new_priority;
924     
925 #else    
926
927     priority = new_priority;
928
929 #endif
930     
931 #endif // CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
932
933     Cyg_Scheduler::scheduler.register_thread(this);
934     
935     // Return thread to scheduler if runnable
936     if( state == RUNNING )
937         Cyg_Scheduler::scheduler.add_thread(this);
938     else if ( state & SLEEPING )
939     {
940         // return to current queue
941         // if indeed we are on a queue
942         if ( NULL != queue ) {
943             CYG_CHECK_DATA_PTR(queue, "Bad queue pointer");
944             queue->enqueue(this);
945         }
946     }
947
948     // If the current thread is being reprioritized, set the
949     // reschedule flag to ensure that it gets rescheduled if
950     // necessary. (Strictly we only need to do this if the new
951     // priority is less than that of some other runnable thread, in
952     // practice checking that is as expensive as what the scheduler
953     // will do anyway).
954     // If it is not the current thread then we need to see whether
955     // it is more worthy of execution than any current thread and
956     // rescheduled if necessary.
957     
958     if( this == Cyg_Scheduler::get_current_thread() )
959          Cyg_Scheduler::set_need_reschedule();
960     else Cyg_Scheduler::set_need_reschedule(this);
961     
962     // Unlock the scheduler and maybe switch threads
963     Cyg_Scheduler::unlock();
964     CYG_REPORT_RETURN();
965 }
966
967 #endif
968
969
970 // -------------------------------------------------------------------------
971 // Thread delay function
972
973 void
974 Cyg_Thread::delay( cyg_tick_count delay)
975 {
976     CYG_REPORT_FUNCTION();
977
978 #ifdef CYGFUN_KERNEL_THREADS_TIMER
979
980     CYG_INSTRUMENT_THREAD(DELAY,this,delay);
981
982     // Prevent preemption
983     Cyg_Scheduler::lock();
984     
985     sleep();
986
987     set_timer( Cyg_Clock::real_time_clock->current_value()+delay, DELAY );
988
989     // Unlock the scheduler and maybe switch threads
990     Cyg_Scheduler::unlock();
991
992     // Clear the timeout. It is irrelevant whether the alarm has
993     // actually gone off or not.
994     clear_timer();
995
996     // and deal with anything else we must do when we return
997     switch( wake_reason ) {
998     case DESTRUCT:
999     case EXIT:            
1000         exit();
1001         break;
1002         
1003     default:
1004         break;
1005     }
1006 #endif
1007     CYG_REPORT_RETURN();
1008 }
1009
1010 // -------------------------------------------------------------------------
1011 //
1012
1013 #ifdef CYGPKG_KERNEL_EXCEPTIONS
1014
1015 void
1016 Cyg_Thread::deliver_exception(
1017     cyg_code            exception_number,       // exception being raised
1018     CYG_ADDRWORD        exception_info          // exception specific info
1019     )
1020 {
1021     if( this == Cyg_Scheduler::get_current_thread() )
1022     {
1023         // Delivering to current thread, probably as a result
1024         // of a real hardware exception. Simply invoke the appropriate
1025         // handler.
1026
1027         exception_control.deliver_exception( exception_number, exception_info );
1028     }
1029 #ifdef CYGIMP_EXCEPTION_ASYNC    
1030     else
1031     {
1032         // Delivering to another thread, probably as a result of one thread
1033         // invoking this function on another thread. Adjust the other thread's
1034         // state to make it execute the exception routine when it next runs.
1035
1036         // At present there is an unresolved problem here. We do not know what
1037         // state the destination thread is in. It may not be a suitable point at
1038         // which to invoke an exception routine. In most cases the exception
1039         // routine will be run in the scheduler thread switch code, where the world is
1040         // in an inconsistent state. We really need to run the routine at the
1041         // end of unlock_inner(). However this would add extra code to the scheduler,
1042         // and require a way of storing pending exceptions. So for now this option is
1043         // disabled and not yet implemented, it may never be.
1044         
1045     }
1046 #endif    
1047 }
1048
1049 #endif
1050
1051 // -------------------------------------------------------------------------
1052 // Per-thread data support
1053
1054 #ifdef CYGVAR_KERNEL_THREADS_DATA
1055
1056 // Set the data map bits for each free slot in the data array.
1057 cyg_ucount32 Cyg_Thread::thread_data_map = (~CYGNUM_KERNEL_THREADS_DATA_ALL) &
1058              (1+(((cyg_ucount32)(1<<(CYGNUM_KERNEL_THREADS_DATA_MAX-1))-1)<<1));
1059 // the second expression is equivalent to ((1<<CYGNUM_KERNEL_THREADS_DATA_MAX)-1);
1060 // but avoids overflow. The compiler will compile to a constant just fine.
1061
1062 Cyg_Thread::cyg_data_index
1063 Cyg_Thread::new_data_index()
1064 {
1065     Cyg_Scheduler::lock();
1066
1067     Cyg_Thread::cyg_data_index index;
1068
1069     if (0 == thread_data_map)
1070         return -1;
1071     
1072     // find ls set bit
1073     HAL_LSBIT_INDEX( index, thread_data_map );
1074
1075     // clear the bit
1076     thread_data_map &= ~(1<<index);
1077     
1078     Cyg_Scheduler::unlock();
1079
1080     return index;
1081 }
1082
1083 void Cyg_Thread::free_data_index( Cyg_Thread::cyg_data_index index )
1084 {
1085     Cyg_Scheduler::lock();
1086
1087     thread_data_map |= (1<<index);
1088     
1089     Cyg_Scheduler::unlock();    
1090 }
1091
1092
1093 #endif
1094
1095 // -------------------------------------------------------------------------
1096 // Allocate some memory at the lower end of the stack
1097 // by moving the stack limit pointer.
1098
1099 #if defined(CYGFUN_KERNEL_THREADS_STACK_LIMIT) && \
1100     defined(CYGFUN_KERNEL_THREADS_STACK_CHECKING)
1101 // if not doing stack checking, implementation can be found in thread.inl
1102 // This implementation puts the magic buffer area (to watch for overruns
1103 // *above* the stack limit, i.e. there is no official demarcation between
1104 // the stack and the buffer. But that's okay if you think about it... having
1105 // a demarcation would not accomplish anything more.
1106 void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size )
1107 {
1108     void *ret = (void *)stack_limit;
1109
1110     // First lock the scheduler because we're going to be tinkering with
1111     // the check data
1112     Cyg_Scheduler::lock();
1113
1114     // if we've inc'd the limit before, it will be off by the check data
1115     // size, so lets correct it
1116     if (stack_limit != stack_base)
1117         stack_limit -= CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
1118     stack_limit += size;
1119
1120     // determine base of check data by rounding up to nearest word aligned
1121     // address if not already aligned
1122     cyg_uint32 *p = (cyg_uint32 *)((stack_limit + 3) & ~3);
1123     // i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1);
1124     cyg_ucount32 i;
1125     cyg_uint32 sig = (cyg_uint32)this;
1126     
1127     for ( i = 0;
1128           i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
1129           i++ ) {
1130         p[i] = (sig ^ (i * 0x01010101));
1131     }
1132
1133     // increment limit by the check size. Note this will not necessarily
1134     // reach the end of the check data. But that doesn't really matter.
1135     // Doing this allows better checking of the saved stack pointer in
1136     // Cyg_Thread::check_this()
1137     stack_limit += CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
1138
1139     Cyg_Scheduler::unlock();
1140     
1141     return ret;
1142 }
1143 #endif
1144     
1145 // =========================================================================
1146 // Cyg_ThreadTimer member functions
1147
1148 // -------------------------------------------------------------------------
1149 // Timer alarm function. Inspect the sleep_reason and if necessary wake
1150 // up the thread with an appropriate wake_reason.
1151
1152 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1153
1154 void
1155 Cyg_ThreadTimer::alarm(
1156     Cyg_Alarm           *alarm,
1157     CYG_ADDRWORD        data
1158 )
1159 {
1160     CYG_REPORT_FUNCTION();
1161
1162     Cyg_ThreadTimer *self = (Cyg_ThreadTimer *)data;
1163     Cyg_Thread *thread = self->thread;
1164     
1165     CYG_INSTRUMENT_THREAD(ALARM, 0, 0);
1166     
1167     Cyg_Scheduler::lock();
1168
1169     Cyg_Thread::cyg_reason sleep_reason = thread->get_sleep_reason();
1170     
1171     switch( sleep_reason ) {
1172         
1173     case Cyg_Thread::DESTRUCT:
1174     case Cyg_Thread::BREAK:
1175     case Cyg_Thread::EXIT:
1176     case Cyg_Thread::NONE:
1177     case Cyg_Thread::WAIT:
1178     case Cyg_Thread::DONE:
1179         // Do nothing in any of these cases. Most are here to
1180         // keep the compiler happy.
1181         Cyg_Scheduler::unlock();
1182         CYG_REPORT_RETURN();
1183         return;
1184
1185     case Cyg_Thread::DELAY:
1186         // The thread was simply delaying, unless it has been
1187         // woken up for some other reason, wake it now.
1188         thread->set_wake_reason(Cyg_Thread::DONE);
1189         break;
1190
1191     case Cyg_Thread::TIMEOUT:
1192         // The thread has timed out, set the wake reason to
1193         // TIMEOUT and restart.
1194         thread->set_wake_reason(Cyg_Thread::TIMEOUT);
1195         break;
1196     }
1197
1198     thread->wake();
1199
1200     Cyg_Scheduler::unlock();
1201     CYG_REPORT_RETURN();
1202 }
1203
1204 #endif
1205
1206 // =========================================================================
1207 // The Idle thread
1208 // The idle thread is implemented as a single instance of the
1209 // Cyg_IdleThread class. This is so that it can be initialized before
1210 // main in a static constructor.
1211
1212 // -------------------------------------------------------------------------
1213 // Data definitions
1214
1215 // stack
1216 #ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM
1217 # ifdef CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE
1218 #  if CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
1219
1220 // then override the configured stack size
1221 #   undef CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE
1222 #   define CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
1223
1224 #  endif // CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE < CYGNUM_HAL_STACK_SIZE_MINIMUM
1225 # endif // CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE
1226 #endif // CYGNUM_HAL_STACK_SIZE_MINIMUM
1227
1228 static char idle_thread_stack[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE];
1229
1230 // Loop counter for debugging/housekeeping
1231 cyg_uint32 idle_thread_loops[CYGNUM_KERNEL_CPU_MAX];
1232
1233 // -------------------------------------------------------------------------
1234 // Idle thread code.
1235
1236 void
1237 idle_thread_main( CYG_ADDRESS data )
1238 {
1239     CYG_REPORT_FUNCTION();
1240
1241     for(;;)
1242     {
1243         idle_thread_loops[CYG_KERNEL_CPU_THIS()]++;
1244
1245         HAL_IDLE_THREAD_ACTION(idle_thread_loops[CYG_KERNEL_CPU_THIS()]);
1246
1247 #if 0
1248         // For testing, it is useful to be able to fake
1249         // clock interrupts in the idle thread.
1250         
1251         Cyg_Clock::real_time_clock->tick();
1252 #endif
1253 #ifdef CYGIMP_IDLE_THREAD_YIELD
1254         // In single priority and non-preemptive systems,
1255         // the idle thread should yield repeatedly to
1256         // other threads.
1257         Cyg_Thread::yield();
1258 #endif
1259     }
1260 }
1261
1262 // -------------------------------------------------------------------------
1263 // Idle thread class
1264
1265 class Cyg_IdleThread : public Cyg_Thread
1266 {
1267 public:
1268     Cyg_IdleThread();
1269         
1270 };
1271
1272 // -------------------------------------------------------------------------
1273 // Instantiate the idle thread
1274
1275 Cyg_IdleThread idle_thread[CYGNUM_KERNEL_CPU_MAX] CYG_INIT_PRIORITY( IDLE_THREAD );
1276
1277 // -------------------------------------------------------------------------
1278 // Idle threads constructor
1279
1280 Cyg_IdleThread::Cyg_IdleThread()
1281     : Cyg_Thread( CYG_THREAD_MIN_PRIORITY,
1282                   idle_thread_main,
1283                   0,
1284                   "Idle Thread",
1285                   (CYG_ADDRESS)idle_thread_stack[this-&idle_thread[0]],
1286                   CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE)
1287 {
1288     CYG_REPORT_FUNCTION();
1289
1290     // Call into scheduler to set up this thread as the default
1291     // current thread for its CPU.
1292     
1293     Cyg_Scheduler::scheduler.set_idle_thread( this, this-&idle_thread[0] );
1294
1295     CYG_REPORT_RETURN();
1296 }
1297
1298 // -------------------------------------------------------------------------
1299 // EOF common/thread.cxx