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

📄 mboxt2.inl

📁 实现快速傅立叶变换算法,provides test framwork for FFT testing
💻 INL
📖 第 1 页 / 共 2 页
字号:

    // 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)&ritem );
        self->sleep();
        get_threadq.enqueue( self );

        CYG_INSTRUMENT_MBOXT(WAIT, this, count);
    }

    // Unlock scheduler and allow other threads to run
    Cyg_Scheduler::unlock_reschedule();

    // 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_bool
Cyg_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 it
template <class T, cyg_count32 QUEUE_SIZE>
CYG_MBOXT_INLINE cyg_bool
Cyg_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_WAIT
template <class T, cyg_count32 QUEUE_SIZE>
CYG_MBOXT_INLINE cyg_bool
Cyg_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);
        
        // when this returns, our item is in the queue.
        Cyg_Scheduler::unlock_reschedule();        // 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_TIMER
template <class T, cyg_count32 QUEUE_SIZE>
CYG_MBOXT_INLINE cyg_bool
Cyg_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);
        }

        // when this returns, our item is in the queue.
        Cyg_Scheduler::unlock_reschedule();        // 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_bool
Cyg_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 + -