Compare commits

..

5 Commits

Author SHA1 Message Date
Jordan Bancino 39c25e5a17 Merge pull request 'Copy filename into preallocated field with Cytoplasm's Memory API' (#33) from lda/Cytoplasm:direct-filenames into master
Compile Cytoplasm / Compile Cytoplasm (x86, alpine-v3.19) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86, debian-v12.4) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86, freebsd-v14.0) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86, netbsd-v9.3) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, alpine-v3.19) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, debian-v12.4) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, freebsd-v14.0) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, netbsd-v9.3) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, openbsd-v7.4) (push) Has been cancelled Details
Reviewed-on: Telodendria/Cytoplasm#33
2024-08-18 19:26:18 -04:00
Jordan Bancino 4903c075e8 Merge pull request 'Pre-emptively free out the key' (#41) from lda/Cytoplasm:hashmap-del-leak into master
Compile Cytoplasm / Compile Cytoplasm (x86, alpine-v3.19) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86, debian-v12.4) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86, freebsd-v14.0) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86, netbsd-v9.3) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, alpine-v3.19) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, debian-v12.4) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, freebsd-v14.0) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, netbsd-v9.3) (push) Has been cancelled Details
Compile Cytoplasm / Compile Cytoplasm (x86_64, openbsd-v7.4) (push) Has been cancelled Details
Reviewed-on: Telodendria/Cytoplasm#41
2024-08-09 09:26:49 -04:00
LDA da857a3d53 [FIX] Pre-emptively free out the key
I fail to see a reason why this shouldn't be done, to be fair, and it
fixes a memory leakage with a Cytoplasm-based project I'm making.
2024-07-19 16:08:25 +02:00
lda 138ea1c8e9 [FIX] Oops. 2024-05-26 22:06:56 +02:00
lda cdf4430a9e [FIX] Fix issue with const strings which may be invalidated 2024-05-26 22:01:06 +02:00
2 changed files with 147 additions and 72 deletions

View File

@ -184,6 +184,8 @@ HashMapDelete(HashMap * map, const char *key)
if (bucket->hash == hash)
{
bucket->hash = 0;
Free(bucket->key);
bucket->key = NULL;
return bucket->value;
}

View File

