summaryrefslogtreecommitdiffstats
path: root/man2/semop.2
diff options
context:
space:
mode:
Diffstat (limited to 'man2/semop.2')
-rw-r--r--man2/semop.2523
1 files changed, 523 insertions, 0 deletions
diff --git a/man2/semop.2 b/man2/semop.2
new file mode 100644
index 0000000..ece7a0e
--- /dev/null
+++ b/man2/semop.2
@@ -0,0 +1,523 @@
+.\" Copyright 1993 Giorgio Ciucci (giorgio@crcc.it)
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.\" 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 2023-05-03 "Linux man-pages 6.05.01"
+.SH NAME
+semop, semtimedop \- System V semaphore operations
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.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 *_Nullable " 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
+ modified the semaphore value */
+.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\[em]it 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] 3
+.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] 3
+.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
+.I 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 STANDARDS
+POSIX.1-2008.
+.SH VERSIONS
+Linux 2.5.52 (backported into Linux 2.4.22),
+glibc 2.3.3.
+POSIX.1-2001, SVr4.
+.\" SVr4 documents additional error conditions EINVAL, EFBIG, ENOSPC.
+.SH NOTES
+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\[em]one 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
+.I 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 Linux 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 Linux 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)