2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

Remove one level of indirection from isc_rwlock [1/2]

Instead of checking the PTHREAD_RUNTIME_CHECK from the header, move it
to the pthread_rwlock implementation functions.  The internal isc_rwlock
actually cannot fail, so the checks in the header was useless anyway.
This commit is contained in:
Ondřej Surý
2022-10-14 12:03:02 +02:00
parent 68cfbd238c
commit 6bd201ccec
2 changed files with 70 additions and 82 deletions

View File

@@ -46,13 +46,13 @@ typedef pthread_rwlock_t isc__rwlock_t;
isc__rwlock_init(*rwl, rq, wq); \ isc__rwlock_init(*rwl, rq, wq); \
} }
#define isc_rwlock_lock(rwl, type) isc__rwlock_lock(*rwl, type) #define isc_rwlock_lock(rwl, type) isc__rwlock_lock(*rwl, type)
#define isc_rwlock_trylock(rwl, type) isc___rwlock_trylock(*rwl, type) #define isc_rwlock_trylock(rwl, type) isc__rwlock_trylock(*rwl, type)
#define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(*rwl, type) #define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(*rwl, type)
#define isc_rwlock_tryupgrade(rwl) isc___rwlock_tryupgrade(*rwl) #define isc_rwlock_tryupgrade(rwl) isc__rwlock_tryupgrade(*rwl)
#define isc_rwlock_destroy(rwl) \ #define isc_rwlock_destroy(rwl) \
{ \ { \
isc___rwlock_destroy(*rwl); \ isc__rwlock_destroy(*rwl); \
free(*rwl); \ free(*rwl); \
} }
#else /* ISC_TRACK_PTHREADS_OBJECTS */ #else /* ISC_TRACK_PTHREADS_OBJECTS */
@@ -62,9 +62,9 @@ typedef pthread_rwlock_t isc__rwlock_t;
#define isc_rwlock_init(rwl, rq, wq) isc__rwlock_init(rwl, rq, wq) #define isc_rwlock_init(rwl, rq, wq) isc__rwlock_init(rwl, rq, wq)
#define isc_rwlock_lock(rwl, type) isc__rwlock_lock(rwl, type) #define isc_rwlock_lock(rwl, type) isc__rwlock_lock(rwl, type)
#define isc_rwlock_trylock(rwl, type) isc___rwlock_trylock(rwl, type) #define isc_rwlock_trylock(rwl, type) isc__rwlock_trylock(rwl, type)
#define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(rwl, type) #define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(rwl, type)
#define isc_rwlock_tryupgrade(rwl) isc___rwlock_tryupgrade(rwl) #define isc_rwlock_tryupgrade(rwl) isc__rwlock_tryupgrade(rwl)
#define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl) #define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl)
#endif /* ISC_TRACK_PTHREADS_OBJECTS */ #endif /* ISC_TRACK_PTHREADS_OBJECTS */
@@ -112,54 +112,30 @@ typedef struct isc_rwlock isc__rwlock_t;
#define isc_rwlock_init(rwl, rq, wq) isc__rwlock_init(rwl, rq, wq) #define isc_rwlock_init(rwl, rq, wq) isc__rwlock_init(rwl, rq, wq)
#define isc_rwlock_lock(rwl, type) isc__rwlock_lock(rwl, type) #define isc_rwlock_lock(rwl, type) isc__rwlock_lock(rwl, type)
#define isc_rwlock_trylock(rwl, type) isc___rwlock_trylock(rwl, type) #define isc_rwlock_trylock(rwl, type) isc__rwlock_trylock(rwl, type)
#define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(rwl, type) #define isc_rwlock_unlock(rwl, type) isc__rwlock_unlock(rwl, type)
#define isc_rwlock_tryupgrade(rwl) isc___rwlock_tryupgrade(rwl) #define isc_rwlock_tryupgrade(rwl) isc__rwlock_tryupgrade(rwl)
#define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl) #define isc_rwlock_destroy(rwl) isc__rwlock_destroy(rwl)
#endif /* USE_PTHREAD_RWLOCK */ #endif /* USE_PTHREAD_RWLOCK */
#define isc__rwlock_init(rwl, rq, wq) \ void
{ \ isc__rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota,
int _ret = isc___rwlock_init(rwl, rq, wq); \ unsigned int write_quota);
PTHREADS_RUNTIME_CHECK(isc___rwlock_init, _ret); \
}
#define isc__rwlock_lock(rwl, type) \ void
{ \ isc__rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
int _ret = isc___rwlock_lock(rwl, type); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_lock, _ret); \
}
#define isc__rwlock_unlock(rwl, type) \
{ \
int _ret = isc___rwlock_unlock(rwl, type); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_unlock, _ret); \
}
#define isc__rwlock_destroy(rwl) \
{ \
int _ret = isc___rwlock_destroy(rwl); \
PTHREADS_RUNTIME_CHECK(isc___rwlock_destroy, _ret); \
}
int
isc___rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota,
unsigned int write_quota);
int
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
isc_result_t isc_result_t
isc___rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type); isc__rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
int void
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type); isc__rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type);
isc_result_t isc_result_t
isc___rwlock_tryupgrade(isc__rwlock_t *rwl); isc__rwlock_tryupgrade(isc__rwlock_t *rwl);
int void
isc___rwlock_destroy(isc__rwlock_t *rwl); isc__rwlock_destroy(isc__rwlock_t *rwl);
ISC_LANG_ENDDECLS ISC_LANG_ENDDECLS

