1 /*
2 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "os_mutex.h"
31 #include "os_util.h"
32
33
34 /**
35 * @brief Create and initialize a mutex object
36 * @note A mutex can only be locked by a single thread at any given time.
37 * @param[in] mutex Pointer to the mutex object
38 * @retval OS_Status, OS_OK on success
39 */
OS_MutexCreate(OS_Mutex_t * mutex)40 OS_Status OS_MutexCreate(OS_Mutex_t *mutex)
41 {
42 OS_HANDLE_ASSERT(!OS_MutexIsValid(mutex), mutex->handle);
43
44 mutex->handle = rt_mutex_create("os_mtx", RT_IPC_FLAG_PRIO);
45 OS_DBG("%s(), handle %p\n", __func__, mutex->handle);
46
47 if (mutex->handle == NULL) {
48 OS_ERR("err %"OS_HANDLE_F"\n", mutex->handle);
49 return OS_FAIL;
50 }
51
52 return OS_OK;
53 }
54
55 /**
56 * @brief Delete the mutex object
57 * @param[in] mutex Pointer to the mutex object
58 * @retval OS_Status, OS_OK on success
59 */
OS_MutexDelete(OS_Mutex_t * mutex)60 OS_Status OS_MutexDelete(OS_Mutex_t *mutex)
61 {
62 rt_err_t ret;
63
64 OS_HANDLE_ASSERT(OS_MutexIsValid(mutex), mutex->handle);
65
66 ret = rt_mutex_delete(mutex->handle);
67 if (ret != RT_EOK) {
68 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
69 return OS_FAIL;
70 }
71 OS_MutexSetInvalid(mutex);
72 return OS_OK;
73 }
74
75 /**
76 * @brief Lock the mutex object
77 * @note A mutex can only be locked by a single thread at any given time. If
78 * the mutex is already locked, the caller will be blocked for the
79 * specified time duration.
80 * @param[in] mutex Pointer to the mutex object
81 * @param[in] waitMS The maximum amount of time (in millisecond) the thread
82 * should remain in the blocked state to wait for the mutex
83 * to become unlocked.
84 * OS_WAIT_FOREVER for waiting forever, zero for no waiting.
85 * @retval OS_Status, OS_OK on success
86 */
OS_MutexLock(OS_Mutex_t * mutex,OS_Time_t waitMS)87 OS_Status OS_MutexLock(OS_Mutex_t *mutex, OS_Time_t waitMS)
88 {
89 rt_err_t ret;
90
91 OS_HANDLE_ASSERT(OS_MutexIsValid(mutex), mutex->handle);
92
93 ret = rt_mutex_take(mutex->handle, OS_CalcWaitTicks(waitMS));
94 if (ret != RT_EOK) {
95 OS_DBG("%s() fail @ %d, %"OS_TIME_F" ms\n", __func__, __LINE__, (unsigned int)waitMS);
96 return OS_FAIL;
97 }
98
99 return OS_OK;
100 }
101
102 /**
103 * @brief Unlock the mutex object previously locked using OS_MutexLock()
104 * @note The mutex should be unlocked from the same thread context from which
105 * it was locked.
106 * @param[in] mutex Pointer to the mutex object
107 * @retval OS_Status, OS_OK on success
108 */
OS_MutexUnlock(OS_Mutex_t * mutex)109 OS_Status OS_MutexUnlock(OS_Mutex_t *mutex)
110 {
111 rt_err_t ret;
112
113 OS_HANDLE_ASSERT(OS_MutexIsValid(mutex), mutex->handle);
114
115 ret = rt_mutex_release(mutex->handle);
116 if (ret != RT_EOK) {
117 OS_DBG("%s() fail @ %d\n", __func__, __LINE__);
118 return OS_FAIL;
119 }
120
121 return OS_OK;
122 }
123