1 .\" Copyright (c) 2003,2004 The DragonFly Project. All rights reserved.
3 .\" This code is derived from software contributed to The DragonFly Project
4 .\" by Matthew Dillon <dillon@backplane.com>
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
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
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.
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
39 .Nd kernel support for userland mutexes
45 .Fn umtx_sleep "volatile const int *ptr" "int value" "int timeout"
47 .Fn umtx_wakeup "volatile const int *ptr" "int count"
51 system call will put the calling process to sleep for
53 microseconds if the contents of the specified pointer matches
55 Specifying a timeout of 0 indicates an indefinite timeout.
56 The comparison is not atomic with the sleep but is properly
57 interlocked against another process calling
59 In particular, while it is possible for two userland threads to race, one
60 going to sleep simultaneously with another releasing the mutex, this condition
61 is caught when the second userland thread calls
63 after releasing the contended mutex.
67 has no specific limitation other than what fits in the signed integer.
68 A negative timeout will return
71 WARNING! In order to properly interlock against
74 do an atomic read-modify-write on the underlying memory by atomically
75 adding the value 0 to it.
79 system call will wakeup the specified number of processes sleeping
82 on the specified user address.
83 A count of 0 will wake up all sleeping processes.
84 This function may wake up more processes then the specified
85 count but will never wake up fewer processes (unless there are simply not
86 that many currently sleeping on the address).
89 implementation optimized the count = 1 case but otherwise just wakes up
90 all processes sleeping on the address.
92 Kernel support for userland mutexes is based on the physical memory backing
94 That is, the kernel will typically construct a sleep id based on the
95 underlying physical memory address.
96 Two userland programs may use this facility through
100 or light weight process-based shared memory.
101 It is important to note that the kernel does not
102 take responsibility for adjusting the contents of the mutex or for the
103 userland implementation of the mutex.
106 does not restart in case of a signal, even if the signal specifies
107 that system calls should restart.
109 Various operating system events can cause
111 to return prematurely, with the contents of the mutex unchanged relative
112 to the compare value.
113 Callers must be able to deal with such returns.
116 will return 0 if it successfully slept and was then woken up.
117 Otherwise it will return -1 and set
122 will generally return 0 unless the address is bad.
124 .Bd -literal -compact
127 userland_get_mutex(struct umtx *mtx)
134 if (atomic_fcmpset_int(&mtx->lock, &v, 1))
136 } else if (atomic_fcmpset_int(&mtx->lock, &v, 2)) {
137 umtx_sleep(&mtx->lock, 2, 0);
143 userland_rel_mutex(struct umtx *mtx)
147 v = atomic_swap_int(&mtx->lock, 0);
149 umtx_wakeup(&mtx->lock, 1);
153 This function can return -1 with errno set to
155 early and even if no timeout is specified due to the kernel failsafe
157 The caller is advised to track the timeout independently using
160 This function can return -1 with errno set to
162 and it is up to the caller to loop if the caller's own API disallows
166 This function can also return -1 with errno set to
168 due to internal kernel effects.
170 This function can return without error when woken up via internal
171 kernel effects and not necessarily just by a
175 Because the kernel will always use the underlying physical address
176 for its tsleep/wakeup id (e.g. which is required to properly supported
177 memory-mapped locks shared between processes), certain actions taken by
178 the program and/or by the kernel can disrupt synchronization between
182 The kernel is responsible for handling
184 actions, and will typically wakeup all blocked
186 for all threads of a process upon any thread forking.
187 However, other actions such as pagein and pageout can also desynchronize
189 To deal with these actions, the kernel typically implements a failsafe
190 timeout of around 2 seconds for
192 To properly resynchronize the physical address, ALL threads blocking on
193 the address should perform a modifying operation on the underlying memory
194 before re-entering the wait state,
195 or otherwise be willing to incur the failsafe timeout as their recovery
202 possibly did not match
204 .It Bq Er EWOULDBLOCK
205 The specified timeout occurred,
206 or a kernel-defined failsafe timeout occurred,
207 or the kernel requires a retry due to a copy-on-write / fork operation.
208 Callers should not assume that the precise requested timeout occurred
209 when this error is returned, and this error can be returned even
210 when no timeout is specified.
214 call was interrupted by a signal.
216 An invalid parameter (typically an invalid timeout) was specified.
225 function calls first appeared in