Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2016-2017 Nest Labs, Inc.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * This file defines the abstraction of mutual exclusion locks
22 : * offered by the target platform.
23 : */
24 :
25 : // Include module header
26 : #include <system/SystemMutex.h>
27 :
28 : #include <lib/support/logging/CHIPLogging.h>
29 :
30 : #if !CHIP_SYSTEM_CONFIG_NO_LOCKING
31 :
32 : // Include system headers
33 : #include <errno.h>
34 :
35 : namespace chip {
36 : namespace System {
37 :
38 : /**
39 : * Initialize the mutual exclusion lock instance.
40 : *
41 : * @param[in,out] aThis A zero-initialized object.
42 : *
43 : * @retval #CHIP_NO_ERROR The mutual exclusion lock is ready to use.
44 : * @retval #CHIP_ERROR_NO_MEMORY Insufficient system memory to allocate the mutual exclusion lock.
45 : * @retval #CHIP_ERROR_INCORRECT_STATE An unexpected system error encountered during initialization.
46 : */
47 :
48 : #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING
49 0 : DLL_EXPORT CHIP_ERROR Mutex::Init(Mutex & aThis)
50 : {
51 0 : int lSysError = pthread_mutex_init(&aThis.mPOSIXMutex, nullptr);
52 : CHIP_ERROR lError;
53 :
54 0 : switch (lSysError)
55 : {
56 0 : case 0:
57 0 : lError = CHIP_NO_ERROR;
58 0 : break;
59 :
60 0 : case ENOMEM:
61 0 : lError = CHIP_ERROR_NO_MEMORY;
62 0 : break;
63 :
64 0 : default:
65 0 : lError = CHIP_ERROR_INCORRECT_STATE;
66 0 : break;
67 : }
68 :
69 0 : return lError;
70 : }
71 : #endif // CHIP_SYSTEM_CONFIG_POSIX_LOCKING
72 :
73 : #if CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
74 : DLL_EXPORT CHIP_ERROR Mutex::Init(Mutex & aThis)
75 : {
76 : restart:
77 : if (__sync_bool_compare_and_swap(&aThis.mInitialized, 0, 1))
78 : {
79 : #if (configSUPPORT_STATIC_ALLOCATION == 1)
80 : aThis.mFreeRTOSSemaphore = xSemaphoreCreateMutexStatic(&aThis.mFreeRTOSSemaphoreObj);
81 : #else
82 : aThis.mFreeRTOSSemaphore = xSemaphoreCreateMutex();
83 : #endif
84 : if (aThis.mFreeRTOSSemaphore == nullptr)
85 : {
86 : aThis.mInitialized = 0;
87 :
88 : return CHIP_ERROR_NO_MEMORY;
89 : }
90 : }
91 : else
92 : {
93 : while (aThis.mFreeRTOSSemaphore == nullptr)
94 : {
95 : vTaskDelay(1);
96 :
97 : if (aThis.mInitialized == 0)
98 : {
99 : goto restart;
100 : }
101 : }
102 : }
103 :
104 : return CHIP_NO_ERROR;
105 : }
106 :
107 : DLL_EXPORT void Mutex::Lock(void)
108 : {
109 : xSemaphoreTake(this->mFreeRTOSSemaphore, portMAX_DELAY);
110 : }
111 : #endif // CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING
112 :
113 : #if CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING
114 : DLL_EXPORT CHIP_ERROR Mutex::Init(Mutex & aThis)
115 : {
116 : aThis.mCmsisRTOSMutex = osMutexNew(NULL);
117 : if (aThis.mCmsisRTOSMutex == NULL)
118 : {
119 : ChipLogError(chipSystemLayer, "osMutexNew failed");
120 : return CHIP_ERROR_NO_MEMORY;
121 : }
122 : return CHIP_NO_ERROR;
123 : }
124 :
125 : DLL_EXPORT void Mutex::Lock(void)
126 : {
127 : if (mCmsisRTOSMutex && osMutexAcquire(mCmsisRTOSMutex, osWaitForever) != osOK)
128 : {
129 : ChipLogError(chipSystemLayer, "osMutexAcquire failed");
130 : }
131 : }
132 :
133 : DLL_EXPORT void Mutex::Unlock(void)
134 : {
135 : if (mCmsisRTOSMutex && osMutexRelease(mCmsisRTOSMutex) != osOK)
136 : {
137 : ChipLogError(chipSystemLayer, "osMutexRelease failed");
138 : }
139 : }
140 : #endif // CHIP_SYSTEM_CONFIG_CMSIS_RTOS_LOCKING
141 :
142 : } // namespace System
143 : } // namespace chip
144 :
145 : #endif // !CHIP_SYSTEM_CONFIG_NO_LOCKING
|