From: Dmitry Eremin-Solenikov <[email protected]> odp_rwlock_read_trylock() currently works only if there are no readers (and writers) as it compares counter with 0. Make it actually work in case there are other active readers.
Fixes: https://bugs.linaro.org/show_bug.cgi?id=2974 Signed-off-by: Dmitry Eremin-Solenikov <[email protected]> --- /** Email created from pull request 19 (lumag:fix-rwlock) ** https://github.com/Linaro/odp/pull/19 ** Patch: https://github.com/Linaro/odp/pull/19.patch ** Base sha: 79ba737a404d2833ad33d8f84ed6ce82c9a8c18e ** Merge commit sha: 8448157882fac03287253bf54c19284b6d52246e **/ platform/linux-generic/odp_rwlock.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/linux-generic/odp_rwlock.c b/platform/linux-generic/odp_rwlock.c index 13c17a2..5bef13a 100644 --- a/platform/linux-generic/odp_rwlock.c +++ b/platform/linux-generic/odp_rwlock.c @@ -33,9 +33,14 @@ void odp_rwlock_read_lock(odp_rwlock_t *rwlock) int odp_rwlock_read_trylock(odp_rwlock_t *rwlock) { - uint32_t zero = 0; + uint32_t cnt = odp_atomic_load_u32(&rwlock->cnt); + + while (cnt != (uint32_t)-1) { + if (odp_atomic_cas_acq_u32(&rwlock->cnt, &cnt, cnt + 1)) + return 1; + } - return odp_atomic_cas_acq_u32(&rwlock->cnt, &zero, (uint32_t)1); + return 0; } void odp_rwlock_read_unlock(odp_rwlock_t *rwlock)
