1.\" $OpenBSD: rwlock.9,v 1.18 2016/06/19 11:54:33 natano Exp $ 2.\" 3.\" Copyright (c) 2006 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: June 19 2016 $ 19.Dt RWLOCK 9 20.Os 21.Sh NAME 22.Nm rwlock , 23.Nm rw_init , 24.Nm rw_enter , 25.Nm rw_exit , 26.Nm rw_enter_read , 27.Nm rw_enter_write , 28.Nm rw_exit_read , 29.Nm rw_exit_write , 30.Nm rw_assert_wrlock , 31.Nm rw_assert_rdlock , 32.Nm rw_assert_unlocked , 33.Nm rw_status , 34.Nm RWLOCK_INITIALIZER , 35.Nm rrw_init , 36.Nm rrw_enter , 37.Nm rrw_exit , 38.Nm rrw_status 39.Nd interface to read/write locks 40.Sh SYNOPSIS 41.In sys/rwlock.h 42.Ft void 43.Fn rw_init "struct rwlock *rwl" "const char *name" 44.Ft int 45.Fn rw_enter "struct rwlock *rwl" "int flags" 46.Ft void 47.Fn rw_exit "struct rwlock *rwl" 48.Ft void 49.Fn rw_enter_read "struct rwlock *rwl" 50.Ft void 51.Fn rw_enter_write "struct rwlock *rwl" 52.Ft void 53.Fn rw_exit_read "struct rwlock *rwl" 54.Ft void 55.Fn rw_exit_write "struct rwlock *rwl" 56.Ft int 57.Fn rw_assert_wrlock "struct rwlock *rwl" 58.Ft void 59.Fn rw_assert_rdlock "struct rwlock *rwl" 60.Ft void 61.Fn rw_assert_unlocked "struct rwlock *rwl" 62.Ft int 63.Fn rw_status "struct rwlock *rwl" 64.Fn RWLOCK_INITIALIZER "const char *name" 65.Ft void 66.Fn rrw_init "struct rrwlock *rrwl" "const char *name" 67.Ft int 68.Fn rrw_enter "struct rrwlock *rrwl" "int flags" 69.Ft void 70.Fn rrw_exit "struct rrwlock *rrwl" 71.Ft int 72.Fn rrw_status "struct rrwlock *rrwl" 73.Sh DESCRIPTION 74The 75.Nm 76set of functions provides a multiple-reader, single-writer locking mechanism to 77ensure mutual exclusion between different threads. 78.Pp 79Read locks can be acquired while the write lock is not held, and may coexist in 80distinct threads at any time. 81A write lock, however, can only be acquired when there are no read locks held, 82granting exclusive access to a single thread. 83.Pp 84The 85.Fn rw_init 86function is used to initiate the lock pointed to by 87.Fa rwl . 88The 89.Fa name 90argument specifies the name of the lock, which is used as the wait message 91if the thread needs to sleep. 92.Pp 93The 94.Fn rw_enter 95function acquires a lock. 96The 97.Fa flags 98argument specifies what kind of lock should be obtained and also 99modifies the operation. 100The possible flags are: 101.Pp 102.Bl -tag -offset indent -width RW_DOWNGRADEXXX -compact 103.It Dv RW_READ 104Acquire a shared lock. 105.It Dv RW_WRITE 106Acquire an exclusive lock. 107.It Dv RW_DOWNGRADE 108Safely release an exclusive lock and acquire a shared lock without 109letting other exclusive locks in between. 110.It Dv RW_INTR 111When waiting for a lock, allow signals to interrupt the sleep. 112.It Dv RW_NOSLEEP 113Do not wait for busy locks, fail with 114.Dv EBUSY 115instead. 116.It Dv RW_SLEEPFAIL 117Wait for busy locks, but do not obtain them, fail with 118.Dv EAGAIN 119instead. 120.El 121.Pp 122The 123.Fn rw_exit 124function is used to release a held lock. 125.Pp 126The 127.Fn rw_enter_read 128function acquires a read lock, sleeping if necessary. 129.Pp 130The 131.Fn rw_enter_write 132function acquires a write lock, sleeping if necessary. 133.Pp 134The 135.Fn rw_exit_read 136function releases a read lock. 137.Pp 138The 139.Fn rw_exit_write 140function releases a write lock. 141.Pp 142The 143.Fn rw_assert_wrlock , 144.Fn rw_assert_rdlock , 145and 146.Fn rw_assert_unlocked 147functions check the status 148.Fa rwl , 149panicking if it is not write-, read-, or unlocked, respectively. 150.Pp 151.Nm rw_status 152returns the current state of the lock: 153.Pp 154.Bl -tag -width "RW_WRITE_OTHER" -offset indent -compact 155.It Dv RW_WRITE 156Lock is write locked by the calling thread. 157.It Dv RW_WRITE_OTHER 158Lock is write locked by a different thread. 159.It Dv RW_READ 160Lock is read locked. 161The current thread may be one of the threads that has it locked. 162.It 0 163Lock is not locked. 164.El 165.Pp 166A lock declaration may be initialised with the 167.Fn RWLOCK_INITIALIZER 168macro. 169The 170.Fa name 171argument specifies the name of the lock, which is used as the wait message 172if the thread needs to sleep. 173.Pp 174The 175.Nm rrwlock 176functions support recursive write locking by the same process. 177They otherwise behave the same as their rwlock counterparts. 178.Sh CONTEXT 179.Fn rw_init 180and 181.Fn rrw_init 182can be called during autoconf, from process context, or from interrupt context. 183.Pp 184All other functions can be called during autoconf or from process context. 185.Sh SEE ALSO 186.Xr mutex 9 , 187.Xr spl 9 188.Sh HISTORY 189The 190.Nm 191functions first appeared in 192.Ox 3.5 . 193.Sh AUTHORS 194The 195.Nm 196functions were written by 197.An Artur Grabowski Aq Mt art@openbsd.org . 198