1SEMOP(2)                   Linux Programmer's Manual                  SEMOP(2)
2
3
4

NAME

6       semop, semtimedop - semaphore operations
7

SYNOPSIS

9       #include <sys/types.h>
10       #include <sys/ipc.h>
11       #include <sys/sem.h>
12
13       int semop(int semid, struct sembuf *sops, unsigned nsops);
14
15       int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
16                      struct timespec *timeout);
17
18   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
19
20       semtimedop(): _GNU_SOURCE
21

DESCRIPTION

23       Each semaphore in a semaphore set has the following associated values:
24
25           unsigned short  semval;   /* semaphore value */
26           unsigned short  semzcnt;  /* # waiting for zero */
27           unsigned short  semncnt;  /* # waiting for increase */
28           pid_t           sempid;   /* process that did last op */
29
30       semop() performs operations on selected semaphores in the set indicated
31       by semid.  Each of the nsops elements in the array pointed to  by  sops
32       specifies an operation to be performed on a single semaphore.  The ele‐
33       ments of this structure are of type struct sembuf, containing the  fol‐
34       lowing members:
35
36           unsigned short sem_num;  /* semaphore number */
37           short          sem_op;   /* semaphore operation */
38           short          sem_flg;  /* operation flags */
39
40       Flags  recognized in sem_flg are IPC_NOWAIT and SEM_UNDO.  If an opera‐
41       tion specifies SEM_UNDO, it  will  be  automatically  undone  when  the
42       process terminates.
43
44       The  set  of  operations contained in sops is performed in array order,
45       and atomically, that is, the operations are performed either as a  com‐
46       plete  unit, or not at all.  The behavior of the system call if not all
47       operations can be performed immediately depends on the presence of  the
48       IPC_NOWAIT flag in the individual sem_flg fields, as noted below.
49
50       Each  operation  is  performed on the sem_num-th semaphore of the sema‐
51       phore set, where the first semaphore of the set is numbered  0.   There
52       are three types of operation, distinguished by the value of sem_op.
53
54       If  sem_op  is a positive integer, the operation adds this value to the
55       semaphore value (semval).  Furthermore, if SEM_UNDO  is  specified  for
56       this  operation, the system updates the process undo count (semadj) for
57       this semaphore.  This operation can always proceed — it never forces  a
58       process to wait.  The calling process must have alter permission on the
59       semaphore set.
60
61       If sem_op is zero, the process must have read permission on  the  sema‐
62       phore set.  This is a "wait-for-zero" operation: if semval is zero, the
63       operation can immediately proceed.  Otherwise, if IPC_NOWAIT is  speci‐
64       fied  in  sem_flg,  semop() fails with errno set to EAGAIN (and none of
65       the operations in sops is performed).  Otherwise semzcnt (the count  of
66       processes  waiting until this semaphore's value becomes zero) is incre‐
67       mented by one and the process sleeps until one of the following occurs:
68
69       ·  semval becomes 0, at which time the value of semzcnt is decremented.
70
71       ·  The semaphore set is removed:  semop()  fails,  with  errno  set  to
72          EIDRM.
73
74       ·  The calling process catches a signal: the value of semzcnt is decre‐
75          mented and semop() fails, with errno set to EINTR.
76
77       ·  The time limit specified by timeout in a semtimedop() call  expires:
78          semop() fails, with errno set to EAGAIN.
79
80       If  sem_op is less than zero, the process must have alter permission on
81       the semaphore set.  If semval is greater than or equal to the  absolute
82       value  of  sem_op,  the operation can proceed immediately: the absolute
83       value of sem_op is subtracted from semval, and, if SEM_UNDO  is  speci‐
84       fied  for  this  operation,  the  system updates the process undo count
85       (semadj) for this semaphore.   If  the  absolute  value  of  sem_op  is
86       greater  than  semval,  and IPC_NOWAIT is specified in sem_flg, semop()
87       fails, with errno set to EAGAIN (and none of the operations in sops  is
88       performed).   Otherwise  semncnt  (the counter of processes waiting for
89       this semaphore's value to increase)  is  incremented  by  one  and  the
90       process sleeps until one of the following occurs:
91
92       ·  semval  becomes  greater  than  or  equal  to  the absolute value of
93          sem_op, at which time the value of semncnt is decremented, the abso‐
94          lute  value  of sem_op is subtracted from semval and, if SEM_UNDO is
95          specified for this operation, the system updates  the  process  undo
96          count (semadj) for this semaphore.
97
98       ·  The  semaphore  set  is removed from the system: semop() fails, with
99          errno set to EIDRM.
100
101       ·  The calling process catches a signal: the value of semncnt is decre‐
102          mented and semop() fails, with errno set to EINTR.
103
104       ·  The  time limit specified by timeout in a semtimedop() call expires:
105          the system call fails, with errno set to EAGAIN.
106
107       On successful completion, the sempid value for each semaphore specified
108       in the array pointed to by sops is set to the process ID of the calling
109       process.  In addition, the sem_otime is set to the current time.
110
111       semtimedop() behaves identically to semop() except that in those  cases
112       were  the  calling  process  would sleep, the duration of that sleep is
113       limited by the amount of elapsed time specified by the timespec  struc‐
114       ture whose address is passed in the timeout argument.  If the specified
115       time limit has been reached,  semtimedop()  fails  with  errno  set  to
116       EAGAIN (and none of the operations in sops is performed).  If the time‐
117       out argument is NULL, then semtimedop() behaves exactly like semop().
118

RETURN VALUE

120       If successful semop() and semtimedop() return 0; otherwise they  return
121       -1 with errno indicating the error.
122

ERRORS

124       On failure, errno is set to one of the following:
125
126       E2BIG  The argument nsops is greater than SEMOPM, the maximum number of
127              operations allowed per system call.
128
129       EACCES The calling process does not have the  permissions  required  to
130              perform  the  specified  semaphore operations, and does not have
131              the CAP_IPC_OWNER capability.
132
133       EAGAIN An operation could not proceed immediately and either IPC_NOWAIT
134              was  specified in sem_flg or the time limit specified in timeout
135              expired.
136
137       EFAULT An address specified in either the sops or the timeout  argument
138              isn't accessible.
139
140       EFBIG  For  some  operation  the  value  of  sem_num  is less than 0 or
141              greater than or equal to the number of semaphores in the set.
142
143       EIDRM  The semaphore set was removed.
144
145       EINTR  While blocked in this system call, the process caught a  signal;
146              see signal(7).
147
148       EINVAL The  semaphore set doesn't exist, or semid is less than zero, or
149              nsops has a nonpositive value.
150
151       ENOMEM The sem_flg of some operation specified SEM_UNDO and the  system
152              does not have enough memory to allocate the undo structure.
153
154       ERANGE For  some  operation  sem_op+semval  is greater than SEMVMX, the
155              implementation dependent maximum value for semval.
156

VERSIONS

158       semtimedop() first appeared in Linux 2.5.52, and was subsequently back‐
159       ported  into  kernel  2.4.22.   Glibc  support  for  semtimedop() first
160       appeared in version 2.3.3.
161

CONFORMING TO

163       SVr4, POSIX.1-2001.
164

NOTES

166       The sem_undo structures of a process aren't inherited by the child pro‐
167       duced  by  fork(2),  but  they are inherited across an execve(2) system
168       call.
169
170       semop() is never automatically restarted after being interrupted  by  a
171       signal  handler,  regardless of the setting of the SA_RESTART flag when
172       establishing a signal handler.
173
174       semadj is a per-process integer which is simply the (negative) count of
175       all  semaphore operations performed specifying the SEM_UNDO flag.  When
176       a semaphore's value is directly set using the SETVAL or SETALL  request
177       to  semctl(2),  the  corresponding  semadj  values in all processes are
178       cleared.
179
180       The semval, sempid, semzcnt, and semnct values for a semaphore can  all
181       be retrieved using appropriate semctl(2) calls.
182
183       The  following  limits  on  semaphore  set resources affect the semop()
184       call:
185
186       SEMOPM Maximum number of operations allowed for one semop()  call  (32)
187              (on  Linux,  this  limit  can be read and modified via the third
188              field of /proc/sys/kernel/sem).
189
190       SEMVMX Maximum allowable value  for  semval:  implementation  dependent
191              (32767).
192
193       The implementation has no intrinsic limits for the adjust on exit maxi‐
194       mum value (SEMAEM), the system wide maximum number of  undo  structures
195       (SEMMNU)  and  the  per-process  maximum  number of undo entries system
196       parameters.
197

BUGS

199       When a process terminates, its set of associated semadj  structures  is
200       used to undo the effect of all of the semaphore operations it performed
201       with the SEM_UNDO flag.  This raises a difficulty: if one (or more)  of
202       these  semaphore  adjustments  would result in an attempt to decrease a
203       semaphore's value below zero, what should an  implementation  do?   One
204       possible approach would be to block until all the semaphore adjustments
205       could be performed.  This is however undesirable since it  could  force
206       process  termination  to  block  for arbitrarily long periods.  Another
207       possibility is that such semaphore adjustments could be  ignored  alto‐
208       gether  (somewhat  analogously  to failing when IPC_NOWAIT is specified
209       for a semaphore operation).  Linux adopts a third approach:  decreasing
210       the  semaphore  value  as  far as possible (i.e., to zero) and allowing
211       process termination to proceed immediately.
212
213       In kernels 2.6.x, x <= 10, there is a bug that  in  some  circumstances
214       prevents a process that is waiting for a semaphore value to become zero
215       from being woken up when the value does actually become zero.  This bug
216       is fixed in kernel 2.6.11.
217

EXAMPLE

219       The  following  code  segment  uses  semop() to atomically wait for the
220       value of semaphore 0 to become zero, and then increment  the  semaphore
221       value by one.
222
223           struct sembuf sops[2];
224           int semid;
225
226           /* Code to set semid omitted */
227
228           sops[0].sem_num = 0;        /* Operate on semaphore 0 */
229           sops[0].sem_op = 0;         /* Wait for value to equal 0 */
230           sops[0].sem_flg = 0;
231
232           sops[1].sem_num = 0;        /* Operate on semaphore 0 */
233           sops[1].sem_op = 1;         /* Increment value by one */
234           sops[1].sem_flg = 0;
235
236           if (semop(semid, sops, 2) == -1) {
237               perror("semop");
238               exit(EXIT_FAILURE);
239           }
240

SEE ALSO

242       semctl(2),  semget(2),  sigaction(2), capabilities(7), sem_overview(7),
243       svipc(7), time(7)
244

COLOPHON

246       This page is part of release 3.25 of the Linux  man-pages  project.   A
247       description  of  the project, and information about reporting bugs, can
248       be found at http://www.kernel.org/doc/man-pages/.
249
250
251
252Linux                             2008-10-04                          SEMOP(2)
Impressum