-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathd_malloc.c
159 lines (138 loc) · 3.87 KB
/
d_malloc.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define NUM_D_CONTROLS 1024
// sizeof(Node)が88
#define D_MEMORY_AVERAGE_SIZE 100
#define D_MEMORY_SIZE NUM_D_CONTROLS *D_MEMORY_AVERAGE_SIZE
char temp[1024];
typedef struct _d_control
{
void *memory;
size_t size;
int8_t is_available; // 初期値0。freeしたら1。再割り当てしたら0。
} d_control_t;
// 割り当てたメモリ領域を管理する配列。
d_control_t d_controls[NUM_D_CONTROLS];
d_control_t *d_controls_head = d_controls;
// 割り当てるメモリ領域。
int8_t d_memory[D_MEMORY_SIZE];
int8_t *d_memory_head = d_memory;
// 配列で指定したアドレスをdmallocとdfreeしたときをデバッグする。
void *check_memories[] = {(void *)0x00000001403cb2e4};
size_t check_memories_size = sizeof(check_memories) / sizeof(void *);
// 配列で指定したアドレスをデバッグするかのフラグ。
int8_t enable_check_memories = 0;
void check_memory(void *memory, const char *from)
{
if (!enable_check_memories)
{
return;
}
for (size_t i = 0; i < check_memories_size; i++)
{
void *cm = check_memories[i];
if (memory == cm)
{
fprintf(stderr, "memory debug: %p at check_memory from %s\n", memory, from);
return;
}
}
}
d_control_t *find_available_control(size_t size)
{
// sizeに一致するis_availableなメモリ領域(d_control_t)を探す
d_control_t *ptr;
for (ptr = d_controls; ptr < d_controls_head; ptr++)
{
if (ptr->size == size && ptr->is_available)
{
return ptr;
}
}
return NULL;
}
_Noreturn void dmalloc_exit(const char *msg)
{
fprintf(stderr, "error: %s\n", msg);
exit(1);
}
void *dmalloc(size_t size)
{
d_control_t *cntrl = find_available_control(size);
if (cntrl)
{
cntrl->is_available = 0;
check_memory(cntrl->memory, "dmalloc");
return cntrl->memory;
}
int8_t *d_memory_return = d_memory_head;
d_memory_head += size;
if (d_memory_head > d_memory + D_MEMORY_SIZE)
{
dmalloc_exit("d_memory limit exceeded at dmalloc");
}
cntrl = d_controls_head;
cntrl->memory = (void *)d_memory_return;
cntrl->is_available = 0;
cntrl->size = size;
d_controls_head++;
if (d_controls_head > d_controls + NUM_D_CONTROLS)
{
dmalloc_exit("d_controls limit exceeded at dmalloc");
}
check_memory(d_memory_return, "dmalloc");
return (void *)d_memory_return;
}
void dfree(void *_memory)
{
check_memory(_memory, "dfree");
d_control_t *ptr;
for (ptr = d_controls; ptr < d_controls_head; ptr++)
{
if (ptr->memory == _memory)
{
if (ptr->is_available)
{
sprintf(temp, "memory %p is available at dfree\n", _memory);
dmalloc_exit(temp);
}
ptr->is_available = 1;
return;
}
}
sprintf(temp, "memory %p is not dmalloc-ed at dfree\n", _memory);
dmalloc_exit(temp);
}
void print_d_malloc_stat()
{
size_t num_mallocs = 0;
size_t num_available_mallocs = 0;
d_control_t *ptr;
for (ptr = d_controls; ptr < d_controls_head; ptr++)
{
if (ptr->is_available)
{
num_available_mallocs++;
}
else
{
num_mallocs++;
}
}
printf("controls stat: (%zu + available %zu) / total %zu\n", num_mallocs, num_available_mallocs, num_mallocs + num_available_mallocs);
printf("memory size: %zu / %u\n", d_memory_head - d_memory, D_MEMORY_SIZE);
}
void print_d_malloc_controls()
{
uint32_t cnt = 0;
d_control_t *ptr;
for (ptr = d_controls; ptr < d_controls_head; ptr++)
{
cnt++;
if (!ptr->is_available)
{
printf("(%04d) %p, %3zu, %d\n", cnt, ptr->memory, ptr->size, ptr->is_available);
}
}
}