mbed library sources. Supersedes mbed-src.
Dependents: LPCXpresso1769_blinky
Fork of mbed-dev by
SingletonPtr.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may 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, 00012 * WITHOUT 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 #ifndef SINGLETONPTR_H 00017 #define SINGLETONPTR_H 00018 00019 #include <stdint.h> 00020 #include <new> 00021 #include "mbed_assert.h" 00022 #ifdef MBED_CONF_RTOS_PRESENT 00023 #include "cmsis_os.h" 00024 #endif 00025 00026 #ifdef MBED_CONF_RTOS_PRESENT 00027 extern osMutexId singleton_mutex_id; 00028 #endif 00029 00030 /** Lock the singleton mutex 00031 * 00032 * This function is typically used to provide 00033 * exclusive access when initializing a 00034 * global object. 00035 */ 00036 inline static void singleton_lock(void) 00037 { 00038 #ifdef MBED_CONF_RTOS_PRESENT 00039 osMutexWait(singleton_mutex_id, osWaitForever); 00040 #endif 00041 } 00042 00043 /** Unlock the singleton mutex 00044 * 00045 * This function is typically used to provide 00046 * exclusive access when initializing a 00047 * global object. 00048 */ 00049 inline static void singleton_unlock(void) 00050 { 00051 #ifdef MBED_CONF_RTOS_PRESENT 00052 osMutexRelease (singleton_mutex_id); 00053 #endif 00054 } 00055 00056 /** Utility class for creating an using a singleton 00057 * 00058 * @Note Synchronization level: Thread safe 00059 * 00060 * @Note: This class must only be used in a static context - 00061 * this class must never be allocated or created on the 00062 * stack. 00063 * 00064 * @Note: This class is lazily initialized on first use. 00065 * This class is a POD type so if it is not used it will 00066 * be garbage collected. 00067 */ 00068 template <class T> 00069 struct SingletonPtr { 00070 00071 /** Get a pointer to the underlying singleton 00072 * 00073 * @returns 00074 * A pointer to the singleton 00075 */ 00076 T* get() { 00077 if (NULL == _ptr) { 00078 singleton_lock(); 00079 if (NULL == _ptr) { 00080 _ptr = new (_data) T(); 00081 } 00082 singleton_unlock(); 00083 } 00084 // _ptr was not zero initialized or was 00085 // corrupted if this assert is hit 00086 MBED_ASSERT(_ptr == (T *)&_data); 00087 return _ptr; 00088 } 00089 00090 /** Get a pointer to the underlying singleton 00091 * 00092 * @returns 00093 * A pointer to the singleton 00094 */ 00095 T* operator->() { 00096 return get(); 00097 } 00098 00099 // This is zero initialized when in global scope 00100 T *_ptr; 00101 // Force data to be 4 byte aligned 00102 uint32_t _data[(sizeof(T) + sizeof(uint32_t) - 1) / sizeof(uint32_t)]; 00103 }; 00104 00105 #endif
Generated on Tue Jul 12 2022 16:04:26 by 1.7.2