1 /*
2 * Copyright (c) 2021 - 2023, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33 #include <helpers/nrfx_flag32_allocator.h>
34
35 #if !defined(NRFX_ATOMIC_CAS)
nrfx_flag32_atomic_cas(nrfx_atomic_t * p_data,uint32_t old_value,uint32_t new_value)36 static bool nrfx_flag32_atomic_cas(nrfx_atomic_t * p_data, uint32_t old_value, uint32_t new_value)
37 {
38 bool status = false;
39 NRFX_CRITICAL_SECTION_ENTER();
40 if (*p_data == old_value)
41 {
42 *p_data = new_value;
43 status = true;
44 }
45 NRFX_CRITICAL_SECTION_EXIT();
46 return status;
47 }
48
49 #define NRFX_ATOMIC_CAS(p_data, old_value, new_value) \
50 nrfx_flag32_atomic_cas(p_data, old_value, new_value)
51 #endif // !defined(NRFX_ATOMIC_CAS)
52
nrfx_flag32_is_allocated(nrfx_atomic_t mask,uint8_t bitpos)53 bool nrfx_flag32_is_allocated(nrfx_atomic_t mask, uint8_t bitpos)
54 {
55 return (mask & NRFX_BIT(bitpos)) ? false : true;
56 }
57
nrfx_flag32_alloc(nrfx_atomic_t * p_mask,uint8_t * p_flag)58 nrfx_err_t nrfx_flag32_alloc(nrfx_atomic_t * p_mask, uint8_t *p_flag)
59 {
60 uint8_t idx;
61 uint32_t new_mask, prev_mask;
62
63 do {
64 prev_mask = *p_mask;
65 if (prev_mask == 0)
66 {
67 return NRFX_ERROR_NO_MEM;
68 }
69 else
70 {
71 idx = (uint8_t)(31UL - NRF_CLZ(prev_mask));
72 }
73
74 new_mask = prev_mask & ~NRFX_BIT(idx);
75 } while (!NRFX_ATOMIC_CAS(p_mask, prev_mask, new_mask));
76
77 *p_flag = idx;
78
79 return NRFX_SUCCESS;
80 }
81
nrfx_flag32_free(nrfx_atomic_t * p_mask,uint8_t flag)82 nrfx_err_t nrfx_flag32_free(nrfx_atomic_t * p_mask, uint8_t flag)
83 {
84 uint32_t new_mask, prev_mask;
85
86 if ((NRFX_BIT(flag) & *p_mask))
87 {
88 return NRFX_ERROR_INVALID_PARAM;
89 }
90
91 do {
92 prev_mask = *p_mask;
93 new_mask = prev_mask | NRFX_BIT(flag);
94 } while (!NRFX_ATOMIC_CAS(p_mask, prev_mask, new_mask));
95
96 return NRFX_SUCCESS;
97 }
98