📄 pthreadlib.c
字号:
( pthread_mutex_t *pMutex /* POSIX mutex */ ) { if (!pMutex || pMutex->mutexValid != TRUE) return (EINVAL); if (_pthreadSemOwnerGet (pMutex->mutexSemId) || pMutex->mutexCondRefCount) return (EBUSY); INIT_MUTEX(pMutex); pthread_mutexattr_destroy(&(pMutex->mutexAttr)); if (semDelete(pMutex->mutexSemId) == ERROR) return (EINVAL); pMutex->mutexValid = FALSE; return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* deadlock - simulate a deadlocked mutex** Unlike mutex semaphores, POSIX mutexes deadlock if the owner tries to acquire* a mutex more than once. This routine ensures that the calling thread will* come to a grinding halt. This routine will only get called if there is an* application programming error.** NOMANUAL*/LOCAL void deadlock(void) { taskSuspend(0); }/********************************************************************************* pthread_mutex_lock - lock a mutex (POSIX)** This routine locks the mutex specified by <pMutex>. If the mutex is* currently unlocked, it becomes locked, and is said to be owned by the* calling thread. In this case pthread_mutex_lock() returns immediately.** If the mutex is already locked by another thread, pthread_mutex_lock()* blocks the calling thread until the mutex is unlocked by its current owner.** If it is already locked by the calling thread, pthread_mutex_lock will* deadlock on itself and the thread will block indefinitely.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* semLib, semMLib,* pthread_mutex_init(),* pthread_mutex_lock(),* pthread_mutex_trylock(),* pthread_mutex_unlock(),* pthread_mutexattr_init(),* semTake()*/int pthread_mutex_lock ( pthread_mutex_t *pMutex /* POSIX mutex */ ) { WIND_TCB * pTcb = taskIdCurrent; int priority; if (!pMutex || pMutex->mutexValid != TRUE) return (EINVAL); INIT_MUTEX(pMutex); taskPriorityGet((int)pTcb, &priority); if ((pMutex->mutexAttr.mutexAttrProtocol == PTHREAD_PRIO_PROTECT) && (priority < PX_VX_PRIORITY_CONVERT(pMutex->mutexAttr.mutexAttrPrioceiling))) { return (EINVAL); /* would violate priority ceiling */ }#if 0 /* this works on an mv2700, but not a Dy4 SVME/DMV-179 */ /* make sure that we're NOT a cancellation point */ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &savstate);#endif /* * Plain old POSIX mutexes deadlock if the owner of a lock tries to * acquire it again. The Open Group's Unix98 standard as well as POSIX * P1003.1j Draft standard allow different lock types that at this point * would have different behavior - an error checking mutex would return * EDEADLK, and a recursive lock would bump a ref count and return * success. */ if (_pthreadSemOwnerGet (pMutex->mutexSemId) == (int) taskIdCurrent) deadlock(); if (semTake(pMutex->mutexSemId, WAIT_FOREVER) == ERROR) return (EINVAL); /* internal error */#if 0 /* restore cancellation state */ pthread_setcancelstate(savstate, NULL);#endif if (pMutex->mutexAttr.mutexAttrProtocol == PTHREAD_PRIO_PROTECT) { pMutex->mutexSavPriority = priority; taskPrioritySet ((int)pTcb, PX_VX_PRIORITY_CONVERT(pMutex->mutexAttr.mutexAttrPrioceiling)); } return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_mutex_trylock - lock mutex if it is available (POSIX)** This routine locks the mutex specified by <pMutex>. If the mutex is* currently unlocked, it becomes locked and owned by the calling thread. In* this case pthread_mutex_trylock() returns immediately.** If the mutex is already locked by another thread, pthread_mutex_trylock()* returns immediately with the error code 'EBUSY'.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL', 'EBUSY'** SEE ALSO:* semLib, semMLib,* pthread_mutex_init(),* pthread_mutex_lock(),* pthread_mutex_trylock(),* pthread_mutex_unlock(),* pthread_mutexattr_init(),* semTake()*/int pthread_mutex_trylock ( pthread_mutex_t *pMutex /* POSIX mutex */ ) { WIND_TCB *pTcb = taskIdCurrent; int priority; if (!pMutex || pMutex->mutexValid != TRUE) return (EINVAL); INIT_MUTEX(pMutex); taskPriorityGet((int)pTcb, &priority); if ((pMutex->mutexAttr.mutexAttrProtocol == PTHREAD_PRIO_PROTECT) && (priority < PX_VX_PRIORITY_CONVERT(pMutex->mutexAttr.mutexAttrPrioceiling))) { return (EINVAL); /* would violate priority ceiling */ } if (_pthreadSemOwnerGet (pMutex->mutexSemId) == (int) taskIdCurrent) return(EBUSY); if (semTake(pMutex->mutexSemId, NO_WAIT) == ERROR) return (EBUSY); /* acquire failed */ if (pMutex->mutexAttr.mutexAttrProtocol == PTHREAD_PRIO_PROTECT) { pMutex->mutexSavPriority = priority; taskPrioritySet ((int)pTcb, PX_VX_PRIORITY_CONVERT(pMutex->mutexAttr.mutexAttrPrioceiling)); } return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_mutex_unlock - unlock a mutex (POSIX)** This routine unlocks the mutex specified by <pMutex>. If the calling thread* is not the current owner of the mutex, pthread_mutex_unlock() returns with* the error code 'EPERM'.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL', 'EPERM', S_objLib_OBJ_ID_ERROR, S_semLib_NOT_ISR_CALLABLE** SEE ALSO:* semLib, semMLib,* pthread_mutex_init(),* pthread_mutex_lock(),* pthread_mutex_trylock(),* pthread_mutex_unlock(),* pthread_mutexattr_init(),* semGive()*/int pthread_mutex_unlock ( pthread_mutex_t *pMutex ) { WIND_TCB *pTcb = taskIdCurrent; if (!pMutex || pMutex->mutexValid != TRUE) return (EINVAL); INIT_MUTEX(pMutex); if (pMutex->mutexAttr.mutexAttrProtocol == PTHREAD_PRIO_PROTECT) taskPrioritySet((int)pTcb, pMutex->mutexSavPriority); errno = 0; if (semGive(pMutex->mutexSemId) == ERROR) { if (errno == S_semLib_INVALID_OPERATION) return (EPERM); /* not owner */ else return (errno); /* some other error */ } return (_RETURN_PTHREAD_SUCCESS); }/* * Section 11.4 - Condition Variables *//********************************************************************************* pthread_condattr_init - initialize a condition attribute object (POSIX)** This routine initializes the condition attribute object <pAttr> and fills* it with default values for the attributes.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_cond_init(),* pthread_condattr_destroy()*/int pthread_condattr_init ( pthread_condattr_t *pAttr /* condition variable attributes */ ) { if (!pAttr) return (EINVAL); pAttr->condAttrStatus = PTHREAD_INITIALIZED; return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_condattr_destroy - destroy a condition attributes object (POSIX)** This routine destroys the condition attribute object <pAttr>. It must* not be reused until it is reinitialized.** RETURNS: Always returns zero.** ERRNOS: None.** SEE ALSO:* pthread_cond_init(),* pthread_condattr_init()*/int pthread_condattr_destroy ( pthread_condattr_t *pAttr /* condition variable attributes */ ) { pAttr->condAttrStatus = PTHREAD_DESTROYED; return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_cond_init - initialize condition variable (POSIX)** DESCRIPTION** This function initializes a condition variable. A condition variable* is a synchronization device that allows threads to block until some* predicate on shared data is satisfied. The basic operations on conditions* are to signal the condition (when the predicate becomes true), and wait* for the condition, blocking the thread until another thread signals the* condition.** A condition variable must always be associated with a mutex to avoid a* race condition between the wait and signal operations.** If <pAttr> is NULL then the default attributes are used as specified by* POSIX; if <pAttr> is non-NULL then it is assumed to point to a condition* attributes object initialized by pthread_condattr_init(), and those are* the attributes used to create the condition variable.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL', 'EBUSY'** SEE ALSO:* pthread_condattr_init(),* pthread_condattr_destroy(),* pthread_cond_broadcast(),* pthread_cond_destroy(),* pthread_cond_signal(),* pthread_cond_timedwait(),* pthread_cond_wait()*/int pthread_cond_init ( pthread_cond_t *pCond, /* condition variable */ pthread_condattr_t *pAttr /* condition variable attributes */ ) { if (!pCond) return (EINVAL); if (!pthreadLibInited) return (EINVAL); /* check for attempt to reinitialize cond - it's already intialized */ if (pCond->condValid == TRUE) return (EBUSY); /* in VxWorks, there is nothing useful in a pthread_condattr_t */ pCond->condValid = TRUE; pCond->condInitted = FALSE; pCond->condIniting = 0; pCond->condMutex = NULL; pCond->condRefCount = 0; return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_cond_destroy - destroy a condition variable (POSIX)** This routine destroys the condition variable pointed to by <pCond>. No* threads can be waiting on the condition variable when this function is* called. If there are threads waiting on the condition variable, then* pthread_cond_destroy() returns 'EBUSY'.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL', 'EBUSY'** SEE ALSO:* pthread_condattr_init(),* pthread_condattr_destroy(),* pthread_cond_broadcast(),* pthread_cond_init(),* pthread_cond_signal(),* pthread_cond_timedwait(),* pthread_cond_wait()*/int pthread_cond_destroy ( pthread_cond_t *pCond /* condition variable */ ) { if (!pCond || pCond->condValid != TRUE) return (EINVAL); if (pCond->condRefCount != 0) return (EBUSY); /* someone else blocked on *pCond */ INIT_COND(pCond); if (semDelete(pCond->condSemId) == ERROR) return (errno); return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_cond_signal - unblock a thread waiting on a condition (POSIX)** This routine unblocks one thread waiting on the specified condition* variable <pCond>. If no threads are waiting on the condition variable then* this routine does nothing; if more than one thread is waiting, then one will* be released, but it is not specified which one.** 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_timedwait(),* pthread_cond_wait()*/int pthread_cond_signal ( pthread_cond_t *pCond ) { if (!pCond || pCond->condValid != TRUE) return (EINVAL); INIT_COND(pCond); if (semGive(pCond->condSemId) == ERROR) return (EINVAL); /* internal error */ return (_RETURN_PTHREAD_SUCCESS); }/********************************************************************************* pthread_cond_broadcast - unblock all threads waiting on a condition (POSIX)** This function unblocks all threads blocked on the condition variable* <pCond>. Nothing happens if no threads are waiting on the specified condition* variable.** RETURNS: On success zero; on failure a non-zero error code.** ERRNOS: 'EINVAL'** SEE ALSO:* pthread_condattr_init(),* pthread_condattr_destroy(),* pthread_cond_destroy(),* pthread_cond_init(),* pthread_cond_signal(),* pthread_cond_timedwait(),* pthread_cond_wait()*/int pthread_cond_broadcast ( pthread_cond_t *pCond )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -