NAME
semop(), semtimedop() — semaphore operations
SYNOPSIS
#include <sys/sem.h>
#include <sys/time.h>
int semop(
int semid,
struct sembuf *sops,
size_t nsops
);
int semtimedop(
int semid,
struct sembuf *sops,
size_t nsops,
const struct timespec *timeout
);
DESCRIPTION
semop()
is used to atomically perform an array of semaphore operations
on the set of semaphores associated with the semaphore identifier
specified by
semid.
sops
is a pointer to the array of semaphore-operation structures.
nsops
is the number of such structures in the array.
The contents of each structure includes the following members:
ushort sem_num; /* semaphore number */
short sem_op /* semaphore operation */
short sem_flg; /* operation flags */
Each semaphore operation specified by
sem_op
is performed on the corresponding semaphore specified by
semid
and
sem_num.
Semaphore array operations are atomic
in that none of the semaphore operations are performed
until blocking conditions on all of the semaphores
in the array have been removed.
sem_op
specifies one of three semaphore operations as follows:
If
sem_op
is a negative integer, one of the following occurs:
If semaphore value
(see
semaphore identifier
in
glossary(9))
is greater than or equal to the absolute value of
sem_op,
the absolute value of
sem_op
is subtracted from
semaphore value.
Also, if
(sem_flg &
SEM_UNDO)
is "true", the absolute value of
sem_op
is added to the calling process's
semadj
value (see
glossary(9)
and
exit(2))
for the specified semaphore.
If
semaphore value
is less than the absolute value of
sem_op
and
(sem_flg &
IPC_NOWAIT)
is "true",
semop()
returns immediately.
If
semaphore value
is less than the absolute value of
sem_op
and
(sem_flg &
IPC_NOWAIT)
is ``false'',
semop()
increments the
internal semaphore waiter count
associated with the
specified semaphore and suspend execution of the calling process
until one of the following conditions occur:
Semaphore value
becomes greater than or equal to the absolute value of
sem_op.
When this occurs, the value of
internal semaphore waiter count
associated with the specified semaphore is decremented,
the absolute value of
sem_op
is subtracted from
semaphore value
and, if
(sem_flg &
SEM_UNDO)
is "true", the absolute value of
sem_op
is added to the calling process's
semadj
value for the specified semaphore.
The
semid
for which the calling process is awaiting action
is removed from the system (see
semctl(2)).
When this occurs,
errno
is set equal to
EIDRM,
and a value of -1 is returned.
The calling process receives a signal that is to be caught.
When this occurs, the value of
internal semaphore waiter count
associated with the specified semaphore is decremented,
and the calling process resumes execution in the manner prescribed in
signal(5).
If
sem_op
is a positive integer, the value of
sem_op
is added to
semaphore value
and, if
(sem_flg &
SEM_UNDO)
is "true", the value of
sem_op
is subtracted from the calling process's
semadj
value
for the specified semaphore.
If
sem_op
is zero,
one of the following occurs:
If
semaphore value
is zero,
semop()
proceeds to the next semaphore operation specified by
sops ,
or returns immediately if this is the last operation.
If
semaphore value
is not equal to zero and
(sem_flg &
IPC_NOWAIT)
is "true",
semop()
returns immediately.
If
semaphore value
is not equal to zero and
(sem_flg &
IPC_NOWAIT)
is ``false'',
semop()
increments the
internal zero waiter count
associated with the specified
semaphore and suspends execution of the calling process until
one of the following occurs:
Semaphore value
becomes zero, at which time the value of
internal zero waiter count
associated with the specified semaphore is decremented.
The
semid
for which the calling process is awaiting action
is removed from the system.
When this occurs,
errno
is set equal to
EIDRM,
and a value of -1 is returned.
The calling process receives a signal that is to be caught.
When this occurs, the value of
internal zero waiter count
associated with the specified semaphore is decremented,
and the calling process resumes execution in the manner prescribed in
signal(5).
semtimedop()
is identical to
semop()
except that an additional constraint is provided by the
timeout
parameter.
If
semtimedop()
must suspend the calling process
longer than the time indicated by
timeout,
or if the
timeout
expires while the calling process is suspended in
semtimedop(),
the
call returns an error.
If the structure pointed to by the
timeout
parameter is zero-valued,
semtimedop()
returns with an error immediately
if it would otherwise have to suspend
the calling program.
If the
timeout
parameter is the
NULL
pointer,
semtimedop()
behaves exactly like
semop().
EXAMPLES
The following call to
semop()
atomically performs
a "P" or "get" operation on the second semaphore in the semaphore
set and a "V" or "release" operation on the third semaphore in
the set. This example assumes the process has a valid
semid
which represents a set of 4 semaphores as shown on the
semget(2)
manual page. It also assumes that the
semaphore values
of the semaphores
in the set have been initialized as shown in the
semctl(2)
manual entry.
struct sembuf sops[4];
sops[0].sem_num = 1;
sops[0].sem_op = -1; /* P (get) */
sops[0].sem_flg = 0;
sops[1].sem_num = 2;
sops[1].sem_op = 1; /* V (release) */
sops[1].sem_flg = 0;
semop (mysemid, sops, 2);
RETURN VALUE
If
semop()
or
semtimedop()
returns due to the receipt of a signal,
a value of -1 is returned to the calling process and
errno
is set to
EINTR.
If it returns due to the removal of a
semid
from the system, a value of -1 is returned and
errno
is set to
EIDRM.
Upon successful completion, a non-negative value is returned.
Otherwise, a value of -1 is returned and
errno
is set to indicate the error.
ERRORS
semop()
fails if one or more of the following is true
for any of the semaphore operations specified by
sops:
- EINVAL
semid
is not a valid semaphore identifier.
- EFBIG
sem_num
is less than zero or greater than or equal to the number of semaphores
in the set associated with
semid.
- E2BIG
nsops
is greater than the system-imposed maximum.
- EACCES
Operation permission is denied to the calling process (see
glossary(9)).
- EAGAIN
The operation would result in suspension of the calling process but
(sem_flg &
IPC_NOWAIT)
is "true".
- ENOSPC
The limit on the number of individual processes requesting an
SEM_UNDO
would be exceeded.
- EINVAL
The number of individual semaphores for which the calling process
requests a
SEM_UNDO
would exceed the limit.
- ERANGE
An operation would cause a
semaphore value
to overflow the system-imposed limit.
- ERANGE
An operation would cause a
semadj
value to overflow the
system-imposed limit.
- EFAULT
sops
points to an illegal address.
The reliable detection of this error will be implementation dependent.
semtimedop()
fails if one or more of the following is true:
- EFAULT
The
timeout
argument points to an illegal address.
- EINVAL
The
timeout
argument has one or more invalid fields.
For example,
tv_sec
or
tv_nsec
is less than 0
or
tv_nsec
is greater than or equal to one billion.
- EAGAIN
The timeout expired before the semaphore operations could be completed.
Upon successful completion, each semaphore specified in the array
pointed to
sops
will be updated to record the current time as the last operation time
and the process ID of the calling process as the last
to have modified that semaphore.
STANDARDS CONFORMANCE
semop(): SVID2, SVID3, XPG2, XPG3, XPG4