1 //==========================================================================
5 // Thread class implementations
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.
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.
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
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.
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.
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.
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####
44 // Contributors: nickg
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.
50 //####DESCRIPTIONEND####
52 //==========================================================================
54 #include <pkgconf/kernel.h> // kernel configuration file
56 #include <cyg/hal/hal_arch.h> // HAL_REORDER_BARRIER &
57 // CYGNUM_HAL_STACK_SIZE_TYPICAL
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
64 #include <cyg/kernel/thread.hxx> // our header
66 #include <cyg/kernel/intr.hxx> // Interrupt support
68 #include <cyg/kernel/thread.inl> // thread inlines
69 #include <cyg/kernel/sched.inl> // scheduler inlines
70 #include <cyg/kernel/clock.inl> // clock inlines
72 #ifdef CYGDBG_KERNEL_THREADS_STACK_MEASUREMENT_VERBOSE_EXIT
73 #include <cyg/infra/diag.h>
76 // =========================================================================
77 // Cyg_HardwareThread members
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.
85 Cyg_HardwareThread::thread_entry( Cyg_Thread *thread )
87 CYG_REPORT_FUNCTION();
89 Cyg_Scheduler::scheduler.clear_need_reschedule(); // finished rescheduling
90 Cyg_Scheduler::scheduler.set_current_thread(thread); // restore current thread pointer
92 CYG_INSTRUMENT_THREAD(ENTER,thread,0);
94 #ifdef CYGSEM_KERNEL_SCHED_TIMESLICE
95 // Reset the timeslice counter so that this thread gets a full
97 Cyg_Scheduler::reset_timeslice_count();
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();
105 // Call entry point in a loop.
109 thread->entry_point(thread->entry_data);
114 // =========================================================================
115 // Cyg_Thread members
117 // -------------------------------------------------------------------------
118 // Statics and thread list functions
120 #ifdef CYGVAR_KERNEL_THREADS_LIST
122 // List of all extant threads
123 Cyg_Thread *Cyg_Thread::thread_list = 0;
126 Cyg_Thread::add_to_list( void )
128 // Add thread to housekeeping list
129 Cyg_Scheduler::lock();
131 if( thread_list == 0 )
134 Cyg_Thread *prev = thread_list;
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;
148 Cyg_Scheduler::unlock();
152 Cyg_Thread::remove_from_list( void )
154 // remove thread from housekeeping list
155 Cyg_Scheduler::lock();
157 Cyg_Thread *prev = thread_list;
160 if( prev->list_next == this ) {
161 prev->list_next = list_next;
162 if( thread_list == this )
163 thread_list = list_next;
166 prev = prev->list_next;
167 } while ( prev != thread_list );
169 Cyg_Scheduler::unlock();
174 static cyg_uint16 next_unique_id = 1;
176 // -------------------------------------------------------------------------
177 // Magic new operator to allow the thread constructor to be
181 operator new(size_t size, Cyg_Thread *ptr)
182 { return (void *)ptr; };
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
194 : Cyg_HardwareThread(entry, entry_data, stack_size, stack_base),
195 Cyg_SchedThread(this, sched_info)
196 #ifdef CYGFUN_KERNEL_THREADS_TIMER
200 CYG_REPORT_FUNCTION();
202 CYG_INSTRUMENT_THREAD(CREATE,this,0);
204 // Start the thread in suspended state.
209 // Initialize sleep_reason which is used by kill, release
213 // Assign a 16 bit id to the thread.
214 unique_id = next_unique_id++;
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++ )
221 #ifdef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
222 for (int j=0; j<CYGNUM_KERNEL_THREADS_DESTRUCTORS; j++) {
223 destructors[j].fn = NULL;
226 #ifdef CYGVAR_KERNEL_THREADS_NAME
229 #ifdef CYGVAR_KERNEL_THREADS_LIST
230 // Add thread to housekeeping list
234 Cyg_Scheduler::scheduler.register_thread(this);
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.
248 Cyg_Thread::reinitialize()
250 CYG_REPORT_FUNCTION();
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");
257 #ifdef CYGFUN_KERNEL_THREADS_TIMER
258 // Clear the timeout. It is irrelevant whether there was
259 // actually a timeout pending.
263 // Ensure the scheduler has let go of us.
264 Cyg_Scheduler::scheduler.deregister_thread(this);
266 cyg_priority pri = get_priority();
267 #ifdef CYGVAR_KERNEL_THREADS_NAME
268 char * name_arg = name;
270 char * name_arg = NULL;
273 new(this) Cyg_Thread( pri,
274 entry_point, entry_data,
276 get_stack_base(), get_stack_size() );
277 // the constructor re-registers the thread with the scheduler.
279 CYG_ASSERTCLASS( this, "Thread corrupted by reinitialize");
284 // -------------------------------------------------------------------------
287 Cyg_Thread::~Cyg_Thread()
289 CYG_REPORT_FUNCTION();
291 Cyg_Scheduler::scheduler.deregister_thread(this);
293 #ifdef CYGVAR_KERNEL_THREADS_LIST
294 // Remove thread from housekeeping list.
298 // Zero the unique_id to render this thread inconsistent.
304 // -------------------------------------------------------------------------
305 // Thread consistency checker.
307 #ifdef CYGDBG_USE_ASSERTS
310 Cyg_Thread::check_this( cyg_assert_class_zeal zeal) const
312 // CYG_REPORT_FUNCTION();
314 // check that we have a non-NULL pointer first
315 if( this == NULL ) return false;
319 case cyg_system_test:
322 if( (state & SUSPENDED) && (suspend_count == 0) ) return false;
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;
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.
351 CYG_REPORT_FUNCTION();
353 Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
355 CYG_ASSERTCLASS( current, "Bad current thread" );
357 CYG_INSTRUMENT_THREAD(SLEEP,current,0);
359 // Prevent preemption
360 Cyg_Scheduler::lock();
362 // If running, remove from run qs
363 if ( current->state == RUNNING )
364 Cyg_Scheduler::scheduler.rem_thread(current);
367 current->state |= SLEEPING;
369 // Unlock the scheduler and switch threads
370 Cyg_Scheduler::unlock();
375 // -------------------------------------------------------------------------
376 // Awaken the thread from sleep.
381 CYG_REPORT_FUNCTION();
383 CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
385 // Prevent preemption
386 Cyg_Scheduler::lock();
388 if( 0 != (state & SLEEPSET) )
393 // remove from any queue we were on
396 // If the thread is now runnable, return it to run queue
397 if( state == RUNNING )
398 Cyg_Scheduler::scheduler.add_thread(this);
402 // Unlock the scheduler and maybe switch threads
403 Cyg_Scheduler::unlock();
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.
414 Cyg_Thread::counted_sleep()
416 CYG_REPORT_FUNCTION();
418 Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
420 CYG_ASSERTCLASS( current, "Bad current thread" );
422 CYG_INSTRUMENT_THREAD(SLEEP,current,0);
424 // Prevent preemption
425 Cyg_Scheduler::lock();
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
433 // there is a queued wakeup, do not sleep
434 current->wakeup_count--;
436 // Unlock the scheduler and switch threads
437 Cyg_Scheduler::unlock();
439 // and deal with anything we must do when we return
440 switch( current->wake_reason ) {
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.
458 #ifdef CYGFUN_KERNEL_THREADS_TIMER
460 Cyg_Thread::counted_sleep( cyg_tick_count delay )
462 CYG_REPORT_FUNCTION();
464 Cyg_Thread *current = Cyg_Scheduler::get_current_thread();
466 CYG_ASSERTCLASS( current, "Bad current thread" );
468 CYG_INSTRUMENT_THREAD(SLEEP,current,0);
470 // Prevent preemption
471 Cyg_Scheduler::lock();
473 if ( 0 == current->wakeup_count ) {
475 // Set the timer (once outside any waiting loop.)
476 set_timer( Cyg_Clock::real_time_clock->current_value()+delay,
477 Cyg_Thread::TIMEOUT );
479 // If the timeout is in the past, the wake reason will have been
480 // set to something other than NONE already.
482 if( current->get_wake_reason() == Cyg_Thread::NONE )
484 set_sleep_reason( Cyg_Thread::TIMEOUT );
485 current->sleep(); // prepare to sleep
486 current->state |= COUNTSLEEP; // Set the state
488 Cyg_Scheduler::reschedule();
490 // clear the timer; if it actually fired, no worries.
495 // there is a queued wakeup, do not sleep
496 current->wakeup_count--;
498 // Unlock the scheduler and switch threads
499 Cyg_Scheduler::unlock();
501 // and deal with anything we must do when we return
502 switch( current->wake_reason ) {
516 // -------------------------------------------------------------------------
517 // Awaken the thread from sleep.
520 Cyg_Thread::counted_wake()
522 CYG_REPORT_FUNCTION();
524 CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
526 // Prevent preemption
527 Cyg_Scheduler::lock();
529 if ( 0 == (state & COUNTSLEEP) ) // already awake, or waiting:
530 wakeup_count++; // not in a counted sleep anyway.
534 wake(); // and awaken the thread
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" );
542 // Unlock the scheduler and maybe switch threads
543 Cyg_Scheduler::unlock();
548 // -------------------------------------------------------------------------
549 // Cancel wakeups for this thread and return how many were pending
551 Cyg_Thread::cancel_counted_wake()
553 CYG_REPORT_FUNCTION();
555 CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread);
557 // Prevent preemption
558 Cyg_Scheduler::lock();
560 cyg_uint32 result = wakeup_count;
563 // Unlock the scheduler
564 Cyg_Scheduler::unlock();
566 CYG_REPORT_RETVAL( result );
570 // -------------------------------------------------------------------------
571 // Suspend thread. Increment suspend count and deschedule thread
575 Cyg_Thread::suspend()
577 CYG_REPORT_FUNCTION();
579 CYG_INSTRUMENT_THREAD(SUSPEND,this,Cyg_Scheduler::current_thread);
581 // Prevent preemption
582 Cyg_Scheduler::lock();
586 #ifdef CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT
587 CYG_ASSERT( CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT > suspend_count,
588 "suspend_count overflow" );
591 // If running, remove from run qs
592 if( state == RUNNING )
593 Cyg_Scheduler::scheduler.rem_thread(this);
598 // Unlock the scheduler and maybe switch threads
599 Cyg_Scheduler::unlock();
604 // -------------------------------------------------------------------------
605 // Resume thread. Decrement suspend count and reschedule if it
611 CYG_REPORT_FUNCTION();
613 CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread);
615 // Prevent preemption
616 Cyg_Scheduler::lock();
618 // If we are about to zero the count, clear the state bit and
619 // reschedule the thread if possible.
621 if( suspend_count == 1 )
625 CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
630 // Return thread to scheduler if runnable
631 if( state == RUNNING )
632 Cyg_Scheduler::scheduler.add_thread(this);
635 if( suspend_count > 0 )
637 // else ignore attempt to resume
639 // Unlock the scheduler and maybe switch threads
640 Cyg_Scheduler::unlock();
645 // -------------------------------------------------------------------------
646 // Forced Resume thread. Zero suspend count and reschedule...
649 Cyg_Thread::force_resume()
651 CYG_REPORT_FUNCTION();
653 CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread);
655 // Prevent preemption
656 Cyg_Scheduler::lock();
658 // If we are about to zero the count, clear the state bit and
659 // reschedule the thread if possible.
661 if ( 0 < suspend_count ) {
664 CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" );
669 // Return thread to scheduler if runnable
670 if( state == RUNNING )
671 Cyg_Scheduler::scheduler.add_thread(this);
674 // Unlock the scheduler and maybe switch threads
675 Cyg_Scheduler::unlock();
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.
685 Cyg_Thread::release()
687 CYG_REPORT_FUNCTION();
688 // Prevent preemption
689 Cyg_Scheduler::lock();
691 // If the thread is in any of the sleep states, set the
692 // wake reason and wake it up.
694 switch( sleep_reason )
698 // The thread is not sleeping for any reason, do nothing.
705 // Do nothing in any of these cases. They are here to
706 // keep the compiler happy.
708 Cyg_Scheduler::unlock();
713 // The thread was waiting for some sync object to do
718 // The thread was waiting on a sync object with a timeout.
722 // The thread was simply delaying, unless it has been
723 // woken up for some other reason, wake it now.
732 Cyg_Scheduler::unlock();
737 // -------------------------------------------------------------------------
738 // Exit thread. This puts the thread into EXITED state.
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 ];
750 CYG_REPORT_FUNCTION();
752 // The thread should never return from this function.
754 Cyg_Thread *self = Cyg_Thread::self();
756 #ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
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;
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() );
771 Cyg_Scheduler::lock();
773 // clear the timer; if there was none, no worries.
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 )
781 self->state = EXITED;
783 Cyg_Scheduler::scheduler.rem_thread(self);
786 Cyg_Scheduler::reschedule();
789 // -------------------------------------------------------------------------
790 // Kill thread. Force the thread into EXITED state externally, or
791 // make it wake up and call exit().
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() )
803 // Prevent preemption
804 Cyg_Scheduler::lock();
806 // We are killing someone else. Find out what state he is
807 // in and force him to wakeup and call exit().
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
816 if ( EXIT != wake_reason ) switch( sleep_reason ) {
817 // Only do any of this if the thread is not in pending death already:
820 // The thread is not sleeping for any reason, it must be
822 // We can safely deschedule and set its state.
823 if( state == RUNNING ) Cyg_Scheduler::scheduler.rem_thread(this);
831 // Do nothing in any of these cases. They are here to
832 // keep the compiler happy.
834 Cyg_Scheduler::unlock();
839 // The thread was waiting for some sync object to do
844 // The thread was waiting on a sync object with a timeout.
848 // The thread was simply delaying, unless it has been
849 // woken up for some other reason, wake it now.
858 Cyg_Scheduler::unlock();
862 // -------------------------------------------------------------------------
863 // Set thread priority
865 #ifdef CYGIMP_THREAD_PRIORITY
868 Cyg_Thread::set_priority( cyg_priority new_priority )
870 CYG_REPORT_FUNCTION();
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");
875 CYG_INSTRUMENT_THREAD(PRIORITY,this,new_priority);
877 // Prevent preemption
878 Cyg_Scheduler::lock();
880 Cyg_ThreadQueue *queue = NULL;
882 // If running, remove from run qs
883 if( state == RUNNING )
884 Cyg_Scheduler::scheduler.rem_thread(this);
885 else if( state & SLEEPING )
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");
896 Cyg_Scheduler::scheduler.deregister_thread(this);
898 #if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
900 // Check that there are no other threads at this priority.
901 // If so, leave is as it is.
903 CYG_ASSERT( Cyg_Scheduler::scheduler.unique(new_priority), "Priority not unique");
905 if( Cyg_Scheduler::scheduler.unique(new_priority) )
906 priority = new_priority;
908 #else // !CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
910 #ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_SIMPLE
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.
918 if( priority_inherited )
920 original_priority = new_priority;
921 if( priority > new_priority ) priority = new_priority;
923 else priority = new_priority;
927 priority = new_priority;
931 #endif // CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES
933 Cyg_Scheduler::scheduler.register_thread(this);
935 // Return thread to scheduler if runnable
936 if( state == RUNNING )
937 Cyg_Scheduler::scheduler.add_thread(this);
938 else if ( state & SLEEPING )
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);
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
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.
958 if( this == Cyg_Scheduler::get_current_thread() )
959 Cyg_Scheduler::set_need_reschedule();
960 else Cyg_Scheduler::set_need_reschedule(this);
962 // Unlock the scheduler and maybe switch threads
963 Cyg_Scheduler::unlock();
970 // -------------------------------------------------------------------------
971 // Thread delay function
974 Cyg_Thread::delay( cyg_tick_count delay)
976 CYG_REPORT_FUNCTION();
978 #ifdef CYGFUN_KERNEL_THREADS_TIMER
980 CYG_INSTRUMENT_THREAD(DELAY,this,delay);
982 // Prevent preemption
983 Cyg_Scheduler::lock();
987 set_timer( Cyg_Clock::real_time_clock->current_value()+delay, DELAY );
989 // Unlock the scheduler and maybe switch threads
990 Cyg_Scheduler::unlock();
992 // Clear the timeout. It is irrelevant whether the alarm has
993 // actually gone off or not.
996 // and deal with anything else we must do when we return
997 switch( wake_reason ) {
1007 CYG_REPORT_RETURN();
1010 // -------------------------------------------------------------------------
1013 #ifdef CYGPKG_KERNEL_EXCEPTIONS
1016 Cyg_Thread::deliver_exception(
1017 cyg_code exception_number, // exception being raised
1018 CYG_ADDRWORD exception_info // exception specific info
1021 if( this == Cyg_Scheduler::get_current_thread() )
1023 // Delivering to current thread, probably as a result
1024 // of a real hardware exception. Simply invoke the appropriate
1027 exception_control.deliver_exception( exception_number, exception_info );
1029 #ifdef CYGIMP_EXCEPTION_ASYNC
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.
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.
1051 // -------------------------------------------------------------------------
1052 // Per-thread data support
1054 #ifdef CYGVAR_KERNEL_THREADS_DATA
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.
1062 Cyg_Thread::cyg_data_index
1063 Cyg_Thread::new_data_index()
1065 Cyg_Scheduler::lock();
1067 Cyg_Thread::cyg_data_index index;
1069 if (0 == thread_data_map)
1073 HAL_LSBIT_INDEX( index, thread_data_map );
1076 thread_data_map &= ~(1<<index);
1078 Cyg_Scheduler::unlock();
1083 void Cyg_Thread::free_data_index( Cyg_Thread::cyg_data_index index )
1085 Cyg_Scheduler::lock();
1087 thread_data_map |= (1<<index);
1089 Cyg_Scheduler::unlock();
1095 // -------------------------------------------------------------------------
1096 // Allocate some memory at the lower end of the stack
1097 // by moving the stack limit pointer.
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 )
1108 void *ret = (void *)stack_limit;
1110 // First lock the scheduler because we're going to be tinkering with
1112 Cyg_Scheduler::lock();
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;
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);
1125 cyg_uint32 sig = (cyg_uint32)this;
1128 i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
1130 p[i] = (sig ^ (i * 0x01010101));
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;
1139 Cyg_Scheduler::unlock();
1145 // =========================================================================
1146 // Cyg_ThreadTimer member functions
1148 // -------------------------------------------------------------------------
1149 // Timer alarm function. Inspect the sleep_reason and if necessary wake
1150 // up the thread with an appropriate wake_reason.
1152 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1155 Cyg_ThreadTimer::alarm(
1160 CYG_REPORT_FUNCTION();
1162 Cyg_ThreadTimer *self = (Cyg_ThreadTimer *)data;
1163 Cyg_Thread *thread = self->thread;
1165 CYG_INSTRUMENT_THREAD(ALARM, 0, 0);
1167 Cyg_Scheduler::lock();
1169 Cyg_Thread::cyg_reason sleep_reason = thread->get_sleep_reason();
1171 switch( sleep_reason ) {
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();
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);
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);
1200 Cyg_Scheduler::unlock();
1201 CYG_REPORT_RETURN();
1206 // =========================================================================
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.
1212 // -------------------------------------------------------------------------
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
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
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
1228 static char idle_thread_stack[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE];
1230 // Loop counter for debugging/housekeeping
1231 cyg_uint32 idle_thread_loops[CYGNUM_KERNEL_CPU_MAX];
1233 // -------------------------------------------------------------------------
1234 // Idle thread code.
1237 idle_thread_main( CYG_ADDRESS data )
1239 CYG_REPORT_FUNCTION();
1243 idle_thread_loops[CYG_KERNEL_CPU_THIS()]++;
1245 HAL_IDLE_THREAD_ACTION(idle_thread_loops[CYG_KERNEL_CPU_THIS()]);
1248 // For testing, it is useful to be able to fake
1249 // clock interrupts in the idle thread.
1251 Cyg_Clock::real_time_clock->tick();
1253 #ifdef CYGIMP_IDLE_THREAD_YIELD
1254 // In single priority and non-preemptive systems,
1255 // the idle thread should yield repeatedly to
1257 Cyg_Thread::yield();
1262 // -------------------------------------------------------------------------
1263 // Idle thread class
1265 class Cyg_IdleThread : public Cyg_Thread
1272 // -------------------------------------------------------------------------
1273 // Instantiate the idle thread
1275 Cyg_IdleThread idle_thread[CYGNUM_KERNEL_CPU_MAX] CYG_INIT_PRIORITY( IDLE_THREAD );
1277 // -------------------------------------------------------------------------
1278 // Idle threads constructor
1280 Cyg_IdleThread::Cyg_IdleThread()
1281 : Cyg_Thread( CYG_THREAD_MIN_PRIORITY,
1285 (CYG_ADDRESS)idle_thread_stack[this-&idle_thread[0]],
1286 CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE)
1288 CYG_REPORT_FUNCTION();
1290 // Call into scheduler to set up this thread as the default
1291 // current thread for its CPU.
1293 Cyg_Scheduler::scheduler.set_idle_thread( this, this-&idle_thread[0] );
1295 CYG_REPORT_RETURN();
1298 // -------------------------------------------------------------------------
1299 // EOF common/thread.cxx