rwlock.c revision 28a8f5b0de57d269cf2845c69cb6abe18cbd3b3a
279c6ec074be17dce62dd1b2c6ed7c2cc56a7b78David Lawrence * Copyright (C) 2004, 2005, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
703e1c0bb66f3cd3d300358ca0c1fdf3cb5fb1c5Brian Wellington * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
279c6ec074be17dce62dd1b2c6ed7c2cc56a7b78David Lawrence * Permission to use, copy, modify, and/or distribute this software for any
279c6ec074be17dce62dd1b2c6ed7c2cc56a7b78David Lawrence * purpose with or without fee is hereby granted, provided that the above
279c6ec074be17dce62dd1b2c6ed7c2cc56a7b78David Lawrence * copyright notice and this permission notice appear in all copies.
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington * PERFORMANCE OF THIS SOFTWARE.
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley#define RWLOCK_MAGIC ISC_MAGIC('R', 'W', 'L', 'k')
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley#define VALID_RWLOCK(rwl) ISC_MAGIC_VALID(rwl, RWLOCK_MAGIC)
a30e7fc23415fd238d067a8a871607bca36068baMichael Graff#include <stdio.h> /* Required for fprintf/stderr. */
8d4257cff01b3821abcb9a21f46c6c6a43bb1e72Bob Halley#include <isc/thread.h> /* Required for isc_thread_self(). */
8d4257cff01b3821abcb9a21f46c6c6a43bb1e72Bob Halleyprint_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence "rwlock %p thread %lu %s(%s): %s, %u active, "
dc97fe4ed08488d314ab5bc8e99ed839542cf411David Lawrence "%u granted, %u rwaiting, %u wwaiting\n"),
7005cfed8cd3296d356883dcb414979f22e06b13Brian Wellington isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
194b6a25192581bbc8ec731e32e8989042b202a4Michael Graffisc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
703e1c0bb66f3cd3d300358ca0c1fdf3cb5fb1c5Brian Wellington * In case there's trouble initializing, we zero magic now. If all
703e1c0bb66f3cd3d300358ca0c1fdf3cb5fb1c5Brian Wellington * goes well, we'll set it to RWLOCK_MAGIC.
0eb2572d79822d02ea05448ce4e5f1759c73d171Michael Graff#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
17012a879742ceb6561dcc4ae3bcd4ff80dc9887David Lawrence "read quota is not supported");
49a2cf8f211213712d452287ae8e121cf59e3178David Lawrence "isc_condition_init(readable) %s: %s",
49a2cf8f211213712d452287ae8e121cf59e3178David Lawrence isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
a14613fce99dee3cad5bf842fd6be78f8e463582Brian Wellington result = isc_condition_init(&rwl->writeable);
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington "isc_condition_init(writeable) %s: %s",
489b76292622f5bc18bf1a18845f8166a73bd797Brian Wellington isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
15bfd48fc5552ff1aae766021f42a250c001a098Michael Graff#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
15bfd48fc5552ff1aae766021f42a250c001a098Michael Graff REQUIRE(rwl->write_requests == rwl->write_completions &&
15bfd48fc5552ff1aae766021f42a250c001a098Michael Graff rwl->cnt_and_flag == 0 && rwl->readers_waiting == 0);
#ifdef ISC_RWLOCK_TRACE
if (cntflag == 0)
#ifdef ISC_RWLOCK_TRACE
return (ISC_R_SUCCESS);
#ifdef ISC_RWLOCK_TRACE
return (ISC_R_LOCKBUSY);
-READER_INCR);
return (ISC_R_LOCKBUSY);
if (cntflag != 0)
return (ISC_R_LOCKBUSY);
#ifdef ISC_RWLOCK_TRACE
return (ISC_R_SUCCESS);
return (ISC_R_LOCKBUSY);
return (ISC_R_SUCCESS);
#ifdef ISC_RWLOCK_TRACE
#ifdef ISC_RWLOCK_TRACE
return (ISC_R_SUCCESS);
static isc_result_t
#ifdef ISC_RWLOCK_TRACE
while (!done) {
if (!skip &&
} else if (nonblock) {
while (!done) {
} else if (nonblock) {
#ifdef ISC_RWLOCK_TRACE
return (result);
return (result);
#ifdef ISC_RWLOCK_TRACE
#ifdef ISC_RWLOCK_TRACE
return (ISC_R_SUCCESS);
unsigned int write_quota)
return (ISC_R_SUCCESS);
return (ISC_R_LOCKBUSY);
return (ISC_R_LOCKBUSY);
return (ISC_R_SUCCESS);
return (result);
return (ISC_R_SUCCESS);