semop() — Semaphore operations

Standards

Standards / Extensions C or C++ Dependencies

XPG4
XPG4.2
Single UNIX Specification, Version 3

both  

Format

#define _XOPEN_SOURCE
#include <sys/sem.h>

int semop(int semid, struct sembuf *sops, size_t nsops);

General description

The semop() function performs semaphore operations atomically on a set of semaphores associated with argument semid. The argument sops is a pointer to an array of sembuf data structures. The argument nsops is the number of sembuf structures in the array.

The structure sembuf is defined as follows:

    short    sem_num    Semaphore number in the range 0 to (nsems - 1)
    short    sem_op     Semaphore operation
    short    sem_flg    Operation flags

Each semaphore in the semaphore set, identified by sem_num, is represented by the following anonymous data structure. This data structure for all semaphores is updated atomically when semop() returns successfully:
unsigned short int semval Semaphore value
pid_t sempid Process ID of last operation
unsigned sort int semcnt Number of processes waiting for semval to become greater than current value
unsigned short int semzcnt Number of processes waiting for semval to become zero

Each semaphore operation specified by sem_op is performed on the corresponding semaphore specified by semid and sem_num.

The variable sem_op specifies one of three semaphore operations:
  1. If sem_op is a negative integer and the calling process has alter permission, one of the following will occur:
    • If semval, see <sys/sem.h>, is greater than or equal to the absolute value of sem_op, the absolute value of sem_op is subtracted from semval.
    • If semval is less than the absolute value of sem_op and (sem_flg & IPC_NOWAIT) is nonzero, semop() will return immediately.
    • If semval is less than the absolute value of sem_op and (sem_flg & IPC_NOWAIT) is zero, semop() will increment the semncnt associated with the specified semaphore and suspend execution of the calling process until one of the following conditions occurs:
      • The value of semval becomes greater than or equal to the absolute value of sem_op. When this occurs, the value of semncnt associated with the specified semaphore is decremented, the absolute value of sem_op is subtracted from semval.
      • 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 -1 is returned.
      • The calling process receives a signal that is to be caught. When this occurs, the value of semncnt associated with the specified semaphore is decremented, and the calling process resumes execution in the manner prescribed in sigaction().
  2. If sem_op is a positive integer and the calling process has alter permission, the value of sem_op is added to semval.
  3. If sem_op is zero and the calling process has read permission, one of the following will occur:
    • If semval is zero, semop() will return immediately.
    • If semval is nonzero and (sem_flg&IPC_NOWAIT) is nonzero, semop() will return immediately.
    • If semval is nonzero and (sem_flg&IPC_NOWAIT) is 0, semop() will increment the semzcnt associated with the specified semaphore and suspend execution of the calling thread until one of the following occurs:
      • The value of semval becomes 0, at which time the value of semzcnt 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 -1 is returned.
      • The calling process receives a signal that is to be caught. When this occurs, the value of semzcnt associated with the specified semaphore is decremented, and the calling process resumes execution in the manner prescribed in sigaction().
      • Upon successful completion, the value of sempid for each semaphore specified in the array pointed to by sops is set equal to the process ID of the calling process.
sem_flg contains the IPC_NOWAIT and SEM_UNDO flags described as follows:
IPC_NOWAIT
Will cause semop() to return EAGAIN rather than place the thread into wait state.
SEM_UNDO
Will result in semadj adjustment values being maintained for each semaphore on a per process basis. If sem_op value is not equal to zero and SEM_UNDO is specified, then sem_op value is subtracted from the current process's semadj value for that semaphore. When the current process is terminated, see exit(), the semadj value(s) will be added to the semval for each semaphore. The semctl() command SETALL may be used to clear all semadj values in all processes. If __IPC_BINSEM was specified on semget for this semaphore, the Sem_UNDO flag will cause an error to be returned.

A semaphore set created with the __IPC_BINSEM flag must behave in the following manner: number of semaphore operations must be 1 and the semop must be +1 with a semval of 0 or the semop must be -1 with a semval of 0 or 1. SEM_UNDO is not allowed on a semop() with this option. The use of this flag will cause improved performance if the PLO instruction is available on the hardware.

Returned value

If successful, semop() returns 0. Also the semid parameter value for each semaphore that is operated upon is set to the process ID of the calling process.

If unsuccessful, semop() returns -1 and sets errno to one of the following values:
Error Code
Description
E2BIG
The value nsops is greater than the system limit.
EACCES
Operation permission is denied to the calling process. Read access is required when sem_op is zero. Write access is required when sem_op is not zero.
EAGAIN
The operation would result in suspension of the calling process but IPC_NOWAIT in sem_flg was specified.
EFBIG
sem_num is less than zero or greater or equal to the number of semaphores in the set specified on in semget() argument nsems.
EIDRM
semid was removed from the system while the invoker was waiting.
EINTR
semop() was interrupted by a signal.
EINVAL
The value of argument semid is not a valid semaphore identifier. For an __IPC_BINSEM semaphore set, the sem_op is other than +1 for a sem_val of 0 or -1 for a sem_val of 0 or 1. Also, for an __IPC_BINSEM semaphore set, the number of semaphore operations is greater than one.
ENOSPC
The limit on the number of individual processes requesting a SEM_UNDO would be exceeded.
ERANGE
An operation would cause semval or semadj to overflow the system limit as defined in <sys/sem.h>.

Related information