diff options
Diffstat (limited to 'man2/semop.2')
-rw-r--r-- | man2/semop.2 | 523 |
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) |