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