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

📄 pthreadlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    {    int taskIdList[1];    if (!pCond || pCond->condValid != TRUE)	return (EINVAL);    INIT_COND(pCond);    /* get number of blocked tasks and give the semaphore for each */    while (semInfo(pCond->condSemId, taskIdList, 1))	{	if (semGive(pCond->condSemId) == ERROR)	    return (EINVAL);                             /* internal error */	}    return (_RETURN_PTHREAD_SUCCESS);    }/********************************************************************************* pthread_cond_wait - wait for a condition variable (POSIX)** This function atomically releases the mutex <pMutex> and waits for the* condition variable <pCond> to be signalled by another thread. The mutex* must be locked by the calling thread when pthread_cond_wait() is called; if* it is not then this function returns an error ('EINVAL').** Before returning to the calling thread, pthread_cond_wait() re-acquires the* mutex.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_condattr_init(),* pthread_condattr_destroy(),* pthread_cond_broadcast(),* pthread_cond_destroy(),* pthread_cond_init(),* pthread_cond_signal(),* pthread_cond_timedwait()*/int pthread_cond_wait    (    pthread_cond_t *pCond,		/* condition variable	*/    pthread_mutex_t *pMutex		/* POSIX mutex		*/    )    {    WIND_TCB *mutexTcb;    int savtype;    if (!pCond || pCond->condValid != TRUE)	return (EINVAL);    INIT_COND(pCond);    if (!pMutex)	return (EINVAL);    /*     * make sure that if anyone else is blocked on this condition variable     * that the same mutex was used to guard it. Also verify that mutex is     * locked and that we are the owner     */    if (((pCond->condMutex != NULL) && (pCond->condMutex != pMutex)) ||	(!(mutexTcb = (WIND_TCB *) _pthreadSemOwnerGet (pMutex->mutexSemId))) ||	(mutexTcb != taskIdCurrent))	{	return (EINVAL);	}    else	pCond->condMutex = pMutex;    pCond->condRefCount++;    pCond->condMutex->mutexCondRefCount++;    if (semGive(pMutex->mutexSemId) == ERROR)	{	return (EINVAL);	}    if (MY_PTHREAD)        MY_PTHREAD->cvcond = pCond;    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);    if (semTake(pCond->condSemId, WAIT_FOREVER) == ERROR)	{	pthread_setcanceltype(savtype, NULL);	return (EINVAL);                                   /* internal error */	}    pthread_setcanceltype(savtype, NULL);    if (MY_PTHREAD)        MY_PTHREAD->cvcond = NULL;    if (semTake(pMutex->mutexSemId, WAIT_FOREVER) == ERROR)	return (EINVAL);    pCond->condMutex->mutexCondRefCount--;    if (--pCond->condRefCount == 0)	pCond->condMutex = NULL;    return (_RETURN_PTHREAD_SUCCESS);    }/********************************************************************************* pthread_cond_timedwait - wait for a condition variable with a timeout (POSIX)** This function atomically releases the mutex <pMutex> and waits for another* thread to signal the condition variable <pCond>. As with pthread_cond_wait(),* the mutex must be locked by the calling thread when pthread_cond_timedwait()* is called.** If the condition variable is signalled before the system time reaches the* time specified by <pAbsTime>, then the mutex is re-acquired and the calling* thread unblocked.** If the system time reaches or exceeds the time specified by <pAbsTime> before* the condition is signalled, then the mutex is re-acquired, the thread* unblocked and ETIMEDOUT returned.** NOTE* The timeout is specified as an absolute value of the system clock in a* <timespec> structure (see clock_gettime() for more information). This is* different from most VxWorks timeouts which are specified in ticks relative* to the current time.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL', 'ETIMEDOUT'** SEE ALSO:* pthread_condattr_init(),* pthread_condattr_destroy(),* pthread_cond_broadcast(),* pthread_cond_destroy(),* pthread_cond_init(),* pthread_cond_signal(),* pthread_cond_wait()*/int pthread_cond_timedwait    (    pthread_cond_t *pCond,		/* condition variable	*/    pthread_mutex_t *pMutex,		/* POSIX mutex		*/    const struct timespec *pAbstime	/* timeout time		*/    )    {    int			nTicks;    struct timespec	tmp;    struct timespec	now;    WIND_TCB *		mutexTcb;    int			savtype;    if (!pCond || pCond->condValid != TRUE)	return (EINVAL);    INIT_COND(pCond);    if (!pMutex || !pAbstime || !TV_VALID(*pAbstime))	{	return (EINVAL);	}    /*     * make sure that if anyone else is blocked on this condition variable     * that the same mutex was used to guard it. Also verify that mutex is     * locked and that we are the owner     */    if (((pCond->condMutex != NULL) && (pCond->condMutex != pMutex)) ||	(!(mutexTcb = (WIND_TCB *) _pthreadSemOwnerGet (pMutex->mutexSemId))) ||	(mutexTcb != taskIdCurrent))	{	return (EINVAL);	}    else	pCond->condMutex = pMutex;    pCond->condMutex->mutexCondRefCount++;    pCond->condRefCount++;    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype);    /*     * convert to number of ticks (relative time) or return if time has     * already passed     */    if (clock_gettime(CLOCK_REALTIME, &now) != 0)        {	pthread_setcanceltype(savtype, NULL);	return (errno);        }    TV_SET(tmp, *pAbstime);    TV_SUB(tmp, now);    if (TV_GT(tmp, *pAbstime))    /* overflow, e.g. too late */	{	/* drop and reacquire mutex as per POSIX */	if (semGive(pMutex->mutexSemId) == ERROR)	    {	    pthread_setcanceltype(savtype, NULL);	    return (EINVAL);        /* internal error */	    }	if (semTake(pMutex->mutexSemId, WAIT_FOREVER) == ERROR)	    {	    pthread_setcanceltype(savtype, NULL);	    return (EINVAL);        /* internal error */	    }	pthread_setcanceltype(savtype, NULL);	return (ETIMEDOUT);	}    TV_CONVERT_TO_TICK(nTicks, tmp);    if (semGive(pMutex->mutexSemId) == ERROR)	{	pthread_setcanceltype(savtype, NULL);	return (EINVAL);	}    if (MY_PTHREAD)        MY_PTHREAD->cvcond = pCond;    if (semTake(pCond->condSemId, nTicks) == ERROR)	{	if (MY_PTHREAD)            MY_PTHREAD->cvcond = NULL;	pthread_setcanceltype(savtype, NULL);	if (semTake(pMutex->mutexSemId, WAIT_FOREVER) == ERROR)	    {	    return (EINVAL);	    }	pCond->condMutex->mutexCondRefCount--;	if (--pCond->condRefCount == 0)	    pCond->condMutex = NULL;	return (ETIMEDOUT);	}    pthread_setcanceltype(savtype, NULL);    if (semTake(pMutex->mutexSemId, WAIT_FOREVER) == ERROR)	{	return (EINVAL);	}    if (MY_PTHREAD)        MY_PTHREAD->cvcond = NULL;    pCond->condMutex->mutexCondRefCount--;    if (--pCond->condRefCount == 0)	pCond->condMutex = NULL;    return (_RETURN_PTHREAD_SUCCESS);    }/* * Section 13.5 - Thread Scheduling *//********************************************************************************* pthread_attr_setscope - set contention scope for thread attributes (POSIX)** For VxWorks PTHREAD_SCOPE_SYSTEM is the only supported contention scope.* Any other value passed to this function will result in 'EINVAL' being* returned.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_attr_getscope(),* pthread_attr_init()*/int pthread_attr_setscope    (    pthread_attr_t *pAttr,		/* thread attributes object	*/    int contentionScope			/* new contention scope		*/    )    {    if (!pAttr || pAttr->threadAttrStatus != PTHREAD_INITIALIZED ||	(contentionScope != PTHREAD_SCOPE_PROCESS &&	contentionScope != PTHREAD_SCOPE_SYSTEM))	{	return (EINVAL);	}#if 0    /*     * Restriction on VxWorks: no multiprocessor, so all threads     * compete for resources, PTHREAD_SCOPE_SYSTEM always in effect     */    pAttr->threadAttrContentionscope = contentionScope;#endif    return (_RETURN_PTHREAD_SUCCESS);    }/********************************************************************************* pthread_attr_getscope - get contention scope from thread attributes (POSIX)** Reads the current contention scope setting from a thread attributes object.* For VxWorks this is always PTHREAD_SCOPE_SYSTEM. If the thread attributes* object is uninitialized then 'EINVAL' will be returned. The contention* scope is returned in the location pointed to by <pContentionScope>.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_attr_init(),* pthread_attr_setscope()*/int pthread_attr_getscope    (    const pthread_attr_t *pAttr,	/* thread attributes object	*/    int *pContentionScope		/* contention scope (out)	*/    )    {    if (!pAttr || pAttr->threadAttrStatus != PTHREAD_INITIALIZED)	return (EINVAL);#if 0  *pContentionScope = pAttr->threadAttrContentionscope;#else  /*   * Restriction on VxWorks: no multiprocessor, so all threads   * compete for resources, PTHREAD_SCOPE_SYSTEM always in effect   */  *pContentionScope = PTHREAD_SCOPE_SYSTEM;#endif  return (_RETURN_PTHREAD_SUCCESS);}/********************************************************************************* pthread_attr_setinheritsched - set inheritsched attribute in thread attribute object (POSIX)** This routine sets the scheduling inheritance to be used when creating a* thread with the thread attributes object specified by <pAttr>.** Possible values are:* .iP PTHREAD_INHERIT_SCHED 4* Inherit scheduling parameters from parent thread.* .iP PTHREAD_EXPLICIT_SCHED* Use explicitly provided scheduling parameters (i.e. those specified in the* thread attributes object).* .LP** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_attr_getinheritsched(),* pthread_attr_init(),* pthread_attr_setschedparam(),* pthread_attr_setschedpolicy()*/int pthread_attr_setinheritsched    (    pthread_attr_t *pAttr,		/* thread attributes object	*/    int inheritsched			/* inheritance mode		*/    )    {    if (!pAttr || pAttr->threadAttrStatus != PTHREAD_INITIALIZED ||	(inheritsched != PTHREAD_INHERIT_SCHED &&	inheritsched != PTHREAD_EXPLICIT_SCHED))	{	return (EINVAL);	}    pAttr->threadAttrInheritsched = inheritsched;    return (_RETURN_PTHREAD_SUCCESS);    }/********************************************************************************* pthread_attr_getinheritsched - get current value if inheritsched attribute in thread attributes object (POSIX)** This routine gets the scheduling inheritance value from the thread* attributes object <pAttr>.** Possible values are:* .iP PTHREAD_INHERIT_SCHED 4* Inherit scheduling parameters from parent thread.* .iP PTHREAD_EXPLICIT_SCHED* Use explicitly provided scheduling parameters (i.e. those specified in the* thread attributes object).* .LP** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_attr_init(),* pthread_attr_getschedparam(),* pthread_attr_getschedpolicy()* pthread_attr_setinheritsched()*/int pthread_attr_getinheritsched    (    const pthread_attr_t *pAttr,	/* thread attributes object	*/    int *pInheritsched			/* inheritance mode (out)	*/    )    {    if (!pAttr || pAttr->threadAttrStatus != PTHREAD_INITIALIZED)	return (EINVAL);    *pInheritsched = pAttr->threadAttrInheritsched;    return (_RETURN_PTHREAD_SUCCESS);    }/********************************************************************************* pthread_attr_setschedpolicy - set schedpolicy attribute in thread attributes object (POSIX)** Select the thread scheduling policy. The default scheduling policy is* to inherit the current system setting. Unlike the POSIX model,* scheduling policies under VxWorks are global. If a scheduling policy is* being set explicitly, the PTHREAD_EXPLICIT_SCHED mode must be set (see* pthread_attr_setinheritsched() for information), and the selected scheduling* policy must match the global scheduling policy in place at* the time; failure to do so will result in pthread_create() failing with* the non-POSIX error 'ENOTTY'.** POSIX defines the following policies:* .iP SCHED_RR 4* Realtime, round-robin scheduling.* .iP SCHED_FIFO* Realtime, first-in first-out scheduling.* .iP SCHED_OTHER

⌨️ 快捷键说明

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