Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Mutex.cpp Source File

Mutex.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2012 ARM Limited
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00020  * SOFTWARE.
00021  */
00022 #include "rtos/Mutex.h"
00023 #include "rtos/Kernel.h"
00024 
00025 #include <string.h>
00026 #include "platform/mbed_error.h"
00027 #include "platform/mbed_assert.h"
00028 
00029 #if MBED_CONF_RTOS_PRESENT
00030 
00031 namespace rtos {
00032 
00033 Mutex::Mutex()
00034 {
00035     constructor();
00036 }
00037 
00038 Mutex::Mutex(const char *name)
00039 {
00040     constructor(name);
00041 }
00042 
00043 void Mutex::constructor(const char *name)
00044 {
00045     _count = 0;
00046     osMutexAttr_t attr =
00047     { 0 };
00048     attr.name = name ? name : "application_unnamed_mutex";
00049     attr.cb_mem = &_obj_mem;
00050     attr.cb_size = sizeof(_obj_mem);
00051     attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
00052     _id = osMutexNew(&attr);
00053     // To permit certain cases where a device may get constructed in
00054     // by the attempt to print an error in a fatal shutdown, let a
00055     // mutex construction error pass.
00056     MBED_ASSERT(_id || mbed_get_error_in_progress());
00057 }
00058 
00059 osStatus Mutex::lock(void)
00060 {
00061     osStatus status = osMutexAcquire(_id, osWaitForever);
00062     if (osOK == status) {
00063         _count++;
00064     }
00065 
00066     if (status != osOK && !mbed_get_error_in_progress()) {
00067         MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "Mutex lock failed", status);
00068     }
00069 
00070     return osOK;
00071 }
00072 
00073 osStatus Mutex::lock(uint32_t millisec)
00074 {
00075     osStatus status = osMutexAcquire(_id, millisec);
00076     if (osOK == status) {
00077         _count++;
00078     }
00079 
00080     bool success = (status == osOK ||
00081                     (status == osErrorResource && millisec == 0) ||
00082                     (status == osErrorTimeout && millisec != osWaitForever));
00083 
00084     if (!success && !mbed_get_error_in_progress()) {
00085         MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "Mutex lock failed", status);
00086     }
00087 
00088     return status;
00089 }
00090 
00091 bool Mutex::trylock()
00092 {
00093     return trylock_for(0);
00094 }
00095 
00096 bool Mutex::trylock_for(uint32_t millisec)
00097 {
00098     osStatus status = osMutexAcquire(_id, millisec);
00099     if (status == osOK) {
00100         _count++;
00101         return true;
00102     }
00103 
00104     bool success = (status == osOK ||
00105                     (status == osErrorResource && millisec == 0) ||
00106                     (status == osErrorTimeout && millisec != osWaitForever));
00107 
00108     if (!success && !mbed_get_error_in_progress()) {
00109         MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_MUTEX_LOCK_FAILED), "Mutex lock failed", status);
00110     }
00111 
00112     return false;
00113 }
00114 
00115 bool Mutex::trylock_until(uint64_t millisec)
00116 {
00117     uint64_t now = Kernel::get_ms_count();
00118 
00119     if (now >= millisec) {
00120         return trylock();
00121     } else if (millisec - now >= osWaitForever) {
00122         // API permits early return
00123         return trylock_for(osWaitForever - 1);
00124     } else {
00125         return trylock_for(millisec - now);
00126     }
00127 }
00128 
00129 osStatus Mutex::unlock()
00130 {
00131     osStatus status = osMutexRelease(_id);
00132     if (osOK == status) {
00133         _count--;
00134     }
00135 
00136     if (status != osOK && !mbed_get_error_in_progress()) {
00137         MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_MUTEX_UNLOCK_FAILED), "Mutex unlock failed", status);
00138     }
00139 
00140     return status;
00141 }
00142 
00143 osThreadId Mutex::get_owner()
00144 {
00145     return osMutexGetOwner(_id);
00146 }
00147 
00148 Mutex::~Mutex()
00149 {
00150     osMutexDelete(_id);
00151 }
00152 
00153 }
00154 
00155 #endif