diff options
author | Matias Elo <matias.elo@nokia.com> | 2022-10-07 14:03:04 +0300 |
---|---|---|
committer | Matias Elo <matias.elo@nokia.com> | 2022-10-14 15:04:24 +0300 |
commit | c368aeebfb903bda602cb450eabf9e73e9697d11 (patch) | |
tree | 34543c0da7795e5ff7e6d975c059b8db47c09054 /platform/linux-generic | |
parent | d936ea858014e748fb83ef6747fd53ebf55308c0 (diff) |
linux-gen: rwlock: inline recursive reader/writer lock implementation
Inline implementations of recursive reader/writer lock functions. Added
debug asserts for detecting recursion count wraparounds and invalid
unlock calls.
Signed-off-by: Matias Elo <matias.elo@nokia.com>
Reviewed-by: Tuomas Taipale <tuomas.taipale@nokia.com>
Diffstat (limited to 'platform/linux-generic')
5 files changed, 157 insertions, 109 deletions
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 4d27afc18..ce8b0ba09 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -49,6 +49,7 @@ odpapiplatinclude_HEADERS = \ include/odp/api/plat/queue_inlines.h \ include/odp/api/plat/queue_inline_types.h \ include/odp/api/plat/rwlock_inlines.h \ + include/odp/api/plat/rwlock_recursive_inlines.h \ include/odp/api/plat/schedule_inlines.h \ include/odp/api/plat/schedule_inline_types.h \ include/odp/api/plat/spinlock_inlines.h \ @@ -231,7 +232,6 @@ __LIB__libodp_linux_la_SOURCES = \ odp_random.c \ odp_random_std.c \ odp_random_openssl.c \ - odp_rwlock_recursive.c \ odp_schedule_basic.c \ odp_schedule_if.c \ odp_schedule_scalable.c \ @@ -294,6 +294,7 @@ __LIB__libodp_linux_la_SOURCES += \ odp_pool_api.c \ odp_queue_api.c \ odp_rwlock_api.c \ + odp_rwlock_recursive_api.c \ odp_schedule_api.c \ odp_spinlock_api.c \ odp_spinlock_recursive_api.c \ diff --git a/platform/linux-generic/include-abi/odp/api/abi/rwlock_recursive.h b/platform/linux-generic/include-abi/odp/api/abi/rwlock_recursive.h index 14c964c9d..ab7150605 100644 --- a/platform/linux-generic/include-abi/odp/api/abi/rwlock_recursive.h +++ b/platform/linux-generic/include-abi/odp/api/abi/rwlock_recursive.h @@ -5,3 +5,6 @@ */ #include <odp/api/abi-default/rwlock_recursive.h> + +/* Inlined API functions */ +#include <odp/api/plat/rwlock_recursive_inlines.h> diff --git a/platform/linux-generic/include/odp/api/plat/rwlock_recursive_inlines.h b/platform/linux-generic/include/odp/api/plat/rwlock_recursive_inlines.h new file mode 100644 index 000000000..21ad4be4a --- /dev/null +++ b/platform/linux-generic/include/odp/api/plat/rwlock_recursive_inlines.h @@ -0,0 +1,142 @@ +/* Copyright (c) 2013-2018, Linaro Limited + * Copyright (c) 2022, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef ODP_PLAT_RWLOCK_RECURSIVE_INLINES_H_ +#define ODP_PLAT_RWLOCK_RECURSIVE_INLINES_H_ + +#include <odp/api/rwlock.h> +#include <odp/api/thread.h> + +#include <odp/api/abi/rwlock_recursive.h> + +#include <odp/api/plat/debug_inlines.h> + +#include <stdint.h> +#include <string.h> + +/** @cond _ODP_HIDE_FROM_DOXYGEN_ */ + +#ifndef _ODP_NO_INLINE + /* Inline functions by default */ + #define _ODP_INLINE static inline + #define odp_rwlock_recursive_init __odp_rwlock_recursive_init + #define odp_rwlock_recursive_read_lock __odp_rwlock_recursive_read_lock + #define odp_rwlock_recursive_read_trylock __odp_rwlock_recursive_read_trylock + #define odp_rwlock_recursive_read_unlock __odp_rwlock_recursive_read_unlock + #define odp_rwlock_recursive_write_lock __odp_rwlock_recursive_write_lock + #define odp_rwlock_recursive_write_trylock __odp_rwlock_recursive_write_trylock + #define odp_rwlock_recursive_write_unlock __odp_rwlock_recursive_write_unlock +#else + #undef _ODP_INLINE + #define _ODP_INLINE +#endif + +_ODP_INLINE void odp_rwlock_recursive_init(odp_rwlock_recursive_t *rlock) +{ + memset(rlock, 0, sizeof(odp_rwlock_recursive_t)); + odp_rwlock_init(&rlock->lock); + rlock->wr_owner = -1; +} + +/* Multiple readers can recurse the lock concurrently */ +_ODP_INLINE void odp_rwlock_recursive_read_lock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + if (rlock->rd_cnt[thr]) { + _ODP_ASSERT(rlock->rd_cnt[thr] < UINT8_MAX); + rlock->rd_cnt[thr]++; + return; + } + + odp_rwlock_read_lock(&rlock->lock); + rlock->rd_cnt[thr] = 1; +} + +/* Multiple readers can recurse the lock concurrently */ +_ODP_INLINE int odp_rwlock_recursive_read_trylock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + if (rlock->rd_cnt[thr]) { + _ODP_ASSERT(rlock->rd_cnt[thr] < UINT8_MAX); + rlock->rd_cnt[thr]++; + return 1; + } + + if (odp_rwlock_read_trylock(&rlock->lock)) { + rlock->rd_cnt[thr] = 1; + return 1; + } + + return 0; +} + +_ODP_INLINE void odp_rwlock_recursive_read_unlock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + _ODP_ASSERT(rlock->rd_cnt[thr]); + rlock->rd_cnt[thr]--; + + if (rlock->rd_cnt[thr] > 0) + return; + + odp_rwlock_read_unlock(&rlock->lock); +} + +/* Only one writer can recurse the lock */ +_ODP_INLINE void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + if (rlock->wr_owner == thr) { + _ODP_ASSERT(rlock->wr_cnt < UINT32_MAX); + rlock->wr_cnt++; + return; + } + + odp_rwlock_write_lock(&rlock->lock); + rlock->wr_owner = thr; + rlock->wr_cnt = 1; +} + +/* Only one writer can recurse the lock */ +_ODP_INLINE int odp_rwlock_recursive_write_trylock(odp_rwlock_recursive_t *rlock) +{ + int thr = odp_thread_id(); + + if (rlock->wr_owner == thr) { + _ODP_ASSERT(rlock->wr_cnt < UINT32_MAX); + rlock->wr_cnt++; + return 1; + } + + if (odp_rwlock_write_trylock(&rlock->lock)) { + rlock->wr_owner = thr; + rlock->wr_cnt = 1; + return 1; + } + + return 0; +} + +_ODP_INLINE void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *rlock) +{ + _ODP_ASSERT(rlock->wr_cnt); + rlock->wr_cnt--; + + if (rlock->wr_cnt > 0) + return; + + rlock->wr_owner = -1; + odp_rwlock_write_unlock(&rlock->lock); +} + +/** @endcond */ + +#endif diff --git a/platform/linux-generic/odp_rwlock_recursive.c b/platform/linux-generic/odp_rwlock_recursive.c deleted file mode 100644 index d7bbf3c8b..000000000 --- a/platform/linux-generic/odp_rwlock_recursive.c +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2013-2018, Linaro Limited - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <odp/api/rwlock_recursive.h> -#include <odp/api/thread.h> -#include <odp/api/plat/thread_inlines.h> -#include <string.h> - -#define NO_OWNER (-1) - -void odp_rwlock_recursive_init(odp_rwlock_recursive_t *rlock) -{ - memset(rlock, 0, sizeof(odp_rwlock_recursive_t)); - odp_rwlock_init(&rlock->lock); - rlock->wr_owner = NO_OWNER; -} - -/* Multiple readers can recurse the lock concurrently */ -void odp_rwlock_recursive_read_lock(odp_rwlock_recursive_t *rlock) -{ - int thr = odp_thread_id(); - - if (rlock->rd_cnt[thr]) { - rlock->rd_cnt[thr]++; - return; - } - - odp_rwlock_read_lock(&rlock->lock); - 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(); - - rlock->rd_cnt[thr]--; - - if (rlock->rd_cnt[thr] > 0) - return; - - odp_rwlock_read_unlock(&rlock->lock); -} - -/* Only one writer can recurse the lock */ -void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *rlock) -{ - int thr = odp_thread_id(); - - if (rlock->wr_owner == thr) { - rlock->wr_cnt++; - return; - } - - odp_rwlock_write_lock(&rlock->lock); - rlock->wr_owner = thr; - 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--; - - if (rlock->wr_cnt > 0) - return; - - rlock->wr_owner = NO_OWNER; - odp_rwlock_write_unlock(&rlock->lock); -} diff --git a/platform/linux-generic/odp_rwlock_recursive_api.c b/platform/linux-generic/odp_rwlock_recursive_api.c new file mode 100644 index 000000000..b2580ae42 --- /dev/null +++ b/platform/linux-generic/odp_rwlock_recursive_api.c @@ -0,0 +1,10 @@ +/* Copyright (c) 2022, Nokia + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp/api/rwlock_recursive.h> + +#define _ODP_NO_INLINE +#include <odp/api/plat/rwlock_recursive_inlines.h> |