pthread.cxx

来自「eCos操作系统源码」· CXX 代码 · 共 1,680 行 · 第 1/4 页

CXX
1,680
字号
        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 objectexternC int pthread_attr_destroy (pthread_attr_t *attr){    PTHREAD_ENTRY();        PTHREAD_CHECK(attr);    // Nothing to do here...        PTHREAD_RETURN(0);}//-----------------------------------------------------------------------------// Set the detachstate attributeexternC 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 attributeexternC 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 scopeexternC 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 scopeexternC 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 attributeexternC 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 attributeexternC 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 policyexternC 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 policyexternC 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 parametersexternC 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 parametersexternC 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 threadexternC 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 + =
减小字号Ctrl + -
显示快捷键?