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 71The 72.Fn umtx_wakeup 73system call will wakeup the specified number of processes sleeping 74in 75.Fn umtx_sleep 76on the specified user address. A count of 0 will wake up all sleeping 77processes. This function may wake up more processes then the specified 78count but will never wake up fewer processes (unless there are simply not 79that many currently sleeping on the address). The current 80.Dx 81implementation optimized the count = 1 case but otherwise just wakes up 82all processes sleeping on the address. 83.Pp 84Kernel support for userland mutexes is based on the physical memory backing 85the user address. 86That is, the kernel will typically construct a sleep id based on the 87underlying physical memory address. 88Two userland programs may use this facility through 89.Fn mmap , 90.Fn sysv , 91.Fn rfork , 92or light weight process-based shared memory. 93It is important to note that the kernel does not 94take responsibility for adjusting the contents of the mutex or for the 95userland implementation of the mutex. 96.Pp 97.Fn umtx_sleep 98does not restart in case of a signal, even if the signal specifies 99that system calls should restart. 100.Pp 101Various operating system events can cause 102.Fn umtx_sleep 103to return prematurely, with the contents of the mutex unchanged relative 104to the compare value. Callers must be able to deal with such returns. 105.Sh RETURN VALUES 106.Fn umtx_sleep 107will return 0 if it successfully slept and was then woken up. Otherwise 108it will return -1 and set 109.Va errno 110as shown below. 111.Pp 112.Fn umtx_wakeup 113will generally return 0 unless the address is bad. 114.Sh EXAMPLE 115.Bd -literal -compact 116 117void 118userland_get_mutex(struct umtx *mtx) 119{ 120 int v; 121 122 v = mtx->lock; 123 for (;;) { 124 if (v == 0) { 125 if (atomic_fcmpset_int(&mtx->lock, &v, 1)) 126 break; 127 } else if (atomic_fcmpset_int(&mtx->lock, &v, 2)) { 128 umtx_sleep(&mtx->lock, 2, 0); 129 } 130 } 131} 132 133void 134userland_rel_mutex(struct umtx *mtx) 135{ 136 int v; 137 138 v = atomic_swap_int(&mtx->lock, 0); 139 if (v == 2) 140 umtx_wakeup(&mtx->lock, 1); 141} 142.Ed 143.Sh WARNINGS 144This function can return -1 with errno set to 145.Er EWOULDBLOCK 146early and even if no timeout is specified due to the kernel failsafe 147timeout activating. 148The caller is advised to track the timeout independently using 149.Fn clock_gettime . 150.Pp 151This function can return -1 with errno set to 152.Er EINTR 153and it is up to the caller to loop if the caller's own API disallows 154returning 155.Er EINTR . 156.Pp 157This function can also return -1 with errno set to 158.Er EBUSY 159due to internal kernel effects. 160.Pp 161This function can return without error when woken up via internal 162kernel effects and not necessarily just by a 163.Fn umtx_wakeup 164call. 165.Pp 166Because the kernel will always use the underlying physical address 167for its tsleep/wakeup id (e.g. which is required to properly supported 168memory-mapped locks shared between processes), certain actions taken by 169the program and/or by the kernel can disrupt synchronization between 170.Fn umtx_sleep 171and 172.Fn umtx_wakeup . 173The kernel is responsible for handling 174.Fn fork 175actions, and will typically wakeup all blocked 176.Fn umtx_sleep 177for all threads of a process upon any thread forking. 178However, other actions such as pagein and pageout can also desynchronize 179sleeps and wakeups. 180To deal with these actions, the kernel typically implements a failsafe 181timeout of around 2 seconds for 182.Fn umtx_sleep . 183To properly resynchronize the physical address, ALL threads blocking on 184the address should perform a modifying operation on the underlying memory 185before re-entering the wait state, 186or otherwise be willing to incur the failsafe timeout as their recovery 187mechanism. 188.Sh ERRORS 189.Bl -tag -width Er 190.It Bq Er EBUSY 191The contents of 192.Fa *ptr 193possibly did not match 194.Fa value 195.It Bq Er EWOULDBLOCK 196The specified timeout occurred, 197or a kernel-defined failsafe timeout occurred. 198Callers should not assume that the precise requested timeout occurred 199when this error is returned, and this error can be returned even 200when no timeout is specified. 201.It Bq Er EINTR 202The 203.Fn umtx_sleep 204call was interrupted by a signal. 205.It Bq Er EINVAL 206An invalid parameter (typically an invalid timeout) was specified. 207.El 208.Sh SEE ALSO 209.Xr tls 2 210.Sh HISTORY 211The 212.Fn umtx_sleep , 213and 214.Fn umtx_wakeup 215function calls first appeared in 216.Dx 1.1 . 217