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