diff options
-rw-r--r-- | platform/linux-generic/odp_rwlock.c | 14 | ||||
-rw-r--r-- | platform/linux-generic/odp_rwlock_recursive.c | 37 |
2 files changed, 51 insertions, 0 deletions
diff --git a/platform/linux-generic/odp_rwlock.c b/platform/linux-generic/odp_rwlock.c index f50fd5f2a..13c17a2c7 100644 --- a/platform/linux-generic/odp_rwlock.c +++ b/platform/linux-generic/odp_rwlock.c @@ -31,6 +31,13 @@ void odp_rwlock_read_lock(odp_rwlock_t *rwlock) } } +int odp_rwlock_read_trylock(odp_rwlock_t *rwlock) +{ + uint32_t zero = 0; + + return odp_atomic_cas_acq_u32(&rwlock->cnt, &zero, (uint32_t)1); +} + void odp_rwlock_read_unlock(odp_rwlock_t *rwlock) { odp_atomic_sub_rel_u32(&rwlock->cnt, 1); @@ -54,6 +61,13 @@ void odp_rwlock_write_lock(odp_rwlock_t *rwlock) } } +int odp_rwlock_write_trylock(odp_rwlock_t *rwlock) +{ + uint32_t zero = 0; + + return odp_atomic_cas_acq_u32(&rwlock->cnt, &zero, (uint32_t)-1); +} + void odp_rwlock_write_unlock(odp_rwlock_t *rwlock) { odp_atomic_store_rel_u32(&rwlock->cnt, 0); diff --git a/platform/linux-generic/odp_rwlock_recursive.c b/platform/linux-generic/odp_rwlock_recursive.c index 2338b535b..6b0228143 100644 --- a/platform/linux-generic/odp_rwlock_recursive.c +++ b/platform/linux-generic/odp_rwlock_recursive.c @@ -31,6 +31,24 @@ void odp_rwlock_recursive_read_lock(odp_rwlock_recursive_t *rlock) rlock->rd_cnt[thr] = 1; } +/* Multiple readers can recurse the lock concurrently */ +int odp_rwlock_recursive_read_trylock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + if (rlock->rd_cnt[thr]) { + rlock->rd_cnt[thr]++; + return 1; + } + + if (odp_rwlock_read_trylock(&rlock->lock)) { + rlock->rd_cnt[thr] = 1; + return 1; + } + + return 0; +} + void odp_rwlock_recursive_read_unlock(odp_rwlock_recursive_t *rlock) { int thr = odp_thread_id(); @@ -58,6 +76,25 @@ void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *rlock) rlock->wr_cnt = 1; } +/* Only one writer can recurse the lock */ +int odp_rwlock_recursive_write_trylock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + if (rlock->wr_owner == thr) { + rlock->wr_cnt++; + return 1; + } + + if (odp_rwlock_write_trylock(&rlock->lock)) { + rlock->wr_owner = thr; + rlock->wr_cnt = 1; + return 1; + } + + return 0; +} + void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *rlock) { rlock->wr_cnt--; |