diff options
author | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-12-31 11:15:35 +0300 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-12-31 11:15:35 +0300 |
commit | 4320d76520e1bf352d1aa2a94a3e8ffe74e003d2 (patch) | |
tree | c699d1e969b2f285bf1dd2e2fa7e770d5db49166 /platform/linux-generic/odp_rwlock_recursive.c | |
parent | a0a20997629be7045222980da6e393bca9a9fa37 (diff) | |
parent | 4b22a3a0853b16b785a88a6a709a3a098cdccc2d (diff) |
Merge branch 'next'v1.6.0.0
Diffstat (limited to 'platform/linux-generic/odp_rwlock_recursive.c')
-rw-r--r-- | platform/linux-generic/odp_rwlock_recursive.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/platform/linux-generic/odp_rwlock_recursive.c b/platform/linux-generic/odp_rwlock_recursive.c new file mode 100644 index 000000000..e3a383caf --- /dev/null +++ b/platform/linux-generic/odp_rwlock_recursive.c @@ -0,0 +1,70 @@ +/* Copyright (c) 2013, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp/rwlock_recursive.h> +#include <odp/thread.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; +} + +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; +} + +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); +} |