Mercurial > flash_v2
diff packages/kernel/current/src/common/thread.cxx @ 177:4c750ce71ae3
Merge from eCos master repository on 2001-08-10-19:22:57-BST
| author | jlarmour |
|---|---|
| date | Fri, 10 Aug 2001 19:27:55 +0000 |
| parents | 0d2b193a635f |
| children | f62680ef1804 |
line wrap: on
line diff
--- a/packages/kernel/current/src/common/thread.cxx +++ b/packages/kernel/current/src/common/thread.cxx @@ -77,8 +77,8 @@ Cyg_HardwareThread::thread_entry( Cyg_Th { CYG_REPORT_FUNCTION(); - Cyg_Scheduler::scheduler.need_reschedule = false; // finished rescheduling - Cyg_Scheduler::scheduler.current_thread = thread; // restore current thread pointer + Cyg_Scheduler::scheduler.clear_need_reschedule(); // finished rescheduling + Cyg_Scheduler::scheduler.set_current_thread(thread); // restore current thread pointer CYG_INSTRUMENT_THREAD(ENTER,thread,0); @@ -90,11 +90,11 @@ Cyg_HardwareThread::thread_entry( Cyg_Th // Zero the lock HAL_REORDER_BARRIER (); // Prevent the compiler from moving - Cyg_Scheduler::sched_lock = 0; // the assignment into the code above. + Cyg_Scheduler::zero_sched_lock(); // the assignment into the code above. HAL_REORDER_BARRIER(); // Call entry point in a loop. - + for(;;) { thread->entry_point(thread->entry_data); @@ -190,6 +190,8 @@ Cyg_Thread::Cyg_Thread( { CYG_REPORT_FUNCTION(); + CYG_INSTRUMENT_THREAD(CREATE,this,0); + // Start the thread in suspended state. state = SUSPENDED; suspend_count = 1; @@ -592,7 +594,7 @@ Cyg_Thread::resume() CYG_REPORT_FUNCTION(); CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread); - + // Prevent preemption Cyg_Scheduler::lock(); @@ -619,6 +621,7 @@ Cyg_Thread::resume() // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); + CYG_REPORT_RETURN(); } @@ -736,13 +739,17 @@ Cyg_Thread::exit() // clear the timer; if there was none, no worries. clear_timer(); - self->state = EXITED; - - Cyg_Scheduler::scheduler.rem_thread(self); + // It is possible that we have already been killed by another + // thread, in which case we do not want to try and take ourself + // out of the scheduler again. + if( self->state != EXITED ) + { + self->state = EXITED; - // Un-nest any scheduler locks we have until we - // suspend. - for( ;; ) Cyg_Scheduler::unlock(); + Cyg_Scheduler::scheduler.rem_thread(self); + } + + Cyg_Scheduler::reschedule(); } // ------------------------------------------------------------------------- @@ -910,9 +917,13 @@ Cyg_Thread::set_priority( cyg_priority n // priority is less than that of some other runnable thread, in // practice checking that is as expensive as what the scheduler // will do anyway). + // If it is not the current thread then we need to see whether + // it is more worthy of execution than any current thread and + // rescheduled if necessary. if( this == Cyg_Scheduler::get_current_thread() ) - Cyg_Scheduler::need_reschedule = true; + Cyg_Scheduler::set_need_reschedule(); + else Cyg_Scheduler::set_need_reschedule(this); // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); @@ -1177,10 +1188,10 @@ Cyg_ThreadTimer::alarm( # endif // CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE #endif // CYGNUM_HAL_STACK_SIZE_MINIMUM -static char idle_thread_stack[CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE]; +static char idle_thread_stack[CYGNUM_KERNEL_CPU_MAX][CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE]; // Loop counter for debugging/housekeeping -cyg_uint32 idle_thread_loops = 1; +cyg_uint32 idle_thread_loops[CYGNUM_KERNEL_CPU_MAX]; // ------------------------------------------------------------------------- // Idle thread code. @@ -1192,9 +1203,9 @@ idle_thread_main( CYG_ADDRESS data ) for(;;) { - idle_thread_loops++; + idle_thread_loops[CYG_KERNEL_CPU_THIS()]++; - HAL_IDLE_THREAD_ACTION(idle_thread_loops); + HAL_IDLE_THREAD_ACTION(idle_thread_loops[CYG_KERNEL_CPU_THIS()]); #if 0 // For testing, it is useful to be able to fake @@ -1217,47 +1228,35 @@ idle_thread_main( CYG_ADDRESS data ) class Cyg_IdleThread : public Cyg_Thread { public: - Cyg_IdleThread( - cyg_thread_entry *entry, // entry point function - CYG_ADDRWORD entry_data, // entry data - cyg_ucount32 stack_size = 0, // stack size, 0 = use default - CYG_ADDRESS stack_base = 0 // stack base, NULL = allocate - ); + Cyg_IdleThread(); }; // ------------------------------------------------------------------------- +// Instantiate the idle thread + +Cyg_IdleThread idle_thread[CYGNUM_KERNEL_CPU_MAX] CYG_INIT_PRIORITY( IDLE_THREAD ); + +// ------------------------------------------------------------------------- // Idle threads constructor -Cyg_IdleThread::Cyg_IdleThread( - cyg_thread_entry *entry, // entry point function - CYG_ADDRWORD entry_data, // entry data - cyg_ucount32 stack_size, // stack size, 0 = use default - CYG_ADDRESS stack_base // stack base, NULL = allocate - ) +Cyg_IdleThread::Cyg_IdleThread() : Cyg_Thread( CYG_THREAD_MIN_PRIORITY, - entry, - entry_data, + idle_thread_main, + 0, "Idle Thread", - stack_base, - stack_size) + (CYG_ADDRESS)idle_thread_stack[this-&idle_thread[0]], + CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE) { CYG_REPORT_FUNCTION(); - resume(); + // Call into scheduler to set up this thread as the default + // current thread for its CPU. + + Cyg_Scheduler::scheduler.set_idle_thread( this, this-&idle_thread[0] ); + CYG_REPORT_RETURN(); } // ------------------------------------------------------------------------- -// Instantiate the idle thread - -Cyg_IdleThread idle_thread CYG_INIT_PRIORITY( IDLE_THREAD ) = -Cyg_IdleThread( idle_thread_main, - 0, - CYGNUM_KERNEL_THREADS_IDLE_STACK_SIZE, - CYG_ADDRESS(idle_thread_stack) - ); - - -// ------------------------------------------------------------------------- // EOF common/thread.cxx
