aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/source/odp_rwlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/source/odp_rwlock.c')
-rw-r--r--platform/linux-generic/source/odp_rwlock.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/platform/linux-generic/source/odp_rwlock.c b/platform/linux-generic/source/odp_rwlock.c
new file mode 100644
index 000000000..19c58e155
--- /dev/null
+++ b/platform/linux-generic/source/odp_rwlock.c
@@ -0,0 +1,63 @@
+/* Copyright (c) 2014, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp_atomic.h>
+#include <odp_rwlock.h>
+
+#include "odp_spin_internal.h"
+
+void odp_rwlock_init(odp_rwlock_t *rwlock)
+{
+ rwlock->cnt = 0;
+}
+
+void odp_rwlock_read_lock(odp_rwlock_t *rwlock)
+{
+ int32_t cnt;
+ int is_locked = 0;
+
+ while (is_locked == 0) {
+ cnt = rwlock->cnt;
+ /* waiting for read lock */
+ if (cnt < 0) {
+ odp_spin();
+ continue;
+ }
+ is_locked = odp_atomic_cmpset_u32(
+ (volatile uint32_t *)&rwlock->cnt,
+ cnt, cnt + 1);
+ }
+}
+
+void odp_rwlock_read_unlock(odp_rwlock_t *rwlock)
+{
+ odp_atomic_dec_u32((odp_atomic_u32_t *)(intptr_t)&rwlock->cnt);
+}
+
+void odp_rwlock_write_lock(odp_rwlock_t *rwlock)
+{
+ int32_t cnt;
+ int is_locked = 0;
+
+ while (is_locked == 0) {
+ cnt = rwlock->cnt;
+ /* lock aquired, wait */
+ if (cnt != 0) {
+ odp_spin();
+ continue;
+ }
+ is_locked = odp_atomic_cmpset_u32(
+ (volatile uint32_t *)&rwlock->cnt,
+ 0, -1);
+ }
+}
+
+void odp_rwlock_write_unlock(odp_rwlock_t *rwlock)
+{
+ odp_atomic_inc_u32((odp_atomic_u32_t *)(intptr_t)&rwlock->cnt);
+}
+
+