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