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/mutex.h
9  * @brief	Zephyr mutex primitives for libmetal.
10  */
11 
12 #ifndef __METAL_MUTEX__H__
13 #error "Include metal/mutex.h instead of metal/zephyr/mutex.h"
14 #endif
15 
16 #ifndef __METAL_ZEPHYR_MUTEX__H__
17 #define __METAL_ZEPHYR_MUTEX__H__
18 
19 #include <metal/atomic.h>
20 #include <zephyr/kernel.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 typedef struct k_sem metal_mutex_t;
27 
28 /*
29  * METAL_MUTEX_INIT - used for initializing an mutex element in a static struct
30  * or global
31  */
32 #define METAL_MUTEX_INIT(m) _K_SEM_INITIALIZER(m, 1, 1)
33 /*
34  * METAL_MUTEX_DEFINE - used for defining and initializing a global or
35  * static singleton mutex
36  */
37 #define METAL_MUTEX_DEFINE(m) K_SEM_DEFINE(m, 1, 1)
38 
__metal_mutex_init(metal_mutex_t * m)39 static inline void __metal_mutex_init(metal_mutex_t *m)
40 {
41 	k_sem_init(m, 1, 1);
42 }
43 
__metal_mutex_deinit(metal_mutex_t * m)44 static inline void __metal_mutex_deinit(metal_mutex_t *m)
45 {
46 	(void)m;
47 }
48 
__metal_mutex_try_acquire(metal_mutex_t * m)49 static inline int __metal_mutex_try_acquire(metal_mutex_t *m)
50 {
51 	int key = irq_lock(), ret = 1;
52 
53 	if (m->count) {
54 		m->count = 0;
55 		ret = 0;
56 	}
57 
58 	irq_unlock(key);
59 
60 	return ret;
61 }
62 
__metal_mutex_is_acquired(metal_mutex_t * m)63 static inline int __metal_mutex_is_acquired(metal_mutex_t *m)
64 {
65 	int key = irq_lock(), ret;
66 
67 	ret = m->count;
68 
69 	irq_unlock(key);
70 
71 	return ret;
72 }
73 
__metal_mutex_acquire(metal_mutex_t * m)74 static inline void __metal_mutex_acquire(metal_mutex_t *m)
75 {
76 	k_sem_take(m, K_FOREVER);
77 }
78 
__metal_mutex_release(metal_mutex_t * m)79 static inline void __metal_mutex_release(metal_mutex_t *m)
80 {
81 	k_sem_give(m);
82 }
83 
84 #ifdef __cplusplus
85 }
86 #endif
87 
88 #endif /* __METAL_ZEPHYR_MUTEX__H__ */
89