Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
sotp_shared_lock.c
00001 /* 00002 * Copyright (c) 2016 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 00018 00019 // ----------------------------------------------------------- Includes ----------------------------------------------------------- 00020 00021 00022 #include "sotp_shared_lock.h" 00023 #include "mbed-trace/mbed_trace.h" 00024 #include "pal.h" 00025 #include <string.h> 00026 #include <stdlib.h> 00027 00028 // --------------------------------------------------------- Definitions ---------------------------------------------------------- 00029 00030 #define TRACE_GROUP "sotp" 00031 00032 #define PR_ERR tr_err 00033 #define PR_INFO tr_info 00034 #define PR_DEBUG tr_debug 00035 00036 #define MEDITATE_TIME_MS 100 00037 00038 #ifdef SOTP_THREAD_SAFE 00039 typedef struct { 00040 int32_t ctr; 00041 // Use semaphore and not mutex, as mutexes don't behave well when trying 00042 // to delete them while taken (which may happen in our tests). 00043 palSemaphoreID_t sem; 00044 } shared_lock_priv_t; 00045 #endif 00046 // -------------------------------------------------- Local Functions Declaration ---------------------------------------------------- 00047 00048 00049 // -------------------------------------------------- Functions Implementation ---------------------------------------------------- 00050 // Create a shared lock. 00051 // Parameters : 00052 // sh_lock - [OUT] lock handle. 00053 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00054 sotp_sh_lock_result_e sotp_sh_lock_create(sotp_shared_lock_t *sh_lock) 00055 { 00056 #ifdef SOTP_THREAD_SAFE 00057 shared_lock_priv_t *lock_priv; 00058 lock_priv = (shared_lock_priv_t *) malloc(sizeof(shared_lock_priv_t)); 00059 00060 if (!lock_priv) { 00061 PR_ERR("sotp_sh_lock_create: Out of memory\n"); 00062 return SOTP_SHL_NO_MEM; 00063 } 00064 00065 lock_priv->ctr = 0; 00066 00067 if (pal_osSemaphoreCreate(1, &(lock_priv->sem)) != PAL_SUCCESS) { 00068 PR_ERR("sotp_sh_lock_shared_lock: PAL error\n"); 00069 free(lock_priv); 00070 return SOTP_SHL_PAL_ERR; 00071 } 00072 00073 *sh_lock = (sotp_shared_lock_t) lock_priv; 00074 #endif 00075 return SOTP_SHL_SUCCESS; 00076 } 00077 00078 // Destroy a shared lock. 00079 // Parameters : 00080 // sh_lock - [OUT] lock handle. 00081 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00082 sotp_sh_lock_result_e sotp_sh_lock_destroy(sotp_shared_lock_t sh_lock) 00083 { 00084 #ifdef SOTP_THREAD_SAFE 00085 shared_lock_priv_t *lock_priv = (shared_lock_priv_t *) sh_lock; 00086 00087 if (!sh_lock) { 00088 PR_ERR("sotp_sh_lock_destroy: NULL parameter\n"); 00089 return SOTP_SHL_NULL_PTR; 00090 } 00091 00092 // Semaphore may be taken, so deleting it would fail. Try releasing (without checking return code). 00093 pal_osSemaphoreRelease(lock_priv->sem); 00094 00095 if (pal_osSemaphoreDelete(&(lock_priv->sem)) != PAL_SUCCESS) { 00096 PR_ERR("sotp_sh_lock_destroy: PAL error\n"); 00097 return SOTP_SHL_PAL_ERR; 00098 } 00099 00100 free(lock_priv); 00101 #endif 00102 return SOTP_SHL_SUCCESS; 00103 } 00104 00105 // Lock a shared-lock in a shared manner. 00106 // Parameters : 00107 // sh_lock - [OUT] lock handle. 00108 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00109 sotp_sh_lock_result_e sotp_sh_lock_shared_lock(sotp_shared_lock_t sh_lock) 00110 { 00111 #ifdef SOTP_THREAD_SAFE 00112 shared_lock_priv_t *lock_priv = (shared_lock_priv_t *) sh_lock; 00113 int32_t ctrs; 00114 00115 if (!sh_lock) 00116 return SOTP_SHL_NULL_PTR; 00117 00118 if (pal_osSemaphoreWait(lock_priv->sem, PAL_RTOS_WAIT_FOREVER, &ctrs) != PAL_SUCCESS) { 00119 PR_ERR("sotp_sh_lock_shared_lock: PAL error\n"); 00120 return SOTP_SHL_PAL_ERR; 00121 } 00122 00123 pal_osAtomicIncrement(&lock_priv->ctr, 1); 00124 00125 if (pal_osSemaphoreRelease(lock_priv->sem) != PAL_SUCCESS) { 00126 PR_ERR("sotp_sh_lock_shared_lock: PAL error\n"); 00127 return SOTP_SHL_PAL_ERR; 00128 } 00129 #endif 00130 return SOTP_SHL_SUCCESS; 00131 } 00132 00133 // Release a shared-lock in a shared manner. 00134 // Parameters : 00135 // sh_lock - [OUT] lock handle. 00136 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00137 sotp_sh_lock_result_e sotp_sh_lock_shared_release(sotp_shared_lock_t sh_lock) 00138 { 00139 #ifdef SOTP_THREAD_SAFE 00140 shared_lock_priv_t *lock_priv = (shared_lock_priv_t *) sh_lock; 00141 int32_t val; 00142 00143 if (!sh_lock) { 00144 PR_ERR("sotp_sh_lock_shared_release: NULL parameter\n"); 00145 return SOTP_SHL_NULL_PTR; 00146 } 00147 00148 val = pal_osAtomicIncrement(&lock_priv->ctr, -1); 00149 if (val < 0) { 00150 PR_ERR("sotp_sh_lock_shared_release: Misuse (released more than locked)\n"); 00151 return SOTP_SHL_MISUSE; 00152 } 00153 00154 #endif 00155 return SOTP_SHL_SUCCESS; 00156 } 00157 00158 // Lock a shared-lock in an exclusive manner. 00159 // Parameters : 00160 // sh_lock - [OUT] lock handle. 00161 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00162 sotp_sh_lock_result_e sotp_sh_lock_exclusive_lock(sotp_shared_lock_t sh_lock) 00163 { 00164 #ifdef SOTP_THREAD_SAFE 00165 shared_lock_priv_t *lock_priv = (shared_lock_priv_t *) sh_lock; 00166 int32_t ctrs; 00167 00168 if (!sh_lock) { 00169 PR_ERR("sotp_sh_lock_exclusive_lock: NULL parameter\n"); 00170 return SOTP_SHL_NULL_PTR; 00171 } 00172 00173 if (pal_osSemaphoreWait(lock_priv->sem, PAL_RTOS_WAIT_FOREVER, &ctrs) != PAL_SUCCESS) { 00174 PR_ERR("sotp_sh_lock_exclusive_lock: PAL error\n"); 00175 return SOTP_SHL_PAL_ERR; 00176 } 00177 00178 while(lock_priv->ctr) 00179 pal_osDelay(MEDITATE_TIME_MS); 00180 00181 #endif 00182 return SOTP_SHL_SUCCESS; 00183 } 00184 00185 // Release a shared-lock in an exclusive manner. 00186 // Parameters : 00187 // sh_lock - [OUT] lock handle. 00188 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00189 sotp_sh_lock_result_e sotp_sh_lock_exclusive_release(sotp_shared_lock_t sh_lock) 00190 { 00191 #ifdef SOTP_THREAD_SAFE 00192 shared_lock_priv_t *lock_priv = (shared_lock_priv_t *) sh_lock; 00193 00194 if (!sh_lock) { 00195 PR_ERR("sotp_sh_lock_exclusive_release: NULL parameter\n"); 00196 return SOTP_SHL_NULL_PTR; 00197 } 00198 00199 if (pal_osSemaphoreRelease(lock_priv->sem) != PAL_SUCCESS) { 00200 PR_ERR("sotp_sh_lock_exclusive_release: PAL error\n"); 00201 return SOTP_SHL_PAL_ERR; 00202 } 00203 00204 #endif 00205 return SOTP_SHL_SUCCESS; 00206 } 00207 00208 // Promote a shared-lock from shared mode to exclusive mode. 00209 // Parameters : 00210 // sh_lock - [OUT] lock handle. 00211 // Return : SOTP_SHL_SUCCESS on success. Error code otherwise. 00212 sotp_sh_lock_result_e sotp_sh_lock_promote(sotp_shared_lock_t sh_lock) 00213 { 00214 #ifdef SOTP_THREAD_SAFE 00215 shared_lock_priv_t *lock_priv = (shared_lock_priv_t *) sh_lock; 00216 int32_t ctrs; 00217 00218 if (!sh_lock) { 00219 PR_ERR("sotp_sh_lock_promote: NULL parameter\n"); 00220 return SOTP_SHL_NULL_PTR; 00221 } 00222 00223 if (pal_osSemaphoreWait(lock_priv->sem, PAL_RTOS_WAIT_FOREVER, &ctrs) != PAL_SUCCESS) { 00224 PR_ERR("sotp_sh_lock_promote: PAL error\n"); 00225 return SOTP_SHL_PAL_ERR; 00226 } 00227 00228 while(lock_priv->ctr > 1) 00229 pal_osDelay(MEDITATE_TIME_MS); 00230 00231 if (lock_priv->ctr != 1) { 00232 PR_ERR("sotp_sh_lock_promote: Misuse (promoted when not locked)\n"); 00233 return SOTP_SHL_MISUSE; 00234 } 00235 00236 pal_osAtomicIncrement(&lock_priv->ctr, -1); 00237 00238 #endif 00239 return SOTP_SHL_SUCCESS; 00240 } 00241
Generated on Tue Jul 12 2022 19:01:37 by 1.7.2