📄 thread.cxx
字号:
else // there is a queued wakeup, do not sleep current->wakeup_count--; // Unlock the scheduler and switch threads Cyg_Scheduler::unlock(); // and deal with anything we must do when we return switch( current->wake_reason ) { case DESTRUCT: case EXIT: current->exit(); break; default: break; } CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Put the thread to sleep for a delay, with wakeup count.// This can only be called by the current thread on itself, hence// it is a static function.#ifdef CYGFUN_KERNEL_THREADS_TIMERvoidCyg_Thread::counted_sleep( cyg_tick_count delay ){ CYG_REPORT_FUNCTION(); Cyg_Thread *current = Cyg_Scheduler::get_current_thread(); CYG_ASSERTCLASS( current, "Bad current thread" ); CYG_INSTRUMENT_THREAD(SLEEP,current,0); // Prevent preemption Cyg_Scheduler::lock(); if ( 0 == current->wakeup_count ) { // Set the timer (once outside any waiting loop.) set_timer( Cyg_Clock::real_time_clock->current_value()+delay, Cyg_Thread::TIMEOUT ); // If the timeout is in the past, the wake reason will have been // set to something other than NONE already. if( current->get_wake_reason() == Cyg_Thread::NONE ) { set_sleep_reason( Cyg_Thread::TIMEOUT ); current->sleep(); // prepare to sleep current->state |= COUNTSLEEP; // Set the state CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1, "Called with non-zero scheduler lock"); Cyg_Scheduler::unlock(); Cyg_Scheduler::lock(); // clear the timer; if it actually fired, no worries. clear_timer(); } } else // there is a queued wakeup, do not sleep current->wakeup_count--; // Unlock the scheduler and switch threads Cyg_Scheduler::unlock(); // and deal with anything we must do when we return switch( current->wake_reason ) { case DESTRUCT: case EXIT: current->exit(); break; default: break; } CYG_REPORT_RETURN();}#endif// -------------------------------------------------------------------------// Awaken the thread from sleep.voidCyg_Thread::counted_wake(){ CYG_REPORT_FUNCTION(); CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread); // Prevent preemption Cyg_Scheduler::lock(); if ( 0 == (state & COUNTSLEEP) ) // already awake, or waiting: wakeup_count++; // not in a counted sleep anyway. else { sleep_reason = NONE; wake_reason = DONE; wake(); // and awaken the thread }#ifdef CYGNUM_KERNEL_MAX_COUNTED_WAKE_COUNT_ASSERT CYG_ASSERT( CYGNUM_KERNEL_MAX_COUNTED_WAKE_COUNT_ASSERT > wakeup_count, "wakeup_count overflow" );#endif // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Cancel wakeups for this thread and return how many were pendingcyg_uint32Cyg_Thread::cancel_counted_wake(){ CYG_REPORT_FUNCTION(); CYG_INSTRUMENT_THREAD(WAKE,this,Cyg_Scheduler::current_thread); // Prevent preemption Cyg_Scheduler::lock(); cyg_uint32 result = wakeup_count; wakeup_count = 0; // Unlock the scheduler Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( result ); return result;}// -------------------------------------------------------------------------// Suspend thread. Increment suspend count and deschedule thread// if still running.voidCyg_Thread::suspend(){ CYG_REPORT_FUNCTION(); CYG_INSTRUMENT_THREAD(SUSPEND,this,Cyg_Scheduler::current_thread); // Prevent preemption Cyg_Scheduler::lock(); suspend_count++; #ifdef CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT CYG_ASSERT( CYGNUM_KERNEL_MAX_SUSPEND_COUNT_ASSERT > suspend_count, "suspend_count overflow" );#endif // If running, remove from run qs if( state == RUNNING ) Cyg_Scheduler::scheduler.rem_thread(this); // Set the state state |= SUSPENDED; // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Resume thread. Decrement suspend count and reschedule if it// is zero.voidCyg_Thread::resume(){ CYG_REPORT_FUNCTION(); CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread); // Prevent preemption Cyg_Scheduler::lock(); // If we are about to zero the count, clear the state bit and // reschedule the thread if possible. if( suspend_count == 1 ) { suspend_count = 0; CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" ); // Set the state state &= ~SUSPENDED; // Return thread to scheduler if runnable if( state == RUNNING ) Cyg_Scheduler::scheduler.add_thread(this); } else if( suspend_count > 0 ) suspend_count--; // else ignore attempt to resume // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Forced Resume thread. Zero suspend count and reschedule...voidCyg_Thread::force_resume(){ CYG_REPORT_FUNCTION(); CYG_INSTRUMENT_THREAD(RESUME,this,Cyg_Scheduler::current_thread); // Prevent preemption Cyg_Scheduler::lock(); // If we are about to zero the count, clear the state bit and // reschedule the thread if possible. if ( 0 < suspend_count ) { suspend_count = 0; CYG_ASSERT( (state & SUSPENDED) != 0, "SUSPENDED bit not set" ); // Set the state state &= ~SUSPENDED; // Return thread to scheduler if runnable if( state == RUNNING ) Cyg_Scheduler::scheduler.add_thread(this); } // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Force thread to wake up from a sleep with a wake_reason of// BREAK. It is the responsibility of the woken thread to detect// the release() and do the right thing.voidCyg_Thread::release(){ CYG_REPORT_FUNCTION(); // Prevent preemption Cyg_Scheduler::lock(); // If the thread is in any of the sleep states, set the // wake reason and wake it up. switch( sleep_reason ) { case NONE: // The thread is not sleeping for any reason, do nothing. // drop through... case DESTRUCT: case BREAK: case EXIT: case DONE: // Do nothing in any of these cases. They are here to // keep the compiler happy. Cyg_Scheduler::unlock(); CYG_REPORT_RETURN(); return; case WAIT: // The thread was waiting for some sync object to do // something. // drop through... case TIMEOUT: // The thread was waiting on a sync object with a timeout. // drop through... case DELAY: // The thread was simply delaying, unless it has been // woken up for some other reason, wake it now. sleep_reason = NONE; wake_reason = BREAK; break; } wake(); // Allow preemption Cyg_Scheduler::unlock(); CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Exit thread. This puts the thread into EXITED state.voidCyg_Thread::exit(){ // The thread should never return from this function. Cyg_Thread *self = Cyg_Thread::self(); Cyg_Scheduler::lock(); // clear the timer; if there was none, no worries. clear_timer(); self->state = EXITED; Cyg_Scheduler::scheduler.rem_thread(self); // Un-nest any scheduler locks we have until we // suspend. for( ;; ) Cyg_Scheduler::unlock();}// -------------------------------------------------------------------------// Kill thread. Force the thread into EXITED state externally, or// make it wake up and call exit().voidCyg_Thread::kill(){ CYG_REPORT_FUNCTION(); // If this is called by the current thread on itself, // just call exit(), which is what he should have done // in the first place. if( this == Cyg_Scheduler::get_current_thread() ) exit(); // Prevent preemption Cyg_Scheduler::lock(); // We are killing someone else. Find out what state he is // in and force him to wakeup and call exit(). force_resume(); // this is necessary for when // he is asleep AND suspended.#ifdef CYGFUN_KERNEL_THREADS_TIMER timer.disable(); // and make sure the timer // does not persist.#endif switch( sleep_reason ) { case NONE: // The thread is not sleeping for any reason, it must be // on a run queue. // We can safely deschedule and set its state. if( state == RUNNING ) Cyg_Scheduler::scheduler.rem_thread(this); state = EXITED; break; case DESTRUCT: case BREAK: case EXIT: case DONE: // Do nothing in any of these cases. They are here to // keep the compiler happy. Cyg_Scheduler::unlock(); CYG_REPORT_RETURN(); return; case WAIT: // The thread was waiting for some sync object to do // something. // drop through... case TIMEOUT: // The thread was waiting on a sync object with a timeout. // drop through... case DELAY: // The thread was simply delaying, unless it has been // woken up for some other reason, wake it now. sleep_reason = NONE; wake_reason = EXIT; break; } wake();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -