RTC auf true

Committer:
kevman
Date:
Wed Nov 28 15:10:15 2018 +0000
Revision:
0:38ceb79fef03
RTC modified

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /* mbed Microcontroller Library
kevman 0:38ceb79fef03 2 * Copyright (c) 2006-2018 ARM Limited
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Licensed under the Apache License, Version 2.0 (the "License");
kevman 0:38ceb79fef03 5 * you may not use this file except in compliance with the License.
kevman 0:38ceb79fef03 6 * You may obtain a copy of the License at
kevman 0:38ceb79fef03 7 *
kevman 0:38ceb79fef03 8 * http://www.apache.org/licenses/LICENSE-2.0
kevman 0:38ceb79fef03 9 *
kevman 0:38ceb79fef03 10 * Unless required by applicable law or agreed to in writing, software
kevman 0:38ceb79fef03 11 * distributed under the License is distributed on an "AS IS" BASIS,
kevman 0:38ceb79fef03 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
kevman 0:38ceb79fef03 13 * See the License for the specific language governing permissions and
kevman 0:38ceb79fef03 14 * limitations under the License.
kevman 0:38ceb79fef03 15 */
kevman 0:38ceb79fef03 16
kevman 0:38ceb79fef03 17 #ifndef __SHAREDPTR_H__
kevman 0:38ceb79fef03 18 #define __SHAREDPTR_H__
kevman 0:38ceb79fef03 19
kevman 0:38ceb79fef03 20 #include <stdlib.h>
kevman 0:38ceb79fef03 21
kevman 0:38ceb79fef03 22 #include <stdint.h>
kevman 0:38ceb79fef03 23 #include <stddef.h>
kevman 0:38ceb79fef03 24
kevman 0:38ceb79fef03 25 #include "platform/mbed_critical.h"
kevman 0:38ceb79fef03 26
kevman 0:38ceb79fef03 27 /** Shared pointer class.
kevman 0:38ceb79fef03 28 *
kevman 0:38ceb79fef03 29 * A shared pointer is a "smart" pointer that retains ownership of an object using
kevman 0:38ceb79fef03 30 * reference counting accross all smart pointers referencing that object.
kevman 0:38ceb79fef03 31 *
kevman 0:38ceb79fef03 32 * @code
kevman 0:38ceb79fef03 33 * #include "platform/SharedPtr.h"
kevman 0:38ceb79fef03 34 *
kevman 0:38ceb79fef03 35 * void test() {
kevman 0:38ceb79fef03 36 * struct MyStruct { int a; };
kevman 0:38ceb79fef03 37 *
kevman 0:38ceb79fef03 38 * // Create shared pointer
kevman 0:38ceb79fef03 39 * SharedPtr<MyStruct> ptr( new MyStruct );
kevman 0:38ceb79fef03 40 *
kevman 0:38ceb79fef03 41 * // Increase reference count
kevman 0:38ceb79fef03 42 * SharedPtr<MyStruct> ptr2( ptr );
kevman 0:38ceb79fef03 43 *
kevman 0:38ceb79fef03 44 * ptr = NULL; // Reference to the struct instance is still held by ptr2
kevman 0:38ceb79fef03 45 *
kevman 0:38ceb79fef03 46 * ptr2 = NULL; // The raw pointer is freed
kevman 0:38ceb79fef03 47 * }
kevman 0:38ceb79fef03 48 * @endcode
kevman 0:38ceb79fef03 49 *
kevman 0:38ceb79fef03 50 *
kevman 0:38ceb79fef03 51 * It is similar to the std::shared_ptr class introduced in C++11;
kevman 0:38ceb79fef03 52 * however, this is not a compatible implementation (no weak pointer, no make_shared, no custom deleters and so on.)
kevman 0:38ceb79fef03 53 *
kevman 0:38ceb79fef03 54 * Usage: SharedPtr<Class> ptr(new Class())
kevman 0:38ceb79fef03 55 *
kevman 0:38ceb79fef03 56 * When ptr is passed around by value, the copy constructor and
kevman 0:38ceb79fef03 57 * destructor manages the reference count of the raw pointer.
kevman 0:38ceb79fef03 58 * If the counter reaches zero, delete is called on the raw pointer.
kevman 0:38ceb79fef03 59 *
kevman 0:38ceb79fef03 60 * To avoid loops, use "weak" references by calling the original
kevman 0:38ceb79fef03 61 * pointer directly through ptr.get().
kevman 0:38ceb79fef03 62 */
kevman 0:38ceb79fef03 63
kevman 0:38ceb79fef03 64 template <class T>
kevman 0:38ceb79fef03 65 class SharedPtr {
kevman 0:38ceb79fef03 66 public:
kevman 0:38ceb79fef03 67 /**
kevman 0:38ceb79fef03 68 * @brief Create empty SharedPtr not pointing to anything.
kevman 0:38ceb79fef03 69 * @details Used for variable declaration.
kevman 0:38ceb79fef03 70 */
kevman 0:38ceb79fef03 71 SharedPtr(): _ptr(NULL), _counter(NULL)
kevman 0:38ceb79fef03 72 {
kevman 0:38ceb79fef03 73 }
kevman 0:38ceb79fef03 74
kevman 0:38ceb79fef03 75 /**
kevman 0:38ceb79fef03 76 * @brief Create new SharedPtr
kevman 0:38ceb79fef03 77 * @param ptr Pointer to take control over
kevman 0:38ceb79fef03 78 */
kevman 0:38ceb79fef03 79 SharedPtr(T *ptr): _ptr(ptr), _counter(NULL)
kevman 0:38ceb79fef03 80 {
kevman 0:38ceb79fef03 81 // Allocate counter on the heap, so it can be shared
kevman 0:38ceb79fef03 82 if (_ptr != NULL) {
kevman 0:38ceb79fef03 83 _counter = new uint32_t;
kevman 0:38ceb79fef03 84 *_counter = 1;
kevman 0:38ceb79fef03 85 }
kevman 0:38ceb79fef03 86 }
kevman 0:38ceb79fef03 87
kevman 0:38ceb79fef03 88 /**
kevman 0:38ceb79fef03 89 * @brief Destructor.
kevman 0:38ceb79fef03 90 * @details Decrement reference counter, and delete object if no longer pointed to.
kevman 0:38ceb79fef03 91 */
kevman 0:38ceb79fef03 92 ~SharedPtr()
kevman 0:38ceb79fef03 93 {
kevman 0:38ceb79fef03 94 decrement_counter();
kevman 0:38ceb79fef03 95 }
kevman 0:38ceb79fef03 96
kevman 0:38ceb79fef03 97 /**
kevman 0:38ceb79fef03 98 * @brief Copy constructor.
kevman 0:38ceb79fef03 99 * @details Create new SharedPtr from other SharedPtr by
kevman 0:38ceb79fef03 100 * copying pointer to original object and pointer to counter.
kevman 0:38ceb79fef03 101 * @param source Object being copied from.
kevman 0:38ceb79fef03 102 */
kevman 0:38ceb79fef03 103 SharedPtr(const SharedPtr &source): _ptr(source._ptr), _counter(source._counter)
kevman 0:38ceb79fef03 104 {
kevman 0:38ceb79fef03 105 // Increment reference counter
kevman 0:38ceb79fef03 106 if (_ptr != NULL) {
kevman 0:38ceb79fef03 107 core_util_atomic_incr_u32(_counter, 1);
kevman 0:38ceb79fef03 108 }
kevman 0:38ceb79fef03 109 }
kevman 0:38ceb79fef03 110
kevman 0:38ceb79fef03 111 /**
kevman 0:38ceb79fef03 112 * @brief Assignment operator.
kevman 0:38ceb79fef03 113 * @details Cleanup previous reference and assign new pointer and counter.
kevman 0:38ceb79fef03 114 * @param source Object being assigned from.
kevman 0:38ceb79fef03 115 * @return Object being assigned.
kevman 0:38ceb79fef03 116 */
kevman 0:38ceb79fef03 117 SharedPtr operator=(const SharedPtr &source)
kevman 0:38ceb79fef03 118 {
kevman 0:38ceb79fef03 119 if (this != &source) {
kevman 0:38ceb79fef03 120 // Clean up by decrementing counter
kevman 0:38ceb79fef03 121 decrement_counter();
kevman 0:38ceb79fef03 122
kevman 0:38ceb79fef03 123 // Assign new values
kevman 0:38ceb79fef03 124 _ptr = source.get();
kevman 0:38ceb79fef03 125 _counter = source.get_counter();
kevman 0:38ceb79fef03 126
kevman 0:38ceb79fef03 127 // Increment new counter
kevman 0:38ceb79fef03 128 if (_ptr != NULL) {
kevman 0:38ceb79fef03 129 core_util_atomic_incr_u32(_counter, 1);
kevman 0:38ceb79fef03 130 }
kevman 0:38ceb79fef03 131 }
kevman 0:38ceb79fef03 132
kevman 0:38ceb79fef03 133 return *this;
kevman 0:38ceb79fef03 134 }
kevman 0:38ceb79fef03 135
kevman 0:38ceb79fef03 136 /**
kevman 0:38ceb79fef03 137 * @brief Replaces the managed pointer with a new unmanaged pointer.
kevman 0:38ceb79fef03 138 * @param[in] ptr the new raw pointer to manage.
kevman 0:38ceb79fef03 139 */
kevman 0:38ceb79fef03 140 void reset(T *ptr)
kevman 0:38ceb79fef03 141 {
kevman 0:38ceb79fef03 142 // Clean up by decrementing counter
kevman 0:38ceb79fef03 143 decrement_counter();
kevman 0:38ceb79fef03 144
kevman 0:38ceb79fef03 145 if (ptr != NULL) {
kevman 0:38ceb79fef03 146 // Allocate counter on the heap, so it can be shared
kevman 0:38ceb79fef03 147 _counter = new uint32_t;
kevman 0:38ceb79fef03 148 *_counter = 1;
kevman 0:38ceb79fef03 149 }
kevman 0:38ceb79fef03 150 }
kevman 0:38ceb79fef03 151
kevman 0:38ceb79fef03 152 /**
kevman 0:38ceb79fef03 153 * @brief Replace the managed pointer with a NULL pointer.
kevman 0:38ceb79fef03 154 */
kevman 0:38ceb79fef03 155 void reset()
kevman 0:38ceb79fef03 156 {
kevman 0:38ceb79fef03 157 reset(NULL);
kevman 0:38ceb79fef03 158 }
kevman 0:38ceb79fef03 159
kevman 0:38ceb79fef03 160 /**
kevman 0:38ceb79fef03 161 * @brief Raw pointer accessor.
kevman 0:38ceb79fef03 162 * @details Get raw pointer to object pointed to.
kevman 0:38ceb79fef03 163 * @return Pointer.
kevman 0:38ceb79fef03 164 */
kevman 0:38ceb79fef03 165 T *get() const
kevman 0:38ceb79fef03 166 {
kevman 0:38ceb79fef03 167 return _ptr;
kevman 0:38ceb79fef03 168 }
kevman 0:38ceb79fef03 169
kevman 0:38ceb79fef03 170 /**
kevman 0:38ceb79fef03 171 * @brief Reference count accessor.
kevman 0:38ceb79fef03 172 * @return Reference count.
kevman 0:38ceb79fef03 173 */
kevman 0:38ceb79fef03 174 uint32_t use_count() const
kevman 0:38ceb79fef03 175 {
kevman 0:38ceb79fef03 176 if (_ptr != NULL) {
kevman 0:38ceb79fef03 177 core_util_critical_section_enter();
kevman 0:38ceb79fef03 178 uint32_t current_counter = *_counter;
kevman 0:38ceb79fef03 179 core_util_critical_section_exit();
kevman 0:38ceb79fef03 180 return current_counter;
kevman 0:38ceb79fef03 181 } else {
kevman 0:38ceb79fef03 182 return 0;
kevman 0:38ceb79fef03 183 }
kevman 0:38ceb79fef03 184 }
kevman 0:38ceb79fef03 185
kevman 0:38ceb79fef03 186 /**
kevman 0:38ceb79fef03 187 * @brief Dereference object operator.
kevman 0:38ceb79fef03 188 * @details Override to return the object pointed to.
kevman 0:38ceb79fef03 189 */
kevman 0:38ceb79fef03 190 T &operator*() const
kevman 0:38ceb79fef03 191 {
kevman 0:38ceb79fef03 192 return *_ptr;
kevman 0:38ceb79fef03 193 }
kevman 0:38ceb79fef03 194
kevman 0:38ceb79fef03 195 /**
kevman 0:38ceb79fef03 196 * @brief Dereference object member operator.
kevman 0:38ceb79fef03 197 * @details Override to return return member in object pointed to.
kevman 0:38ceb79fef03 198 */
kevman 0:38ceb79fef03 199 T *operator->() const
kevman 0:38ceb79fef03 200 {
kevman 0:38ceb79fef03 201 return _ptr;
kevman 0:38ceb79fef03 202 }
kevman 0:38ceb79fef03 203
kevman 0:38ceb79fef03 204 /**
kevman 0:38ceb79fef03 205 * @brief Boolean conversion operator.
kevman 0:38ceb79fef03 206 * @return Whether or not the pointer is NULL.
kevman 0:38ceb79fef03 207 */
kevman 0:38ceb79fef03 208 operator bool() const
kevman 0:38ceb79fef03 209 {
kevman 0:38ceb79fef03 210 return (_ptr != NULL);
kevman 0:38ceb79fef03 211 }
kevman 0:38ceb79fef03 212
kevman 0:38ceb79fef03 213 private:
kevman 0:38ceb79fef03 214 /**
kevman 0:38ceb79fef03 215 * @brief Get pointer to reference counter.
kevman 0:38ceb79fef03 216 * @return Pointer to reference counter.
kevman 0:38ceb79fef03 217 */
kevman 0:38ceb79fef03 218 uint32_t *get_counter() const
kevman 0:38ceb79fef03 219 {
kevman 0:38ceb79fef03 220 return _counter;
kevman 0:38ceb79fef03 221 }
kevman 0:38ceb79fef03 222
kevman 0:38ceb79fef03 223 /**
kevman 0:38ceb79fef03 224 * @brief Decrement reference counter.
kevman 0:38ceb79fef03 225 * @details If count reaches zero, free counter and delete object pointed to.
kevman 0:38ceb79fef03 226 */
kevman 0:38ceb79fef03 227 void decrement_counter()
kevman 0:38ceb79fef03 228 {
kevman 0:38ceb79fef03 229 if (_ptr != NULL) {
kevman 0:38ceb79fef03 230 uint32_t new_value = core_util_atomic_decr_u32(_counter, 1);
kevman 0:38ceb79fef03 231 if (new_value == 0) {
kevman 0:38ceb79fef03 232 delete _counter;
kevman 0:38ceb79fef03 233 _counter = NULL;
kevman 0:38ceb79fef03 234 delete _ptr;
kevman 0:38ceb79fef03 235 _ptr = NULL;
kevman 0:38ceb79fef03 236 }
kevman 0:38ceb79fef03 237 }
kevman 0:38ceb79fef03 238 }
kevman 0:38ceb79fef03 239
kevman 0:38ceb79fef03 240 private:
kevman 0:38ceb79fef03 241 // Pointer to shared object
kevman 0:38ceb79fef03 242 T *_ptr;
kevman 0:38ceb79fef03 243
kevman 0:38ceb79fef03 244 // Pointer to shared reference counter
kevman 0:38ceb79fef03 245 uint32_t *_counter;
kevman 0:38ceb79fef03 246 };
kevman 0:38ceb79fef03 247
kevman 0:38ceb79fef03 248 /** Non-member relational operators.
kevman 0:38ceb79fef03 249 */
kevman 0:38ceb79fef03 250 template <class T, class U>
kevman 0:38ceb79fef03 251 bool operator== (const SharedPtr<T> &lhs, const SharedPtr<U> &rhs)
kevman 0:38ceb79fef03 252 {
kevman 0:38ceb79fef03 253 return (lhs.get() == rhs.get());
kevman 0:38ceb79fef03 254 }
kevman 0:38ceb79fef03 255
kevman 0:38ceb79fef03 256 template <class T, typename U>
kevman 0:38ceb79fef03 257 bool operator== (const SharedPtr<T> &lhs, U rhs)
kevman 0:38ceb79fef03 258 {
kevman 0:38ceb79fef03 259 return (lhs.get() == (T *) rhs);
kevman 0:38ceb79fef03 260 }
kevman 0:38ceb79fef03 261
kevman 0:38ceb79fef03 262 template <class T, typename U>
kevman 0:38ceb79fef03 263 bool operator== (U lhs, const SharedPtr<T> &rhs)
kevman 0:38ceb79fef03 264 {
kevman 0:38ceb79fef03 265 return ((T *) lhs == rhs.get());
kevman 0:38ceb79fef03 266 }
kevman 0:38ceb79fef03 267
kevman 0:38ceb79fef03 268 /** Non-member relational operators.
kevman 0:38ceb79fef03 269 */
kevman 0:38ceb79fef03 270 template <class T, class U>
kevman 0:38ceb79fef03 271 bool operator!= (const SharedPtr<T> &lhs, const SharedPtr<U> &rhs)
kevman 0:38ceb79fef03 272 {
kevman 0:38ceb79fef03 273 return (lhs.get() != rhs.get());
kevman 0:38ceb79fef03 274 }
kevman 0:38ceb79fef03 275
kevman 0:38ceb79fef03 276 template <class T, typename U>
kevman 0:38ceb79fef03 277 bool operator!= (const SharedPtr<T> &lhs, U rhs)
kevman 0:38ceb79fef03 278 {
kevman 0:38ceb79fef03 279 return (lhs.get() != (T *) rhs);
kevman 0:38ceb79fef03 280 }
kevman 0:38ceb79fef03 281
kevman 0:38ceb79fef03 282 template <class T, typename U>
kevman 0:38ceb79fef03 283 bool operator!= (U lhs, const SharedPtr<T> &rhs)
kevman 0:38ceb79fef03 284 {
kevman 0:38ceb79fef03 285 return ((T *) lhs != rhs.get());
kevman 0:38ceb79fef03 286 }
kevman 0:38ceb79fef03 287
kevman 0:38ceb79fef03 288 #endif // __SHAREDPTR_H__