1361
|
1 #include "dbmalloc.h" |
|
2 #include "dbutil.h" |
|
3 |
|
4 #define LIST_SIZE 1000 |
|
5 |
|
6 struct dbmalloc_header { |
|
7 unsigned int index; |
|
8 unsigned int epoch; |
|
9 }; |
|
10 |
|
11 static struct dbmalloc_header* dbmalloc_list[LIST_SIZE]; |
|
12 |
|
13 unsigned int current_epoch = 0; |
|
14 |
|
15 void m_malloc_set_epoch(unsigned int epoch) { |
|
16 current_epoch = epoch; |
|
17 } |
|
18 |
|
19 void m_malloc_free_epoch(unsigned int epoch) { |
|
20 unsigned int i; |
|
21 unsigned int freed = 0; |
|
22 for (i = 0; i < LIST_SIZE; i++) { |
|
23 if (dbmalloc_list[i] != NULL) { |
|
24 assert(dbmalloc_list[i]->index == i); |
|
25 if (dbmalloc_list[i]->epoch == epoch) { |
|
26 free(dbmalloc_list[i]); |
|
27 dbmalloc_list[i] = NULL; |
|
28 freed++; |
|
29 } |
|
30 } |
|
31 } |
|
32 TRACE(("free_epoch freed %d", freed)) |
|
33 } |
|
34 |
|
35 static void put_alloc(struct dbmalloc_header *header) { |
|
36 unsigned int i; |
|
37 for (i = 0; i < LIST_SIZE; i++) { |
|
38 if (dbmalloc_list[i] == NULL) { |
|
39 dbmalloc_list[i] = header; |
|
40 header->index = i; |
|
41 return; |
|
42 } |
|
43 } |
|
44 dropbear_exit("ran out of dbmalloc entries"); |
|
45 } |
|
46 |
|
47 static void remove_alloc(struct dbmalloc_header *header) { |
|
48 assert(header->index < LIST_SIZE); |
|
49 assert(dbmalloc_list[header->index] == header); |
|
50 assert(header->epoch == current_epoch); |
|
51 dbmalloc_list[header->index] = NULL; |
|
52 } |
|
53 |
|
54 static struct dbmalloc_header* get_header(void* ptr) { |
|
55 char* bptr = ptr; |
|
56 return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)]; |
|
57 } |
|
58 |
|
59 void * m_malloc(size_t size) { |
|
60 char* mem = NULL; |
|
61 struct dbmalloc_header* header = NULL; |
|
62 |
|
63 if (size == 0 || size > 1e9) { |
|
64 dropbear_exit("m_malloc failed"); |
|
65 } |
|
66 |
|
67 size = size + sizeof(struct dbmalloc_header); |
|
68 |
|
69 mem = calloc(1, size); |
|
70 if (mem == NULL) { |
|
71 dropbear_exit("m_malloc failed"); |
|
72 } |
|
73 header = (struct dbmalloc_header*)mem; |
|
74 put_alloc(header); |
|
75 header->epoch = current_epoch; |
|
76 return &mem[sizeof(struct dbmalloc_header)]; |
|
77 } |
|
78 |
|
79 void * m_calloc(size_t nmemb, size_t size) { |
|
80 assert(nmemb <= 1000 && size <= 10000); |
|
81 return m_malloc(nmemb*size); |
|
82 } |
|
83 |
|
84 void * m_realloc(void* ptr, size_t size) { |
|
85 char* mem = NULL; |
|
86 struct dbmalloc_header* header = NULL; |
|
87 if (size == 0 || size > 1e9) { |
|
88 dropbear_exit("m_realloc failed"); |
|
89 } |
|
90 |
|
91 header = get_header(ptr); |
|
92 remove_alloc(header); |
|
93 |
|
94 size = size + sizeof(struct dbmalloc_header); |
|
95 mem = realloc(header, size); |
|
96 if (mem == NULL) { |
|
97 dropbear_exit("m_realloc failed"); |
|
98 } |
|
99 |
|
100 header = (struct dbmalloc_header*)mem; |
|
101 put_alloc(header); |
|
102 return &mem[sizeof(struct dbmalloc_header)]; |
|
103 } |
|
104 |
|
105 void m_free_direct(void* ptr) { |
|
106 struct dbmalloc_header* header = NULL; |
|
107 if (!ptr) { |
|
108 return; |
|
109 } |
|
110 header = get_header(ptr); |
|
111 remove_alloc(header); |
|
112 free(header); |
|
113 } |
|
114 |
|
115 void * m_strdup(const char * str) { |
|
116 char* ret; |
|
117 unsigned int len; |
|
118 len = strlen(str); |
|
119 |
|
120 ret = m_malloc(len+1); |
|
121 if (ret == NULL) { |
|
122 dropbear_exit("m_strdup failed"); |
|
123 } |
|
124 memcpy(ret, str, len+1); |
|
125 return ret; |
|
126 } |
|
127 |
|
128 |