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 30ISC_LANG_BEGINDECLS 31 32typedef 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 43struct 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 */ 103struct isc_rwlock { 104 unsigned int magic; 105 isc_rwlocktype_t type; 106 unsigned int active; 107}; 108#endif /* ISC_PLATFORM_USETHREADS */ 109 110 111isc_result_t 112isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, 113 unsigned int write_quota); 114 115isc_result_t 116isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type); 117 118isc_result_t 119isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type); 120 121isc_result_t 122isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type); 123 124isc_result_t 125isc_rwlock_tryupgrade(isc_rwlock_t *rwl); 126 127void 128isc_rwlock_downgrade(isc_rwlock_t *rwl); 129 130void 131isc_rwlock_destroy(isc_rwlock_t *rwl); 132 133ISC_LANG_ENDDECLS 134 135#endif /* ISC_RWLOCK_H */ 136