Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sotp_shared_lock.c Source File

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