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.\" $DragonFly: src/lib/libc/sys/umtx.2,v 1.11 2007/07/23 23:04:21 dillon Exp $ 34.\" 35.Dd February 21, 2005 36.Dt UMTX 2 37.Os 38.Sh NAME 39.Nm umtx_sleep , 40.Nm umtx_wakeup 41.Nd kernel support for userland mutexes 42.Sh LIBRARY 43.Lb libc 44.Sh SYNOPSIS 45.Ft int 46.Fn umtx_sleep "const int *ptr" "int value" "int timeout" 47.Ft int 48.Fn umtx_wakeup "const int *ptr" "int count" 49.Sh DESCRIPTION 50The 51.Fn umtx_sleep 52system call will put the calling process to sleep for 53.Fa timeout 54microseconds if the contents of the specified point matches 55the specified value. 56Specifying a timeout of 0 indicates an indefinite timeout. 57The comparison is not atomic with the sleep but is properly 58interlocked against another process calling 59.Fn umtx_wakeup . 60In particular, while it is possible for two userland threads to race, one 61going to sleep simultaneously with another releasing the mutex, this condition 62is caught when the second userland thread calls 63.Fn umtx_wakeup 64after releasing the contended mutex. 65The 66.Fa timeout 67is limited to the range 0-1000000 microseconds. 68.Pp 69The 70.Fn umtx_wakeup 71system call will wakeup the specified number of processes sleeping 72in 73.Fn umtx_sleep 74on the specified user address. A count of 0 will wake up all sleeping 75processes. This function may wake up more processes then the specified 76count but will never wake up fewer processes (unless there are simply not 77that many currently sleeping on the address). The current 78.Dx 79implementation optimized the count = 1 case but otherwise just wakes up 80all processes sleeping on the address. 81.Pp 82Kernel support for userland mutexes is based on the physical memory backing 83the user address. Two userland programs may use this facility through 84.Fn mmap , 85.Fn sysv , 86.Fn rfork , 87or light weight process-based shared memory. 88It is important to note that the kernel does not 89take responsibility for adjusting the contents of the mutex or for the 90userland implementation of the mutex. 91.Pp 92.Fn umtx_sleep 93does not restart in case of a signal, even if the signal specifies 94that system calls should restart. 95.Sh RETURN VALUES 96.Fn umtx_sleep 97will return 0 if it successfully slept and was then woken up. Otherwise 98it will return -1 and set 99.Va errno 100as shown below. 101.Pp 102.Fn umtx_wakeup 103will generally return 0 unless the address is bad. 104.Sh EXAMPLE 105.Bd -literal -compact 106 107void 108userland_get_mutex(struct umtx *mtx) 109{ 110 int v; 111 112 for (;;) { 113 v = mtx->lock; 114 if ((v & MTX_LOCKED) == 0) { 115 /* 116 * not locked, attempt to lock. 117 */ 118 if (cmp_and_exg(&mtx->lock, v, v | MTX_LOCKED) == 0) 119 return; 120 } else { 121 /* 122 * Locked, bump the contested count and obtain the contested 123 * mutex. 124 */ 125 if (cmp_and_exg(&mtx->lock, v, v + 1) == 0) { 126 userland_get_mutex_contested(mtx); 127 return; 128 } 129 } 130 } 131} 132 133static void 134userland_get_mutex_contested(struct umtx *mtx) 135{ 136 int v; 137 138 for (;;) { 139 v = mtx->lock; 140 assert(v & ~MTX_LOCKED); /* our contesting count still there */ 141 if ((v & MTX_LOCKED) == 0) { 142 /* 143 * not locked, attempt to remove our contested count and 144 * lock at the same time. 145 */ 146 if (cmp_and_exg(&mtx->lock, v, (v - 1) | MTX_LOCKED) == 0) 147 return; 148 } else { 149 /* 150 * Still locked, sleep and try again. 151 */ 152 umtx_sleep(&mtx->lock, v, 0); 153 /* 154 * XXX note: if we are woken up here but do not proceed to 155 * attempt to obtain the mutex, we should chain the 156 * umtx_wakeup() along. 157 */ 158 } 159 } 160} 161 162void 163userland_rel_mutex(struct umtx *mtx) 164{ 165 int v; 166 167 for (;;) { 168 v = mtx->lock; 169 assert(v & MTX_LOCKED); /* we still have it locked */ 170 if (v == MTX_LOCKED) { 171 /* 172 * We hold an uncontested lock, try to set to an unlocked 173 * state. 174 */ 175 if (cmp_and_exg(&mtx->lock, MTX_LOCKED, 0) == 0) 176 return; 177 } else { 178 /* 179 * We hold a contested lock, unlock and wakeup exactly 180 * one sleeper. It is possible for this to race a new 181 * thread obtaining a lock, in which case any contested 182 * sleeper we wake up will simply go back to sleep. 183 */ 184 if (cmp_and_exg(&mtx->lock, v, v & ~MTX_LOCKED) == 0) { 185 umtx_wakeup(&mtx->lock, 1); 186 return; 187 } 188 } 189 } 190} 191.Ed 192.Sh ERRORS 193.Bl -tag -width Er 194.It Bq Er EBUSY 195The contents of 196.Fa *ptr 197did not match 198.Fa value 199.It Bq Er ETIMEDOUT 200The specified timeout occurred. 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