Azure IoT common library

Fork of azure_c_shared_utility by Azure IoT

Committer:
Azure.IoT Build
Date:
Fri Apr 08 12:01:36 2016 -0700
Revision:
0:fa2de1b79154
Child:
1:9190c0f4d23a
1.0.4

Who changed what in which revision?

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