2 * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and 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.
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.
18 /* $Id: rwlock.h,v 1.21.18.3 2005/06/04 06:23:44 jinmei Exp $ */
21 #define ISC_RWLOCK_H 1
25 #include <isc/condition.h>
27 #include <isc/platform.h>
28 #include <isc/types.h>
33 isc_rwlocktype_none = 0,
38 #ifdef ISC_PLATFORM_USETHREADS
39 #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
40 #define ISC_RWLOCK_USEATOMIC 1
48 #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
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.
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.
62 /* Read or modified atomically. */
63 isc_int32_t write_requests;
64 isc_int32_t write_completions;
65 isc_int32_t cnt_and_flag;
68 isc_condition_t readable;
69 isc_condition_t writeable;
70 unsigned int readers_waiting;
72 /* Locked by rwlock itself. */
73 unsigned int write_granted;
76 unsigned int write_quota;
78 #else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
80 /*%< Locked by lock. */
81 isc_condition_t readable;
82 isc_condition_t writeable;
83 isc_rwlocktype_t type;
85 /*% The number of threads that have the lock. */
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.
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 */
102 #else /* ISC_PLATFORM_USETHREADS */
105 isc_rwlocktype_t type;
108 #endif /* ISC_PLATFORM_USETHREADS */
112 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
113 unsigned int write_quota);
116 isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
119 isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
122 isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
125 isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
128 isc_rwlock_downgrade(isc_rwlock_t *rwl);
131 isc_rwlock_destroy(isc_rwlock_t *rwl);
135 #endif /* ISC_RWLOCK_H */