1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <cmsis_os.h>
9 #include <string.h>
10 
11 K_MEM_SLAB_DEFINE(cmsis_mutex_slab, sizeof(struct k_mutex),
12 		CONFIG_CMSIS_MUTEX_MAX_COUNT, 4);
13 
14 /**
15  * @brief Create and Initialize a Mutex object.
16  */
osMutexCreate(const osMutexDef_t * mutex_def)17 osMutexId osMutexCreate(const osMutexDef_t *mutex_def)
18 {
19 	struct k_mutex *mutex;
20 
21 	if (mutex_def == NULL) {
22 		return NULL;
23 	}
24 
25 	if (k_is_in_isr()) {
26 		return NULL;
27 	}
28 
29 	if (k_mem_slab_alloc(&cmsis_mutex_slab, (void **)&mutex, K_MSEC(100)) == 0) {
30 		(void)memset(mutex, 0, sizeof(struct k_mutex));
31 	} else {
32 		return NULL;
33 	}
34 
35 	k_mutex_init(mutex);
36 
37 	return (osMutexId)mutex;
38 }
39 
40 /**
41  * @brief Wait until a Mutex becomes available.
42  */
osMutexWait(osMutexId mutex_id,uint32_t timeout)43 osStatus osMutexWait(osMutexId mutex_id, uint32_t timeout)
44 {
45 	struct k_mutex *mutex = (struct k_mutex *) mutex_id;
46 	int status;
47 
48 	if (mutex_id == NULL) {
49 		return osErrorParameter;
50 	}
51 
52 	if (k_is_in_isr()) {
53 		return osErrorISR;
54 	}
55 
56 	if (timeout == osWaitForever) {
57 		status = k_mutex_lock(mutex, K_FOREVER);
58 	} else if (timeout == 0U) {
59 		status = k_mutex_lock(mutex, K_NO_WAIT);
60 	} else {
61 		status = k_mutex_lock(mutex, K_MSEC(timeout));
62 	}
63 
64 	if (timeout != 0 && (status == -EAGAIN || status == -EBUSY)) {
65 		return osErrorTimeoutResource;
66 	} else if (status == 0) {
67 		return osOK;
68 	} else {
69 		return osErrorResource;
70 	}
71 }
72 
73 /**
74  * @brief Release a Mutex that was obtained by osMutexWait.
75  */
osMutexRelease(osMutexId mutex_id)76 osStatus osMutexRelease(osMutexId mutex_id)
77 {
78 	struct k_mutex *mutex = (struct k_mutex *) mutex_id;
79 
80 	if (mutex_id == NULL) {
81 		return osErrorParameter;
82 	}
83 
84 	if (k_is_in_isr()) {
85 		return osErrorISR;
86 	}
87 
88 	if (k_mutex_unlock(mutex) != 0) {
89 		return osErrorResource;
90 	}
91 
92 	return osOK;
93 }
94 
95 /**
96  * @brief Delete a Mutex that was created by osMutexCreate.
97  */
osMutexDelete(osMutexId mutex_id)98 osStatus osMutexDelete(osMutexId mutex_id)
99 {
100 	struct k_mutex *mutex = (struct k_mutex *) mutex_id;
101 
102 	if (mutex_id == NULL) {
103 		return osErrorParameter;
104 	}
105 
106 	if (k_is_in_isr()) {
107 		return osErrorISR;
108 	}
109 
110 	/* The status code "osErrorResource" (mutex object could
111 	 * not be deleted) is not supported in Zephyr.
112 	 */
113 
114 	k_mem_slab_free(&cmsis_mutex_slab, (void *)mutex);
115 
116 	return osOK;
117 }
118