diff --git a/lib/isc/probes.d b/lib/isc/probes.d index bc587ed4f7..f482f78976 100644 --- a/lib/isc/probes.d +++ b/lib/isc/probes.d @@ -12,4 +12,16 @@ */ provider libisc { + probe rwlock_init(void *); + probe rwlock_rdlock_req(void *); + probe rwlock_rdlock_acq(void *); + probe rwlock_wrlock_req(void *); + probe rwlock_wrlock_acq(void *); + probe rwlock_tryrdlock(void *, int); + probe rwlock_trywrlock(void *, int); + probe rwlock_rdunlock(void *); + probe rwlock_wrunlock(void *); + probe rwlock_downgrade(void *); + probe rwlock_tryupgrade(void *, int); + probe rwlock_destroy(void *); }; diff --git a/lib/isc/rwlock.c b/lib/isc/rwlock.c index ae4fc388a0..f2f3a49398 100644 --- a/lib/isc/rwlock.c +++ b/lib/isc/rwlock.c @@ -62,6 +62,8 @@ #include #include +#include "probes.h" + static atomic_uint_fast16_t isc__crwlock_workers = 128; #define ISC_RWLOCK_UNLOCKED false @@ -137,6 +139,8 @@ isc_rwlock_rdlock(isc_rwlock_t *rwl) { uint32_t cnt = 0; bool barrier_raised = false; + LIBISC_RWLOCK_RDLOCK_REQ(rwl); + while (true) { read_indicator_arrive(rwl); if (!writers_lock_islocked(rwl)) { @@ -158,6 +162,8 @@ isc_rwlock_rdlock(isc_rwlock_t *rwl) { if (barrier_raised) { writers_barrier_lower(rwl); } + + LIBISC_RWLOCK_RDLOCK_ACQ(rwl); } isc_result_t @@ -167,27 +173,32 @@ isc_rwlock_tryrdlock(isc_rwlock_t *rwl) { /* Writer has acquired the lock, release the read lock */ read_indicator_depart(rwl); + LIBISC_RWLOCK_TRYRDLOCK(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } /* Acquired lock in read-only mode */ + LIBISC_RWLOCK_TRYRDLOCK(rwl, ISC_R_SUCCESS); return (ISC_R_SUCCESS); } void isc_rwlock_rdunlock(isc_rwlock_t *rwl) { read_indicator_depart(rwl); + LIBISC_RWLOCK_RDUNLOCK(rwl); } isc_result_t isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { /* Write Barriers has been raised */ if (writers_barrier_israised(rwl)) { + LIBISC_RWLOCK_TRYUPGRADE(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } /* Try to acquire the write-lock */ if (!writers_lock_acquire(rwl)) { + LIBISC_RWLOCK_TRYUPGRADE(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } @@ -200,8 +211,10 @@ isc_rwlock_tryupgrade(isc_rwlock_t *rwl) { /* Unlock the write-lock */ writers_lock_release(rwl); + LIBISC_RWLOCK_TRYUPGRADE(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } + LIBISC_RWLOCK_TRYUPGRADE(rwl, ISC_R_SUCCESS); return (ISC_R_SUCCESS); } @@ -218,6 +231,8 @@ read_indicator_wait_until_empty(isc_rwlock_t *rwl) { void isc_rwlock_wrlock(isc_rwlock_t *rwl) { + LIBISC_RWLOCK_WRLOCK_REQ(rwl); + /* Write Barriers has been raised, wait */ while (writers_barrier_israised(rwl)) { isc_pause(); @@ -229,22 +244,27 @@ isc_rwlock_wrlock(isc_rwlock_t *rwl) { } read_indicator_wait_until_empty(rwl); + + LIBISC_RWLOCK_WRLOCK_ACQ(rwl); } void isc_rwlock_wrunlock(isc_rwlock_t *rwl) { writers_lock_release(rwl); + LIBISC_RWLOCK_WRUNLOCK(rwl); } isc_result_t isc_rwlock_trywrlock(isc_rwlock_t *rwl) { /* Write Barriers has been raised */ if (writers_barrier_israised(rwl)) { + LIBISC_RWLOCK_TRYWRLOCK(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } /* Try to acquire the write-lock */ if (!writers_lock_acquire(rwl)) { + LIBISC_RWLOCK_TRYWRLOCK(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } @@ -252,9 +272,11 @@ isc_rwlock_trywrlock(isc_rwlock_t *rwl) { /* Unlock the write-lock */ writers_lock_release(rwl); + LIBISC_RWLOCK_TRYWRLOCK(rwl, ISC_R_LOCKBUSY); return (ISC_R_LOCKBUSY); } + LIBISC_RWLOCK_TRYWRLOCK(rwl, ISC_R_SUCCESS); return (ISC_R_SUCCESS); } @@ -263,6 +285,8 @@ isc_rwlock_downgrade(isc_rwlock_t *rwl) { read_indicator_arrive(rwl); writers_lock_release(rwl); + + LIBISC_RWLOCK_DOWNGRADE(rwl); } void @@ -273,10 +297,12 @@ isc_rwlock_init(isc_rwlock_t *rwl) { atomic_init(&rwl->writers_barrier, 0); atomic_init(&rwl->readers_ingress, 0); atomic_init(&rwl->readers_egress, 0); + LIBISC_RWLOCK_INIT(rwl); } void isc_rwlock_destroy(isc_rwlock_t *rwl) { + LIBISC_RWLOCK_DESTROY(rwl); /* Check whether write lock has been unlocked */ REQUIRE(atomic_load(&rwl->writers_lock) == ISC_RWLOCK_UNLOCKED); REQUIRE(read_indicator_isempty(rwl));