Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

UserRevisionLine numberNew contents of line
XinZhangMS 0:f7f1f0d76dd6 1 // Copyright (c) Microsoft. All rights reserved.
XinZhangMS 0:f7f1f0d76dd6 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
XinZhangMS 0:f7f1f0d76dd6 3
XinZhangMS 0:f7f1f0d76dd6 4
XinZhangMS 0:f7f1f0d76dd6 5 #include <stdlib.h>
XinZhangMS 0:f7f1f0d76dd6 6 #include <stdint.h>
XinZhangMS 0:f7f1f0d76dd6 7 #include <stddef.h>
XinZhangMS 0:f7f1f0d76dd6 8 #include "azure_c_shared_utility/lock.h"
XinZhangMS 0:f7f1f0d76dd6 9 #include "azure_c_shared_utility/optimize_size.h"
XinZhangMS 0:f7f1f0d76dd6 10 #include "azure_c_shared_utility/xlogging.h"
XinZhangMS 0:f7f1f0d76dd6 11
XinZhangMS 0:f7f1f0d76dd6 12 #ifndef GB_USE_CUSTOM_HEAP
XinZhangMS 0:f7f1f0d76dd6 13
XinZhangMS 0:f7f1f0d76dd6 14 #ifndef SIZE_MAX
XinZhangMS 0:f7f1f0d76dd6 15 #define SIZE_MAX ((size_t)~(size_t)0)
XinZhangMS 0:f7f1f0d76dd6 16 #endif
XinZhangMS 0:f7f1f0d76dd6 17
XinZhangMS 0:f7f1f0d76dd6 18 typedef struct ALLOCATION_TAG
XinZhangMS 0:f7f1f0d76dd6 19 {
XinZhangMS 0:f7f1f0d76dd6 20 size_t size;
XinZhangMS 0:f7f1f0d76dd6 21 void* ptr;
XinZhangMS 0:f7f1f0d76dd6 22 void* next;
XinZhangMS 0:f7f1f0d76dd6 23 } ALLOCATION;
XinZhangMS 0:f7f1f0d76dd6 24
XinZhangMS 0:f7f1f0d76dd6 25 typedef enum GBALLOC_STATE_TAG
XinZhangMS 0:f7f1f0d76dd6 26 {
XinZhangMS 0:f7f1f0d76dd6 27 GBALLOC_STATE_INIT,
XinZhangMS 0:f7f1f0d76dd6 28 GBALLOC_STATE_NOT_INIT
XinZhangMS 0:f7f1f0d76dd6 29 } GBALLOC_STATE;
XinZhangMS 0:f7f1f0d76dd6 30
XinZhangMS 0:f7f1f0d76dd6 31 static ALLOCATION* head = NULL;
XinZhangMS 0:f7f1f0d76dd6 32 static size_t totalSize = 0;
XinZhangMS 0:f7f1f0d76dd6 33 static size_t maxSize = 0;
XinZhangMS 0:f7f1f0d76dd6 34 static size_t g_allocations = 0;
XinZhangMS 0:f7f1f0d76dd6 35 static GBALLOC_STATE gballocState = GBALLOC_STATE_NOT_INIT;
XinZhangMS 0:f7f1f0d76dd6 36
XinZhangMS 0:f7f1f0d76dd6 37 static LOCK_HANDLE gballocThreadSafeLock = NULL;
XinZhangMS 0:f7f1f0d76dd6 38
XinZhangMS 0:f7f1f0d76dd6 39 int gballoc_init(void)
XinZhangMS 0:f7f1f0d76dd6 40 {
XinZhangMS 0:f7f1f0d76dd6 41 int result;
XinZhangMS 0:f7f1f0d76dd6 42
XinZhangMS 0:f7f1f0d76dd6 43 if (gballocState != GBALLOC_STATE_NOT_INIT)
XinZhangMS 0:f7f1f0d76dd6 44 {
XinZhangMS 0:f7f1f0d76dd6 45 /* Codes_SRS_GBALLOC_01_025: [Init after Init shall fail and return a non-zero value.] */
XinZhangMS 0:f7f1f0d76dd6 46 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 47 }
XinZhangMS 0:f7f1f0d76dd6 48 /* Codes_SRS_GBALLOC_01_026: [gballoc_Init shall create a lock handle that will be used to make the other gballoc APIs thread-safe.] */
XinZhangMS 0:f7f1f0d76dd6 49 else if ((gballocThreadSafeLock = Lock_Init()) == NULL)
XinZhangMS 0:f7f1f0d76dd6 50 {
XinZhangMS 0:f7f1f0d76dd6 51 /* Codes_SRS_GBALLOC_01_027: [If the Lock creation fails, gballoc_init shall return a non-zero value.]*/
XinZhangMS 0:f7f1f0d76dd6 52 result = __FAILURE__;
XinZhangMS 0:f7f1f0d76dd6 53 }
XinZhangMS 0:f7f1f0d76dd6 54 else
XinZhangMS 0:f7f1f0d76dd6 55 {
XinZhangMS 0:f7f1f0d76dd6 56 gballocState = GBALLOC_STATE_INIT;
XinZhangMS 0:f7f1f0d76dd6 57
XinZhangMS 0:f7f1f0d76dd6 58 /* Codes_ SRS_GBALLOC_01_002: [Upon initialization the total memory used and maximum total memory used tracked by the module shall be set to 0.] */
XinZhangMS 0:f7f1f0d76dd6 59 totalSize = 0;
XinZhangMS 0:f7f1f0d76dd6 60 maxSize = 0;
XinZhangMS 0:f7f1f0d76dd6 61 g_allocations = 0;
XinZhangMS 0:f7f1f0d76dd6 62
XinZhangMS 0:f7f1f0d76dd6 63 /* Codes_SRS_GBALLOC_01_024: [gballoc_init shall initialize the gballoc module and return 0 upon success.] */
XinZhangMS 0:f7f1f0d76dd6 64 result = 0;
XinZhangMS 0:f7f1f0d76dd6 65 }
XinZhangMS 0:f7f1f0d76dd6 66
XinZhangMS 0:f7f1f0d76dd6 67 return result;
XinZhangMS 0:f7f1f0d76dd6 68 }
XinZhangMS 0:f7f1f0d76dd6 69
XinZhangMS 0:f7f1f0d76dd6 70 void gballoc_deinit(void)
XinZhangMS 0:f7f1f0d76dd6 71 {
XinZhangMS 0:f7f1f0d76dd6 72 if (gballocState == GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 73 {
XinZhangMS 0:f7f1f0d76dd6 74 /* Codes_SRS_GBALLOC_01_028: [gballoc_deinit shall free all resources allocated by gballoc_init.] */
XinZhangMS 0:f7f1f0d76dd6 75 (void)Lock_Deinit(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 76 }
XinZhangMS 0:f7f1f0d76dd6 77
XinZhangMS 0:f7f1f0d76dd6 78 gballocState = GBALLOC_STATE_NOT_INIT;
XinZhangMS 0:f7f1f0d76dd6 79 }
XinZhangMS 0:f7f1f0d76dd6 80
XinZhangMS 0:f7f1f0d76dd6 81 void* gballoc_malloc(size_t size)
XinZhangMS 0:f7f1f0d76dd6 82 {
XinZhangMS 0:f7f1f0d76dd6 83 void* result;
XinZhangMS 0:f7f1f0d76dd6 84
XinZhangMS 0:f7f1f0d76dd6 85 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 86 {
XinZhangMS 0:f7f1f0d76dd6 87 /* Codes_SRS_GBALLOC_01_039: [If gballoc was not initialized gballoc_malloc shall simply call malloc without any memory tracking being performed.] */
XinZhangMS 0:f7f1f0d76dd6 88 result = malloc(size);
XinZhangMS 0:f7f1f0d76dd6 89 }
XinZhangMS 0:f7f1f0d76dd6 90 /* Codes_SRS_GBALLOC_01_030: [gballoc_malloc shall ensure thread safety by using the lock created by gballoc_Init.] */
XinZhangMS 0:f7f1f0d76dd6 91 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 92 {
XinZhangMS 0:f7f1f0d76dd6 93 /* Codes_SRS_GBALLOC_01_048: [If acquiring the lock fails, gballoc_malloc shall return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 94 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 95 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 96 }
XinZhangMS 0:f7f1f0d76dd6 97 else
XinZhangMS 0:f7f1f0d76dd6 98 {
XinZhangMS 0:f7f1f0d76dd6 99 ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
XinZhangMS 0:f7f1f0d76dd6 100 if (allocation == NULL)
XinZhangMS 0:f7f1f0d76dd6 101 {
XinZhangMS 0:f7f1f0d76dd6 102 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 103 }
XinZhangMS 0:f7f1f0d76dd6 104 else
XinZhangMS 0:f7f1f0d76dd6 105 {
XinZhangMS 0:f7f1f0d76dd6 106 /* Codes_SRS_GBALLOC_01_003: [gb_malloc shall call the C99 malloc function and return its result.] */
XinZhangMS 0:f7f1f0d76dd6 107 result = malloc(size);
XinZhangMS 0:f7f1f0d76dd6 108 if (result == NULL)
XinZhangMS 0:f7f1f0d76dd6 109 {
XinZhangMS 0:f7f1f0d76dd6 110 /* Codes_SRS_GBALLOC_01_012: [When the underlying malloc call fails, gballoc_malloc shall return NULL and size should not be counted towards total memory used.] */
XinZhangMS 0:f7f1f0d76dd6 111 free(allocation);
XinZhangMS 0:f7f1f0d76dd6 112 }
XinZhangMS 0:f7f1f0d76dd6 113 else
XinZhangMS 0:f7f1f0d76dd6 114 {
XinZhangMS 0:f7f1f0d76dd6 115 /* Codes_SRS_GBALLOC_01_004: [If the underlying malloc call is successful, gb_malloc shall increment the total memory used with the amount indicated by size.] */
XinZhangMS 0:f7f1f0d76dd6 116 allocation->ptr = result;
XinZhangMS 0:f7f1f0d76dd6 117 allocation->size = size;
XinZhangMS 0:f7f1f0d76dd6 118 allocation->next = head;
XinZhangMS 0:f7f1f0d76dd6 119 head = allocation;
XinZhangMS 0:f7f1f0d76dd6 120
XinZhangMS 0:f7f1f0d76dd6 121 g_allocations++;
XinZhangMS 0:f7f1f0d76dd6 122 totalSize += size;
XinZhangMS 0:f7f1f0d76dd6 123 /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
XinZhangMS 0:f7f1f0d76dd6 124 if (maxSize < totalSize)
XinZhangMS 0:f7f1f0d76dd6 125 {
XinZhangMS 0:f7f1f0d76dd6 126 maxSize = totalSize;
XinZhangMS 0:f7f1f0d76dd6 127 }
XinZhangMS 0:f7f1f0d76dd6 128 }
XinZhangMS 0:f7f1f0d76dd6 129 }
XinZhangMS 0:f7f1f0d76dd6 130
XinZhangMS 0:f7f1f0d76dd6 131 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 132 }
XinZhangMS 0:f7f1f0d76dd6 133
XinZhangMS 0:f7f1f0d76dd6 134 return result;
XinZhangMS 0:f7f1f0d76dd6 135 }
XinZhangMS 0:f7f1f0d76dd6 136
XinZhangMS 0:f7f1f0d76dd6 137 void* gballoc_calloc(size_t nmemb, size_t size)
XinZhangMS 0:f7f1f0d76dd6 138 {
XinZhangMS 0:f7f1f0d76dd6 139 void* result;
XinZhangMS 0:f7f1f0d76dd6 140
XinZhangMS 0:f7f1f0d76dd6 141 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 142 {
XinZhangMS 0:f7f1f0d76dd6 143 /* Codes_SRS_GBALLOC_01_040: [If gballoc was not initialized gballoc_calloc shall simply call calloc without any memory tracking being performed.] */
XinZhangMS 0:f7f1f0d76dd6 144 result = calloc(nmemb, size);
XinZhangMS 0:f7f1f0d76dd6 145 }
XinZhangMS 0:f7f1f0d76dd6 146 /* Codes_SRS_GBALLOC_01_031: [gballoc_calloc shall ensure thread safety by using the lock created by gballoc_Init] */
XinZhangMS 0:f7f1f0d76dd6 147 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 148 {
XinZhangMS 0:f7f1f0d76dd6 149 /* Codes_SRS_GBALLOC_01_046: [If acquiring the lock fails, gballoc_calloc shall return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 150 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 151 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 152 }
XinZhangMS 0:f7f1f0d76dd6 153 else
XinZhangMS 0:f7f1f0d76dd6 154 {
XinZhangMS 0:f7f1f0d76dd6 155 ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
XinZhangMS 0:f7f1f0d76dd6 156 if (allocation == NULL)
XinZhangMS 0:f7f1f0d76dd6 157 {
XinZhangMS 0:f7f1f0d76dd6 158 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 159 }
XinZhangMS 0:f7f1f0d76dd6 160 else
XinZhangMS 0:f7f1f0d76dd6 161 {
XinZhangMS 0:f7f1f0d76dd6 162 /* Codes_SRS_GBALLOC_01_020: [gballoc_calloc shall call the C99 calloc function and return its result.] */
XinZhangMS 0:f7f1f0d76dd6 163 result = calloc(nmemb, size);
XinZhangMS 0:f7f1f0d76dd6 164 if (result == NULL)
XinZhangMS 0:f7f1f0d76dd6 165 {
XinZhangMS 0:f7f1f0d76dd6 166 /* Codes_SRS_GBALLOC_01_022: [When the underlying calloc call fails, gballoc_calloc shall return NULL and size should not be counted towards total memory used.] */
XinZhangMS 0:f7f1f0d76dd6 167 free(allocation);
XinZhangMS 0:f7f1f0d76dd6 168 }
XinZhangMS 0:f7f1f0d76dd6 169 else
XinZhangMS 0:f7f1f0d76dd6 170 {
XinZhangMS 0:f7f1f0d76dd6 171 /* Codes_SRS_GBALLOC_01_021: [If the underlying calloc call is successful, gballoc_calloc shall increment the total memory used with nmemb*size.] */
XinZhangMS 0:f7f1f0d76dd6 172 allocation->ptr = result;
XinZhangMS 0:f7f1f0d76dd6 173 allocation->size = nmemb * size;
XinZhangMS 0:f7f1f0d76dd6 174 allocation->next = head;
XinZhangMS 0:f7f1f0d76dd6 175 head = allocation;
XinZhangMS 0:f7f1f0d76dd6 176 g_allocations++;
XinZhangMS 0:f7f1f0d76dd6 177
XinZhangMS 0:f7f1f0d76dd6 178 totalSize += allocation->size;
XinZhangMS 0:f7f1f0d76dd6 179 /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
XinZhangMS 0:f7f1f0d76dd6 180 if (maxSize < totalSize)
XinZhangMS 0:f7f1f0d76dd6 181 {
XinZhangMS 0:f7f1f0d76dd6 182 maxSize = totalSize;
XinZhangMS 0:f7f1f0d76dd6 183 }
XinZhangMS 0:f7f1f0d76dd6 184 }
XinZhangMS 0:f7f1f0d76dd6 185 }
XinZhangMS 0:f7f1f0d76dd6 186
XinZhangMS 0:f7f1f0d76dd6 187 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 188 }
XinZhangMS 0:f7f1f0d76dd6 189
XinZhangMS 0:f7f1f0d76dd6 190 return result;
XinZhangMS 0:f7f1f0d76dd6 191 }
XinZhangMS 0:f7f1f0d76dd6 192
XinZhangMS 0:f7f1f0d76dd6 193 void* gballoc_realloc(void* ptr, size_t size)
XinZhangMS 0:f7f1f0d76dd6 194 {
XinZhangMS 0:f7f1f0d76dd6 195 ALLOCATION* curr;
XinZhangMS 0:f7f1f0d76dd6 196 void* result;
XinZhangMS 0:f7f1f0d76dd6 197 ALLOCATION* allocation = NULL;
XinZhangMS 0:f7f1f0d76dd6 198
XinZhangMS 0:f7f1f0d76dd6 199 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 200 {
XinZhangMS 0:f7f1f0d76dd6 201 /* Codes_SRS_GBALLOC_01_041: [If gballoc was not initialized gballoc_realloc shall shall simply call realloc without any memory tracking being performed.] */
XinZhangMS 0:f7f1f0d76dd6 202 result = realloc(ptr, size);
XinZhangMS 0:f7f1f0d76dd6 203 }
XinZhangMS 0:f7f1f0d76dd6 204 /* Codes_SRS_GBALLOC_01_032: [gballoc_realloc shall ensure thread safety by using the lock created by gballoc_Init.] */
XinZhangMS 0:f7f1f0d76dd6 205 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 206 {
XinZhangMS 0:f7f1f0d76dd6 207 /* Codes_SRS_GBALLOC_01_047: [If acquiring the lock fails, gballoc_realloc shall return NULL.] */
XinZhangMS 0:f7f1f0d76dd6 208 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 209 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 210 }
XinZhangMS 0:f7f1f0d76dd6 211 else
XinZhangMS 0:f7f1f0d76dd6 212 {
XinZhangMS 0:f7f1f0d76dd6 213 if (ptr == NULL)
XinZhangMS 0:f7f1f0d76dd6 214 {
XinZhangMS 0:f7f1f0d76dd6 215 /* Codes_SRS_GBALLOC_01_017: [When ptr is NULL, gballoc_realloc shall call the underlying realloc with ptr being NULL and the realloc result shall be tracked by gballoc.] */
XinZhangMS 0:f7f1f0d76dd6 216 allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
XinZhangMS 0:f7f1f0d76dd6 217 }
XinZhangMS 0:f7f1f0d76dd6 218 else
XinZhangMS 0:f7f1f0d76dd6 219 {
XinZhangMS 0:f7f1f0d76dd6 220 curr = head;
XinZhangMS 0:f7f1f0d76dd6 221 while (curr != NULL)
XinZhangMS 0:f7f1f0d76dd6 222 {
XinZhangMS 0:f7f1f0d76dd6 223 if (curr->ptr == ptr)
XinZhangMS 0:f7f1f0d76dd6 224 {
XinZhangMS 0:f7f1f0d76dd6 225 allocation = curr;
XinZhangMS 0:f7f1f0d76dd6 226 break;
XinZhangMS 0:f7f1f0d76dd6 227 }
XinZhangMS 0:f7f1f0d76dd6 228 else
XinZhangMS 0:f7f1f0d76dd6 229 {
XinZhangMS 0:f7f1f0d76dd6 230 curr = (ALLOCATION*)curr->next;
XinZhangMS 0:f7f1f0d76dd6 231 }
XinZhangMS 0:f7f1f0d76dd6 232 }
XinZhangMS 0:f7f1f0d76dd6 233 }
XinZhangMS 0:f7f1f0d76dd6 234
XinZhangMS 0:f7f1f0d76dd6 235 if (allocation == NULL)
XinZhangMS 0:f7f1f0d76dd6 236 {
XinZhangMS 0:f7f1f0d76dd6 237 /* Codes_SRS_GBALLOC_01_015: [When allocating memory used for tracking by gballoc_realloc fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
XinZhangMS 0:f7f1f0d76dd6 238 /* Codes_SRS_GBALLOC_01_016: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_realloc shall return NULL and the underlying realloc shall not be called.] */
XinZhangMS 0:f7f1f0d76dd6 239 result = NULL;
XinZhangMS 0:f7f1f0d76dd6 240 }
XinZhangMS 0:f7f1f0d76dd6 241 else
XinZhangMS 0:f7f1f0d76dd6 242 {
XinZhangMS 0:f7f1f0d76dd6 243 result = realloc(ptr, size);
XinZhangMS 0:f7f1f0d76dd6 244 if (result == NULL)
XinZhangMS 0:f7f1f0d76dd6 245 {
XinZhangMS 0:f7f1f0d76dd6 246 /* Codes_SRS_GBALLOC_01_014: [When the underlying realloc call fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
XinZhangMS 0:f7f1f0d76dd6 247 if (ptr == NULL)
XinZhangMS 0:f7f1f0d76dd6 248 {
XinZhangMS 0:f7f1f0d76dd6 249 free(allocation);
XinZhangMS 0:f7f1f0d76dd6 250 }
XinZhangMS 0:f7f1f0d76dd6 251 }
XinZhangMS 0:f7f1f0d76dd6 252 else
XinZhangMS 0:f7f1f0d76dd6 253 {
XinZhangMS 0:f7f1f0d76dd6 254 if (ptr != NULL)
XinZhangMS 0:f7f1f0d76dd6 255 {
XinZhangMS 0:f7f1f0d76dd6 256 /* Codes_SRS_GBALLOC_01_006: [If the underlying realloc call is successful, gballoc_realloc shall look up the size associated with the pointer ptr and decrease the total memory used with that size.] */
XinZhangMS 0:f7f1f0d76dd6 257 allocation->ptr = result;
XinZhangMS 0:f7f1f0d76dd6 258 totalSize -= allocation->size;
XinZhangMS 0:f7f1f0d76dd6 259 allocation->size = size;
XinZhangMS 0:f7f1f0d76dd6 260 }
XinZhangMS 0:f7f1f0d76dd6 261 else
XinZhangMS 0:f7f1f0d76dd6 262 {
XinZhangMS 0:f7f1f0d76dd6 263 /* add block */
XinZhangMS 0:f7f1f0d76dd6 264 allocation->ptr = result;
XinZhangMS 0:f7f1f0d76dd6 265 allocation->size = size;
XinZhangMS 0:f7f1f0d76dd6 266 allocation->next = head;
XinZhangMS 0:f7f1f0d76dd6 267 head = allocation;
XinZhangMS 0:f7f1f0d76dd6 268 }
XinZhangMS 0:f7f1f0d76dd6 269
XinZhangMS 0:f7f1f0d76dd6 270 /* Codes_SRS_GBALLOC_01_007: [If realloc is successful, gballoc_realloc shall also increment the total memory used value tracked by this module.] */
XinZhangMS 0:f7f1f0d76dd6 271 totalSize += size;
XinZhangMS 0:f7f1f0d76dd6 272 g_allocations++;
XinZhangMS 0:f7f1f0d76dd6 273
XinZhangMS 0:f7f1f0d76dd6 274 /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
XinZhangMS 0:f7f1f0d76dd6 275 if (maxSize < totalSize)
XinZhangMS 0:f7f1f0d76dd6 276 {
XinZhangMS 0:f7f1f0d76dd6 277 maxSize = totalSize;
XinZhangMS 0:f7f1f0d76dd6 278 }
XinZhangMS 0:f7f1f0d76dd6 279 }
XinZhangMS 0:f7f1f0d76dd6 280 }
XinZhangMS 0:f7f1f0d76dd6 281
XinZhangMS 0:f7f1f0d76dd6 282 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 283 }
XinZhangMS 0:f7f1f0d76dd6 284
XinZhangMS 0:f7f1f0d76dd6 285 return result;
XinZhangMS 0:f7f1f0d76dd6 286 }
XinZhangMS 0:f7f1f0d76dd6 287
XinZhangMS 0:f7f1f0d76dd6 288 void gballoc_free(void* ptr)
XinZhangMS 0:f7f1f0d76dd6 289 {
XinZhangMS 0:f7f1f0d76dd6 290 ALLOCATION* curr = head;
XinZhangMS 0:f7f1f0d76dd6 291 ALLOCATION* prev = NULL;
XinZhangMS 0:f7f1f0d76dd6 292
XinZhangMS 0:f7f1f0d76dd6 293 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 294 {
XinZhangMS 0:f7f1f0d76dd6 295 /* Codes_SRS_GBALLOC_01_042: [If gballoc was not initialized gballoc_free shall shall simply call free.] */
XinZhangMS 0:f7f1f0d76dd6 296 free(ptr);
XinZhangMS 0:f7f1f0d76dd6 297 }
XinZhangMS 0:f7f1f0d76dd6 298 /* Codes_SRS_GBALLOC_01_033: [gballoc_free shall ensure thread safety by using the lock created by gballoc_Init.] */
XinZhangMS 0:f7f1f0d76dd6 299 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 300 {
XinZhangMS 0:f7f1f0d76dd6 301 /* Codes_SRS_GBALLOC_01_049: [If acquiring the lock fails, gballoc_free shall do nothing.] */
XinZhangMS 0:f7f1f0d76dd6 302 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 303 }
XinZhangMS 0:f7f1f0d76dd6 304 else
XinZhangMS 0:f7f1f0d76dd6 305 {
XinZhangMS 0:f7f1f0d76dd6 306 /* Codes_SRS_GBALLOC_01_009: [gballoc_free shall also look up the size associated with the ptr pointer and decrease the total memory used with the associated size amount.] */
XinZhangMS 0:f7f1f0d76dd6 307 while (curr != NULL)
XinZhangMS 0:f7f1f0d76dd6 308 {
XinZhangMS 0:f7f1f0d76dd6 309 if (curr->ptr == ptr)
XinZhangMS 0:f7f1f0d76dd6 310 {
XinZhangMS 0:f7f1f0d76dd6 311 /* Codes_SRS_GBALLOC_01_008: [gballoc_free shall call the C99 free function.] */
XinZhangMS 0:f7f1f0d76dd6 312 free(ptr);
XinZhangMS 0:f7f1f0d76dd6 313 totalSize -= curr->size;
XinZhangMS 0:f7f1f0d76dd6 314 if (prev != NULL)
XinZhangMS 0:f7f1f0d76dd6 315 {
XinZhangMS 0:f7f1f0d76dd6 316 prev->next = curr->next;
XinZhangMS 0:f7f1f0d76dd6 317 }
XinZhangMS 0:f7f1f0d76dd6 318 else
XinZhangMS 0:f7f1f0d76dd6 319 {
XinZhangMS 0:f7f1f0d76dd6 320 head = (ALLOCATION*)curr->next;
XinZhangMS 0:f7f1f0d76dd6 321 }
XinZhangMS 0:f7f1f0d76dd6 322
XinZhangMS 0:f7f1f0d76dd6 323 free(curr);
XinZhangMS 0:f7f1f0d76dd6 324 break;
XinZhangMS 0:f7f1f0d76dd6 325 }
XinZhangMS 0:f7f1f0d76dd6 326
XinZhangMS 0:f7f1f0d76dd6 327 prev = curr;
XinZhangMS 0:f7f1f0d76dd6 328 curr = (ALLOCATION*)curr->next;
XinZhangMS 0:f7f1f0d76dd6 329 }
XinZhangMS 0:f7f1f0d76dd6 330
XinZhangMS 0:f7f1f0d76dd6 331 if ((curr == NULL) && (ptr != NULL))
XinZhangMS 0:f7f1f0d76dd6 332 {
XinZhangMS 0:f7f1f0d76dd6 333 /* Codes_SRS_GBALLOC_01_019: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_free shall not free any memory.] */
XinZhangMS 0:f7f1f0d76dd6 334
XinZhangMS 0:f7f1f0d76dd6 335 /* could not find the allocation */
XinZhangMS 0:f7f1f0d76dd6 336 LogError("Could not free allocation for address %p (not found)", ptr);
XinZhangMS 0:f7f1f0d76dd6 337 }
XinZhangMS 0:f7f1f0d76dd6 338 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 339 }
XinZhangMS 0:f7f1f0d76dd6 340 }
XinZhangMS 0:f7f1f0d76dd6 341
XinZhangMS 0:f7f1f0d76dd6 342 size_t gballoc_getMaximumMemoryUsed(void)
XinZhangMS 0:f7f1f0d76dd6 343 {
XinZhangMS 0:f7f1f0d76dd6 344 size_t result;
XinZhangMS 0:f7f1f0d76dd6 345
XinZhangMS 0:f7f1f0d76dd6 346 /* Codes_SRS_GBALLOC_01_038: [If gballoc was not initialized gballoc_getMaximumMemoryUsed shall return MAX_INT_SIZE.] */
XinZhangMS 0:f7f1f0d76dd6 347 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 348 {
XinZhangMS 0:f7f1f0d76dd6 349 LogError("gballoc is not initialized.");
XinZhangMS 0:f7f1f0d76dd6 350 result = SIZE_MAX;
XinZhangMS 0:f7f1f0d76dd6 351 }
XinZhangMS 0:f7f1f0d76dd6 352 /* Codes_SRS_GBALLOC_01_034: [gballoc_getMaximumMemoryUsed shall ensure thread safety by using the lock created by gballoc_Init.] */
XinZhangMS 0:f7f1f0d76dd6 353 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 354 {
XinZhangMS 0:f7f1f0d76dd6 355 /* Codes_SRS_GBALLOC_01_050: [If the lock cannot be acquired, gballoc_getMaximumMemoryUsed shall return SIZE_MAX.] */
XinZhangMS 0:f7f1f0d76dd6 356 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 357 result = SIZE_MAX;
XinZhangMS 0:f7f1f0d76dd6 358 }
XinZhangMS 0:f7f1f0d76dd6 359 else
XinZhangMS 0:f7f1f0d76dd6 360 {
XinZhangMS 0:f7f1f0d76dd6 361 /* Codes_SRS_GBALLOC_01_010: [gballoc_getMaximumMemoryUsed shall return the maximum amount of total memory used recorded since the module initialization.] */
XinZhangMS 0:f7f1f0d76dd6 362 result = maxSize;
XinZhangMS 0:f7f1f0d76dd6 363 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 364 }
XinZhangMS 0:f7f1f0d76dd6 365
XinZhangMS 0:f7f1f0d76dd6 366 return result;
XinZhangMS 0:f7f1f0d76dd6 367 }
XinZhangMS 0:f7f1f0d76dd6 368
XinZhangMS 0:f7f1f0d76dd6 369 size_t gballoc_getCurrentMemoryUsed(void)
XinZhangMS 0:f7f1f0d76dd6 370 {
XinZhangMS 0:f7f1f0d76dd6 371 size_t result;
XinZhangMS 0:f7f1f0d76dd6 372
XinZhangMS 0:f7f1f0d76dd6 373 /* Codes_SRS_GBALLOC_01_044: [If gballoc was not initialized gballoc_getCurrentMemoryUsed shall return SIZE_MAX.] */
XinZhangMS 0:f7f1f0d76dd6 374 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 375 {
XinZhangMS 0:f7f1f0d76dd6 376 LogError("gballoc is not initialized.");
XinZhangMS 0:f7f1f0d76dd6 377 result = SIZE_MAX;
XinZhangMS 0:f7f1f0d76dd6 378 }
XinZhangMS 0:f7f1f0d76dd6 379 /* Codes_SRS_GBALLOC_01_036: [gballoc_getCurrentMemoryUsed shall ensure thread safety by using the lock created by gballoc_Init.]*/
XinZhangMS 0:f7f1f0d76dd6 380 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 381 {
XinZhangMS 0:f7f1f0d76dd6 382 /* Codes_SRS_GBALLOC_01_051: [If the lock cannot be acquired, gballoc_getCurrentMemoryUsed shall return SIZE_MAX.] */
XinZhangMS 0:f7f1f0d76dd6 383 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 384 result = SIZE_MAX;
XinZhangMS 0:f7f1f0d76dd6 385 }
XinZhangMS 0:f7f1f0d76dd6 386 else
XinZhangMS 0:f7f1f0d76dd6 387 {
XinZhangMS 0:f7f1f0d76dd6 388 /*Codes_SRS_GBALLOC_02_001: [gballoc_getCurrentMemoryUsed shall return the currently used memory size.] */
XinZhangMS 0:f7f1f0d76dd6 389 result = totalSize;
XinZhangMS 0:f7f1f0d76dd6 390 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 391 }
XinZhangMS 0:f7f1f0d76dd6 392
XinZhangMS 0:f7f1f0d76dd6 393 return result;
XinZhangMS 0:f7f1f0d76dd6 394 }
XinZhangMS 0:f7f1f0d76dd6 395
XinZhangMS 0:f7f1f0d76dd6 396 size_t gballoc_getAllocationCount(void)
XinZhangMS 0:f7f1f0d76dd6 397 {
XinZhangMS 0:f7f1f0d76dd6 398 size_t result;
XinZhangMS 0:f7f1f0d76dd6 399
XinZhangMS 0:f7f1f0d76dd6 400 /* Codes_SRS_GBALLOC_07_001: [ If gballoc was not initialized gballoc_getAllocationCount shall return 0. ] */
XinZhangMS 0:f7f1f0d76dd6 401 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 402 {
XinZhangMS 0:f7f1f0d76dd6 403 LogError("gballoc is not initialized.");
XinZhangMS 0:f7f1f0d76dd6 404 result = 0;
XinZhangMS 0:f7f1f0d76dd6 405 }
XinZhangMS 0:f7f1f0d76dd6 406 /* Codes_SRS_GBALLOC_07_002: [ gballoc_getAllocationCount shall ensure thread safety by using the lock created by gballoc_Init ] */
XinZhangMS 0:f7f1f0d76dd6 407 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 408 {
XinZhangMS 0:f7f1f0d76dd6 409 /* Codes_SRS_GBALLOC_07_003: [ If the lock cannot be acquired, gballoc_getAllocationCount shall return 0. ] */
XinZhangMS 0:f7f1f0d76dd6 410 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 411 result = 0;
XinZhangMS 0:f7f1f0d76dd6 412 }
XinZhangMS 0:f7f1f0d76dd6 413 else
XinZhangMS 0:f7f1f0d76dd6 414 {
XinZhangMS 0:f7f1f0d76dd6 415 /* Codes_SRS_GBALLOC_07_004: [ gballoc_getAllocationCount shall return the currently number of allocations. ] */
XinZhangMS 0:f7f1f0d76dd6 416 result = g_allocations;
XinZhangMS 0:f7f1f0d76dd6 417 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 418 }
XinZhangMS 0:f7f1f0d76dd6 419
XinZhangMS 0:f7f1f0d76dd6 420 return result;
XinZhangMS 0:f7f1f0d76dd6 421 }
XinZhangMS 0:f7f1f0d76dd6 422
XinZhangMS 0:f7f1f0d76dd6 423 void gballoc_resetMetrics()
XinZhangMS 0:f7f1f0d76dd6 424 {
XinZhangMS 0:f7f1f0d76dd6 425 /* Codes_SRS_GBALLOC_07_005: [ If gballoc was not initialized gballoc_reset Metrics shall do nothing.] */
XinZhangMS 0:f7f1f0d76dd6 426 if (gballocState != GBALLOC_STATE_INIT)
XinZhangMS 0:f7f1f0d76dd6 427 {
XinZhangMS 0:f7f1f0d76dd6 428 LogError("gballoc is not initialized.");
XinZhangMS 0:f7f1f0d76dd6 429 }
XinZhangMS 0:f7f1f0d76dd6 430 /* Codes_SRS_GBALLOC_07_006: [ gballoc_resetMetrics shall ensure thread safety by using the lock created by gballoc_Init ]*/
XinZhangMS 0:f7f1f0d76dd6 431 else if (LOCK_OK != Lock(gballocThreadSafeLock))
XinZhangMS 0:f7f1f0d76dd6 432 {
XinZhangMS 0:f7f1f0d76dd6 433 /* Codes_SRS_GBALLOC_07_007: [ If the lock cannot be acquired, gballoc_reset Metrics shall do nothing.] */
XinZhangMS 0:f7f1f0d76dd6 434 LogError("Failed to get the Lock.");
XinZhangMS 0:f7f1f0d76dd6 435 }
XinZhangMS 0:f7f1f0d76dd6 436 else
XinZhangMS 0:f7f1f0d76dd6 437 {
XinZhangMS 0:f7f1f0d76dd6 438 /* Codes_SRS_GBALLOC_07_008: [ gballoc_resetMetrics shall reset the total allocation size, max allocation size and number of allocation to zero. ] */
XinZhangMS 0:f7f1f0d76dd6 439 totalSize = 0;
XinZhangMS 0:f7f1f0d76dd6 440 maxSize = 0;
XinZhangMS 0:f7f1f0d76dd6 441 g_allocations = 0;
XinZhangMS 0:f7f1f0d76dd6 442 (void)Unlock(gballocThreadSafeLock);
XinZhangMS 0:f7f1f0d76dd6 443 }
XinZhangMS 0:f7f1f0d76dd6 444 }
XinZhangMS 0:f7f1f0d76dd6 445
XinZhangMS 0:f7f1f0d76dd6 446 #endif // GB_USE_CUSTOM_HEAP