| .\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it) |
| .\" |
| .\" %%%LICENSE_START(VERBATIM) |
| .\" Permission is granted to make and distribute verbatim copies of this |
| .\" manual provided the copyright notice and this permission notice are |
| .\" preserved on all copies. |
| .\" |
| .\" Permission is granted to copy and distribute modified versions of this |
| .\" manual under the conditions for verbatim copying, provided that the |
| .\" entire resulting derived work is distributed under the terms of a |
| .\" permission notice identical to this one. |
| .\" |
| .\" Since the Linux kernel and libraries are constantly changing, this |
| .\" manual page may be incorrect or out-of-date. The author(s) assume no |
| .\" responsibility for errors or omissions, or for damages resulting from |
| .\" the use of the information contained herein. The author(s) may not |
| .\" have taken the same level of care in the production of this manual, |
| .\" which is licensed free of charge, as they might when working |
| .\" professionally. |
| .\" |
| .\" Formatted or processed versions of this manual, if unaccompanied by |
| .\" the source, must acknowledge the copyright and authors of this work. |
| .\" %%%LICENSE_END |
| .\" |
| .\" Modified 1996-10-22, Eric S. Raymond <esr@thyrsus.com> |
| .\" Modified 2002-01-08, Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" Modified 2003-04-28, Ernie Petrides <petrides@redhat.com> |
| .\" Modified 2004-05-27, Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" Modified, 11 Nov 2004, Michael Kerrisk <mtk.manpages@gmail.com> |
| .\" Language and formatting clean-ups |
| .\" Added notes on /proc files |
| .\" 2005-04-08, mtk, Noted kernel version numbers for semtimedop() |
| .\" 2007-07-09, mtk, Added an EXAMPLE code segment. |
| .\" |
| .TH SEMOP 2 2021-03-22 "Linux" "Linux Programmer's Manual" |
| .SH NAME |
| semop, semtimedop \- System V semaphore operations |
| .SH SYNOPSIS |
| .nf |
| .B #include <sys/ipc.h> |
| .B #include <sys/sem.h> |
| .PP |
| .BI "int semop(int " semid ", struct sembuf *" sops ", size_t " nsops ); |
| .BI "int semtimedop(int " semid ", struct sembuf *" sops ", size_t " nsops , |
| .BI " const struct timespec *" timeout ); |
| .fi |
| .PP |
| .RS -4 |
| Feature Test Macro Requirements for glibc (see |
| .BR feature_test_macros (7)): |
| .RE |
| .PP |
| .BR semtimedop (): |
| .nf |
| _GNU_SOURCE |
| .fi |
| .SH DESCRIPTION |
| Each semaphore in a System\ V semaphore set |
| has the following associated values: |
| .PP |
| .in +4n |
| .EX |
| unsigned short semval; /* semaphore value */ |
| unsigned short semzcnt; /* # waiting for zero */ |
| unsigned short semncnt; /* # waiting for increase */ |
| pid_t sempid; /* PID of process that last |
| .EE |
| .in |
| .PP |
| .BR semop () |
| performs operations on selected semaphores in the set indicated by |
| .IR semid . |
| Each of the |
| .I nsops |
| elements in the array pointed to by |
| .I sops |
| is a structure that |
| specifies an operation to be performed on a single semaphore. |
| The elements of this structure are of type |
| .IR "struct sembuf" , |
| containing the following members: |
| .PP |
| .in +4n |
| .EX |
| unsigned short sem_num; /* semaphore number */ |
| short sem_op; /* semaphore operation */ |
| short sem_flg; /* operation flags */ |
| .EE |
| .in |
| .PP |
| Flags recognized in |
| .I sem_flg |
| are |
| .B IPC_NOWAIT |
| and |
| .BR SEM_UNDO . |
| If an operation specifies |
| .BR SEM_UNDO , |
| it will be automatically undone when the process terminates. |
| .PP |
| The set of operations contained in |
| .I sops |
| is performed in |
| .IR "array order" , |
| and |
| .IR atomically , |
| that is, the operations are performed either as a complete unit, |
| or not at all. |
| The behavior of the system call if not all operations can be |
| performed immediately depends on the presence of the |
| .B IPC_NOWAIT |
| flag in the individual |
| .I sem_flg |
| fields, as noted below. |
| .PP |
| Each operation is performed on the |
| .IR sem_num \-th |
| semaphore of the semaphore set, where the first semaphore of the set |
| is numbered 0. |
| There are three types of operation, distinguished by the value of |
| .IR sem_op . |
| .PP |
| If |
| .I sem_op |
| is a positive integer, the operation adds this value to |
| the semaphore value |
| .RI ( semval ). |
| Furthermore, if |
| .B SEM_UNDO |
| is specified for this operation, the system subtracts the value |
| .I sem_op |
| from the semaphore adjustment |
| .RI ( semadj ) |
| value for this semaphore. |
| This operation can always proceed\(emit never forces a thread to wait. |
| The calling process must have alter permission on the semaphore set. |
| .PP |
| If |
| .I sem_op |
| is zero, the process must have read permission on the semaphore |
| set. |
| This is a "wait-for-zero" operation: if |
| .I semval |
| is zero, the operation can immediately proceed. |
| Otherwise, if |
| .B IPC_NOWAIT |
| is specified in |
| .IR sem_flg , |
| .BR semop () |
| fails with |
| .I errno |
| set to |
| .B EAGAIN |
| (and none of the operations in |
| .I sops |
| is performed). |
| Otherwise, |
| .I semzcnt |
| (the count of threads waiting until this semaphore's value becomes zero) |
| is incremented by one and the thread sleeps until |
| one of the following occurs: |
| .IP \(bu 2 |
| .I semval |
| becomes 0, at which time the value of |
| .I semzcnt |
| is decremented. |
| .IP \(bu |
| The semaphore set |
| is removed: |
| .BR semop () |
| fails, with |
| .I errno |
| set to |
| .BR EIDRM . |
| .IP \(bu |
| The calling thread catches a signal: |
| the value of |
| .I semzcnt |
| is decremented and |
| .BR semop () |
| fails, with |
| .I errno |
| set to |
| .BR EINTR . |
| .PP |
| If |
| .I sem_op |
| is less than zero, the process must have alter permission on the |
| semaphore set. |
| If |
| .I semval |
| is greater than or equal to the absolute value of |
| .IR sem_op , |
| the operation can proceed immediately: |
| the absolute value of |
| .I sem_op |
| is subtracted from |
| .IR semval , |
| and, if |
| .B SEM_UNDO |
| is specified for this operation, the system adds the absolute value of |
| .I sem_op |
| to the semaphore adjustment |
| .RI ( semadj ) |
| value for this semaphore. |
| If the absolute value of |
| .I sem_op |
| is greater than |
| .IR semval , |
| and |
| .B IPC_NOWAIT |
| is specified in |
| .IR sem_flg , |
| .BR semop () |
| fails, with |
| .I errno |
| set to |
| .B EAGAIN |
| (and none of the operations in |
| .I sops |
| is performed). |
| Otherwise, |
| .I semncnt |
| (the counter of threads waiting for this semaphore's value to increase) |
| is incremented by one and the thread sleeps until |
| one of the following occurs: |
| .IP \(bu 2 |
| .I semval |
| becomes greater than or equal to the absolute value of |
| .IR sem_op : |
| the operation now proceeds, as described above. |
| .IP \(bu |
| The semaphore set is removed from the system: |
| .BR semop () |
| fails, with |
| .I errno |
| set to |
| .BR EIDRM . |
| .IP \(bu |
| The calling thread catches a signal: |
| the value of |
| .I semncnt |
| is decremented and |
| .BR semop () |
| fails, with |
| .I errno |
| set to |
| .BR EINTR . |
| .PP |
| On successful completion, the |
| .I sempid |
| value for each semaphore specified in the array pointed to by |
| .I sops |
| is set to the caller's process ID. |
| In addition, the |
| .I sem_otime |
| .\" and |
| .\" .I sem_ctime |
| is set to the current time. |
| .SS semtimedop() |
| .BR semtimedop () |
| behaves identically to |
| .BR semop () |
| except that in those cases where the calling thread would sleep, |
| the duration of that sleep is limited by the amount of elapsed |
| time specified by the |
| .I timespec |
| structure whose address is passed in the |
| .I timeout |
| argument. |
| (This sleep interval will be rounded up to the system clock granularity, |
| and kernel scheduling delays mean that the interval |
| may overrun by a small amount.) |
| If the specified time limit has been reached, |
| .BR semtimedop () |
| fails with |
| .I errno |
| set to |
| .B EAGAIN |
| (and none of the operations in |
| .I sops |
| is performed). |
| If the |
| .I timeout |
| argument is NULL, |
| then |
| .BR semtimedop () |
| behaves exactly like |
| .BR semop (). |
| .PP |
| Note that if |
| .BR semtimedop () |
| is interrupted by a signal, causing the call to fail with the error |
| .BR EINTR , |
| the contents of |
| .IR timeout |
| are left unchanged. |
| .SH RETURN VALUE |
| On success, |
| .BR semop () |
| and |
| .BR semtimedop () |
| return 0. |
| On failure, they return \-1, and set |
| .I errno |
| to indicate the error. |
| .SH ERRORS |
| .TP |
| .B E2BIG |
| The argument |
| .I nsops |
| is greater than |
| .BR SEMOPM , |
| the maximum number of operations allowed per system |
| call. |
| .TP |
| .B EACCES |
| The calling process does not have the permissions required |
| to perform the specified semaphore operations, |
| and does not have the |
| .B CAP_IPC_OWNER |
| capability in the user namespace that governs its IPC namespace. |
| .TP |
| .B EAGAIN |
| An operation could not proceed immediately and either |
| .B IPC_NOWAIT |
| was specified in |
| .I sem_flg |
| or the time limit specified in |
| .I timeout |
| expired. |
| .TP |
| .B EFAULT |
| An address specified in either the |
| .I sops |
| or the |
| .I timeout |
| argument isn't accessible. |
| .TP |
| .B EFBIG |
| For some operation the value of |
| .I sem_num |
| is less than 0 or greater than or equal to the number |
| of semaphores in the set. |
| .TP |
| .B EIDRM |
| The semaphore set was removed. |
| .TP |
| .B EINTR |
| While blocked in this system call, the thread caught a signal; see |
| .BR signal (7). |
| .TP |
| .B EINVAL |
| The semaphore set doesn't exist, or |
| .I semid |
| is less than zero, or |
| .I nsops |
| has a nonpositive value. |
| .TP |
| .B ENOMEM |
| The |
| .I sem_flg |
| of some operation specified |
| .B SEM_UNDO |
| and the system does not have enough memory to allocate the undo |
| structure. |
| .TP |
| .B ERANGE |
| For some operation |
| .I sem_op+semval |
| is greater than |
| .BR SEMVMX , |
| the implementation dependent maximum value for |
| .IR semval . |
| .SH VERSIONS |
| .BR semtimedop () |
| first appeared in Linux 2.5.52, |
| and was subsequently backported into kernel 2.4.22. |
| Glibc support for |
| .BR semtimedop () |
| first appeared in version 2.3.3. |
| .SH CONFORMING TO |
| POSIX.1-2001, POSIX.1-2008, SVr4. |
| .\" SVr4 documents additional error conditions EINVAL, EFBIG, ENOSPC. |
| .SH NOTES |
| The inclusion of |
| .I <sys/ipc.h> |
| isn't required on Linux or by any version of POSIX. |
| However, |
| some old implementations required the inclusion of this header file, |
| and the SVID also documented its inclusion. |
| Applications intended to be portable to such old systems may need |
| to include this header file. |
| .\" Like Linux, the FreeBSD man pages still document |
| .\" the inclusion of this header file. |
| .PP |
| The |
| .I sem_undo |
| structures of a process aren't inherited by the child produced by |
| .BR fork (2), |
| but they are inherited across an |
| .BR execve (2) |
| system call. |
| .PP |
| .BR semop () |
| is never automatically restarted after being interrupted by a signal handler, |
| regardless of the setting of the |
| .B SA_RESTART |
| flag when establishing a signal handler. |
| .PP |
| A semaphore adjustment |
| .RI ( semadj ) |
| value is a per-process, per-semaphore integer that is the negated sum |
| of all operations performed on a semaphore specifying the |
| .B SEM_UNDO |
| flag. |
| Each process has a list of |
| .I semadj |
| values\(emone value for each semaphore on which it has operated using |
| .BR SEM_UNDO . |
| When a process terminates, each of its per-semaphore |
| .I semadj |
| values is added to the corresponding semaphore, |
| thus undoing the effect of that process's operations on the semaphore |
| (but see BUGS below). |
| When a semaphore's value is directly set using the |
| .B SETVAL |
| or |
| .B SETALL |
| request to |
| .BR semctl (2), |
| the corresponding |
| .I semadj |
| values in all processes are cleared. |
| The |
| .BR clone (2) |
| .B CLONE_SYSVSEM |
| flag allows more than one process to share a |
| .I semadj |
| list; see |
| .BR clone (2) |
| for details. |
| .PP |
| The \fIsemval\fP, \fIsempid\fP, \fIsemzcnt\fP, and \fIsemnct\fP values |
| for a semaphore can all be retrieved using appropriate |
| .BR semctl (2) |
| calls. |
| .SS Semaphore limits |
| The following limits on semaphore set resources affect the |
| .BR semop () |
| call: |
| .TP |
| .B SEMOPM |
| Maximum number of operations allowed for one |
| .BR semop () |
| call. |
| Before Linux 3.19, |
| .\" commit e843e7d2c88b7db107a86bd2c7145dc715c058f4 |
| the default value for this limit was 32. |
| Since Linux 3.19, the default value is 500. |
| On Linux, this limit can be read and modified via the third field of |
| .IR /proc/sys/kernel/sem . |
| .\" This /proc file is not available in Linux 2.2 and earlier -- MTK |
| .IR Note : |
| this limit should not be raised above 1000, |
| .\" See comment in Linux 3.19 source file include/uapi/linux/sem.h |
| because of the risk of that |
| .BR semop () |
| fails due to kernel memory fragmentation when allocating memory to copy the |
| .IR sops |
| array. |
| .TP |
| .B SEMVMX |
| Maximum allowable value for |
| .IR semval : |
| implementation dependent (32767). |
| .PP |
| The implementation has no intrinsic limits for |
| the adjust on exit maximum value |
| .RB ( SEMAEM ), |
| the system wide maximum number of undo structures |
| .RB ( SEMMNU ) |
| and the per-process maximum number of undo entries system parameters. |
| .SH BUGS |
| When a process terminates, its set of associated |
| .I semadj |
| structures is used to undo the effect of all of the |
| semaphore operations it performed with the |
| .B SEM_UNDO |
| flag. |
| This raises a difficulty: if one (or more) of these semaphore adjustments |
| would result in an attempt to decrease a semaphore's value below zero, |
| what should an implementation do? |
| One possible approach would be to block until all the semaphore |
| adjustments could be performed. |
| This is however undesirable since it could force process termination to |
| block for arbitrarily long periods. |
| Another possibility is that such semaphore adjustments could be ignored |
| altogether (somewhat analogously to failing when |
| .B IPC_NOWAIT |
| is specified for a semaphore operation). |
| Linux adopts a third approach: decreasing the semaphore value |
| as far as possible (i.e., to zero) and allowing process |
| termination to proceed immediately. |
| .PP |
| In kernels 2.6.x, x <= 10, there is a bug that in some circumstances |
| prevents a thread that is waiting for a semaphore value to become |
| zero from being woken up when the value does actually become zero. |
| This bug is fixed in kernel 2.6.11. |
| .\" The bug report: |
| .\" http://marc.theaimsgroup.com/?l=linux-kernel&m=110260821123863&w=2 |
| .\" the fix: |
| .\" http://marc.theaimsgroup.com/?l=linux-kernel&m=110261701025794&w=2 |
| .SH EXAMPLES |
| The following code segment uses |
| .BR semop () |
| to atomically wait for the value of semaphore 0 to become zero, |
| and then increment the semaphore value by one. |
| .PP |
| .in +4n |
| .EX |
| struct sembuf sops[2]; |
| int semid; |
| |
| /* Code to set \fIsemid\fP omitted */ |
| |
| sops[0].sem_num = 0; /* Operate on semaphore 0 */ |
| sops[0].sem_op = 0; /* Wait for value to equal 0 */ |
| sops[0].sem_flg = 0; |
| |
| sops[1].sem_num = 0; /* Operate on semaphore 0 */ |
| sops[1].sem_op = 1; /* Increment value by one */ |
| sops[1].sem_flg = 0; |
| |
| if (semop(semid, sops, 2) == \-1) { |
| perror("semop"); |
| exit(EXIT_FAILURE); |
| } |
| .EE |
| .in |
| .PP |
| A further example of the use of |
| .BR semop () |
| can be found in |
| .BR shmop (2). |
| .SH SEE ALSO |
| .BR clone (2), |
| .BR semctl (2), |
| .BR semget (2), |
| .BR sigaction (2), |
| .BR capabilities (7), |
| .BR sem_overview (7), |
| .BR sysvipc (7), |
| .BR time (7) |