rwlock.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1998-2001, 2003  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: rwlock.h,v 1.28 2007/06/19 23:47:18 tbox Exp $ */
00019 
00020 #ifndef ISC_RWLOCK_H
00021 #define ISC_RWLOCK_H 1
00022 
00023 /*! \file isc/rwlock.h */
00024 
00025 #include <isc/condition.h>
00026 #include <isc/lang.h>
00027 #include <isc/platform.h>
00028 #include <isc/types.h>
00029 
00030 ISC_LANG_BEGINDECLS
00031 
00032 typedef enum {
00033         isc_rwlocktype_none = 0,
00034         isc_rwlocktype_read,
00035         isc_rwlocktype_write
00036 } isc_rwlocktype_t;
00037 
00038 #ifdef ISC_PLATFORM_USETHREADS
00039 #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
00040 #define ISC_RWLOCK_USEATOMIC 1
00041 #endif
00042 
00043 struct isc_rwlock {
00044         /* Unlocked. */
00045         unsigned int            magic;
00046         isc_mutex_t             lock;
00047 
00048 #if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
00049         /*
00050          * When some atomic instructions with hardware assistance are
00051          * available, rwlock will use those so that concurrent readers do not
00052          * interfere with each other through mutex as long as no writers
00053          * appear, massively reducing the lock overhead in the typical case.
00054          *
00055          * The basic algorithm of this approach is the "simple
00056          * writer-preference lock" shown in the following URL:
00057          * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
00058          * but our implementation does not rely on the spin lock unlike the
00059          * original algorithm to be more portable as a user space application.
00060          */
00061 
00062         /* Read or modified atomically. */
00063         isc_int32_t             write_requests;
00064         isc_int32_t             write_completions;
00065         isc_int32_t             cnt_and_flag;
00066 
00067         /* Locked by lock. */
00068         isc_condition_t         readable;
00069         isc_condition_t         writeable;
00070         unsigned int            readers_waiting;
00071 
00072         /* Locked by rwlock itself. */
00073         unsigned int            write_granted;
00074 
00075         /* Unlocked. */
00076         unsigned int            write_quota;
00077 
00078 #else  /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
00079 
00080         /*%< Locked by lock. */
00081         isc_condition_t         readable;
00082         isc_condition_t         writeable;
00083         isc_rwlocktype_t        type;
00084 
00085         /*% The number of threads that have the lock. */
00086         unsigned int            active;
00087 
00088         /*%
00089          * The number of lock grants made since the lock was last switched
00090          * from reading to writing or vice versa; used in determining
00091          * when the quota is reached and it is time to switch.
00092          */
00093         unsigned int            granted;
00094         
00095         unsigned int            readers_waiting;
00096         unsigned int            writers_waiting;
00097         unsigned int            read_quota;
00098         unsigned int            write_quota;
00099         isc_rwlocktype_t        original;
00100 #endif  /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
00101 };
00102 #else /* ISC_PLATFORM_USETHREADS */
00103 struct isc_rwlock {
00104         unsigned int            magic;
00105         isc_rwlocktype_t        type;
00106         unsigned int            active;
00107 };
00108 #endif /* ISC_PLATFORM_USETHREADS */
00109 
00110 
00111 isc_result_t
00112 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
00113                 unsigned int write_quota);
00114 
00115 isc_result_t
00116 isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
00117 
00118 isc_result_t
00119 isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
00120 
00121 isc_result_t
00122 isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
00123 
00124 isc_result_t
00125 isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
00126 
00127 void
00128 isc_rwlock_downgrade(isc_rwlock_t *rwl);
00129 
00130 void
00131 isc_rwlock_destroy(isc_rwlock_t *rwl);
00132 
00133 ISC_LANG_ENDDECLS
00134 
00135 #endif /* ISC_RWLOCK_H */

Generated on Tue Apr 28 17:41:04 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha