xref: /dragonfly/lib/libc/sys/umtx.2 (revision 89656a4e)
1.\" Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
2.\"
3.\" This code is derived from software contributed to The DragonFly Project
4.\" by Matthew Dillon <dillon@backplane.com>
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\"
10.\" 1. Redistributions of source code must retain the above copyright
11.\"    notice, this list of conditions and the following disclaimer.
12.\" 2. Redistributions in binary form must reproduce the above copyright
13.\"    notice, this list of conditions and the following disclaimer in
14.\"    the documentation and/or other materials provided with the
15.\"    distribution.
16.\" 3. Neither the name of The DragonFly Project nor the names of its
17.\"    contributors may be used to endorse or promote products derived
18.\"    from this software without specific, prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
24.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31.\" SUCH DAMAGE.
32.\"
33.Dd January 15, 2015
34.Dt UMTX 2
35.Os
36.Sh NAME
37.Nm umtx_sleep ,
38.Nm umtx_wakeup
39.Nd kernel support for userland mutexes
40.Sh LIBRARY
41.Lb libc
42.Sh SYNOPSIS
43.In unistd.h
44.Ft int
45.Fn umtx_sleep "volatile const int *ptr" "int value" "int timeout"
46.Ft int
47.Fn umtx_wakeup "volatile const int *ptr" "int count"
48.Sh DESCRIPTION
49The
50.Fn umtx_sleep
51system call will put the calling process to sleep for
52.Fa timeout
53microseconds if the contents of the specified pointer matches
54the specified value.
55Specifying a timeout of 0 indicates an indefinite timeout.
56The comparison is not atomic with the sleep but is properly
57interlocked against another process calling
58.Fn umtx_wakeup .
59In particular, while it is possible for two userland threads to race, one
60going to sleep simultaneously with another releasing the mutex, this condition
61is caught when the second userland thread calls
62.Fn umtx_wakeup
63after releasing the contended mutex.
64.Pp
65The
66.Fa timeout
67has no specific limitation other than what fits in the signed integer.
68A negative timeout will return
69.Er EINVAL .
70.Pp
71WARNING! In order to properly interlock against
72.Fn fork ,
73this function will
74do an atomic read-modify-write on the underlying memory by atomically
75adding the value 0 to it.
76.Pp
77The
78.Fn umtx_wakeup
79system call will wakeup the specified number of processes sleeping
80in
81.Fn umtx_sleep
82on the specified user address.
83A count of 0 will wake up all sleeping processes.
84This function may wake up more processes then the specified
85count but will never wake up fewer processes (unless there are simply not
86that many currently sleeping on the address).
87The current
88.Dx
89implementation optimized the count = 1 case but otherwise just wakes up
90all processes sleeping on the address.
91.Pp
92Kernel support for userland mutexes is based on the physical memory backing
93the user address.
94That is, the kernel will typically construct a sleep id based on the
95underlying physical memory address.
96Two userland programs may use this facility through
97.Fn mmap ,
98.Fn sysv ,
99.Fn rfork ,
100or light weight process-based shared memory.
101It is important to note that the kernel does not
102take responsibility for adjusting the contents of the mutex or for the
103userland implementation of the mutex.
104.Pp
105.Fn umtx_sleep
106does not restart in case of a signal, even if the signal specifies
107that system calls should restart.
108.Pp
109Various operating system events can cause
110.Fn umtx_sleep
111to return prematurely, with the contents of the mutex unchanged relative
112to the compare value.
113Callers must be able to deal with such returns.
114.Sh RETURN VALUES
115.Fn umtx_sleep
116will return 0 if it successfully slept and was then woken up.
117Otherwise it will return -1 and set
118.Va errno
119as shown below.
120.Pp
121.Fn umtx_wakeup
122will generally return 0 unless the address is bad.
123.Sh EXAMPLES
124.Bd -literal -compact
125
126void
127userland_get_mutex(struct umtx *mtx)
128{
129	int v;
130
131	v = mtx->lock;
132	for (;;) {
133		if (v == 0) {
134			if (atomic_fcmpset_int(&mtx->lock, &v, 1))
135				break;
136		} else if (atomic_fcmpset_int(&mtx->lock, &v, 2)) {
137			umtx_sleep(&mtx->lock, 2, 0);
138		}
139	}
140}
141
142void
143userland_rel_mutex(struct umtx *mtx)
144{
145    int v;
146
147    v = atomic_swap_int(&mtx->lock, 0);
148    if (v == 2)
149	    umtx_wakeup(&mtx->lock, 1);
150}
151.Ed
152.Sh WARNINGS
153This function can return -1 with errno set to
154.Er EWOULDBLOCK
155early and even if no timeout is specified due to the kernel failsafe
156timeout activating.
157The caller is advised to track the timeout independently using
158.Fn clock_gettime .
159.Pp
160This function can return -1 with errno set to
161.Er EINTR
162and it is up to the caller to loop if the caller's own API disallows
163returning
164.Er EINTR .
165.Pp
166This function can also return -1 with errno set to
167.Er EBUSY
168due to internal kernel effects.
169.Pp
170This function can return without error when woken up via internal
171kernel effects and not necessarily just by a
172.Fn umtx_wakeup
173call.
174.Pp
175Because the kernel will always use the underlying physical address
176for its tsleep/wakeup id (e.g. which is required to properly supported
177memory-mapped locks shared between processes), certain actions taken by
178the program and/or by the kernel can disrupt synchronization between
179.Fn umtx_sleep
180and
181.Fn umtx_wakeup .
182The kernel is responsible for handling
183.Fn fork
184actions, and will typically wakeup all blocked
185.Fn umtx_sleep
186for all threads of a process upon any thread forking.
187However, other actions such as pagein and pageout can also desynchronize
188sleeps and wakeups.
189To deal with these actions, the kernel typically implements a failsafe
190timeout of around 2 seconds for
191.Fn umtx_sleep .
192To properly resynchronize the physical address, ALL threads blocking on
193the address should perform a modifying operation on the underlying memory
194before re-entering the wait state,
195or otherwise be willing to incur the failsafe timeout as their recovery
196mechanism.
197.Sh ERRORS
198.Bl -tag -width Er
199.It Bq Er EBUSY
200The contents of
201.Fa *ptr
202possibly did not match
203.Fa value
204.It Bq Er EWOULDBLOCK
205The specified timeout occurred,
206or a kernel-defined failsafe timeout occurred,
207or the kernel requires a retry due to a copy-on-write / fork operation.
208Callers should not assume that the precise requested timeout occurred
209when this error is returned, and this error can be returned even
210when no timeout is specified.
211.It Bq Er EINTR
212The
213.Fn umtx_sleep
214call was interrupted by a signal.
215.It Bq Er EINVAL
216An invalid parameter (typically an invalid timeout) was specified.
217.El
218.Sh SEE ALSO
219.Xr tls 2
220.Sh HISTORY
221The
222.Fn umtx_sleep ,
223and
224.Fn umtx_wakeup
225function calls first appeared in
226.Dx 1.1 .
227