forked from Telodendria/Cytoplasm
Compare commits
5 Commits
mem-moment
...
master
Author | SHA1 | Date |
---|---|---|
|
39c25e5a17 | |
|
4903c075e8 | |
![]() |
da857a3d53 | |
|
138ea1c8e9 | |
|
cdf4430a9e |
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
217
src/Memory.c
217
src/Memory.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue