Nicolas Borla / Mbed OS ROME2_Robot_Firmware
Committer:
boro
Date:
Mon Mar 16 13:12:31 2020 +0000
Revision:
0:4beb2ea291ec
a

Who changed what in which revision?

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