From 9c7a81083c69b8afb9deb9b5fa3f1034bfa4c630 Mon Sep 17 00:00:00 2001 From: luoxu Date: Tue, 28 May 2024 17:52:36 +0800 Subject: [PATCH] feat(ble_mesh): add cas operation for bt_mesh_atomic_val_t --- components/bt/esp_ble_mesh/common/atomic.c | 19 ++++++++++++- .../esp_ble_mesh/common/include/mesh/atomic.h | 27 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/components/bt/esp_ble_mesh/common/atomic.c b/components/bt/esp_ble_mesh/common/atomic.c index 723ce7e3ac..40f163ab45 100644 --- a/components/bt/esp_ble_mesh/common/atomic.c +++ b/components/bt/esp_ble_mesh/common/atomic.c @@ -13,7 +13,7 @@ /* * SPDX-FileCopyrightText: 2016 Intel Corporation * SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc. - * SPDX-FileContributor: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -170,4 +170,21 @@ bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target) return ret; } +bool bt_mesh_atomic_campare_and_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val) +{ + bt_mesh_atomic_val_t ret = 0; + + bt_mesh_atomic_lock(); + + ret = *target; + if (*target == excepted) { + *target = new_val; + bt_mesh_atomic_unlock(); + return true; + } + + bt_mesh_atomic_unlock(); + return false; +} + #endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */ diff --git a/components/bt/esp_ble_mesh/common/include/mesh/atomic.h b/components/bt/esp_ble_mesh/common/include/mesh/atomic.h index f72834369f..c6ef0fc5ae 100644 --- a/components/bt/esp_ble_mesh/common/include/mesh/atomic.h +++ b/components/bt/esp_ble_mesh/common/include/mesh/atomic.h @@ -147,6 +147,33 @@ static inline bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, extern bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value); #endif +/** + * @brief Atomic CAS operation. + * + * This compares the contents of @a *target + * with the contents of @a excepted. If equal, + * the operation is a read-modify-write operation + * that writes @a new_val into @a *target and return true. + * If they are not equal, the operation is a read + * and return false. + * + * @param target Address of atomic variable. + * @param excepted Value of excepted. + * @param new_val Write value if compare sunncess. + * + * @return + * - true: write operation succeeded. + * - false: write operation failed. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline bool bt_mesh_atomic_campare_and_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val) +{ + return __atomic_compare_exchange_n(target, &excepted, &new_val, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +} +#else +extern bool bt_mesh_atomic_campare_and_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t excepted, bt_mesh_atomic_val_t new_val); +#endif + /** * @cond INTERNAL_HIDDEN */