uspsema - acquire a semaphore
int uspsema (usema_t *sema);
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
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
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
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).
uscpsema(3P), usctlsema(3P), usinit(3P), usinitsema(3P), usnewsema(3P),
usnewpollsema(3P), usopenpollsema(3P), ustestsema(3P), usvsema(3P),
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
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.
PPPPaaaaggggeeee 2222 [ Back ]