📄 mboxt2.inl
字号:
if( Cyg_Thread::NONE == self->get_wake_reason() ) { self->set_wait_info( (CYG_ADDRWORD)&ritem ); self->sleep(); get_threadq.enqueue( self ); CYG_INSTRUMENT_MBOXT(WAIT, this, count); } CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(), "Called with non-zero scheduler lock"); // Unlock scheduler and allow other threads to run Cyg_Scheduler::unlock(); // clear the timer; if it actually fired, no worries. self->clear_timer(); CYG_ASSERTCLASS( this, "Bad this pointer"); cyg_bool result = true; switch( self->get_wake_reason() ) { case Cyg_Thread::TIMEOUT: result = false; CYG_INSTRUMENT_MBOXT(TIMEOUT, this, count); break; case Cyg_Thread::DESTRUCT: case Cyg_Thread::BREAK: result = false; break; case Cyg_Thread::EXIT: self->exit(); break; default: break; } CYG_REPORT_RETVAL( result ); return result;}#endif // CYGFUN_KERNEL_THREADS_TIMER// -------------------------------------------------------------------------// Try to get an item and return success.template <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt2<T,QUEUE_SIZE>::tryget( T &ritem ){ CYG_REPORT_FUNCTION(); CYG_ASSERTCLASS( this, "Bad this pointer"); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(TRY, this, count); cyg_bool result = ( 0 < count ); // If the mboxt2 is not empty, grab an item and return it. if ( result ) { ritem = itemqueue[ (count--, base++) ]; CYG_ASSERT( 0 <= count, "Count went -ve" ); CYG_ASSERT( size >= base, "Base overflow" ); if ( size <= base ) base = 0;#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT wakeup_putter();#endif } // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( result ); return result; }// -------------------------------------------------------------------------// get next item without removing ittemplate <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt2<T,QUEUE_SIZE>::peek_item( T &ritem ){ CYG_REPORT_FUNCTION(); CYG_ASSERTCLASS( this, "Bad this pointer"); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(TRY, this, count); cyg_bool result = ( 0 < count ); // If the mboxt2 is not empty, grab an item and return it. if ( result ) ritem = itemqueue[ base ]; // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( result ); return result; }// -------------------------------------------------------------------------// Put an item in the queue; wait if full.#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAITtemplate <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt2<T,QUEUE_SIZE>::put( const T item ){ CYG_REPORT_FUNCTION(); Cyg_Thread *self = Cyg_Thread::self(); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(PUT, this, count); CYG_ASSERTCLASS( this, "Bad this pointer"); if ( size == count ) { CYG_ASSERT( get_threadq.empty(), "Threads waiting AND queue full?" ); self->set_wait_info( (CYG_ADDRWORD)&item ); self->set_sleep_reason( Cyg_Thread::WAIT ); self->sleep(); put_threadq.enqueue( self ); CYG_INSTRUMENT_MBOXT(WAIT, this, count); CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(), "Called with non-zero scheduler lock"); // when this returns, our item is in the queue. Cyg_Scheduler::unlock(); // unlock, switch threads CYG_ASSERTCLASS( this, "Bad this pointer"); cyg_bool result = true; switch( self->get_wake_reason() ) { case Cyg_Thread::DESTRUCT: case Cyg_Thread::BREAK: result = false; break; case Cyg_Thread::EXIT: self->exit(); break; default: break; } CYG_REPORT_RETVAL( result ); return result; } if ( !get_threadq.empty() ) { wakeup_winner( item ); Cyg_Scheduler::unlock(); // unlock, maybe switch threads CYG_ASSERTCLASS( this, "Bad this pointer"); CYG_REPORT_RETVAL( true ); return true; } cyg_count32 in = base + (count++); if ( size <= in ) in -= size; CYG_ASSERT( size > in, "in overflow" ); CYG_ASSERT( 0 <= in, "in overflow" ); CYG_ASSERT( size >= count, "count overflow" ); itemqueue[ in ] = item; CYG_ASSERTCLASS( this, "Bad this pointer"); // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( true ); return true;}// -------------------------------------------------------------------------// Put an item in the queue; wait if full, with an absolute timeout;// return success.#ifdef CYGFUN_KERNEL_THREADS_TIMERtemplate <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt2<T,QUEUE_SIZE>::put( const T item, cyg_tick_count abs_timeout ){ CYG_REPORT_FUNCTION(); Cyg_Thread *self = Cyg_Thread::self(); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(PUT, this, count); CYG_ASSERTCLASS( this, "Bad this pointer"); if ( size == count ) { CYG_ASSERT( get_threadq.empty(), "Threads waiting AND queue full?" ); // Set the timer self->set_timer( abs_timeout, Cyg_Thread::TIMEOUT ); // If the timeout is in the past, the wake reason will have been set to // something other than NONE already. If so, skip the wait and go // straight to unlock. if( Cyg_Thread::NONE == self->get_wake_reason() ) { self->set_wait_info( (CYG_ADDRWORD)&item ); self->sleep(); put_threadq.enqueue( self ); CYG_INSTRUMENT_MBOXT(WAIT, this, count); } CYG_ASSERT( 1 == Cyg_Scheduler::get_sched_lock(), "Called with non-zero scheduler lock"); // when this returns, our item is in the queue. Cyg_Scheduler::unlock(); // unlock, switch threads // clear the timer; if it actually fired, no worries. self->clear_timer(); cyg_bool result = true; switch( self->get_wake_reason() ) { case Cyg_Thread::TIMEOUT: result = false; CYG_INSTRUMENT_MBOXT(TIMEOUT, this, count); break; case Cyg_Thread::DESTRUCT: case Cyg_Thread::BREAK: result = false; break; case Cyg_Thread::EXIT: self->exit(); break; default: break; } CYG_ASSERTCLASS( this, "Bad this pointer"); CYG_REPORT_RETVAL( result ); return result; } if ( !get_threadq.empty() ) { wakeup_winner( item ); Cyg_Scheduler::unlock(); // unlock, maybe switch threads CYG_ASSERTCLASS( this, "Bad this pointer"); CYG_REPORT_RETVAL( true ); return true; } cyg_count32 in = base + (count++); if ( size <= in ) in -= size; CYG_ASSERT( size > in, "in overflow" ); CYG_ASSERT( 0 <= in, "in overflow" ); CYG_ASSERT( size >= count, "count overflow" ); itemqueue[ in ] = item; // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_ASSERTCLASS( this, "Bad this pointer"); CYG_REPORT_RETVAL( true ); return true;}#endif // CYGFUN_KERNEL_THREADS_TIMER#endif // CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT// -------------------------------------------------------------------------// Try to put an item in the queue and return success; queue may be full.template <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt2<T,QUEUE_SIZE>::tryput( const T item ){ CYG_REPORT_FUNCTION(); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(PUT, this, count); CYG_ASSERTCLASS( this, "Bad this pointer"); if ( size == count ) { CYG_ASSERT( get_threadq.empty(), "Threads waiting AND queue full?" ); Cyg_Scheduler::unlock(); // unlock, maybe switch threads CYG_REPORT_RETVAL( false ); return false; // the mboxt2 is full } if ( !get_threadq.empty() ) { CYG_ASSERT( 0 == count, "Threads waiting AND queue not empty" ); wakeup_winner( item ); Cyg_Scheduler::unlock(); // unlock, maybe switch threads CYG_REPORT_RETVAL( true ); return true; } cyg_count32 in = base + (count++); if ( size <= in ) in -= size; CYG_ASSERT( size > in, "in overflow" ); CYG_ASSERT( 0 <= in, "in overflow" ); CYG_ASSERT( size >= count, "count overflow" ); itemqueue[ in ] = item; CYG_ASSERTCLASS( this, "Bad this pointer"); // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( true ); return true;}// -------------------------------------------------------------------------#endif // ifndef CYGONCE_KERNEL_MBOXT2_INL// EOF mboxt2.inl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -