2019-01-07 02:16:47 -05:00
|
|
|
/**
|
|
|
|
* @brief Atomically set a bit.
|
|
|
|
*
|
|
|
|
* Atomically set bit number @a bit of @a target.
|
|
|
|
* The target may be a single atomic variable or an array of them.
|
|
|
|
*
|
|
|
|
* @param target Address of atomic variable or array.
|
|
|
|
* @param bit Bit number (starting from 0).
|
|
|
|
*
|
|
|
|
* @return N/A
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2021-10-26 04:24:54 -04:00
|
|
|
* SPDX-FileCopyrightText: 2016 Intel Corporation
|
|
|
|
* SPDX-FileCopyrightText: 2011-2014 Wind River Systems, Inc.
|
2024-06-17 22:53:35 -04:00
|
|
|
* SPDX-FileContributor: 2018-2024 Espressif Systems (Shanghai) CO LTD
|
2019-01-07 02:16:47 -05:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mesh_atomic.h"
|
2020-03-30 06:24:59 -04:00
|
|
|
#include "mesh_mutex.h"
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
#ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @brief Atomic get primitive
|
|
|
|
*
|
|
|
|
* @param target memory location to read from
|
|
|
|
*
|
|
|
|
* This routine provides the atomic get primitive to atomically read
|
|
|
|
* a value from <target>. It simply does an ordinary load. Note that <target>
|
|
|
|
* is expected to be aligned to a 4-byte boundary.
|
|
|
|
*
|
|
|
|
* @return The value read from <target>
|
|
|
|
*/
|
|
|
|
bt_mesh_atomic_val_t bt_mesh_atomic_get(const bt_mesh_atomic_t *target)
|
|
|
|
{
|
|
|
|
return *target;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @brief Atomic get-and-set primitive
|
|
|
|
*
|
|
|
|
* This routine provides the atomic set operator. The <value> is atomically
|
|
|
|
* written at <target> and the previous value at <target> is returned.
|
|
|
|
*
|
|
|
|
* @param target the memory location to write to
|
|
|
|
* @param value the value to write
|
|
|
|
*
|
|
|
|
* @return The previous value from <target>
|
|
|
|
*/
|
|
|
|
bt_mesh_atomic_val_t bt_mesh_atomic_set(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
|
|
|
|
{
|
2020-01-19 05:57:13 -05:00
|
|
|
bt_mesh_atomic_val_t ret = 0;
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_lock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
ret = *target;
|
|
|
|
*target = value;
|
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @brief Atomic bitwise inclusive OR primitive
|
|
|
|
*
|
|
|
|
* This routine provides the atomic bitwise inclusive OR operator. The <value>
|
|
|
|
* is atomically bitwise OR'ed with the value at <target>, placing the result
|
|
|
|
* at <target>, and the previous value at <target> is returned.
|
|
|
|
*
|
|
|
|
* @param target the memory location to be modified
|
|
|
|
* @param value the value to OR
|
|
|
|
*
|
|
|
|
* @return The previous value from <target>
|
|
|
|
*/
|
|
|
|
bt_mesh_atomic_val_t bt_mesh_atomic_or(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
|
|
|
|
{
|
2020-01-19 05:57:13 -05:00
|
|
|
bt_mesh_atomic_val_t ret = 0;
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_lock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
ret = *target;
|
|
|
|
*target |= value;
|
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @brief Atomic bitwise AND primitive
|
|
|
|
*
|
|
|
|
* This routine provides the atomic bitwise AND operator. The <value> is
|
|
|
|
* atomically bitwise AND'ed with the value at <target>, placing the result
|
|
|
|
* at <target>, and the previous value at <target> is returned.
|
|
|
|
*
|
|
|
|
* @param target the memory location to be modified
|
|
|
|
* @param value the value to AND
|
|
|
|
*
|
|
|
|
* @return The previous value from <target>
|
|
|
|
*/
|
|
|
|
bt_mesh_atomic_val_t bt_mesh_atomic_and(bt_mesh_atomic_t *target, bt_mesh_atomic_val_t value)
|
|
|
|
{
|
2020-01-19 05:57:13 -05:00
|
|
|
bt_mesh_atomic_val_t ret = 0;
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_lock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
ret = *target;
|
|
|
|
*target &= value;
|
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @brief Atomic decrement primitive
|
|
|
|
*
|
|
|
|
* @param target memory location to decrement
|
|
|
|
*
|
|
|
|
* This routine provides the atomic decrement operator. The value at <target>
|
|
|
|
* is atomically decremented by 1, and the old value from <target> is returned.
|
|
|
|
*
|
|
|
|
* @return The value from <target> prior to the decrement
|
|
|
|
*/
|
|
|
|
bt_mesh_atomic_val_t bt_mesh_atomic_dec(bt_mesh_atomic_t *target)
|
|
|
|
{
|
2020-01-19 05:57:13 -05:00
|
|
|
bt_mesh_atomic_val_t ret = 0;
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_lock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
ret = *target;
|
|
|
|
(*target)--;
|
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @brief Atomic increment primitive
|
|
|
|
*
|
|
|
|
* @param target memory location to increment
|
|
|
|
*
|
|
|
|
* This routine provides the atomic increment operator. The value at <target>
|
|
|
|
* is atomically incremented by 1, and the old value from <target> is returned.
|
|
|
|
*
|
|
|
|
* @return The value from <target> before the increment
|
|
|
|
*/
|
|
|
|
bt_mesh_atomic_val_t bt_mesh_atomic_inc(bt_mesh_atomic_t *target)
|
|
|
|
{
|
2020-01-19 05:57:13 -05:00
|
|
|
bt_mesh_atomic_val_t ret = 0;
|
2019-01-07 02:16:47 -05:00
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_lock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
ret = *target;
|
|
|
|
(*target)++;
|
|
|
|
|
2019-12-19 22:26:55 -05:00
|
|
|
bt_mesh_atomic_unlock();
|
2019-01-07 02:16:47 -05:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-06-17 22:53:35 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-01-07 02:16:47 -05:00
|
|
|
#endif /* #ifndef CONFIG_ATOMIC_OPERATIONS_BUILTIN */
|