diff options
author | Petri Savolainen <petri.savolainen@nokia.com> | 2015-09-09 13:52:24 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-12-29 14:07:51 +0300 |
commit | a0b30a27b75bfef55d72f05da3b43cd26c6a4543 (patch) | |
tree | 8060a57ac8da585aee96a06dab470b1a393d18e0 /platform/linux-generic/odp_spinlock_recursive.c | |
parent | 7168948a67a0317008c6fd9dc4abff3948bfecc9 (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/linux-generic/odp_spinlock_recursive.c')
-rw-r--r-- | platform/linux-generic/odp_spinlock_recursive.c | 70 |
1 files changed, 70 insertions, 0 deletions
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); +} |