📄 sempxlib.c
字号:
errno = EINVAL; return ((sem_t *) ERROR); } if ((pSemDesc = (sem_t *) objAllocExtra (semPxClassId, strlen (name) + 1, &pPool)) == NULL) { symTblUnlock (posixNameTbl); /* UNLOCK NAME TABLE */ errno = ENOSPC; return ((sem_t *) ERROR); } strcpy ((char *) pPool, name); /* initialize name */ /* create a semaphore & initialize semaphore structure */ if ((pSemDesc->semId = semCCreate (SEM_Q_PRIORITY, value)) == NULL) { symTblUnlock (posixNameTbl); /* UNLOCK NAME TABLE */ objFree (semPxClassId, (char *) pSemDesc); errno = ENOSPC; return ((sem_t *) ERROR); } objCoreInit (&pSemDesc->objCore, semPxClassId); /* validate file object */ pSemDesc->refCnt = 1; /* first opening */ pSemDesc->sem_name = pPool; /* initialize object name */ /* add name to name table */ if ((symAdd (posixNameTbl, (char *) name, (char *) pSemDesc, 0, 0)) == ERROR) { symTblUnlock (posixNameTbl); /* UNLOCK NAME TABLE */ semDelete (pSemDesc->semId); objFree (semPxClassId, (char *) pSemDesc); errno = EINVAL; return ((sem_t *) ERROR); } symTblUnlock (posixNameTbl); /* UNLOCK NAME TABLE */ return (pSemDesc); }/******************************************************************************** sem_close - close a named semaphore (POSIX)** This routine is called to indicate that the calling task is finished with* the specified named semaphore, <sem>. Do not call this routine* with an unnamed semaphore (i.e., one created by sem_init()); the* effects are undefined. The sem_close() call deallocates any system* resources allocated by the system for use by this task for this semaphore.** If the semaphore has not been removed with a call to sem_unlink(),* then sem_close() has no effect on the state of the semaphore.* However, if the semaphore has been unlinked, the semaphore vanishes* when the last task closes it.** WARNING* Take care to avoid risking the deletion of a semaphore that another* task has already locked. Applications should only close semaphores* that the closing task has opened.** RETURNS: 0 (OK), or -1 (ERROR) if unsuccessful.** ERRNO:* EINVAL* - invalid semaphore descriptor.** SEE ALSO: sem_unlink(), sem_open(), sem_init()**/int sem_close ( sem_t * sem /* semaphore descriptor */ ) { taskLock (); /* TASK LOCK */ /* validate semaphore */ if (OBJ_VERIFY (sem, semPxClassId) != 0) { taskUnlock (); /* TASK UNLOCK */ errno = EINVAL; return (ERROR); /* invalid object */ } /* semaphore already closed */ if (sem->refCnt != 0) { sem->refCnt--; } /* No effect unless the name has been unlinked from name table */ if ((sem->sem_name == NULL) && (sem->refCnt == 0)) { /* release semaphore descriptor */ objCoreTerminate (&sem->objCore); /* terminate object */ taskUnlock (); /* TASK UNLOCK */ semDelete (sem->semId); objFree (semPxClassId, (char *) sem); } else { taskUnlock (); /* TASK UNLOCK */ } return (OK); }/********************************************************************************* sem_unlink - remove a named semaphore (POSIX)** This routine removes the string <name> from the semaphore name* table, and marks the corresponding semaphore for destruction. An* unlinked semaphore is destroyed when the last task closes it with* sem_close(). After a particular name is removed from the table,* calls to sem_open() using the same name cannot connect to the same* semaphore, even if other tasks are still using it. Instead, such* calls refer to a new semaphore with the same name.** RETURNS: 0 (OK), or -1 (ERROR) if unsuccessful.** ERRNO:* ENAMETOOLONG* - semaphore name too long.* ENOENT* - named semaphore does not exist.** SEE ALSO: sem_open(), sem_close()** INTERNAL:* This routine should have no immediate effect if the semaphore is* currently referenced by other tasks.**/int sem_unlink ( const char * name /* semaphore name */ ) { sem_t * pSemDesc = NULL; SYM_TYPE dummy; /* dummy var for calling symFindByName */#if _POSIX_NO_TRUNC if (strlen (name) > NAME_MAX) /* check name length */ { errno = ENAMETOOLONG; return (ERROR); }#endif symTblLock (posixNameTbl); /* LOCK NAME TABLE */ /* find name in the name table */ if (symFindByName (posixNameTbl, (char *)name, (char **) &pSemDesc, &dummy) == ERROR) { symTblUnlock (posixNameTbl); /* UNLOCK NAME TABLE */ errno = ENOENT; /* name not found */ return (ERROR); } /* remove name from table*/ symRemove (posixNameTbl, (char *) name, 0); symTblUnlock (posixNameTbl); /* UNLOCK NAME TABLE */ /* The following taskLock is used to insure that sem_close cannot * destroy pSemDesc between unlinking the semaphore name and * going on to invalidate the semaphore descriptor. */ taskLock (); /* TASK LOCK */ /* release semaphore descriptor */ if (OBJ_VERIFY (pSemDesc, semPxClassId) != 0) { taskUnlock (); /* TASK UNLOCK */ errno = ENOENT; return (ERROR); /* invalid object */ } /* initialize name string */ pSemDesc->sem_name = NULL; if (pSemDesc->refCnt == 0) { /* invalidate semaphore descriptor */ objCoreTerminate (&pSemDesc->objCore); taskUnlock (); /* TASK UNLOCK */ semDelete (pSemDesc->semId); objFree (semPxClassId, (char *) pSemDesc); } else { taskUnlock (); /* TASK UNLOCK */ } return (OK); }/********************************************************************************* sem_wait - lock (take) a semaphore, blocking if not available (POSIX)** This routine locks the semaphore referenced by <sem> by performing the* semaphore lock operation on that semaphore. If the semaphore value is* currently zero, the calling task will not return from the call* to sem_wait() until it either locks the semaphore or the call is* interrupted by a signal. ** On return, the state of the semaphore is locked and will remain locked* until sem_post() is executed and returns successfully.** Deadlock detection is not implemented.** Note that the POSIX term \f2lock\f1 corresponds to the term \f2take\f1 used* in other VxWorks documentation regarding semaphores.** RETURNS: 0 (OK), or -1 (ERROR) if unsuccessful.** ERRNO:* EINVAL* - invalid semaphore descriptor, or semaphore destroyed while task waiting.* * SEE ALSO: sem_trywait(), sem_post()**/int sem_wait ( sem_t * sem /* semaphore descriptor */ ) { int savtype; /* validate the semaphore */ if (OBJ_VERIFY (sem, semPxClassId) != OK) { errno = EINVAL; return (ERROR); /* invalid object */ } /* Link to pthreads support code */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &savtype); } /* lock the semaphore */ if (semTake (sem->semId, WAIT_FOREVER) == ERROR) { /* Link to pthreads support code */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } errno = EINVAL; return (ERROR); } /* Link to pthreads support code */ if (_func_pthread_setcanceltype != NULL) { _func_pthread_setcanceltype(savtype, NULL); } return (OK); }/********************************************************************************* sem_trywait - lock (take) a semaphore, returning error if unavailable (POSIX)** This routine locks the semaphore referenced by <sem> only if the * semaphore is currently not locked; that is, if the semaphore value is* currently positive. Otherwise, it does not lock the semaphore.* In either case, this call returns immediately without blocking.** Upon return, the state of the semaphore is always locked (either * as a result of this call or by a previous sem_wait() or sem_trywait()).* The semaphore will remain locked until sem_post() is executed and returns* successfully.** Deadlock detection is not implemented.** Note that the POSIX term \f2lock\f1 corresponds to the term \f2take\f1 used* in other VxWorks semaphore documentation.** RETURNS: 0 (OK), or -1 (ERROR) if unsuccessful.** ERRNO:* EAGAIN* - semaphore is already locked.* EINVAL* - invalid semaphore descriptor.* * SEE ALSO: sem_wait(), sem_post()**/int sem_trywait ( sem_t * sem /* semaphore descriptor */ ) { /* validate the semaphore */ if (OBJ_VERIFY (sem, semPxClassId) != OK) { errno = EINVAL; return (ERROR); /* invalid object */ } /* lock the semaphore */ if (semTake (sem->semId, NO_WAIT) == ERROR) { errno = EAGAIN; return (ERROR); } return (OK); }/********************************************************************************* sem_post - unlock (give) a semaphore (POSIX)** This routine unlocks the semaphore referenced by <sem> by performing* the semaphore unlock operation on that semaphore.** If the semaphore value resulting from the operation is positive, then no* tasks were blocked waiting for the semaphore to become unlocked;* the semaphore value is simply incremented.** If the value of the semaphore resulting from this semaphore is zero, then* one of the tasks blocked waiting for the semaphore will* return successfully from its call to sem_wait(). ** NOTE* The _POSIX_PRIORITY_SCHEDULING functionality is not yet supported.** Note that the POSIX terms \f2unlock\f1 and \f2post\f1 correspond to* the term \f2give\f1 used in other VxWorks semaphore documentation.** RETURNS: 0 (OK), or -1 (ERROR) if unsuccessful.** ERRNO:* EINVAL* - invalid semaphore descriptor.** SEE ALSO: sem_wait(), sem_trywait()**/int sem_post ( sem_t * sem /* semaphore descriptor */ ) { /* validate the semaphore */ if (OBJ_VERIFY (sem, semPxClassId) != OK) { errno = EINVAL; return (ERROR); /* invalid object */ } /* unlock the semaphore */ if (semGive (sem->semId) == ERROR) { errno = EINVAL; return (ERROR); } return (OK); }/********************************************************************************* sem_getvalue - get the value of a semaphore (POSIX)** This routine updates the location referenced by the <sval> argument* to have the value of the semaphore referenced by <sem> without affecting* the state of the semaphore. The updated value represents an actual semaphore* value that occurred at some unspecified time during the call, but may* not be the actual value of the semaphore when it is returned to the calling * task.** If <sem> is locked, the value returned by sem_getvalue() will either be * zero or a negative number whose absolute value represents the number * of tasks waiting for the semaphore at some unspecified time during the call.** RETURNS: 0 (OK), or -1 (ERROR) if unsuccessful.** ERRNO:* EINVAL* - invalid semaphore descriptor.** SEE ALSO: sem_post(), sem_trywait(), sem_trywait()**/int sem_getvalue ( sem_t * sem, /* semaphore descriptor */ int * sval /* buffer by which the value is returned */ ) { int taskIdList [MAX_TASKS]; int count; SEM_ID temp; /* validate the semaphore */ if (OBJ_VERIFY (sem, semPxClassId) != OK) { errno = EINVAL; return (ERROR); /* invalid object */ } /* determine semaphore count */ temp = sem->semId; count = temp->semCount; if (count == 0) { /* number of tasks waiting */ *sval = -semInfo (sem->semId, &taskIdList[0], MAX_TASKS); return (OK); } *sval = count; return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -