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

📄 pthread.cxx

📁 开放源码实时操作系统源码.
💻 CXX
📖 第 1 页 / 共 4 页
字号:

    if ( !err ) {
        switch ( joinee->state )
        {
        case PTHREAD_STATE_RUNNING:
            // The thread is still running, we must wait for it.
        while( joinee->state == PTHREAD_STATE_RUNNING ) {
            if ( !joinee->joiner->wait() )
                // check if we were woken because we were being cancelled
                if ( checkforcancel() ) {
                    err = EAGAIN;  // value unimportant, just some error
                    break;
                }
        }

        // check that the thread is still joinable
        if( joinee->state == PTHREAD_STATE_JOIN )
            break;

        // The thread has become unjoinable while we waited, so we
        // fall through to complain.
        
        case PTHREAD_STATE_FREE:
        case PTHREAD_STATE_DETACHED:
        case PTHREAD_STATE_EXITED:
        // None of these may be joined.
            err = EINVAL;
            break;
            
        case PTHREAD_STATE_JOIN:
            break;
        }
    }

    if ( !err ) {
    
        // here, we know that joinee is a thread that has exited and is
        // ready to be joined.

        // Get the retval
        if( thread_return != NULL )
            *thread_return = joinee->retval;
        
        // set state to exited.
        joinee->state = PTHREAD_STATE_EXITED;
        pthreads_exited++;
        pthreads_tobejoined--;
    
        // Dispose of any dead threads
        pthread_reap();
    }

    pthread_mutex.unlock();
    
    // check for cancellation before returning
    pthread_testcancel();

    PTHREAD_RETURN(err);
}

//-----------------------------------------------------------------------------
// Set the detachstate of the thread to "detached". The thread then does not
// need to be joined and its resources will be freed when it exits.

externC int pthread_detach (pthread_t thread)
{
    PTHREAD_ENTRY();
    
    int ret = 0;
    
    pthread_mutex.lock();

    pthread_info *detachee = pthread_info_id( thread );
    
    if( detachee == NULL )
        ret = ESRCH;                    // No such thread
    else if( detachee->state == PTHREAD_STATE_DETACHED )
        ret = EINVAL;                   // Already detached!
    else
    {
        // Set state to detached and kick any joinees to
        // make them return.
        detachee->state = PTHREAD_STATE_DETACHED;
        detachee->joiner->broadcast();
    }
    
    // Dispose of any dead threads
    pthread_reap();
    
    pthread_mutex.unlock();

    PTHREAD_RETURN(ret);
}


//-----------------------------------------------------------------------------
// Thread attribute handling.

//-----------------------------------------------------------------------------
// Initialize attributes object with default attributes:
// detachstate          == PTHREAD_CREATE_JOINABLE
// scope                == PTHREAD_SCOPE_SYSTEM
// inheritsched         == PTHREAD_INHERIT_SCHED
// schedpolicy          == SCHED_OTHER
// schedparam           == unset
// stackaddr            == unset
// stacksize            == 0
// 

externC int pthread_attr_init (pthread_attr_t *attr)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);
    
    attr->detachstate                 = PTHREAD_CREATE_JOINABLE;
    attr->scope                       = PTHREAD_SCOPE_SYSTEM;
    attr->inheritsched                = PTHREAD_INHERIT_SCHED;
    attr->schedpolicy                 = SCHED_OTHER;
    attr->schedparam.sched_priority   = 0;
    attr->stackaddr_valid             = 0;    
    attr->stackaddr                   = NULL;
    attr->stacksize_valid             = 0;    
    attr->stacksize                   = 0;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Destroy thread attributes object

externC int pthread_attr_destroy (pthread_attr_t *attr)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

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

//-----------------------------------------------------------------------------
// Set the detachstate attribute

externC int pthread_attr_setdetachstate (pthread_attr_t *attr,
                                         int detachstate)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( detachstate == PTHREAD_CREATE_JOINABLE ||
        detachstate == PTHREAD_CREATE_DETACHED )
    {
        attr->detachstate = detachstate;
        PTHREAD_RETURN(0);
    }
    
    PTHREAD_RETURN(EINVAL);
}

//-----------------------------------------------------------------------------
// Get the detachstate attribute
externC int pthread_attr_getdetachstate (const pthread_attr_t *attr,
                                         int *detachstate)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( detachstate != NULL )
        *detachstate = attr->detachstate;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Set scheduling contention scope

