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