diff mbox

[API-NEXT,2/3] linux-generic: rwlock: implement trylock variants of rwlock and rwlock_recursive

Message ID 1457045968-31405-2-git-send-email-bill.fischofer@linaro.org
State Superseded
Headers show

Commit Message

Bill Fischofer March 3, 2016, 10:59 p.m. UTC
Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
---
 platform/linux-generic/odp_rwlock.c           | 14 ++++++++++
 platform/linux-generic/odp_rwlock_recursive.c | 37 +++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
diff mbox

Patch

diff --git a/platform/linux-generic/odp_rwlock.c b/platform/linux-generic/odp_rwlock.c
index f50fd5f..13c17a2 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 2338b53..6b02281 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--;