diff options
-rw-r--r-- | include/odp.h | 1 | ||||
-rw-r--r-- | include/odp/api/spinlock_recursive.h | 82 | ||||
-rw-r--r-- | platform/Makefile.inc | 1 | ||||
-rw-r--r-- | platform/linux-generic/Makefile.am | 3 | ||||
-rw-r--r-- | platform/linux-generic/include/odp/plat/spinlock_recursive_types.h | 47 | ||||
-rw-r--r-- | platform/linux-generic/include/odp/spinlock_recursive.h | 28 | ||||
-rw-r--r-- | platform/linux-generic/odp_spinlock_recursive.c | 70 |
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); +} |