Mark Radbourne / Mbed 2 deprecated FXOS8700CQ_To_Azure_IoT

Dependencies:   azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers gballoc.c Source File

gballoc.c

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 #include <stdlib.h>
00005 #ifdef _CRTDBG_MAP_ALLOC
00006 #include <crtdbg.h>
00007 #endif
00008 
00009 #include "azure_c_shared_utility/lock.h"
00010 #include "azure_c_shared_utility/xlogging.h"
00011 #include <stdint.h>
00012 
00013 #ifndef SIZE_MAX
00014 #define SIZE_MAX ((size_t)~(size_t)0)
00015 #endif
00016 
00017 typedef struct ALLOCATION_TAG
00018 {
00019     size_t size;
00020     void* ptr;
00021     void* next;
00022 } ALLOCATION;
00023 
00024 typedef enum GBALLOC_STATE_TAG
00025 {
00026     GBALLOC_STATE_INIT,
00027     GBALLOC_STATE_NOT_INIT
00028 } GBALLOC_STATE;
00029 
00030 static ALLOCATION* head = NULL;
00031 static size_t totalSize = 0;
00032 static size_t maxSize = 0;
00033 static GBALLOC_STATE gballocState = GBALLOC_STATE_NOT_INIT;
00034 
00035 static LOCK_HANDLE gballocThreadSafeLock = NULL;
00036 
00037 int gballoc_init(void)
00038 {
00039     int result;
00040 
00041     if (gballocState != GBALLOC_STATE_NOT_INIT)
00042     {
00043         /* Codes_SRS_GBALLOC_01_025: [Init after Init shall fail and return a non-zero value.] */
00044         result = __LINE__;
00045     }
00046     /* Codes_SRS_GBALLOC_01_026: [gballoc_Init shall create a lock handle that will be used to make the other gballoc APIs thread-safe.] */
00047     else if ((gballocThreadSafeLock = Lock_Init()) == NULL)
00048     {
00049         /* Codes_SRS_GBALLOC_01_027: [If the Lock creation fails, gballoc_init shall return a non-zero value.]*/
00050         result = __LINE__;
00051     }
00052     else
00053     {
00054         gballocState = GBALLOC_STATE_INIT;
00055 
00056         /* 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.] */
00057         totalSize = 0;
00058         maxSize = 0;
00059 
00060         /* Codes_SRS_GBALLOC_01_024: [gballoc_init shall initialize the gballoc module and return 0 upon success.] */
00061         result = 0;
00062     }
00063 
00064     return result;
00065 }
00066 
00067 void gballoc_deinit(void)
00068 {
00069     if (gballocState == GBALLOC_STATE_INIT)
00070     {
00071         /* Codes_SRS_GBALLOC_01_028: [gballoc_deinit shall free all resources allocated by gballoc_init.] */
00072         (void)Lock_Deinit(gballocThreadSafeLock);
00073     }
00074 
00075     gballocState = GBALLOC_STATE_NOT_INIT;
00076 }
00077 
00078 void* gballoc_malloc(size_t size)
00079 {
00080     void* result;
00081 
00082     if (gballocState != GBALLOC_STATE_INIT)
00083     {
00084         /* Codes_SRS_GBALLOC_01_039: [If gballoc was not initialized gballoc_malloc shall simply call malloc without any memory tracking being performed.] */
00085         result = malloc(size);
00086     }
00087     /* Codes_SRS_GBALLOC_01_030: [gballoc_malloc shall ensure thread safety by using the lock created by gballoc_Init.] */
00088     else if (LOCK_OK != Lock(gballocThreadSafeLock))
00089     {
00090         /* Codes_SRS_GBALLOC_01_048: [If acquiring the lock fails, gballoc_malloc shall return NULL.] */
00091         LogError("Failed to get the Lock.");
00092         result = NULL;
00093     }
00094     else
00095     {
00096     ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
00097     if (allocation == NULL)
00098     {
00099         result = NULL;
00100     }
00101     else
00102     {
00103         /* Codes_SRS_GBALLOC_01_003: [gb_malloc shall call the C99 malloc function and return its result.] */
00104         result = malloc(size);
00105         if (result == NULL)
00106         {
00107             /* 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.] */
00108             free(allocation);
00109         }
00110         else
00111         {
00112             /* 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.] */
00113             allocation->ptr = result;
00114             allocation->size = size;
00115             allocation->next = head;
00116             head = allocation;
00117 
00118             totalSize += size;
00119             /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
00120             if (maxSize < totalSize)
00121             {
00122                 maxSize = totalSize;
00123             }
00124         }
00125     }
00126 
00127         (void)Unlock(gballocThreadSafeLock);
00128     }
00129     
00130     return result;
00131 }
00132 
00133 void* gballoc_calloc(size_t nmemb, size_t size)
00134 {
00135     void* result;
00136 
00137     if (gballocState != GBALLOC_STATE_INIT)
00138     {
00139         /* Codes_SRS_GBALLOC_01_040: [If gballoc was not initialized gballoc_calloc shall simply call calloc without any memory tracking being performed.] */
00140         result = calloc(nmemb, size);
00141     }
00142     /* Codes_SRS_GBALLOC_01_031: [gballoc_calloc shall ensure thread safety by using the lock created by gballoc_Init]  */
00143     else if (LOCK_OK != Lock(gballocThreadSafeLock))
00144     {
00145         /* Codes_SRS_GBALLOC_01_046: [If acquiring the lock fails, gballoc_calloc shall return NULL.] */
00146         LogError("Failed to get the Lock.");
00147         result = NULL;
00148     }
00149     else
00150     {
00151     ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
00152     if (allocation == NULL)
00153     {
00154         result = NULL;
00155     }
00156     else
00157     {
00158         /* Codes_SRS_GBALLOC_01_020: [gballoc_calloc shall call the C99 calloc function and return its result.] */
00159         result = calloc(nmemb, size);
00160         if (result == NULL)
00161         {
00162             /* 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.] */
00163             free(allocation);
00164         }
00165         else
00166         {
00167             /* Codes_SRS_GBALLOC_01_021: [If the underlying calloc call is successful, gballoc_calloc shall increment the total memory used with nmemb*size.] */
00168             allocation->ptr = result;
00169             allocation->size = nmemb * size;
00170             allocation->next = head;
00171             head = allocation;
00172 
00173             totalSize += allocation->size;
00174             /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
00175             if (maxSize < totalSize)
00176             {
00177                 maxSize = totalSize;
00178             }
00179         }
00180         }
00181 
00182         (void)Unlock(gballocThreadSafeLock);
00183     }
00184 
00185     return result;
00186 }
00187 
00188 void* gballoc_realloc(void* ptr, size_t size)
00189 {
00190     ALLOCATION* curr;
00191     void* result;
00192     ALLOCATION* allocation = NULL;
00193 
00194     if (gballocState != GBALLOC_STATE_INIT)
00195     {
00196         /* Codes_SRS_GBALLOC_01_041: [If gballoc was not initialized gballoc_realloc shall shall simply call realloc without any memory tracking being performed.] */
00197         result = realloc(ptr, size);
00198     }
00199     /* Codes_SRS_GBALLOC_01_032: [gballoc_realloc shall ensure thread safety by using the lock created by gballoc_Init.] */
00200     else if (LOCK_OK != Lock(gballocThreadSafeLock))
00201     {
00202         /* Codes_SRS_GBALLOC_01_047: [If acquiring the lock fails, gballoc_realloc shall return NULL.] */
00203         LogError("Failed to get the Lock.");
00204         result = NULL;
00205     }
00206     else
00207     {
00208     if (ptr == NULL)
00209     {
00210         /* 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.] */
00211         allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
00212     }
00213     else
00214     {
00215         curr = head;
00216         while (curr != NULL)
00217         {
00218             if (curr->ptr == ptr)
00219             {
00220                 allocation = curr;
00221                 break;
00222             }
00223             else
00224             {
00225                 curr = (ALLOCATION*)curr->next;
00226             }
00227         }
00228     }
00229 
00230     if (allocation == NULL)
00231     {
00232         /* 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.] */
00233         /* 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.] */
00234         result = NULL;
00235     }
00236     else
00237     {
00238         result = realloc(ptr, size);
00239         if (result == NULL)
00240         {
00241             /* 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.] */
00242             if (ptr == NULL)
00243             {
00244                 free(allocation);
00245             }
00246         }
00247         else
00248         {
00249             if (ptr != NULL)
00250             {
00251                 /* 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.] */
00252                 allocation->ptr = result;
00253                 totalSize -= allocation->size;
00254                 allocation->size = size;
00255             }
00256             else
00257             {
00258                 /* add block */
00259                 allocation->ptr = result;
00260                 allocation->size = size;
00261                 allocation->next = head;
00262                 head = allocation;
00263             }
00264 
00265             /* Codes_SRS_GBALLOC_01_007: [If realloc is successful, gballoc_realloc shall also increment the total memory used value tracked by this module.] */
00266             totalSize += size;
00267 
00268             /* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
00269             if (maxSize < totalSize)
00270             {
00271                 maxSize = totalSize;
00272             }
00273         }
00274         }
00275 
00276         (void)Unlock(gballocThreadSafeLock);
00277     }
00278 
00279     return result;
00280 }
00281 
00282 void gballoc_free(void* ptr)
00283 {
00284     ALLOCATION* curr = head;
00285     ALLOCATION* prev = NULL;
00286 
00287     if (gballocState != GBALLOC_STATE_INIT)
00288     {
00289         /* Codes_SRS_GBALLOC_01_042: [If gballoc was not initialized gballoc_free shall shall simply call free.] */
00290         free(ptr);
00291     }
00292     /* Codes_SRS_GBALLOC_01_033: [gballoc_free shall ensure thread safety by using the lock created by gballoc_Init.] */
00293     else if (LOCK_OK != Lock(gballocThreadSafeLock))
00294     {
00295         /* Codes_SRS_GBALLOC_01_049: [If acquiring the lock fails, gballoc_free shall do nothing.] */
00296         LogError("Failed to get the Lock.");
00297     }
00298     else
00299     {
00300     /* 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.] */
00301     while (curr != NULL)
00302     {
00303         if (curr->ptr == ptr)
00304         {
00305             /* Codes_SRS_GBALLOC_01_008: [gballoc_free shall call the C99 free function.] */
00306             free(ptr);
00307             totalSize -= curr->size;
00308             if (prev != NULL)
00309             {
00310                 prev->next = curr->next;
00311             }
00312             else
00313             {
00314                 head = (ALLOCATION*)curr->next;
00315             }
00316 
00317             free(curr);
00318             break;
00319         }
00320 
00321         prev = curr;
00322         curr = (ALLOCATION*)curr->next;
00323     }
00324 
00325         if ((curr == NULL) && (ptr != NULL))
00326     {
00327         /* 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.] */
00328 
00329         /* could not find the allocation */
00330         LogError("Could not free allocation for address %p (not found)", ptr);
00331     }
00332         (void)Unlock(gballocThreadSafeLock);
00333     }
00334 }
00335 
00336 size_t gballoc_getMaximumMemoryUsed(void)
00337 {
00338     size_t result;
00339 
00340     /* Codes_SRS_GBALLOC_01_038: [If gballoc was not initialized gballoc_getMaximumMemoryUsed shall return MAX_INT_SIZE.] */
00341     if (gballocState != GBALLOC_STATE_INIT)
00342     {
00343         LogError("gballoc is not initialized.");
00344         result = SIZE_MAX;
00345     }
00346     /* Codes_SRS_GBALLOC_01_034: [gballoc_getMaximumMemoryUsed shall ensure thread safety by using the lock created by gballoc_Init.]  */
00347     else if (LOCK_OK != Lock(gballocThreadSafeLock))
00348     {
00349         /* Codes_SRS_GBALLOC_01_050: [If the lock cannot be acquired, gballoc_getMaximumMemoryUsed shall return SIZE_MAX.]  */
00350         LogError("Failed to get the Lock.");
00351         result = SIZE_MAX;
00352     }
00353     else
00354     {
00355     /* Codes_SRS_GBALLOC_01_010: [gballoc_getMaximumMemoryUsed shall return the maximum amount of total memory used recorded since the module initialization.] */
00356         result = maxSize;
00357         Unlock(gballocThreadSafeLock);
00358 }
00359 
00360     return result;
00361 }
00362 
00363 size_t gballoc_getCurrentMemoryUsed(void)
00364 {
00365     size_t result;
00366 
00367     /* Codes_SRS_GBALLOC_01_044: [If gballoc was not initialized gballoc_getCurrentMemoryUsed shall return SIZE_MAX.] */
00368     if (gballocState != GBALLOC_STATE_INIT)
00369     {
00370         LogError("gballoc is not initialized.");
00371         result = SIZE_MAX;
00372     }
00373     /* Codes_SRS_GBALLOC_01_036: [gballoc_getCurrentMemoryUsed shall ensure thread safety by using the lock created by gballoc_Init.]*/
00374     else if (LOCK_OK != Lock(gballocThreadSafeLock))
00375     {
00376         /* Codes_SRS_GBALLOC_01_051: [If the lock cannot be acquired, gballoc_getCurrentMemoryUsed shall return SIZE_MAX.] */
00377         LogError("Failed to get the Lock.");
00378         result = SIZE_MAX;
00379     }
00380     else
00381     {
00382     /*Codes_SRS_GBALLOC_02_001: [gballoc_getCurrentMemoryUsed shall return the currently used memory size.] */
00383         result = totalSize;
00384         Unlock(gballocThreadSafeLock);
00385     }
00386 
00387     return result;
00388 }