@ -40,22 +40,18 @@
#define MEMORY_HEXDUMP_WIDTH 16
#endif
#define MEMORY_FILE_SIZE 256
struct MemoryInfo
{
uint64_t magic;
size_t size;
const char *file;
char file[MEMORY_FILE_SIZE];
int line;
void *pointer;
MemoryInfo *prev;
MemoryInfo *next;
};
#define MEM_BOUND_TYPE uint32_t
#define MEM_BOUND 0xDEADBEEF
#define MEM_MAGIC 0xDEADBEEFDEADBEEF
#define MEM_BOUND_LOWER(p) *((MEM_BOUND_TYPE *) p)
#define MEM_BOUND_UPPER(p, x) *(((MEM_BOUND_TYPE *) (((uint8_t *) p) + x)) + 1)
@ -65,10 +61,10 @@ static pthread_mutex_t lock;
static void (*hook) (MemoryAction, MemoryInfo *, void *) = MemoryDefaultHook;
static void *hookArgs = NULL;
static MemoryInfo **allocations = NULL;
static size_t allocationsSize = 0;
static size_t allocationsLen = 0;
static MemoryInfo *allocationTail = NULL;
int
MemoryRuntimeInit(void)
{
@ -97,18 +93,70 @@ MemoryRuntimeDestroy(void)
return pthread_mutex_destroy(&lock) == 0;
}
static size_t
MemoryHash(void *p)
{
return (((size_t) p) >> 2 * 7) % allocationsSize;
}
static int
MemoryInsert(MemoryInfo * a)
{
if (allocationTail)
{
allocationTail->next = a;
}
a->next = NULL;
a->prev = allocationTail;
a->magic = MEM_MAGIC;
size_t hash;
allocationTail = a;
if (!allocations)
{
allocationsSize = MEMORY_TABLE_CHUNK;
allocations = calloc(allocationsSize, sizeof(void *));
if (!allocations)
{
return 0;
}
}
/* If the next insertion would cause the table to be at least 3/4
* full, re-allocate and re-hash. */
if ((allocationsLen + 1) >= ((allocationsSize * 3) >> 2))
{
size_t i;
size_t tmpAllocationsSize = allocationsSize;
MemoryInfo **tmpAllocations;
allocationsSize += MEMORY_TABLE_CHUNK;
tmpAllocations = calloc(allocationsSize, sizeof(void *));
if (!tmpAllocations)
{
return 0;
}
for (i = 0; i < tmpAllocationsSize; i++)
{
if (allocations[i])
{
hash = MemoryHash(allocations[i]->pointer);
while (tmpAllocations[hash])
{
hash = (hash + 1) % allocationsSize;
}
tmpAllocations[hash] = allocations[i];
}
}
free(allocations);
allocations = tmpAllocations;
}
hash = MemoryHash(a->pointer);
while (allocations[hash])
{
hash = (hash + 1) % allocationsSize;
}
allocations[hash] = a;
allocationsLen++;
return 1;
@ -117,24 +165,23 @@ MemoryInsert(MemoryInfo * a)
static void
MemoryDelete(MemoryInfo * a)
{
MemoryInfo *aPrev = a->prev;
MemoryInfo *aNext = a->next;
size_t hash = MemoryHash(a->pointer);
size_t count = 0;
if (aPrev)
while (count <= allocationsSize)
{
aPrev->next = aNext;
if (allocations[hash] && allocations[hash] == a)
{
allocations[hash] = NULL;
allocationsLen--;
return;
}
else
{
hash = (hash + 1) % allocationsSize;
count++;
}
}
if (aNext)
{
aNext->prev = aPrev;
}
if (a == allocationTail)
{
allocationTail = aPrev;
}
a->magic = ~MEM_MAGIC;
}
static int
@ -158,31 +205,38 @@ MemoryAllocate(size_t size, const char *file, int line)
void *p;
MemoryInfo *a;
//MemoryIterate(NULL, NULL);
MemoryIterate(NULL, NULL);
pthread_mutex_lock(&lock);
a = malloc(sizeof(MemoryInfo) + MEM_SIZE_ACTUAL(size));
a = malloc(sizeof(MemoryInfo));
if (!a)
{
pthread_mutex_unlock(&lock);
return NULL;
}
p = a + 1;
p = malloc(MEM_SIZE_ACTUAL(size));
if (!p)
{
free(a);
pthread_mutex_unlock(&lock);
return NULL;
}
memset(p, 0, MEM_SIZE_ACTUAL(size));
MEM_BOUND_LOWER(p) = MEM_BOUND;
MEM_BOUND_UPPER(p, size) = MEM_BOUND;
a->size = MEM_SIZE_ACTUAL(size);
a->file = file;
strncpy(a->file, file, MEMORY_FILE_SIZE - 1);
a->line = line;
a->pointer = p;
if (!MemoryInsert(a))
{
free(a);
free(p);
pthread_mutex_unlock(&lock);
return NULL;
}
@ -202,7 +256,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
MemoryInfo *a;
void *new = NULL;
//MemoryIterate(NULL, NULL);
MemoryIterate(NULL, NULL);
if (!p)
{
@ -213,17 +267,15 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
if (a)
{
pthread_mutex_lock(&lock);
MemoryDelete(a);
new = realloc(a, sizeof(MemoryInfo) + MEM_SIZE_ACTUAL(size));
new = realloc(a->pointer, MEM_SIZE_ACTUAL(size));
if (new)
{
a = new;
MemoryDelete(a);
a->size = MEM_SIZE_ACTUAL(size);
a->file = file;
strncpy(a->file, file, MEMORY_FILE_SIZE - 1);
a->line = line;
a->magic = MEM_MAGIC;
a->pointer = a + 1;
a->pointer = new;
MemoryInsert(a);
MEM_BOUND_LOWER(a->pointer) = MEM_BOUND;
@ -233,7 +285,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
{
hook(MEMORY_REALLOCATE, a, hookArgs);
}
}
pthread_mutex_unlock(&lock);
}
@ -243,7 +295,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
if (a)
{
a->size = 0;
a->file = file;
strncpy(a->file, file, MEMORY_FILE_SIZE - 1);
a->line = line;
a->pointer = p;
hook(MEMORY_BAD_POINTER, a, hookArgs);
@ -251,7 +303,7 @@ MemoryReallocate(void *p, size_t size, const char *file, int line)
}
}
return ((MEM_BOUND_TYPE *) a->pointer) + 1;
return ((MEM_BOUND_TYPE *) new) + 1;
}
void
@ -259,7 +311,7 @@ MemoryFree(void *p, const char *file, int line)
{
MemoryInfo *a;
//MemoryIterate(NULL, NULL);
MemoryIterate(NULL, NULL);
if (!p)
{
@ -272,11 +324,12 @@ MemoryFree(void *p, const char *file, int line)
pthread_mutex_lock(&lock);
if (hook)
{
a->file = file;
strncpy(a->file, file, MEMORY_FILE_SIZE - 1);
a->line = line;
hook(MEMORY_FREE, a, hookArgs);
}
MemoryDelete(a);
free(a->pointer);
free(a);
pthread_mutex_unlock(&lock);
@ -286,7 +339,7 @@ MemoryFree(void *p, const char *file, int line)
a = malloc(sizeof(MemoryInfo));
if (a)
{
a->file = file;
strncpy(a->file, file, MEMORY_FILE_SIZE - 1);
a->line = line;
a->size = 0;
a->pointer = p;
@ -299,15 +352,17 @@ MemoryFree(void *p, const char *file, int line)
size_t
MemoryAllocated(void)
{
size_t i;
size_t total = 0;
MemoryInfo *cur;
pthread_mutex_lock(&lock);
/* TODO */
for (cur = allocationTail; cur; cur = cur->prev)
for (i = 0; i < allocationsSize; i++)
{
total += MemoryInfoGetSize(cur);
if (allocations[i])
{
total += MemoryInfoGetSize(allocations[i]);
}
}
pthread_mutex_unlock(&lock);
@ -318,40 +373,55 @@ MemoryAllocated(void)
void
MemoryFreeAll(void)
{
MemoryInfo *cur;
MemoryInfo *prev;
size_t i;
pthread_mutex_lock(&lock);
/* TODO */
for (cur = allocationTail; cur; cur = prev)
for (i = 0; i < allocationsSize; i++)
{
prev = cur->prev;
free(cur);
if (allocations[i])
{
free(allocations[i]->pointer);
free(allocations[i]);
}
}
free(allocations);
allocations = NULL;
allocationsSize = 0;
allocationsLen = 0;
pthread_mutex_unlock(&lock);
}
MemoryInfo *
MemoryInfoGet(void *po)
MemoryInfoGet(void *p)
{
void *p = po;
size_t hash, count;
pthread_mutex_lock(&lock);
p = ((MEM_BOUND_TYPE *) po) - 1;
p = ((MemoryInfo *) p) - 1;
p = ((MEM_BOUND_TYPE *) p) - 1;
hash = MemoryHash(p);
if (((MemoryInfo *)p)->magic != MEM_MAGIC)
count = 0;
while (count <= allocationsSize)
{
p = NULL;
if (!allocations[hash] || allocations[hash]->pointer != p)
{
hash = (hash + 1) % allocationsSize;
count++;
}
else
{
MemoryCheck(allocations[hash]);
pthread_mutex_unlock(&lock);
return allocations[hash];
}
}
pthread_mutex_unlock(&lock);
return p;
return NULL;
}
size_t
@ -399,18 +469,21 @@ MemoryInfoGetPointer(MemoryInfo * a)
}
void
MemoryIterate(void (*iterFunc) (MemoryInfo *, void *), void *args)
MemoryIterate(void (*iterFunc) (MemoryInfo *, void *), void *args)
{
MemoryInfo *cur;
size_t i;
pthread_mutex_lock(&lock);
for (cur = allocationTail; cur; cur = cur->prev)
for (i = 0; i < allocationsSize; i++)
{
MemoryCheck(cur);
if (iterFunc)
if (allocations[i])
{
iterFunc(cur, args);
MemoryCheck(allocations[i]);
if (iterFunc)
{
iterFunc(allocations[i], args);
}
}
}