Pinned to some recent date

Committer:
Simon Cooksey
Date:
Thu Nov 17 16:43:53 2016 +0000
Revision:
0:fb7af294d5d9
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Simon Cooksey 0:fb7af294d5d9 1
Simon Cooksey 0:fb7af294d5d9 2 /** \addtogroup platform */
Simon Cooksey 0:fb7af294d5d9 3 /** @{*/
Simon Cooksey 0:fb7af294d5d9 4 /* mbed Microcontroller Library
Simon Cooksey 0:fb7af294d5d9 5 * Copyright (c) 2006-2013 ARM Limited
Simon Cooksey 0:fb7af294d5d9 6 *
Simon Cooksey 0:fb7af294d5d9 7 * Licensed under the Apache License, Version 2.0 (the "License");
Simon Cooksey 0:fb7af294d5d9 8 * you may not use this file except in compliance with the License.
Simon Cooksey 0:fb7af294d5d9 9 * You may obtain a copy of the License at
Simon Cooksey 0:fb7af294d5d9 10 *
Simon Cooksey 0:fb7af294d5d9 11 * http://www.apache.org/licenses/LICENSE-2.0
Simon Cooksey 0:fb7af294d5d9 12 *
Simon Cooksey 0:fb7af294d5d9 13 * Unless required by applicable law or agreed to in writing, software
Simon Cooksey 0:fb7af294d5d9 14 * distributed under the License is distributed on an "AS IS" BASIS,
Simon Cooksey 0:fb7af294d5d9 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Simon Cooksey 0:fb7af294d5d9 16 * See the License for the specific language governing permissions and
Simon Cooksey 0:fb7af294d5d9 17 * limitations under the License.
Simon Cooksey 0:fb7af294d5d9 18 */
Simon Cooksey 0:fb7af294d5d9 19 #ifndef SINGLETONPTR_H
Simon Cooksey 0:fb7af294d5d9 20 #define SINGLETONPTR_H
Simon Cooksey 0:fb7af294d5d9 21
Simon Cooksey 0:fb7af294d5d9 22 #include <stdint.h>
Simon Cooksey 0:fb7af294d5d9 23 #include <new>
Simon Cooksey 0:fb7af294d5d9 24 #include "platform/mbed_assert.h"
Simon Cooksey 0:fb7af294d5d9 25 #ifdef MBED_CONF_RTOS_PRESENT
Simon Cooksey 0:fb7af294d5d9 26 #include "cmsis_os.h"
Simon Cooksey 0:fb7af294d5d9 27 #endif
Simon Cooksey 0:fb7af294d5d9 28
Simon Cooksey 0:fb7af294d5d9 29 #ifdef MBED_CONF_RTOS_PRESENT
Simon Cooksey 0:fb7af294d5d9 30 extern osMutexId singleton_mutex_id;
Simon Cooksey 0:fb7af294d5d9 31 #endif
Simon Cooksey 0:fb7af294d5d9 32
Simon Cooksey 0:fb7af294d5d9 33 /** Lock the singleton mutex
Simon Cooksey 0:fb7af294d5d9 34 *
Simon Cooksey 0:fb7af294d5d9 35 * This function is typically used to provide
Simon Cooksey 0:fb7af294d5d9 36 * exclusive access when initializing a
Simon Cooksey 0:fb7af294d5d9 37 * global object.
Simon Cooksey 0:fb7af294d5d9 38 */
Simon Cooksey 0:fb7af294d5d9 39 inline static void singleton_lock(void)
Simon Cooksey 0:fb7af294d5d9 40 {
Simon Cooksey 0:fb7af294d5d9 41 #ifdef MBED_CONF_RTOS_PRESENT
Simon Cooksey 0:fb7af294d5d9 42 osMutexWait(singleton_mutex_id, osWaitForever);
Simon Cooksey 0:fb7af294d5d9 43 #endif
Simon Cooksey 0:fb7af294d5d9 44 }
Simon Cooksey 0:fb7af294d5d9 45
Simon Cooksey 0:fb7af294d5d9 46 /** Unlock the singleton mutex
Simon Cooksey 0:fb7af294d5d9 47 *
Simon Cooksey 0:fb7af294d5d9 48 * This function is typically used to provide
Simon Cooksey 0:fb7af294d5d9 49 * exclusive access when initializing a
Simon Cooksey 0:fb7af294d5d9 50 * global object.
Simon Cooksey 0:fb7af294d5d9 51 */
Simon Cooksey 0:fb7af294d5d9 52 inline static void singleton_unlock(void)
Simon Cooksey 0:fb7af294d5d9 53 {
Simon Cooksey 0:fb7af294d5d9 54 #ifdef MBED_CONF_RTOS_PRESENT
Simon Cooksey 0:fb7af294d5d9 55 osMutexRelease (singleton_mutex_id);
Simon Cooksey 0:fb7af294d5d9 56 #endif
Simon Cooksey 0:fb7af294d5d9 57 }
Simon Cooksey 0:fb7af294d5d9 58
Simon Cooksey 0:fb7af294d5d9 59 /** Utility class for creating an using a singleton
Simon Cooksey 0:fb7af294d5d9 60 *
Simon Cooksey 0:fb7af294d5d9 61 * @Note Synchronization level: Thread safe
Simon Cooksey 0:fb7af294d5d9 62 *
Simon Cooksey 0:fb7af294d5d9 63 * @Note: This class must only be used in a static context -
Simon Cooksey 0:fb7af294d5d9 64 * this class must never be allocated or created on the
Simon Cooksey 0:fb7af294d5d9 65 * stack.
Simon Cooksey 0:fb7af294d5d9 66 *
Simon Cooksey 0:fb7af294d5d9 67 * @Note: This class is lazily initialized on first use.
Simon Cooksey 0:fb7af294d5d9 68 * This class is a POD type so if it is not used it will
Simon Cooksey 0:fb7af294d5d9 69 * be garbage collected.
Simon Cooksey 0:fb7af294d5d9 70 */
Simon Cooksey 0:fb7af294d5d9 71 template <class T>
Simon Cooksey 0:fb7af294d5d9 72 struct SingletonPtr {
Simon Cooksey 0:fb7af294d5d9 73
Simon Cooksey 0:fb7af294d5d9 74 /** Get a pointer to the underlying singleton
Simon Cooksey 0:fb7af294d5d9 75 *
Simon Cooksey 0:fb7af294d5d9 76 * @returns
Simon Cooksey 0:fb7af294d5d9 77 * A pointer to the singleton
Simon Cooksey 0:fb7af294d5d9 78 */
Simon Cooksey 0:fb7af294d5d9 79 T* get() {
Simon Cooksey 0:fb7af294d5d9 80 if (NULL == _ptr) {
Simon Cooksey 0:fb7af294d5d9 81 singleton_lock();
Simon Cooksey 0:fb7af294d5d9 82 if (NULL == _ptr) {
Simon Cooksey 0:fb7af294d5d9 83 _ptr = new (_data) T();
Simon Cooksey 0:fb7af294d5d9 84 }
Simon Cooksey 0:fb7af294d5d9 85 singleton_unlock();
Simon Cooksey 0:fb7af294d5d9 86 }
Simon Cooksey 0:fb7af294d5d9 87 // _ptr was not zero initialized or was
Simon Cooksey 0:fb7af294d5d9 88 // corrupted if this assert is hit
Simon Cooksey 0:fb7af294d5d9 89 MBED_ASSERT(_ptr == (T *)&_data);
Simon Cooksey 0:fb7af294d5d9 90 return _ptr;
Simon Cooksey 0:fb7af294d5d9 91 }
Simon Cooksey 0:fb7af294d5d9 92
Simon Cooksey 0:fb7af294d5d9 93 /** Get a pointer to the underlying singleton
Simon Cooksey 0:fb7af294d5d9 94 *
Simon Cooksey 0:fb7af294d5d9 95 * @returns
Simon Cooksey 0:fb7af294d5d9 96 * A pointer to the singleton
Simon Cooksey 0:fb7af294d5d9 97 */
Simon Cooksey 0:fb7af294d5d9 98 T* operator->() {
Simon Cooksey 0:fb7af294d5d9 99 return get();
Simon Cooksey 0:fb7af294d5d9 100 }
Simon Cooksey 0:fb7af294d5d9 101
Simon Cooksey 0:fb7af294d5d9 102 // This is zero initialized when in global scope
Simon Cooksey 0:fb7af294d5d9 103 T *_ptr;
Simon Cooksey 0:fb7af294d5d9 104 // Force data to be 4 byte aligned
Simon Cooksey 0:fb7af294d5d9 105 uint32_t _data[(sizeof(T) + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
Simon Cooksey 0:fb7af294d5d9 106 };
Simon Cooksey 0:fb7af294d5d9 107
Simon Cooksey 0:fb7af294d5d9 108 #endif
Simon Cooksey 0:fb7af294d5d9 109
Simon Cooksey 0:fb7af294d5d9 110 /** @}*/