diff options
| author | Wayne Lin <[email protected]> | 2021-11-10 16:01:38 +0800 |
|---|---|---|
| committer | Wayne Lin <[email protected]> | 2021-11-10 16:01:38 +0800 |
| commit | 9b44e57a6022b8eb46eda7037b719ec918fdcc55 (patch) | |
| tree | 26be9facf0f37d1c38b9e4b6e4abc99d6f8b5a8d /components/cplusplus/cpp11/armclang/mutex.cpp | |
| parent | 37f5236dfa45b98d02e867536a10ac0b6622b80b (diff) | |
| parent | fdbaa2a808d12d522ad90702795c08ae8443aab9 (diff) | |
Merge branch 'master' of https://github.com/RT-Thread/rt-thread into nuvoton
Diffstat (limited to 'components/cplusplus/cpp11/armclang/mutex.cpp')
| -rw-r--r-- | components/cplusplus/cpp11/armclang/mutex.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/components/cplusplus/cpp11/armclang/mutex.cpp b/components/cplusplus/cpp11/armclang/mutex.cpp new file mode 100644 index 0000000000..44a70efcf7 --- /dev/null +++ b/components/cplusplus/cpp11/armclang/mutex.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-04-27 flybreak the first version. + */ + +#include <arm-tpl.h> +#include <cstdint> +#include <stdatomic.h> +#include "tpl.h" + +static int check_create(volatile __ARM_TPL_mutex_t *__vm, bool recursive = false) +{ + if (__vm->data == 0) + { + uintptr_t mut_null = 0; + arm_tpl_mutex_struct *mutex_p = (arm_tpl_mutex_struct *)rt_malloc(sizeof(arm_tpl_mutex_struct)); + if (mutex_p == nullptr) return -1; + + if (recursive) + mutex_p->mutex = rt_mutex_create("mutexx", RT_IPC_FLAG_PRIO); + else + mutex_p->mutex = rt_mutex_create("mutexx", RT_IPC_FLAG_PRIO); + + if (mutex_p->mutex == nullptr) + { + rt_free(mutex_p); + return -1; + } + mutex_p->type = recursive ? RECURSIVE : NORMAL; + uintptr_t mut_new = reinterpret_cast<uintptr_t>(mutex_p); + if (!atomic_compare_exchange_strong(&__vm->data, &mut_null, mut_new)) + { + rt_mutex_delete(mutex_p->mutex); + rt_free(mutex_p); + } + } + return 0; +} + +static int mutexLock(arm_tpl_mutex_struct *mutex_p, rt_tick_t timeOut) +{ + if (mutex_p->type == RECURSIVE) + { + if (rt_mutex_take(mutex_p->mutex, timeOut) == 0) + return 0; + } + else + { + if (rt_mutex_take(mutex_p->mutex, timeOut) == 0) + return 0; + } + return -1; +} + +static int mutexUnlock(arm_tpl_mutex_struct *mutex_p) +{ + if (mutex_p->type == RECURSIVE) + rt_mutex_release(mutex_p->mutex); + else + rt_mutex_release(mutex_p->mutex); + return 0; +} + +extern "C" int __ARM_TPL_recursive_mutex_init(__ARM_TPL_mutex_t *__m) +{ + volatile __ARM_TPL_mutex_t *__vm = __m; + return check_create(__vm, true); +} + +extern "C" int __ARM_TPL_mutex_lock(__ARM_TPL_mutex_t *__m) +{ + volatile __ARM_TPL_mutex_t *__vm = __m; + if (check_create(__vm)) + return -1; + while (mutexLock((arm_tpl_mutex_struct *)(__vm->data), ARM_TPL_MAX_DELAY) != 0); + return 0; +} + +extern "C" int __ARM_TPL_mutex_trylock(__ARM_TPL_mutex_t *__m) +{ + volatile __ARM_TPL_mutex_t *__vm = __m; + if (check_create(__vm)) + return -1; + return mutexLock((arm_tpl_mutex_struct *)(__vm->data), 0); +} + +extern "C" int __ARM_TPL_mutex_unlock(__ARM_TPL_mutex_t *__m) +{ + volatile __ARM_TPL_mutex_t *__vm = __m; + return mutexUnlock((arm_tpl_mutex_struct *)(__vm->data)); +} + +extern "C" int __ARM_TPL_mutex_destroy(__ARM_TPL_mutex_t *__m) +{ + volatile __ARM_TPL_mutex_t *__vm = __m; + if (__vm->data != 0) + { + rt_mutex_delete(((arm_tpl_mutex_struct *)(__vm->data))->mutex); + rt_free((void *)(__vm->data)); + __vm->data = 0; + } + return 0; +} |
