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

📄 mutex.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 CXX
📖 第 1 页 / 共 2 页
字号:

    mx = mx; // silence compiler warning
#if defined(_POSIX_THREAD_PRIO_PROTECT)
    if ( protocol == Cyg_Mutex::CEILING )
        mx->set_ceiling( use_attr.prioceiling );
#endif
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Destroy mutex.

externC int pthread_mutex_destroy (pthread_mutex_t *mutex)
{
    PTHREAD_ENTRY();

    int err = ENOERR;
    
    PTHREAD_CHECK( mutex );

    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;
    
    if( mx->get_owner() != NULL )
        err = EBUSY;
    else mx->~Cyg_Mutex();
    
    PTHREAD_RETURN(err);
}

//-----------------------------------------------------------------------------
// Lock mutex, waiting for it if necessary.

externC int pthread_mutex_lock (pthread_mutex_t *mutex)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( mutex );

    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;

    if( mx->get_owner() == Cyg_Thread::self() )
        PTHREAD_RETURN(EDEADLK);
    
    // Loop here until we acquire the mutex. Even if we are kicked out
    // of the wait by a signal or release we must retry.
    while( !mx->lock() )
        continue;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Try to lock mutex.

externC int pthread_mutex_trylock (pthread_mutex_t *mutex)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( mutex );
    
    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;

    if( mx->get_owner() == Cyg_Thread::self() )
        PTHREAD_RETURN(EDEADLK);
    
    if( mx->trylock() )
        PTHREAD_RETURN(0);

    PTHREAD_RETURN(EBUSY);
}


//-----------------------------------------------------------------------------
// Unlock mutex.

externC int pthread_mutex_unlock (pthread_mutex_t *mutex)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( mutex );
    
    Cyg_Mutex *mx = (Cyg_Mutex *)mutex;

    mx->unlock();
    
    PTHREAD_RETURN(0);
}


//=============================================================================
// Condition Variables

//-----------------------------------------------------------------------------
// Attribute manipulation functions
// We do not actually support any attributes at present, so these do nothing.

//-----------------------------------------------------------------------------
// Initialize condition variable attributes

externC int pthread_condattr_init (pthread_condattr_t *attr)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    // There are no condition variable attributes at present
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Destroy condition variable attributes

externC int pthread_condattr_destroy (pthread_condattr_t *attr)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    // nothing to do here...
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Condition variable functions

//-----------------------------------------------------------------------------
// Initialize condition variable.

externC int pthread_cond_init (pthread_cond_t *cond,
                               const pthread_condattr_t *attr)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( cond );

    Cyg_Condition_Variable *cv =
        new((cyg_uint8 *)cond) Cyg_Condition_Variable();

    cv = cv;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Destroy condition variable.

externC int pthread_cond_destroy (pthread_cond_t *cond)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( cond );

    ((Cyg_Condition_Variable *)cond)->~Cyg_Condition_Variable();
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Wake up one thread waiting for condition variable

externC int pthread_cond_signal (pthread_cond_t *cond)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( cond );

    ((Cyg_Condition_Variable *)cond)->signal();
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Wake up all threads waiting for condition variable

externC int pthread_cond_broadcast (pthread_cond_t *cond)
{
    PTHREAD_ENTRY();

    PTHREAD_CHECK( cond );

    ((Cyg_Condition_Variable *)cond)->broadcast();
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Block on condition variable until signalled. The mutex is
// assumed to be locked before this call, will be unlocked
// during the wait, and will be re-locked on wakeup.

externC int pthread_cond_wait (pthread_cond_t *cond,
                               pthread_mutex_t *mutex)
{
    PTHREAD_ENTRY();

    // check for cancellation first.
    PTHREAD_TESTCANCEL();

    PTHREAD_CHECK( cond );
    PTHREAD_CHECK( mutex );    

    ((Cyg_Condition_Variable *)cond)->wait( *(Cyg_Mutex *)mutex );
    
    // check if we were woken because we were being cancelled
    PTHREAD_TESTCANCEL();

    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Block on condition variable until signalled, or the timeout expires.

externC int pthread_cond_timedwait (pthread_cond_t *cond,
                                    pthread_mutex_t *mutex,
                                    const struct timespec *abstime)
{
    PTHREAD_ENTRY();

    // check for cancellation first.
    PTHREAD_TESTCANCEL();

    PTHREAD_CHECK( cond );
    PTHREAD_CHECK( mutex );    
    PTHREAD_CHECK( abstime );    

    // Only initialize the converters once or they will consume a huge
    // amount or runtime.

    static struct Cyg_Clock::converter ns_converter;
    static struct Cyg_Clock::converter sec_converter;
    static volatile cyg_atomic conv_init;
    if (!conv_init)
    {

        // Try to avoid unnecessarily locking the scheduler when we are not
        // initializing the converters.  Check the conv_init flag again to
        // avoid race conditions.

        struct Cyg_Clock::converter temp_ns_converter, temp_sec_converter;
    
        Cyg_Clock::real_time_clock
            ->get_other_to_clock_converter( 1, &temp_ns_converter );
        Cyg_Clock::real_time_clock
            ->get_other_to_clock_converter( 1000000000, &temp_sec_converter );

        Cyg_Scheduler::lock();
        if (!conv_init)
        {
            ns_converter = temp_ns_converter;
            sec_converter = temp_sec_converter;
            conv_init=1;
        }
        Cyg_Scheduler::unlock();
    }

    cyg_tick_count ticks;
    ticks = Cyg_Clock::convert( abstime->tv_sec, &sec_converter );
    ticks += Cyg_Clock::convert( abstime->tv_nsec, &ns_converter );
    
    ((Cyg_Condition_Variable *)cond)->wait( *(Cyg_Mutex *)mutex, ticks );
    
    // check if we were woken because we were being cancelled
    PTHREAD_TESTCANCEL();

    if ( Cyg_Thread::self()->get_wake_reason() == Cyg_Thread::TIMEOUT )
        PTHREAD_RETURN(ETIMEDOUT);
    else
        PTHREAD_RETURN(0);
}

// -------------------------------------------------------------------------
// EOF mutex.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -