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