View File

@@ -32,32 +32,36 @@
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
int void
isc___rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota, isc__rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota,
unsigned int write_quota) { unsigned int write_quota) {
int ret; int ret;
UNUSED(read_quota); UNUSED(read_quota);
UNUSED(write_quota); UNUSED(write_quota);
ret = pthread_rwlock_init(rwl, NULL); ret = pthread_rwlock_init(rwl, NULL);
PTHREADS_RUNTIME_CHECK(pthread_rwlock_init, ret);
return (ret);
} }
int void
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) { isc__rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int ret;
switch (type) { switch (type) {
case isc_rwlocktype_read: case isc_rwlocktype_read:
return (pthread_rwlock_rdlock(rwl)); ret = pthread_rwlock_rdlock(rwl);
PTHREADS_RUNTIME_CHECK(pthread_rwlock_rdlock, ret);
break;
case isc_rwlocktype_write: case isc_rwlocktype_write:
return (pthread_rwlock_wrlock(rwl)); ret = pthread_rwlock_wrlock(rwl);
PTHREADS_RUNTIME_CHECK(pthread_rwlock_rwlock, ret);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
} }
isc_result_t isc_result_t
isc___rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type) { isc__rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int ret = 0; int ret = 0;
switch (type) { switch (type) {
case isc_rwlocktype_read: case isc_rwlocktype_read:
@@ -78,25 +82,41 @@ isc___rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
case EAGAIN: case EAGAIN:
return (ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY);
default: default:
UNREACHABLE(); break;
} }
switch (type) {
case isc_rwlocktype_read:
PTHREADS_RUNTIME_CHECK(pthread_rwlock_tryrdlock, ret);
break;
case isc_rwlocktype_write:
PTHREADS_RUNTIME_CHECK(pthread_rwlock_trywrlock, ret);
break;
default:
break;
}
UNREACHABLE();
} }
int void
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) { isc__rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int ret;
UNUSED(type); UNUSED(type);
return (pthread_rwlock_unlock(rwl)); ret = pthread_rwlock_unlock(rwl);
PTHREADS_RUNTIME_CHECK(pthread_rwlock_rwlock, ret);
} }
isc_result_t isc_result_t
isc___rwlock_tryupgrade(isc__rwlock_t *rwl) { isc__rwlock_tryupgrade(isc__rwlock_t *rwl) {
UNUSED(rwl); UNUSED(rwl);
return (ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY);
} }
int void
isc___rwlock_destroy(isc__rwlock_t *rwl) { isc__rwlock_destroy(isc__rwlock_t *rwl) {
return (pthread_rwlock_destroy(rwl)); int ret = pthread_rwlock_destroy(rwl);
PTHREADS_RUNTIME_CHECK(pthread_rwlock_destroy, ret);
} }
#else /* if USE_PTHREAD_RWLOCK */ #else /* if USE_PTHREAD_RWLOCK */
@@ -160,9 +180,9 @@ print_lock(const char *operation, isc__rwlock_t *rwl, isc_rwlocktype_t type) {
} }
#endif /* ISC_RWLOCK_TRACE */ #endif /* ISC_RWLOCK_TRACE */
int void
isc___rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota, isc__rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota,
unsigned int write_quota) { unsigned int write_quota) {
REQUIRE(rwl != NULL); REQUIRE(rwl != NULL);
/* /*
@@ -191,12 +211,10 @@ isc___rwlock_init(isc__rwlock_t *rwl, unsigned int read_quota,
isc_condition_init(&rwl->writeable); isc_condition_init(&rwl->writeable);
rwl->magic = RWLOCK_MAGIC; rwl->magic = RWLOCK_MAGIC;
return (0);
} }
int void
isc___rwlock_destroy(isc__rwlock_t *rwl) { isc__rwlock_destroy(isc__rwlock_t *rwl) {
REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(VALID_RWLOCK(rwl));
REQUIRE(atomic_load_acquire(&rwl->write_requests) == REQUIRE(atomic_load_acquire(&rwl->write_requests) ==
@@ -208,8 +226,6 @@ isc___rwlock_destroy(isc__rwlock_t *rwl) {
isc_condition_destroy(&rwl->readable); isc_condition_destroy(&rwl->readable);
isc_condition_destroy(&rwl->writeable); isc_condition_destroy(&rwl->writeable);
isc_mutex_destroy(&rwl->lock); isc_mutex_destroy(&rwl->lock);
return (0);
} }
/* /*
@@ -394,8 +410,8 @@ rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
#endif /* ifdef ISC_RWLOCK_TRACE */ #endif /* ifdef ISC_RWLOCK_TRACE */
} }
int void
isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) { isc__rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int32_t cnt = 0; int32_t cnt = 0;
int32_t spins = atomic_load_acquire(&rwl->spins) * 2 + 10; int32_t spins = atomic_load_acquire(&rwl->spins) * 2 + 10;
int32_t max_cnt = ISC_MAX(spins, RWLOCK_MAX_ADAPTIVE_COUNT); int32_t max_cnt = ISC_MAX(spins, RWLOCK_MAX_ADAPTIVE_COUNT);
@@ -409,12 +425,10 @@ isc___rwlock_lock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
} while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS); } while (isc_rwlock_trylock(rwl, type) != ISC_R_SUCCESS);
atomic_fetch_add_release(&rwl->spins, (cnt - spins) / 8); atomic_fetch_add_release(&rwl->spins, (cnt - spins) / 8);
return (0);
} }
isc_result_t isc_result_t
isc___rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type) { isc__rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int32_t cntflag; int32_t cntflag;
REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(VALID_RWLOCK(rwl));
@@ -481,7 +495,7 @@ isc___rwlock_trylock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
} }
isc_result_t isc_result_t
isc___rwlock_tryupgrade(isc__rwlock_t *rwl) { isc__rwlock_tryupgrade(isc__rwlock_t *rwl) {
REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(VALID_RWLOCK(rwl));
int_fast32_t reader_incr = READER_INCR; int_fast32_t reader_incr = READER_INCR;
@@ -509,8 +523,8 @@ isc___rwlock_tryupgrade(isc__rwlock_t *rwl) {
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
int void
isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) { isc__rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
int32_t prev_cnt; int32_t prev_cnt;
REQUIRE(VALID_RWLOCK(rwl)); REQUIRE(VALID_RWLOCK(rwl));
@@ -580,8 +594,6 @@ isc___rwlock_unlock(isc__rwlock_t *rwl, isc_rwlocktype_t type) {
#ifdef ISC_RWLOCK_TRACE #ifdef ISC_RWLOCK_TRACE
print_lock("postunlock", rwl, type); print_lock("postunlock", rwl, type);
#endif /* ifdef ISC_RWLOCK_TRACE */ #endif /* ifdef ISC_RWLOCK_TRACE */
return (0);
} }
#endif /* USE_PTHREAD_RWLOCK */ #endif /* USE_PTHREAD_RWLOCK */