1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * Provides a way to set/clear and block on binary flags.
5  *
6  * These flags are often used to wait until the test has gotten in a particular
7  * state, e.g. a connection is established or a message has been successfully
8  * sent.
9  *
10  * These macros can only be called from Zephyr threads. They can't be called
11  * from e.g. a bs_tests callback.
12  *
13  * SPDX-License-Identifier: Apache-2.0
14  */
15 
16 #include <zephyr/sys/atomic.h>
17 
18 /* Declare a flag that has been defined in another file */
19 #define DECLARE_FLAG(flag) extern atomic_t flag
20 
21 /* Define a new binary flag.
22  * Declare them static if defining flags with the same name in multiple files.
23  *
24  * @param flag Name of the flag
25  */
26 #define DEFINE_FLAG(flag)  atomic_t flag = (atomic_t) false
27 
28 #define SET_FLAG(flag)     (void)atomic_set(&flag, (atomic_t) true)
29 #define UNSET_FLAG(flag)   (void)atomic_set(&flag, (atomic_t) false)
30 
31 #define IS_FLAG_SET(flag) (atomic_get(&flag) != false)
32 
33 /* Block until `flag` is equal to `val` */
34 #define WAIT_FOR_VAL(var, val)                                                                     \
35 	while (atomic_get(&var) != val) {                                                          \
36 		(void)k_sleep(K_MSEC(1));                                                          \
37 	}
38 
39 /* Block until `flag` is true */
40 #define WAIT_FOR_FLAG(flag)                                                                        \
41 	while (!(bool)atomic_get(&flag)) {                                                         \
42 		(void)k_sleep(K_MSEC(1));                                                          \
43 	}
44 
45 /* Block until `flag` is false */
46 #define WAIT_FOR_FLAG_UNSET(flag)                                                                  \
47 	while ((bool)atomic_get(&flag)) {                                                          \
48 		(void)k_sleep(K_MSEC(1));                                                          \
49 	}
50 
51 /* Block until `flag` is true and set it to false */
52 #define TAKE_FLAG(flag)                                                                            \
53 	while (!(bool)atomic_cas(&flag, true, false)) {                                            \
54 		(void)k_sleep(K_MSEC(1));                                                          \
55 	}
56