aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/odp.h1
-rw-r--r--include/odp/api/spinlock_recursive.h82
-rw-r--r--platform/Makefile.inc1
-rw-r--r--platform/linux-generic/Makefile.am3
-rw-r--r--platform/linux-generic/include/odp/plat/spinlock_recursive_types.h47
-rw-r--r--platform/linux-generic/include/odp/spinlock_recursive.h28
-rw-r--r--platform/linux-generic/odp_spinlock_recursive.c70
7 files changed, 232 insertions, 0 deletions
diff --git a/include/odp.h b/include/odp.h
index fe1dc7459..b47ab8231 100644
--- a/include/odp.h
+++ b/include/odp.h
@@ -54,6 +54,7 @@ extern "C" {
#include <odp/random.h>
#include <odp/errno.h>
#include <odp/thrmask.h>
+#include <odp/spinlock_recursive.h>
#ifdef __cplusplus
}
diff --git a/include/odp/api/spinlock_recursive.h b/include/odp/api/spinlock_recursive.h
new file mode 100644
index 000000000..46b6be762
--- /dev/null
+++ b/include/odp/api/spinlock_recursive.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive spinlock
+ */
+
+#ifndef ODP_API_SPINLOCK_RECURSIVE_H_
+#define ODP_API_SPINLOCK_RECURSIVE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup odp_synchronizers
+ * Operations on recursive spinlocks.
+ * @{
+ */
+
+/**
+ * @typedef odp_spinlock_recursive_t
+ * Recursive spinlock
+ *
+ * A thread can acquire the lock multiple times without a deadlock. To release
+ * the lock, the thread must unlock it the same number of times.
+ */
+
+/**
+ * Initialize recursive spinlock.
+ *
+ * @param lock Pointer to a lock
+ */
+void odp_spinlock_recursive_init(odp_spinlock_recursive_t *lock);
+
+/**
+ * Acquire recursive spinlock.
+ *
+ * @param lock Pointer to a lock
+ */
+void odp_spinlock_recursive_lock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Try to acquire recursive spinlock.
+ *
+ * @param lock Pointer to a lock
+ *
+ * @retval 1 lock acquired
+ * @retval 0 lock not acquired
+ */
+int odp_spinlock_recursive_trylock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Release recursive spinlock.
+ *
+ * @param lock Pointer to a lock
+ */
+void odp_spinlock_recursive_unlock(odp_spinlock_recursive_t *lock);
+
+/**
+ * Check if recursive spinlock is locked.
+ *
+ * @param lock Pointer to a lock
+ *
+ * @retval 1 lock is locked
+ * @retval 0 lock is not locked
+ */
+int odp_spinlock_recursive_is_locked(odp_spinlock_recursive_t *lock);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/Makefile.inc b/platform/Makefile.inc
index 5d589b1b0..cc86b993a 100644
--- a/platform/Makefile.inc
+++ b/platform/Makefile.inc
@@ -45,6 +45,7 @@ odpapiinclude_HEADERS = \
$(top_srcdir)/include/odp/api/schedule_types.h \
$(top_srcdir)/include/odp/api/shared_memory.h \
$(top_srcdir)/include/odp/api/spinlock.h \
+ $(top_srcdir)/include/odp/api/spinlock_recursive.h \
$(top_srcdir)/include/odp/api/std_types.h \
$(top_srcdir)/include/odp/api/sync.h \
$(top_srcdir)/include/odp/api/system_info.h \
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index a0de35b03..8bcd6a943 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -39,6 +39,7 @@ odpinclude_HEADERS = \
$(srcdir)/include/odp/schedule_types.h \
$(srcdir)/include/odp/shared_memory.h \
$(srcdir)/include/odp/spinlock.h \
+ $(srcdir)/include/odp/spinlock_recursive.h \
$(srcdir)/include/odp/std_types.h \
$(srcdir)/include/odp/sync.h \
$(srcdir)/include/odp/system_info.h \
@@ -67,6 +68,7 @@ odpplatinclude_HEADERS = \
$(srcdir)/include/odp/plat/schedule_types.h \
$(srcdir)/include/odp/plat/shared_memory_types.h \
$(srcdir)/include/odp/plat/spinlock_types.h \
+ $(srcdir)/include/odp/plat/spinlock_recursive_types.h \
$(srcdir)/include/odp/plat/strong_types.h \
$(srcdir)/include/odp/plat/thread_types.h \
$(srcdir)/include/odp/plat/thrmask_types.h \
@@ -129,6 +131,7 @@ __LIB__libodp_la_SOURCES = \
odp_schedule.c \
odp_shared_memory.c \
odp_spinlock.c \
+ odp_spinlock_recursive.c \
odp_system_info.c \
odp_thread.c \
odp_thrmask.c \
diff --git a/platform/linux-generic/include/odp/plat/spinlock_recursive_types.h b/platform/linux-generic/include/odp/plat/spinlock_recursive_types.h
new file mode 100644
index 000000000..cae47a4b1
--- /dev/null
+++ b/platform/linux-generic/include/odp/plat/spinlock_recursive_types.h
@@ -0,0 +1,47 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP recursive spinlock
+ */
+
+#ifndef ODP_SPINLOCK_RECURSIVE_TYPES_H_
+#define ODP_SPINLOCK_RECURSIVE_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/spinlock.h>
+#include <odp/std_types.h>
+
+/**
+ * @internal
+ * ODP recursive spinlock
+ */
+struct odp_spinlock_recursive_s {
+ odp_spinlock_t lock; /**< the lock */
+ int owner; /**< thread owning the lock */
+ uint32_t cnt; /**< recursion count */
+};
+
+/** @addtogroup odp_synchronizers
+ * @{
+ */
+
+typedef struct odp_spinlock_recursive_s odp_spinlock_recursive_t;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/spinlock_recursive.h b/platform/linux-generic/include/odp/spinlock_recursive.h
new file mode 100644
index 000000000..e8a996837
--- /dev/null
+++ b/platform/linux-generic/include/odp/spinlock_recursive.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2015, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODP resursive spinlock
+ */
+
+#ifndef ODP_PLAT_SPINLOCK_RECURSIVE_H_
+#define ODP_PLAT_SPINLOCK_RECURSIVE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/plat/spinlock_recursive_types.h>
+
+#include <odp/api/spinlock_recursive.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/odp_spinlock_recursive.c b/platform/linux-generic/odp_spinlock_recursive.c
new file mode 100644
index 000000000..8ffe6b3dd
--- /dev/null
+++ b/platform/linux-generic/odp_spinlock_recursive.c
@@ -0,0 +1,70 @@
+/* Copyright (c) 2013, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp/spinlock_recursive.h>
+#include <odp/thread.h>
+
+#define NO_OWNER (-1)
+
+void odp_spinlock_recursive_init(odp_spinlock_recursive_t *rlock)
+{
+ odp_spinlock_init(&rlock->lock);
+ rlock->owner = NO_OWNER;
+ rlock->cnt = 0;
+}
+
+void odp_spinlock_recursive_lock(odp_spinlock_recursive_t *rlock)
+{
+ int thr = odp_thread_id();
+
+ if (rlock->owner == thr) {
+ rlock->cnt++;
+ return;
+ }
+
+ odp_spinlock_lock(&rlock->lock);
+ rlock->owner = thr;
+ rlock->cnt = 1;
+}
+
+int odp_spinlock_recursive_trylock(odp_spinlock_recursive_t *rlock)
+{
+ int thr = odp_thread_id();
+
+ if (rlock->owner == thr) {
+ rlock->cnt++;
+ return 1;
+ }
+
+ if (odp_spinlock_trylock(&rlock->lock)) {
+ rlock->owner = thr;
+ rlock->cnt = 1;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void odp_spinlock_recursive_unlock(odp_spinlock_recursive_t *rlock)
+{
+ rlock->cnt--;
+
+ if (rlock->cnt > 0)
+ return;
+
+ rlock->owner = NO_OWNER;
+ odp_spinlock_unlock(&rlock->lock);
+}
+
+int odp_spinlock_recursive_is_locked(odp_spinlock_recursive_t *rlock)
+{
+ int thr = odp_thread_id();
+
+ if (rlock->owner == thr)
+ return 1;
+
+ return odp_spinlock_is_locked(&rlock->lock);
+}