-
Notifications
You must be signed in to change notification settings - Fork 85
/
alloc.c
127 lines (113 loc) · 3.14 KB
/
alloc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "common/alloc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/log.h"
#include "common/map.h"
#include "common/thread.h"
typedef struct _golf_alloc_info {
const char *category;
size_t size;
struct _golf_alloc_info *prev, *next;
} _golf_alloc_info_t;
static golf_mutex_t _alloc_lock;
static _golf_alloc_info_t *head;
void golf_alloc_init(void) {
golf_mutex_init(&_alloc_lock);
head = malloc(sizeof(_golf_alloc_info_t));
head->category = NULL;
head->size = 0;
head->prev = head;
head->next = head;
}
void *golf_alloc_tracked(size_t size, const char *category) {
golf_mutex_lock(&_alloc_lock);
_golf_alloc_info_t *mem = malloc(sizeof(_golf_alloc_info_t) + size);
mem->category = category;
mem->size = size;
mem->prev = head;
mem->next = head->next;
mem->next->prev = mem;
head->next = mem;
golf_mutex_unlock(&_alloc_lock);
return mem + 1;
}
void *golf_realloc_tracked(void *mem, size_t size, const char *category) {
if (mem == NULL) {
return golf_alloc_tracked(size, category);
}
else if (size == 0) {
golf_free_tracked(mem);
return NULL;
}
else {
_golf_alloc_info_t *info = (_golf_alloc_info_t*)mem - 1;
if (size <= info->size) {
return mem;
}
else {
void *mem2 = golf_alloc_tracked(size, category);
if (mem2) {
memcpy(mem2, mem, info->size);
golf_free_tracked(mem);
}
return mem2;
}
}
}
void golf_free_tracked(void *mem) {
if (!mem) {
return;
}
golf_mutex_lock(&_alloc_lock);
_golf_alloc_info_t *info = (_golf_alloc_info_t*)mem - 1;
info->prev->next = info->next;
info->next->prev = info->prev;
free(info);
golf_mutex_unlock(&_alloc_lock);
}
void golf_alloc_get_debug_info(size_t *total_size) {
golf_mutex_lock(&_alloc_lock);
*total_size = 0;
_golf_alloc_info_t *info = head;
while (info->next != head) {
info = info->next;
*total_size += info->size;
}
golf_mutex_unlock(&_alloc_lock);
}
void golf_debug_print_allocations(void) {
golf_log_note("=====Memory Allocations=====");
_golf_alloc_info_t *info = head;
map_int_t category_size;
map_init(&category_size, "alloc");
while (info->next != head) {
info = info->next;
int *size;
if (info->category) {
size = map_get(&category_size, info->category);
}
else {
size = map_get(&category_size, "null");
}
if (size) {
*size += (int)info->size;
}
else {
if (info->category) {
map_set(&category_size, info->category, (int)info->size);
}
else {
map_set(&category_size, "null", (int)info->size);
}
}
}
{
const char *key;
map_iter_t iter = map_iter(&category_size);
while ((key = map_next(&category_size, &iter))) {
printf("%s -> %d\n", key, *map_get(&category_size, key));
}
}
map_deinit(&category_size);
}