Clarify two usage cases for umtx.2
[dragonfly.git] / lib / libc / sys / umtx.2
CommitLineData
791e9ddb
MD
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.\"
4f8a9830 33.\" $DragonFly: src/lib/libc/sys/umtx.2,v 1.11 2007/07/23 23:04:21 dillon Exp $
791e9ddb
MD
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
1bf4b486 54microseconds if the contents of the specified point matches
791e9ddb
MD
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
3f5e28f4 61going to sleep simultaneously with another releasing the mutex, this condition
791e9ddb
MD
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
a3220ac5
SW
77that many currently sleeping on the address). The current
78.Dx
791e9ddb
MD
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 ,
4f8a9830
MD
86.Fn rfork ,
87or light weight process-based shared memory.
88It is important to note that the kernel does not
791e9ddb
MD
89take responsibility for adjusting the contents of the mutex or for the
90userland implementation of the mutex.
4f8a9830
MD
91.Pp
92.Fn umtx_sleep
93does not restart in case of a signal, even if the signal specifies
94that system calls should restart.
791e9ddb
MD
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
0f09e575 99.Va errno
791e9ddb
MD
100as shown below.
101.Pp
102.Fn umtx_wakeup
1bf4b486 103will generally return 0 unless the address is bad.
791e9ddb
MD
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
1bf4b486 155 * attempt to obtain the mutex, we should chain the
791e9ddb
MD
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
0b84df5c
SW
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
3f625015 200The specified timeout occurred.
0b84df5c
SW
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
791e9ddb 208.Sh SEE ALSO
1bf4b486 209.Xr tls 2
791e9ddb
MD
210.Sh HISTORY
211The
212.Fn umtx_sleep ,
213and
214.Fn umtx_wakeup
a3220ac5
SW
215function calls first appeared in
216.Dx 1.1 .