1.\" $OpenBSD: mutex.9,v 1.25 2019/11/04 18:18:03 anton Exp $ 2.\" 3.\" Copyright (c) 2005 Pedro Martelletto <pedro@ambientworks.net> 4.\" All rights reserved. 5.\" 6.\" Permission to use, copy, modify, and distribute this software for any 7.\" purpose with or without fee is hereby granted, provided that the above 8.\" copyright notice and this permission notice appear in all copies. 9.\" 10.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17.\" 18.Dd $Mdocdate: November 4 2019 $ 19.Dt MUTEX 9 20.Os 21.Sh NAME 22.Nm mutex , 23.Nm mtx_init , 24.Nm mtx_init_flags , 25.Nm mtx_enter , 26.Nm mtx_enter_try , 27.Nm mtx_leave , 28.Nm MUTEX_ASSERT_LOCKED , 29.Nm MUTEX_ASSERT_UNLOCKED , 30.Nm MUTEX_INITIALIZER , 31.Nm MUTEX_INITIALIZER_FLAGS 32.Nd interface to CPU mutexes 33.Sh SYNOPSIS 34.In sys/mutex.h 35.Ft void 36.Fn mtx_init "struct mutex *mtxp" "int wantipl" 37.Ft void 38.Fn mtx_init_flags "struct mutex *mtxp" "int wantipl" "const char *name" \ 39"int flags" 40.Ft void 41.Fn mtx_enter "struct mutex *mtxp" 42.Ft int 43.Fn mtx_enter_try "struct mutex *mtxp" 44.Ft void 45.Fn mtx_leave "struct mutex *mtxp" 46.Fn MUTEX_ASSERT_LOCKED "struct mutex *mtxp" 47.Fn MUTEX_ASSERT_UNLOCKED "struct mutex *mtxp" 48.Fn MUTEX_INITIALIZER "int wantipl" 49.Fn MUTEX_INITIALIZER_FLAGS "int wantipl" "const char *name" "int flags" 50.Sh DESCRIPTION 51The 52.Nm 53set of functions provides a non-recursive, interrupt-aware spinning mechanism 54to ensure mutual exclusion between different CPUs. 55.Pp 56The 57.Fn mtx_init 58function is used to initiate the mutex pointed to by 59.Fa mtxp . 60When acquired, the mutex will cause the processor interrupt level to be raised 61to 62.Fa wantipl 63if necessary. 64.Pp 65The 66.Fn mtx_init_flags 67macro is similar to 68.Fn mtx_init , 69but it additionally accepts parameters for 70.Xr witness 4 . 71The pointer 72.Fa name 73differentiates a lock type. 74Two mutexes have the same lock type only if they have been created by the same 75occurrence of 76.Fn mtx_init_flags 77with the same pointer 78.Fa name . 79The 80.Fa flags 81parameter is a bitwise OR of the following options: 82.Bl -tag -width MTX_NOWITNESS -offset indent 83.It Dv MTX_DUPOK 84Prevents 85.Xr witness 4 86from logging when a CPU acquires more than one lock of this lock type. 87.It Dv MTX_NOWITNESS 88Instructs 89.Xr witness 4 90to ignore this lock. 91.El 92.Pp 93The 94.Fn mtx_enter 95function acquires a mutex, spinning if necessary. 96.Pp 97The 98.Fn mtx_enter_try 99function attempts to acquire a mutex. 100.Pp 101The 102.Fn mtx_leave 103function releases a mutex. 104In case the acquisition of the mutex caused the interrupt level to be changed, 105it is then restored. 106.Pp 107The 108.Fn MUTEX_ASSERT_LOCKED 109and 110.Fn MUTEX_ASSERT_UNLOCKED 111macros may be used to assert that a mutex is held locked or unlocked by 112the current CPU. 113.Pp 114A mutex declaration may be initialised with the 115.Fn MUTEX_INITIALIZER 116macro. 117When acquired, the mutex will cause the processor interrupt level to be raised 118to 119.Fa wantipl 120if necessary. 121.Pp 122The 123.Fn MUTEX_INITIALIZER_FLAGS 124macro is similar to 125.Fn MUTEX_INITIALIZER , 126but it additionally accepts parameters for 127.Xr witness 4 . 128See the 129.Fn mtx_init_flags 130macro for details. 131.Sh CONTEXT 132.Fn mtx_init 133and 134.Fn mtx_init_flags 135can be called during autoconf, from process context, or from interrupt 136context. 137.Pp 138.Fn mtx_enter , 139.Fn mtx_enter_try , 140and 141.Fn mtx_leave 142can be called during autoconf, from process context, or from any 143interrupt context at or below the interrupt level 144.Fa mtxp 145was initialised with. 146.Sh RETURN VALUES 147The 148.Fn mtx_enter_try 149function will return non-zero if it succeeds in acquiring the mutex 150.Fa mtxp , 151otherwise it will return 0. 152.Sh SEE ALSO 153.Xr witness 4 , 154.Xr msleep 9 , 155.Xr rwlock 9 , 156.Xr spl 9 157.Sh HISTORY 158The 159.Nm 160functions first appeared in 161.Ox 3.6 . 162.Sh AUTHORS 163The 164.Nm 165functions were written by 166.An Artur Grabowski Aq Mt art@openbsd.org . 167.Sh CAVEATS 168As these are spinning locks, don't sleep while holding one. 169.Pp 170Multiple mutexes may be nested, but not interleaved. 171This is okay: 172.Bd -literal -offset indent 173mtx_enter(foo); 174mtx_enter(bar); 175mtx_leave(bar); 176mtx_leave(foo); 177.Ed 178.Pp 179While this is 180.Fa not : 181.Bd -literal -offset indent 182mtx_enter(foo); 183mtx_enter(bar); 184mtx_leave(foo); 185mtx_leave(bar); 186.Ed 187