USPSEMA(3P) USPSEMA(3P) NAME uspsema - acquire a semaphore C SYNOPSIS #include <ulocks.h> int uspsema (usema_t *sema); DESCRIPTION uspsema decrements the count of the previously allocated semaphore specified by sema. If the count is then negative, the semaphore will logically block the calling process until the count is incremented due to a usvsema(3P) call made by another process. The count can be interpreted in the following way: if it is greater than zero, there are 'count' resources available, namely 'count' processes can call uspsema and not block; if the count is negative then the absolute value of count is the number of waiting processes. ustestsema(3P) can be used to obtain the semaphore count. uspsema can operate on either polling (those allocated via usnewpollsema(3P)) or non-polling (those allocated via usnewsema(3P)) semaphores. The semantics of uspsema are different for the two types of semaphores. For non-polling semaphores, the caller is actually suspended if the semaphore is not available. During suspension signals may be received and processed. The caller must not longjmp out of a signal handler and bypass the semaphore operation as this will result in corruption of the internal data structures of the semaphore. It the user does this, the semaphore must be re-initialized via usinitsema(3P). uspsema uses the usema(7M) device to perform the actual suspending of the caller if necessary. Processes are unblocked in FIFO order. If the current owner of the semaphore abnormally exits while still holding one or more semaphores, no corrective action is taken. This means that the only way a process that is blocked waiting for a semaphore to recover is to take a signal, longjmp out of the handler and re-initialize the semaphore (see FUTURE DIRECTIONS). With either type of semaphore, the semaphore can be made recursive by using the CS_RECURSIVEON option to usctlsema(3P). Recursive semaphores permit the current owner to acquire the semaphore multiple times. A matching number of usvsema(3P) calls will release the semaphore. Recursive semaphores only work with semaphores that have been initialized to 1 (i.e. mutual exclusion semaphores). For polling semaphores, the caller is never actually suspended - either 1 or 0 is returned based on whether the semaphore was available. If the semaphore was not available, the process is placed on the queue of processes waiting for the semaphore and the caller must perform either a poll(2) or select(2) on the file descriptor returned by usopenpollsema(3P) to determine when the semaphore becomes available. The POLLIN event should be used with poll(2). The semaphore file descriptor should be passed in as a read descriptor for select(2). The caller must not call uspsema again until having acquired the semaphore by receiving a ready status from select or poll. Use uscpsema(3P) to acquire a semaphore if its available but not be queued if it isn't. Note that only in the transition from unavailable to available will the file descriptor of a pollable semaphore trip a poll(2) or select(2) call. In other words, poll(2) or select(2) will block if you have already successfully acquired the semaphore with uspsema. In order to use a semaphore, the caller must have joined the shared arena out of which the semaphore is allocated (via usinit(3P)), and have a file descriptor to a usema device to suspend on. As a convenience, uspsema will automatically do this for members of a share group, or for related (via fork(2)) processes. This automatic facility can generate the same errors as usinit(3P), and usopenpollsema(3P). These errors will be passed back to the caller. If tracing is enabled (see usinit(3P)) then any errors will cause a message to be printed to stderr. To avoid these errors and therefore not need to check for errors on every uspsema call, have each process call usinit(3P) and each user of a pollable semaphore call usopenpollsema(3P). The following errors can occur due to misuse of a semaphore: [EBADF] The underlying file descriptor for the semaphore was closed or re-used by the application. [EBADF] uspsema was called on a polling semaphore which was not available and no one had ever done a usopenpollsema(3P)). [ERANGE] The semaphore queue overflowed. This is caused when using a polling semaphore and the caller has 'double-tripped', i.e. calls uspsema more than once without properly having received the semaphore via poll(2) or select(2). This can also occur if the number of users of a semaphore exceeds the number that the arena was originally configured for. This will never happen if ALL users register with the arena via usinit(3P). SEE ALSO uscpsema(3P), usctlsema(3P), usinit(3P), usinitsema(3P), usnewsema(3P), usnewpollsema(3P), usopenpollsema(3P), ustestsema(3P), usvsema(3P), usema(7M). DIAGNOSTICS Upon successful completion the semaphore has been acquired and a value of 1 is returned. For polling semaphores, 0 is returned if the semaphore is unavailable. On error, -1 is returned and errno is set to indicate the error. FUTURE DIRECTIONS To facilitate error handling, uspsema will return distinctive affirmative results based on whether the semaphore was acquired normally or was acquired due to the owner having abnormally terminated. Page 2