COHERENT manpages

This page displays the COHERENT manpage for semop() [Perform semaphore operations].

List of available manpages
Index


semop() -- General Function (libc)

Perform semaphore operations
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(id, operation, nops)
int id, nops; struct sembuf operation[];

semop() performs semaphore operations.

id identifies the  set of semaphores to be manipulated.   It must have been
returned by a call to semget().

nops gives the number of structures in the array pointed to by operation.

operation points to an array of structures of type sembuf, which the header
file sem.h defines as follows:

struct sembuf {
     unsigned short sem_num;       /* semaphore # */
     short sem_op;                 /* semaphore operation */
     short sem_flg;                /* operation flags */
};

Each sembuf  describes a semaphore operation.   Field sem_op identifies the
operation to perform on the semaphore  in the set identified by id and with
offset  sem_num. sem_op  specifies one  of  three semaphore  operations, as
follows:

1. If sem_op is negative, one of the following occurs:

   A. If semval in the semaphore structure identified by id is greater than
      or  equal to  the  absolute value  of sem_op,  semop() subtracts  the
      absolute value of sem_op from semval.

   B. If  semval is  less than  the absolute value  of sem_op  and (sem_flg
      &  IPC_NOWAIT)   is  true,  semop()  sets   errno  to  EGAIN  and
      immediately returns -1.

   C. If  semval is  less than  the absolute value  of sem_op  and (sem_flg
      &  IPC_NOWAIT)  is false,  then  semop()  increments the  semncnt
      associated with the specified semaphore and suspends execution of the
      calling process until one of the following occurs:

      a. semval equals  or exceeds the absolute value  of sem_op. When this
         occurs, semop()  decrements the  value of semncnt  associated with
         the  specified  semaphore, and  subtracts  the  absolute value  of
         sem_op from semval.

      b. The id for which the calling process is awaiting action is removed
         from the system.

      c. The calling process  receives a signal.  When this occurs, semop()
         decrements  the  field  semncnt  in  the  sem  structure  that  id
         identifies,  and  the calling  process  resumes  execution in  the
         manner defined by the signal.  (See the Lexicon entry for signal()
         for details of what behavior each signal initiates.)

2. If sem_op is positive, semop() adds sem_op to semval.

3. If sem_op is zero, one of the following occurs:

   A. If semval is zero, semop() returns immediately.

   B. If semval does not equal zero and (sem_flg & IPC_NOWAIT) is true,
      semop() sets errno to EGAIN, and immediately returns -1.

   C. If  semval does  not  equal zero  and (sem_flg  & IPC_NOWAIT)  is
      false, semop()  increments the semzcnt associated  with the specified
      semaphore and suspends execution  of the calling process until one of
      the following occurs:

      a. semval becomes  zero.  semop() decrements  the value of  the field
         semzcnt associated with the specified semaphore.

      b. The set of semaphores identified by id is removed from the system.

      c. The calling  process receives  a signal.  semop()  then decrements
         the value of  the semzcnt associated with the specified semaphore,
         and the calling process resumes execution in the manner prescribed
         by the signal.

If  field sem_flg  in  a sembuf  structure contains  value SEM_UNDO  (i.e.,
expression  (sem_flg &  SEM_UNDO) is  true) then  the system  stores an
adjust value  for this semaphore operation for this  semaphore and links it
to the process that has invoked  semop(). The adjust value is the inversion
of this  semaphore operation;  when the  process dies, the  system executes
these adjust  values, to undo  each of these semaphore  operations.  If you
use the  function semctl() to change  the value of a semaphore  or a set of
semaphores, then the system erases all adjust values for those semaphores.

semop() returns -1 and sets errno to the value in parentheses if any of the
following error conditions occurs:

-> id is not a valid semaphore identifier (EINVAL).

-> sem_num is  less than  zero or  greater than or  equal to the  number of
   semaphores in the set associated with id (EFBIG).

-> nops exceeds the system-imposed maximum (E2BIG).

-> Permission is denied to the calling process (EACCES).

-> operation  would   suspend  the  calling  process   but  (sem_flg  &
   IPC_NOWAIT) is true (EAGAIN).

-> operation  would  cause  semval  to  overflow the  system-imposed  limit
   (ERANGE).

-> operation points to an illegal address (EFAULT).

-> The calling processing receives a signal (EINTR).

-> The set of semaphores identified by  id has been removed from the system
   (EDOM).

If all  goes well, semop() sets  the sempid of each  semaphore specified in
the array pointed to by operation  to the process identifier of the calling
process.  It  then returns the value  that semval had had  at the time that
the last operation in the array pointed to by operation was executed.

Files

/usr/include/sys/ipc.h
/usr/include/sys/sem.h

See Also

libc,
semctl(),
semget()

Notes

The COHERENT implementation of semaphores does not permit a process to lock
or unlock  a semaphore unless it  can gain access to  all of the semaphores
that it requests.  This is to  prevent the situation in which two processes
have each  locked semaphores that the other wants,  and each has IPC_NOWAIT
set to false -- thus suspending each other forever.