📄 mboxt.inl
字号:
case Cyg_Thread::DESTRUCT: case Cyg_Thread::BREAK: result = false; break; case Cyg_Thread::EXIT: self->exit(); break; default: break; } } // clear the timer; if it actually fired, no worries. self->clear_timer(); if ( result ) { CYG_INSTRUMENT_MBOXT(GOT, this, count); 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_waiter( put_threadq );#endif } // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_ASSERTCLASS( this, "Bad this pointer"); 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_Mboxt<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 mboxt 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_waiter( put_threadq );#endif } // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); return result; }// -------------------------------------------------------------------------// get next item without removing ittemplate <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt<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 mboxt is not empty, grab an item and return it. if ( result ) ritem = itemqueue[ base ]; // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); 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_Mboxt<T,QUEUE_SIZE>::put( const T item ){ CYG_REPORT_FUNCTION(); cyg_bool result = true; Cyg_Thread *self = Cyg_Thread::self(); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(PUT, this, count); CYG_ASSERTCLASS( this, "Bad this pointer"); while ( result && (size == count) ) { 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"); Cyg_Scheduler::unlock(); // unlock, maybe switch threads Cyg_Scheduler::lock(); CYG_ASSERTCLASS( this, "Bad this pointer"); 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; } } if ( result ) { 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; wakeup_waiter( get_threadq ); } CYG_ASSERTCLASS( this, "Bad this pointer"); // 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, with an absolute timeout;// return success.#ifdef CYGFUN_KERNEL_THREADS_TIMERtemplate <class T, cyg_count32 QUEUE_SIZE>CYG_MBOXT_INLINE cyg_boolCyg_Mboxt<T,QUEUE_SIZE>::put( const T item, cyg_tick_count abs_timeout ){ CYG_REPORT_FUNCTION(); cyg_bool result = true; Cyg_Thread *self = Cyg_Thread::self(); // Prevent preemption Cyg_Scheduler::lock(); CYG_INSTRUMENT_MBOXT(PUT, this, count); CYG_ASSERTCLASS( this, "Bad this pointer"); // Set the timer _once_ outside the loop. 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. Set the result false // to force an immediate return. if( self->get_wake_reason() != Cyg_Thread::NONE ) result = false; // Loop while the mboxt is full, sleeping each time around the loop. // This copes with the possibility of a higher priority thread filling // the empty slot between the wakeup in get()&c and this thread // actually starting. while ( result && (size == count) ) { // must reset the sleep reason every time self->set_sleep_reason( Cyg_Thread::TIMEOUT ); 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"); // Unlock scheduler and allow other threads to run Cyg_Scheduler::unlock(); Cyg_Scheduler::lock(); CYG_ASSERTCLASS( this, "Bad this pointer"); 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; } } // clear the timer; if it actually fired, no worries. self->clear_timer(); if ( result ) { 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; wakeup_waiter( get_threadq ); } CYG_ASSERTCLASS( this, "Bad this pointer"); // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); CYG_REPORT_RETVAL( result ); return result;}#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_Mboxt<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_Scheduler::unlock(); // unlock, maybe switch threads return false; // the mboxt is full } 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"); wakeup_waiter( get_threadq ); // Unlock the scheduler and maybe switch threads Cyg_Scheduler::unlock(); return true;}// -------------------------------------------------------------------------#endif // ifndef CYGONCE_KERNEL_MBOXT_INL// EOF mboxt.inl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -