xref: /minix3/external/bsd/bind/dist/lib/isc/include/isc/rwlock.h (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: rwlock.h,v 1.5 2014/12/10 04:38:00 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: rwlock.h,v 1.28 2007/06/19 23:47:18 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek #ifndef ISC_RWLOCK_H
23*00b67f09SDavid van Moolenbroek #define ISC_RWLOCK_H 1
24*00b67f09SDavid van Moolenbroek 
25*00b67f09SDavid van Moolenbroek /*! \file isc/rwlock.h */
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include <isc/condition.h>
28*00b67f09SDavid van Moolenbroek #include <isc/lang.h>
29*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
30*00b67f09SDavid van Moolenbroek #include <isc/types.h>
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek ISC_LANG_BEGINDECLS
33*00b67f09SDavid van Moolenbroek 
34*00b67f09SDavid van Moolenbroek typedef enum {
35*00b67f09SDavid van Moolenbroek 	isc_rwlocktype_none = 0,
36*00b67f09SDavid van Moolenbroek 	isc_rwlocktype_read,
37*00b67f09SDavid van Moolenbroek 	isc_rwlocktype_write
38*00b67f09SDavid van Moolenbroek } isc_rwlocktype_t;
39*00b67f09SDavid van Moolenbroek 
40*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
41*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USE_NATIVE_RWLOCKS
42*00b67f09SDavid van Moolenbroek #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
43*00b67f09SDavid van Moolenbroek #define ISC_RWLOCK_USEATOMIC 1
44*00b67f09SDavid van Moolenbroek #endif
45*00b67f09SDavid van Moolenbroek 
46*00b67f09SDavid van Moolenbroek struct isc_rwlock {
47*00b67f09SDavid van Moolenbroek 	/* Unlocked. */
48*00b67f09SDavid van Moolenbroek 	unsigned int		magic;
49*00b67f09SDavid van Moolenbroek 	isc_mutex_t		lock;
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
52*00b67f09SDavid van Moolenbroek 	/*
53*00b67f09SDavid van Moolenbroek 	 * When some atomic instructions with hardware assistance are
54*00b67f09SDavid van Moolenbroek 	 * available, rwlock will use those so that concurrent readers do not
55*00b67f09SDavid van Moolenbroek 	 * interfere with each other through mutex as long as no writers
56*00b67f09SDavid van Moolenbroek 	 * appear, massively reducing the lock overhead in the typical case.
57*00b67f09SDavid van Moolenbroek 	 *
58*00b67f09SDavid van Moolenbroek 	 * The basic algorithm of this approach is the "simple
59*00b67f09SDavid van Moolenbroek 	 * writer-preference lock" shown in the following URL:
60*00b67f09SDavid van Moolenbroek 	 * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
61*00b67f09SDavid van Moolenbroek 	 * but our implementation does not rely on the spin lock unlike the
62*00b67f09SDavid van Moolenbroek 	 * original algorithm to be more portable as a user space application.
63*00b67f09SDavid van Moolenbroek 	 */
64*00b67f09SDavid van Moolenbroek 
65*00b67f09SDavid van Moolenbroek 	/* Read or modified atomically. */
66*00b67f09SDavid van Moolenbroek 	isc_int32_t		write_requests;
67*00b67f09SDavid van Moolenbroek 	isc_int32_t		write_completions;
68*00b67f09SDavid van Moolenbroek 	isc_int32_t		cnt_and_flag;
69*00b67f09SDavid van Moolenbroek 
70*00b67f09SDavid van Moolenbroek 	/* Locked by lock. */
71*00b67f09SDavid van Moolenbroek 	isc_condition_t		readable;
72*00b67f09SDavid van Moolenbroek 	isc_condition_t		writeable;
73*00b67f09SDavid van Moolenbroek 	unsigned int		readers_waiting;
74*00b67f09SDavid van Moolenbroek 
75*00b67f09SDavid van Moolenbroek 	/* Locked by rwlock itself. */
76*00b67f09SDavid van Moolenbroek 	unsigned int		write_granted;
77*00b67f09SDavid van Moolenbroek 
78*00b67f09SDavid van Moolenbroek 	/* Unlocked. */
79*00b67f09SDavid van Moolenbroek 	unsigned int		write_quota;
80*00b67f09SDavid van Moolenbroek 
81*00b67f09SDavid van Moolenbroek #else  /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
82*00b67f09SDavid van Moolenbroek 
83*00b67f09SDavid van Moolenbroek 	/*%< Locked by lock. */
84*00b67f09SDavid van Moolenbroek 	isc_condition_t		readable;
85*00b67f09SDavid van Moolenbroek 	isc_condition_t		writeable;
86*00b67f09SDavid van Moolenbroek 	isc_rwlocktype_t	type;
87*00b67f09SDavid van Moolenbroek 
88*00b67f09SDavid van Moolenbroek 	/*% The number of threads that have the lock. */
89*00b67f09SDavid van Moolenbroek 	unsigned int		active;
90*00b67f09SDavid van Moolenbroek 
91*00b67f09SDavid van Moolenbroek 	/*%
92*00b67f09SDavid van Moolenbroek 	 * The number of lock grants made since the lock was last switched
93*00b67f09SDavid van Moolenbroek 	 * from reading to writing or vice versa; used in determining
94*00b67f09SDavid van Moolenbroek 	 * when the quota is reached and it is time to switch.
95*00b67f09SDavid van Moolenbroek 	 */
96*00b67f09SDavid van Moolenbroek 	unsigned int		granted;
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek 	unsigned int		readers_waiting;
99*00b67f09SDavid van Moolenbroek 	unsigned int		writers_waiting;
100*00b67f09SDavid van Moolenbroek 	unsigned int		read_quota;
101*00b67f09SDavid van Moolenbroek 	unsigned int		write_quota;
102*00b67f09SDavid van Moolenbroek 	isc_rwlocktype_t	original;
103*00b67f09SDavid van Moolenbroek #endif  /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
104*00b67f09SDavid van Moolenbroek };
105*00b67f09SDavid van Moolenbroek #endif /* !ISC_PLATFORM_USE_NATIVE_RWLOCKS */
106*00b67f09SDavid van Moolenbroek #else /* ISC_PLATFORM_USETHREADS */
107*00b67f09SDavid van Moolenbroek struct isc_rwlock {
108*00b67f09SDavid van Moolenbroek 	unsigned int		magic;
109*00b67f09SDavid van Moolenbroek 	isc_rwlocktype_t	type;
110*00b67f09SDavid van Moolenbroek 	unsigned int		active;
111*00b67f09SDavid van Moolenbroek };
112*00b67f09SDavid van Moolenbroek #endif /* ISC_PLATFORM_USETHREADS */
113*00b67f09SDavid van Moolenbroek 
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek isc_result_t
116*00b67f09SDavid van Moolenbroek isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
117*00b67f09SDavid van Moolenbroek 		unsigned int write_quota);
118*00b67f09SDavid van Moolenbroek 
119*00b67f09SDavid van Moolenbroek isc_result_t
120*00b67f09SDavid van Moolenbroek isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek isc_result_t
123*00b67f09SDavid van Moolenbroek isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek isc_result_t
126*00b67f09SDavid van Moolenbroek isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
127*00b67f09SDavid van Moolenbroek 
128*00b67f09SDavid van Moolenbroek isc_result_t
129*00b67f09SDavid van Moolenbroek isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
130*00b67f09SDavid van Moolenbroek 
131*00b67f09SDavid van Moolenbroek void
132*00b67f09SDavid van Moolenbroek isc_rwlock_downgrade(isc_rwlock_t *rwl);
133*00b67f09SDavid van Moolenbroek 
134*00b67f09SDavid van Moolenbroek void
135*00b67f09SDavid van Moolenbroek isc_rwlock_destroy(isc_rwlock_t *rwl);
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek ISC_LANG_ENDDECLS
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek #endif /* ISC_RWLOCK_H */
140