/* * dynamicMemory.c * * Created on: 22 dic 2018 * Author: ugo */ #include #include #define _REENTRANT #include #include #include "dynamicMemory.h" #include "errorHandling.h" #include "../debugHelper.h" //total memory allocated static unsigned long long int theTotalMemory; static pthread_mutex_t memoryCountMutex; void DYNMEM_Init(void) { static int state = 0; if(state != 0) return; state = 1; theTotalMemory = 0; if (pthread_mutex_init(&memoryCountMutex, NULL) != 0) { report_error_q("Unable to init the mutex", __FILE__, __LINE__, 0); } } unsigned long long int DYNMEM_GetTotalMemory(void) { return theTotalMemory; } unsigned long long int DYNMEM_IncreaseMemoryCounter(unsigned long long int theSize) { pthread_mutex_lock(&memoryCountMutex); theTotalMemory = theTotalMemory + theSize; pthread_mutex_unlock(&memoryCountMutex); return theTotalMemory; } unsigned long long int DYNMEM_DecreaseMemoryCounter(unsigned long long int theSize) { pthread_mutex_lock(&memoryCountMutex); theTotalMemory = theTotalMemory - theSize; pthread_mutex_unlock(&memoryCountMutex); return theTotalMemory; } void *DYNMEM_malloc(size_t bytes, DYNMEM_MemoryTable_DataType **memoryListHead, char * theName) { void *memory = NULL; DYNMEM_MemoryTable_DataType *newItem = NULL; memory = calloc(bytes,1); newItem = calloc(1, sizeof(DYNMEM_MemoryTable_DataType)); //my_printf("Allocating new item in memory, size of %d", bytes); if(memory) { if(newItem == NULL) { report_error_q("Memory allocation error, no room for memory list item.",__FILE__,__LINE__, 0); free(memory); return NULL; } DYNMEM_IncreaseMemoryCounter(bytes + sizeof(DYNMEM_MemoryTable_DataType)); newItem->address = memory; newItem->size = bytes; newItem->nextElement = NULL; newItem->previousElement = NULL; strncpy(newItem->theName, theName, 20); if( (*memoryListHead) != NULL) { newItem->nextElement = *memoryListHead; (*memoryListHead)->previousElement = newItem; (*memoryListHead) = newItem; } else { //my_printf("\nmemoryListHead = %ld", (int) *memoryListHead); *memoryListHead = newItem; //my_printf("\nmemoryListHead = newItem %ld", (int) *memoryListHead); } // my_printf("\nElement size: %ld", (*memoryListHead)->size); // my_printf("\nElement address: %ld", (long int) (*memoryListHead)->address); // my_printf("\nElement nextElement: %ld",(long int) (*memoryListHead)->nextElement); // my_printf("\nElement previousElement: %ld",(long int) (*memoryListHead)->previousElement); return memory; } else { if(newItem) free(newItem); report_error_q("Memory allocation error, out of memory.", __FILE__,__LINE__,0); return NULL; } } void *DYNMEM_realloc(void *theMemoryAddress, size_t bytes, DYNMEM_MemoryTable_DataType **memoryListHead) { void *newMemory = NULL; //my_printf("\nSearching address %lld", theMemoryAddress); newMemory = realloc(theMemoryAddress, bytes); //my_printf("\nReallocating item in memory, size of %d", bytes); //my_printf("\nSearching address %lld", theMemoryAddress); //my_printf("(*memoryListHead) = %lld", (*memoryListHead)); if(newMemory) { DYNMEM_MemoryTable_DataType *temp = NULL,*found = NULL; for( temp = (*memoryListHead); temp!=NULL; temp = temp->nextElement) { //my_printf("\n %lld == %lld", temp->address, theMemoryAddress); if(temp->address == theMemoryAddress) { found = temp; break; } } if(!found) { //Debug TRAP //char *theData ="c"; //strcpy(theData, "NOOOOOOOOOOOOOOOO"); report_error_q("Unable to reallocate memory not previously allocated",__FILE__,__LINE__, 0); free(newMemory); // Report this as an error return NULL; } if (found->size > bytes) { DYNMEM_DecreaseMemoryCounter((found->size-bytes)); } else if (found->size < bytes) { DYNMEM_IncreaseMemoryCounter((bytes-found->size)); } found->address = newMemory; found->size = bytes; //my_printf("\nElement size: %ld", (*found)->size); //my_printf("\nElement address: %ld", (long int) (*found)->address); //my_printf("\nElement nextElement: %ld",(long int) (*found)->nextElement); //my_printf("\nElement previousElement: %ld",(long int) (*found)->previousElement); return newMemory; } else { report_error_q("Memory reallocation error, out of memory.", __FILE__,__LINE__,0); return NULL; } } void DYNMEM_free(void *f_address, DYNMEM_MemoryTable_DataType ** memoryListHead) { DYNMEM_MemoryTable_DataType *temp = NULL,*found = NULL; if(f_address == NULL) return; for(temp=(*memoryListHead); temp!=NULL; temp = temp->nextElement) { if(temp->address == f_address) { found = temp; break; } } if(!found) { //my_printf("\n\nMemory address : %ld not found\n\n", f_address); //Debug TRAP //char *theData ="c"; //strcpy(theData, "ciaociaociao"); report_error_q("Unable to free memory not previously allocated",__FILE__,__LINE__, 1); // Report this as an error return; } DYNMEM_DecreaseMemoryCounter(found->size + sizeof(DYNMEM_MemoryTable_DataType)); //my_printf("\nFree of %ld", f_address); free(f_address); if(found->previousElement) found->previousElement->nextElement = found->nextElement; if(found->nextElement) found->nextElement->previousElement = found->previousElement; if(found == (*memoryListHead)) (*memoryListHead) = found->nextElement; free(found); } void DYNMEM_freeAll(DYNMEM_MemoryTable_DataType **memoryListHead) { DYNMEM_MemoryTable_DataType *temp = NULL; while((*memoryListHead) != NULL) { // my_printf("\nDYNMEM_freeAll called"); // my_printf("\nElement size: %ld", (*memoryListHead)->size); // my_printf("\nElement address: %ld", (long int) (*memoryListHead)->address); // my_printf("\nElement nextElement: %ld",(long int) (*memoryListHead)->nextElement); // my_printf("\nElement previousElement: %ld",(long int) (*memoryListHead)->previousElement); DYNMEM_DecreaseMemoryCounter((*memoryListHead)->size + sizeof(DYNMEM_MemoryTable_DataType)); //my_printf("\nFree table element"); free((*memoryListHead)->address); temp = (*memoryListHead)->nextElement; free((*memoryListHead)); (*memoryListHead) = temp; } }