Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
SingletonPtr.h
00001 00002 /** \addtogroup platform */ 00003 /** @{*/ 00004 /** 00005 * \defgroup platform_SingletonPtr SingletonPtr class 00006 * @{ 00007 */ 00008 /* mbed Microcontroller Library 00009 * Copyright (c) 2006-2013 ARM Limited 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); 00012 * you may not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, 00019 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 */ 00023 #ifndef SINGLETONPTR_H 00024 #define SINGLETONPTR_H 00025 00026 #include <stdint.h> 00027 #include <new> 00028 #include "platform/mbed_assert.h" 00029 #ifdef MBED_CONF_RTOS_PRESENT 00030 #include "cmsis_os2.h" 00031 #endif 00032 00033 #ifdef MBED_CONF_RTOS_PRESENT 00034 extern osMutexId_t singleton_mutex_id; 00035 #endif 00036 00037 /** Lock the singleton mutex 00038 * 00039 * This function is typically used to provide 00040 * exclusive access when initializing a 00041 * global object. 00042 */ 00043 inline static void singleton_lock(void) 00044 { 00045 #ifdef MBED_CONF_RTOS_PRESENT 00046 osMutexAcquire(singleton_mutex_id, osWaitForever); 00047 #endif 00048 } 00049 00050 /** Unlock the singleton mutex 00051 * 00052 * This function is typically used to provide 00053 * exclusive access when initializing a 00054 * global object. 00055 */ 00056 inline static void singleton_unlock(void) 00057 { 00058 #ifdef MBED_CONF_RTOS_PRESENT 00059 osMutexRelease (singleton_mutex_id); 00060 #endif 00061 } 00062 00063 /** Utility class for creating an using a singleton 00064 * 00065 * @note Synchronization level: Thread safe 00066 * 00067 * @note: This class must only be used in a static context - 00068 * this class must never be allocated or created on the 00069 * stack. 00070 * 00071 * @note: This class is lazily initialized on first use. 00072 * This class is a POD type so if it is not used it will 00073 * be garbage collected. 00074 */ 00075 template <class T> 00076 struct SingletonPtr { 00077 00078 /** Get a pointer to the underlying singleton 00079 * 00080 * @returns 00081 * A pointer to the singleton 00082 */ 00083 T* get() { 00084 if (NULL == _ptr) { 00085 singleton_lock(); 00086 if (NULL == _ptr) { 00087 _ptr = new (_data) T(); 00088 } 00089 singleton_unlock(); 00090 } 00091 // _ptr was not zero initialized or was 00092 // corrupted if this assert is hit 00093 MBED_ASSERT(_ptr == (T *)&_data); 00094 return _ptr; 00095 } 00096 00097 /** Get a pointer to the underlying singleton 00098 * 00099 * @returns 00100 * A pointer to the singleton 00101 */ 00102 T* operator->() { 00103 return get(); 00104 } 00105 00106 // This is zero initialized when in global scope 00107 T *_ptr; 00108 // Force data to be 4 byte aligned 00109 uint32_t _data[(sizeof(T) + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; 00110 }; 00111 00112 #endif 00113 /**@}*/ 00114 00115 /**@}*/
Generated on Sun Jul 17 2022 08:25:30 by 1.7.2