externC int pthread_attr_setscope (pthread_attr_t *attr, int scope)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( scope == PTHREAD_SCOPE_SYSTEM ||
        scope == PTHREAD_SCOPE_PROCESS )
    {
        if( scope == PTHREAD_SCOPE_PROCESS )
            PTHREAD_RETURN(ENOTSUP);

        attr->scope = scope;

        PTHREAD_RETURN(0);
    }
    
    PTHREAD_RETURN(EINVAL);
}

//-----------------------------------------------------------------------------
// Get scheduling contention scope

externC int pthread_attr_getscope (const pthread_attr_t *attr, int *scope)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( scope != NULL )
        *scope = attr->scope;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Set scheduling inheritance attribute

externC int pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( inherit == PTHREAD_INHERIT_SCHED ||
        inherit == PTHREAD_EXPLICIT_SCHED )
    {
        attr->inheritsched = inherit;

        PTHREAD_RETURN(0);
    }

    PTHREAD_RETURN(EINVAL);
}

//-----------------------------------------------------------------------------
// Get scheduling inheritance attribute

externC int pthread_attr_getinheritsched (const pthread_attr_t *attr,
                                          int *inherit)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( inherit != NULL )
        *inherit = attr->inheritsched;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Set scheduling policy

externC int pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( policy == SCHED_OTHER ||
        policy == SCHED_FIFO ||
        policy == SCHED_RR )
    {
        attr->schedpolicy = policy;

        PTHREAD_RETURN(0);
    }
    
    PTHREAD_RETURN(EINVAL);
}

//-----------------------------------------------------------------------------
// Get scheduling policy

externC int pthread_attr_getschedpolicy (const pthread_attr_t *attr,
                                         int *policy)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( policy != NULL )
        *policy = attr->schedpolicy;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Set scheduling parameters
externC int pthread_attr_setschedparam (pthread_attr_t *attr,
				        const struct sched_param *param)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);
    PTHREAD_CHECK(param);

    attr->schedparam = *param;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Get scheduling parameters

externC int pthread_attr_getschedparam (const pthread_attr_t *attr,
                                        struct sched_param *param)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( param != NULL )
        *param = attr->schedparam;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Set starting address of stack. Whether this is at the start or end of
// the memory block allocated for the stack depends on whether the stack
// grows up or down.

externC int pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    attr->stackaddr       = stackaddr;
    attr->stackaddr_valid = 1;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Get any previously set stack address.

externC int pthread_attr_getstackaddr (const pthread_attr_t *attr,
                                       void **stackaddr)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    if( stackaddr != NULL )
    {
        if( attr->stackaddr_valid )
        {
            *stackaddr = attr->stackaddr;
            PTHREAD_RETURN(0);
        }
        // Stack address not set, return EINVAL.
        else PTHREAD_RETURN(EINVAL);
    }

    PTHREAD_RETURN(0);
}


//-----------------------------------------------------------------------------
// Set minimum creation stack size.

externC int pthread_attr_setstacksize (pthread_attr_t *attr,
                                       size_t stacksize)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    CYG_ASSERT( stacksize >= PTHREAD_STACK_MIN, "Inadequate stack size supplied");
    
    // Reject inadequate stack sizes
    if( stacksize < PTHREAD_STACK_MIN )
        PTHREAD_RETURN(EINVAL);
        
    attr->stacksize_valid = 1;    
    attr->stacksize = stacksize;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Get current minimal stack size.

externC int pthread_attr_getstacksize (const pthread_attr_t *attr,
                                       size_t *stacksize)
{
    PTHREAD_ENTRY();
    
    PTHREAD_CHECK(attr);

    // Reject attempts to get a stack size when one has not been set.
    if( !attr->stacksize_valid )
        PTHREAD_RETURN(EINVAL);
    
    if( stacksize != NULL )
        *stacksize = attr->stacksize;
    
    PTHREAD_RETURN(0);
}

//-----------------------------------------------------------------------------
// Thread scheduling controls

//-----------------------------------------------------------------------------
// Set scheduling policy and parameters for the thread

externC int pthread_setschedparam (pthread_t thread_id,
                                   int policy,
                                   const struct sched_param *param)
{
    PTHREAD_ENTRY();

    if( policy != SCHED_OTHER &&
        policy != SCHED_FIFO &&
        policy != SCHED_RR )
        PTHREAD_RETURN(EINVAL);

    PTHREAD_CHECK(param);

⌨️ 快捷键说明

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