aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dmitry.ereminsolenikov@linaro.org>2017-05-05 01:00:08 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2017-05-12 01:27:29 +0300
commit86e5b478325a0f5422fc6edff9db168d44852d2e (patch)
tree3fc87b349500574b5c30df1296878a4f6721951c /platform/linux-generic
parentc1e962548f5082554bb52137765a258b3a29283c (diff)
linux-generic: rwlock: fix odp_rwlock_read_trylock()
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 <dmitry.ereminsolenikov@linaro.org> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'platform/linux-generic')
-rw-r--r--platform/linux-generic/odp_rwlock.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/platform/linux-generic/odp_rwlock.c b/platform/linux-generic/odp_rwlock.c
index 13c17a2c7..5bef13a45 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)