aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2015-09-09 13:52:24 +0300
committerMaxim Uvarov <maxim.uvarov@linaro.org>2015-12-29 14:07:51 +0300
commita0b30a27b75bfef55d72f05da3b43cd26c6a4543 (patch)
tree8060a57ac8da585aee96a06dab470b1a393d18e0 /platform
parent7168948a67a0317008c6fd9dc4abff3948bfecc9 (diff)
api: spinlock_recursive: added recursive spinlock
Applications can use recursive spinlocks to avoid deadlock from single thread acquiring the same lock multiple times. Recursive locks are used in legacy applications. ODP version of recursive spinlock enable porting of those applications. Signed-off-by: Petri Savolainen <petri.savolainen@nokia.com> Reviewed-by: Bill Fischofer <bill.fischofer@linaro.org> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org> Conflicts: platform/linux-generic/Makefile.am
Diffstat (limited to 'platform')
-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
5 files changed, 149 insertions, 0 deletions
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);
+}