Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed
Fork of iothub_client_sample_amqp by
refcount.h
00001 // Copyright (c) Microsoft. All rights reserved. 00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 00003 00004 00005 /*this header contains macros for ref_counting a variable. 00006 00007 There are no upper bound checks related to uint32_t overflow because we expect that bigger issues are in 00008 the system when more than 4 billion references exist to the same variable. In the case when such an overflow 00009 occurs, the object's ref count will reach zero (while still having 0xFFFFFFFF references) and likely the 00010 controlling code will take the decision to free the object's resources. Then, any of the 0xFFFFFFFF references 00011 will interact with deallocated memory / resources resulting in an undefined behavior. 00012 */ 00013 00014 #ifndef REFCOUNT_H 00015 #define REFCOUNT_H 00016 00017 #ifdef __cplusplus 00018 #include <cstdlib> 00019 #include <cstdint> 00020 extern "C" 00021 { 00022 #else 00023 #include <stdlib.h> 00024 #include <stdint.h> 00025 #endif 00026 00027 00028 #include "azure_c_shared_utility/macro_utils.h" 00029 00030 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ == 201112) && (__STDC_NO_ATOMICS__!=1) 00031 #define REFCOUNT_USE_STD_ATOMIC 1 00032 #endif 00033 00034 #if defined(ARDUINO_ARCH_SAMD) 00035 #undef REFCOUNT_USE_STD_ATOMIC 00036 #endif 00037 00038 #define REFCOUNT_TYPE(type) \ 00039 struct C2(C2(REFCOUNT_, type), _TAG) 00040 00041 #define REFCOUNT_SHORT_TYPE(type) \ 00042 C2(REFCOUNT_, type) 00043 00044 #define REFCOUNT_TYPE_DECLARE_CREATE(type) C2(REFCOUNT_SHORT_TYPE(type), _Create) 00045 #define REFCOUNT_TYPE_CREATE(type) C2(REFCOUNT_SHORT_TYPE(type), _Create)() 00046 00047 /*this introduces a new refcount'd type based on another type */ 00048 /*and an initializer for that new type that also sets the ref count to 1. The type must not have a flexible array*/ 00049 /*the newly allocated memory shall be free'd by free()*/ 00050 /*and the ref counting is handled internally by the type in the _Create/ _Clone /_Destroy functions */ 00051 00052 #if defined(REFCOUNT_USE_STD_ATOMIC) 00053 #define COUNT_TYPE _Atomic uint32_t 00054 #elif defined(WIN32) 00055 #define COUNT_TYPE LONG 00056 #else 00057 #define COUNT_TYPE uint32_t 00058 #endif 00059 00060 #define DEFINE_REFCOUNT_TYPE(type) \ 00061 REFCOUNT_TYPE(type) \ 00062 { \ 00063 type counted; \ 00064 COUNT_TYPE count; \ 00065 }; \ 00066 static type* REFCOUNT_TYPE_DECLARE_CREATE(type) (void) \ 00067 { \ 00068 REFCOUNT_TYPE(type)* result = (REFCOUNT_TYPE(type)*)malloc(sizeof(REFCOUNT_TYPE(type))); \ 00069 if (result != NULL) \ 00070 { \ 00071 result->count = 1; \ 00072 } \ 00073 return (type*)result; \ 00074 } \ 00075 00076 /*the following macros increment/decrement a ref count in an atomic way, depending on the platform*/ 00077 /*The following mechanisms are considered in this order 00078 C11 00079 - will result in #include <stdatomic.h> 00080 - will use atomic_fetch_add/sub; 00081 - about the return value: "Atomically, the value pointed to by object immediately before the effects" 00082 windows 00083 - will result in #include "windows.h" 00084 - will use InterlockedIncrement/InterlockedDecrement; 00085 - about the return value: https://msdn.microsoft.com/en-us/library/windows/desktop/ms683580(v=vs.85).aspx "The function returns the resulting decremented value" 00086 gcc 00087 - will result in no include (for gcc these are intrinsics build in) 00088 - will use __sync_fetch_and_add/sub 00089 - about the return value: "... returns the value that had previously been in memory." (https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Atomic-Builtins.html#Atomic-Builtins) 00090 other cases 00091 - if REFCOUNT_ATOMIC_DONTCARE is defined, then 00092 will result in ++/-- used for increment/decrement. 00093 - if it is not defined, then error out 00094 00095 It seems windows is "one off" because it returns the value "after" the decrement, as opposed to C11 standard and gcc that return the value "before". 00096 The macro DEC_RETURN_ZERO will be "0" on windows, and "1" on the other cases. 00097 */ 00098 00099 /*if macro DEC_REF returns DEC_RETURN_ZERO that means the ref count has reached zero.*/ 00100 #if defined(REFCOUNT_USE_STD_ATOMIC) 00101 #include <stdatomic.h> 00102 #define DEC_RETURN_ZERO (1) 00103 #define INC_REF(type, var) atomic_fetch_add((&((REFCOUNT_TYPE(type)*)var)->count), 1) 00104 #define DEC_REF(type, var) atomic_fetch_sub((&((REFCOUNT_TYPE(type)*)var)->count), 1) 00105 00106 #elif defined(WIN32) 00107 #include "windows.h" 00108 #define DEC_RETURN_ZERO (0) 00109 #define INC_REF(type, var) InterlockedIncrement(&(((REFCOUNT_TYPE(type)*)var)->count)) 00110 #define DEC_REF(type, var) InterlockedDecrement(&(((REFCOUNT_TYPE(type)*)var)->count)) 00111 00112 #elif defined(__GNUC__) 00113 #define DEC_RETURN_ZERO (0) 00114 #define INC_REF(type, var) __sync_add_and_fetch((&((REFCOUNT_TYPE(type)*)var)->count), 1) 00115 #define DEC_REF(type, var) __sync_sub_and_fetch((&((REFCOUNT_TYPE(type)*)var)->count), 1) 00116 00117 #else 00118 #if defined(REFCOUNT_ATOMIC_DONTCARE) 00119 #define DEC_RETURN_ZERO (0) 00120 #define INC_REF(type, var) ++((((REFCOUNT_TYPE(type)*)var)->count)) 00121 #define DEC_REF(type, var) --((((REFCOUNT_TYPE(type)*)var)->count)) 00122 #else 00123 #error do not know how to atomically increment and decrement a uint32_t :(. Platform support needs to be extended to your platform. 00124 #endif /*defined(REFCOUNT_ATOMIC_DONTCARE)*/ 00125 #endif 00126 00127 00128 00129 #ifdef __cplusplus 00130 } 00131 #endif 00132 00133 #endif /*REFCOUNT_H*/ 00134 00135
Generated on Tue Jul 12 2022 12:43:22 by
