1 /*
2  * Copyright (c) 2017, Linaro Limited. and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * @file	zephyr/condition.h
9  * @brief	Zephyr condition variable primitives for libmetal.
10  */
11 
12 #ifndef __METAL_CONDITION__H__
13 #error "Include metal/condition.h instead of metal/generic/condition.h"
14 #endif
15 
16 #ifndef __METAL_ZEPHYR_CONDITION__H__
17 #define __METAL_ZEPHYR_CONDITION__H__
18 
19 #include <metal/atomic.h>
20 #include <metal/errno.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 struct metal_condition {
29 	atomic_uintptr_t mptr; /**< mutex pointer.
30 				 * The condition variable is attached to
31 				 * this mutex when it is waiting.
32 				 * It is also used to check correctness
33 				 * in case there are multiple waiters.
34 				 */
35 
36 	atomic_int v; /**< condition variable value. */
37 };
38 
39 /** Static metal condition variable initialization. */
40 #define METAL_CONDITION_INIT	{ ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0) }
41 
metal_condition_init(struct metal_condition * cv)42 static inline void metal_condition_init(struct metal_condition *cv)
43 {
44 	atomic_init(&cv->mptr, 0);
45 	atomic_init(&cv->v, 0);
46 }
47 
metal_condition_signal(struct metal_condition * cv)48 static inline int metal_condition_signal(struct metal_condition *cv)
49 {
50 	if (!cv)
51 		return -EINVAL;
52 
53 	/** wake up waiters if there are any. */
54 	atomic_fetch_add(&cv->v, 1);
55 	return 0;
56 }
57 
metal_condition_broadcast(struct metal_condition * cv)58 static inline int metal_condition_broadcast(struct metal_condition *cv)
59 {
60 	return metal_condition_signal(cv);
61 }
62 
63 
64 #ifdef __cplusplus
65 }
66 #endif
67 
68 #endif /* __METAL_ZEPHYR_CONDITION__H__ */
69