1.\" $NetBSD: __cpu_simple_lock.9,v 1.2 2024/10/26 03:05:06 riastradh Exp $ 2.\" 3.\" Copyright (c) 2022 The NetBSD Foundation, Inc. 4.\" All rights reserved. 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.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 2. Redistributions in binary form must reproduce the above copyright 12.\" notice, this list of conditions and the following disclaimer in the 13.\" documentation and/or other materials provided with the distribution. 14.\" 15.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25.\" POSSIBILITY OF SUCH DAMAGE. 26.\" 27.Dd October 25, 2024 28.Dt __CPU_SIMPLE_LOCK 9 29.Os 30.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 31.Sh NAME 32.Nm __cpu_simple_lock 33.Nd simple spin locks 34.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 35.Sh SYNOPSIS 36.In sys/lock.h 37.\" 38.Ft void 39.Fn __cpu_simple_lock_init "__cpu_simple_lock_t *lock" 40.\" 41.Vt #define __SIMPLELOCK_UNLOCKED ... 42.\" 43.Ft void 44.Fn __cpu_simple_lock "__cpu_simple_lock_t *lock" 45.Ft int 46.Fn __cpu_simple_lock_try "__cpu_simple_lock *lock" 47.Ft void 48.Fn __cpu_simple_unlock "__cpu_simple_lock_t *lock" 49.\" 50.Ft int 51.Fn __SIMPLELOCK_LOCKED_P "__cpu_simple_lock *lock" 52.\" 53.Fd "/* obsolete and for ABI compat only -- do not use */" 54.Ft void 55.Fn __cpu_simple_lock_set "__cpu_simple_Lock *lock" 56.Ft void 57.Fn __cpu_simple_lock_clear "__cpu_simple_lock *lock" 58.Ft int 59.Fn __SIMPLELOCK_UNLOCKED_P "__cpu_simple_lock *lock" 60.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 61.Sh DESCRIPTION 62The 63.Nm 64functions provide a simple spin-lock facility for limited purposes that 65cannot be served by 66.Xr mutex 9 , 67such as inside the implementation of 68.Xr mutex 9 69itself on platforms with limited atomic read/modify/write operations. 70.Pp 71.Nm 72is very limited: 73.Bl -bullet 74.It 75.Nm 76provides no debugging or diagnostic support through the 77.Dv LOCKDEBUG 78option. 79.It 80.Nm 81does not synchronize between code on a CPU and interrupt handlers 82running on that CPU \(em you must use it with 83.Xr spl 9 84for any locks that may be taken in interrupt context; failing to do so 85will likely lead to hard-to-debug deadlock. 86.It 87.Nm 88does not block preemption, so a thread holding a lock may be preempted, 89potentially requiring other callers to spin for long durations until 90the scheduler runs the holder again. 91.It 92.Nm 93does no exponential backoff to reduce memory traffic during 94contention. 95.El 96.Pp 97Unless you know what you are doing, you should use 98.Xr mutex 9 99instead. 100.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 101.Sh INITIALIZATION 102The macro 103.Dv __SIMPLELOCK_UNLOCKED 104expands to an initializer for the type 105.Vt __cpu_simple_lock_t : 106.Dl "__cpu_simple_lock_t lock = __SIMPLELOCK_UNLOCKED;" 107.Pp 108A 109.Vt __cpu_simple_lock_t 110object can also be initialized with 111.Fn __cpu_simple_lock_init . 112.Pp 113No actions are needed to destroy a 114.Vt __cpu_simple_lock_t 115object. 116.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 117.Sh FUNCTIONS 118.Bl -tag -width abcd 119.It Fn __cpu_simple_lock_init lock 120Initialize 121.Fa lock 122for use with the other 123.Nm 124functions. 125.Pp 126The caller is responsible for ensuring 127.Fn __cpu_simple_lock_init 128happens before any use of the other functions. 129.Fn __cpu_simple_lock_init 130implies no particular memory ordering on its own. 131.\"""""""""""""""" 132.It Fn __cpu_simple_lock lock 133Acquire 134.Fa lock , 135waiting until it is released if currently held. 136.Pp 137Any memory operations preceding the previous 138.Fn __cpu_simple_unlock 139call that released the lock happen before any memory operations after 140the next 141.Fn __cpu_simple_lock 142call that acquires it. 143.\"""""""""""""""" 144.It Fn __cpu_simple_lock_try lock 145Try to acquire 146.Fa lock , 147without waiting if it is currently held. 148Return 1 if successful, 0 if not. 149.Pp 150Any memory operations preceding the previous 151.Fn __cpu_simple_unlock 152call that released the lock happen before any memory operations after 153the next 154.Em successful 155.Fn __cpu_simple_lock_try 156call that acquires it. 157.\"""""""""""""""" 158.It Fn __cpu_simple_unlock lock 159Release 160.Fa lock . 161.Pp 162Any memory operations preceding 163.Fn __cpu_simple_unlock 164happen before the next call to 165.Fn __cpu_simple_lock , 166or the next successful call to 167.Fn __cpu_simple_lock_try , 168that acquires 169.Fa lock . 170.\"""""""""""""""" 171.It Fn __SIMPLELOCK_LOCKED_P lock 172True if 173.Fa lock 174is currently locked, by anyone. 175.Pp 176This is normally only used for diagnostic assertions, or for loops 177around 178.Fn __cpu_simple_lock_try 179that also have higher-level functions like blocking interrupts and 180performing exponential backoff. 181.Pp 182No memory ordering is implied. 183.El 184.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 185.Sh OBSOLETE FUNCTIONS 186The following functions abuse the 187.Vt __cpu_simple_lock_t 188type to store a boolean. 189They are used inside the 190.Xr pthread 3 191library, and were included in the library ABI, so they can't be removed 192without breaking the 193.Xr pthread 3 194ABI. 195Do not use these in new code 196.Po 197except 198.Fn __SIMPLELOCK_LOCKED_P 199.Pc . 200.Bl -tag -width ".Fn __SIMPLELOCK_UNLOCKED_P lock" 201.It Fn __cpu_simple_lock_set lock 202Set 203.Fa lock 204to true. 205.It Fn __cpu_simple_lock_clear lock 206Set 207.Fa lock 208to false. 209.It Fn __SIMPLELOCK_LOCKED_P lock 210True iff 211.Fa lock 212is true. 213.It Fn __SIMPLELOCK_UNLOCKED_P lock 214True iff 215.Fa lock 216is false. 217.El 218.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 219.Sh CODE REFERENCES 220The 221.Nm 222functions are implemented in 223.Pa sys/arch/$ARCH/include/lock.h . 224.Pp 225A machine-independent implementation, using compiler support for 226atomic and memory barrier builtins, is available in 227.Pa sys/sys/common_lock.h . 228.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 229.Sh SEE ALSO 230.Xr locking 9 , 231.Xr mutex 9 232.\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 233.Sh HISTORY 234.Nm 235appeared a long time ago. 236