From 994ba9c913a973025de6a4f32c8a6b73f9f2ff4f Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Thu, 12 Nov 1998 22:27:30 +0000 Subject: [PATCH] add write quota --- bin/tests/rwlock_test.c | 4 ++-- lib/isc/include/isc/rwlock.h | 4 +++- lib/isc/rwlock.c | 27 ++++++++++++++++++++++----- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/bin/tests/rwlock_test.c b/bin/tests/rwlock_test.c index 91fb784b74..9238a7bacb 100644 --- a/bin/tests/rwlock_test.c +++ b/bin/tests/rwlock_test.c @@ -79,14 +79,14 @@ main(int argc, char *argv[]) { nworkers = 24; printf("%d workers\n", nworkers); - INSIST(isc_rwlock_init(&lock) == ISC_R_SUCCESS); + INSIST(isc_rwlock_init(&lock, 5, 10) == ISC_R_SUCCESS); for (i = 0; i < nworkers; i++) { sprintf(name, "%02u", i); dupname = strdup(name); INSIST(dupname != NULL); if (i != 0 && i % 3 == 0) - INSIST(isc_thread_create(run2, dupname, &workers[i]) == + INSIST(isc_thread_create(run1, dupname, &workers[i]) == ISC_R_SUCCESS); else INSIST(isc_thread_create(run1, dupname, &workers[i]) == diff --git a/lib/isc/include/isc/rwlock.h b/lib/isc/include/isc/rwlock.h index 7f3b009cb3..b87377a2a7 100644 --- a/lib/isc/include/isc/rwlock.h +++ b/lib/isc/include/isc/rwlock.h @@ -21,10 +21,12 @@ typedef struct isc_rwlock { unsigned int readers_waiting; unsigned int writers_waiting; unsigned int read_quota; + unsigned int write_quota; } isc_rwlock_t; isc_result_t -isc_rwlock_init(isc_rwlock_t *rwl); +isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota, + unsigned int write_quota); isc_result_t isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type); diff --git a/lib/isc/rwlock.c b/lib/isc/rwlock.c index f8fb10be0d..3b3b342627 100644 --- a/lib/isc/rwlock.c +++ b/lib/isc/rwlock.c @@ -32,7 +32,10 @@ print_lock(char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) { } isc_result_t -isc_rwlock_init(isc_rwlock_t *rwl) { +isc_rwlock_init(isc_rwlock_t *rwl, + unsigned int read_quota, + unsigned int write_quota) +{ isc_result_t result; REQUIRE(rwl != NULL); @@ -42,7 +45,12 @@ isc_rwlock_init(isc_rwlock_t *rwl) { rwl->granted = 0; rwl->readers_waiting = 0; rwl->writers_waiting = 0; - rwl->read_quota = 5; /* XXX */ + if (read_quota == 0) + read_quota = 4; + rwl->read_quota = read_quota; + if (write_quota == 0) + write_quota = 4; + rwl->write_quota = write_quota; result = isc_mutex_init(&rwl->lock); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, @@ -105,6 +113,7 @@ isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { if (!skip && rwl->active == 0) { rwl->type = isc_rwlocktype_write; rwl->active = 1; + rwl->granted++; done = ISC_TRUE; } else { skip = ISC_FALSE; @@ -135,19 +144,27 @@ isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type) { rwl->active--; if (rwl->active == 0) { - rwl->granted = 0; if (rwl->type == isc_rwlocktype_read) { + rwl->granted = 0; if (rwl->writers_waiting > 0) { rwl->type = isc_rwlocktype_write; SIGNAL(&rwl->writeable); } else if (rwl->readers_waiting > 0) { + /* Does this case ever happen? */ BROADCAST(&rwl->readable); } } else { if (rwl->readers_waiting > 0) { - rwl->type = isc_rwlocktype_read; - BROADCAST(&rwl->readable); + if (rwl->writers_waiting > 0 && + rwl->granted < rwl->write_quota) { + SIGNAL(&rwl->writeable); + } else { + rwl->granted = 0; + rwl->type = isc_rwlocktype_read; + BROADCAST(&rwl->readable); + } } else if (rwl->writers_waiting > 0) { + rwl->granted = 0; SIGNAL(&rwl->writeable); } }