⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mboxt.inl

📁 实现快速傅立叶变换算法,provides test framwork for FFT testing
💻 INL
📖 第 1 页 / 共 2 页
字号:
        {
        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_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_bool
Cyg_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 it
template <class T, cyg_count32 QUEUE_SIZE>
CYG_MBOXT_INLINE cyg_bool
Cyg_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_WAIT
template <class T, cyg_count32 QUEUE_SIZE>
CYG_MBOXT_INLINE cyg_bool
Cyg_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);

        // Allow other threads to run
        Cyg_Scheduler::reschedule();

        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_TIMER
template <class T, cyg_count32 QUEUE_SIZE>
CYG_MBOXT_INLINE cyg_bool
Cyg_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);

        // Allow other threads to run
        Cyg_Scheduler::reschedule();

        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_bool
Cyg_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 + -