📄 pthread.cxx
字号:
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 + -