annotate dbmalloc.c @ 1564:86e4995bbedf

more portable for `which hg` test
author Matt Johnston <matt@ucc.asn.au>
date Wed, 28 Feb 2018 23:42:57 +0800
parents 7209a6e30932
children c42e8ff42bd1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 #include "dbmalloc.h"
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 #include "dbutil.h"
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 struct dbmalloc_header {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 unsigned int epoch;
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
6 struct dbmalloc_header *prev;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
7 struct dbmalloc_header *next;
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 };
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
10 static void put_alloc(struct dbmalloc_header *header);
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
11 static void remove_alloc(struct dbmalloc_header *header);
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
12
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
13 /* end of the linked list */
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
14 static struct dbmalloc_header* staple;
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 unsigned int current_epoch = 0;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 void m_malloc_set_epoch(unsigned int epoch) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 current_epoch = epoch;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
22 void m_malloc_free_epoch(unsigned int epoch, int dofree) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
23 struct dbmalloc_header* header;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
24 struct dbmalloc_header* nextheader = NULL;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
25 struct dbmalloc_header* oldstaple = staple;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
26 staple = NULL;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
27 /* free allocations from this epoch, create a new staple-anchored list from
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
28 the remainder */
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
29 for (header = oldstaple; header; header = nextheader)
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
30 {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
31 nextheader = header->next;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
32 if (header->epoch == epoch) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
33 if (dofree) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
34 free(header);
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 }
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
36 } else {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
37 header->prev = NULL;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
38 header->next = NULL;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
39 put_alloc(header);
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44 static void put_alloc(struct dbmalloc_header *header) {
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
45 assert(header->next == NULL);
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
46 assert(header->prev == NULL);
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
47 if (staple) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
48 staple->prev = header;
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49 }
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
50 header->next = staple;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
51 staple = header;
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54 static void remove_alloc(struct dbmalloc_header *header) {
1378
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
55 if (header->prev) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
56 header->prev->next = header->next;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
57 }
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
58 if (header->next) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
59 header->next->prev = header->prev;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
60 }
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
61 if (staple == header) {
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
62 staple = header->next;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
63 }
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
64 header->prev = NULL;
7209a6e30932 linked list dbmalloc now
Matt Johnston <matt@ucc.asn.au>
parents: 1365
diff changeset
65 header->next = NULL;
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68 static struct dbmalloc_header* get_header(void* ptr) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
69 char* bptr = ptr;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
70 return (struct dbmalloc_header*)&bptr[-sizeof(struct dbmalloc_header)];
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
71 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
73 void * m_malloc(size_t size) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
74 char* mem = NULL;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
75 struct dbmalloc_header* header = NULL;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
76
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
77 if (size == 0 || size > 1e9) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 dropbear_exit("m_malloc failed");
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
79 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81 size = size + sizeof(struct dbmalloc_header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
82
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
83 mem = calloc(1, size);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
84 if (mem == NULL) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
85 dropbear_exit("m_malloc failed");
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
86 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
87 header = (struct dbmalloc_header*)mem;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
88 put_alloc(header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
89 header->epoch = current_epoch;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 return &mem[sizeof(struct dbmalloc_header)];
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 void * m_calloc(size_t nmemb, size_t size) {
1365
9aa6cd66b51d zlib can use m_malloc/m_free too
Matt Johnston <matt@ucc.asn.au>
parents: 1361
diff changeset
94 if (SIZE_T_MAX / nmemb < size) {
9aa6cd66b51d zlib can use m_malloc/m_free too
Matt Johnston <matt@ucc.asn.au>
parents: 1361
diff changeset
95 dropbear_exit("m_calloc failed");
9aa6cd66b51d zlib can use m_malloc/m_free too
Matt Johnston <matt@ucc.asn.au>
parents: 1361
diff changeset
96 }
1361
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
97 return m_malloc(nmemb*size);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100 void * m_realloc(void* ptr, size_t size) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101 char* mem = NULL;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102 struct dbmalloc_header* header = NULL;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
103 if (size == 0 || size > 1e9) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
104 dropbear_exit("m_realloc failed");
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
105 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
106
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
107 header = get_header(ptr);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108 remove_alloc(header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
109
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
110 size = size + sizeof(struct dbmalloc_header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111 mem = realloc(header, size);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
112 if (mem == NULL) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
113 dropbear_exit("m_realloc failed");
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
114 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
115
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116 header = (struct dbmalloc_header*)mem;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117 put_alloc(header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
118 return &mem[sizeof(struct dbmalloc_header)];
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
119 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121 void m_free_direct(void* ptr) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
122 struct dbmalloc_header* header = NULL;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
123 if (!ptr) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
124 return;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
125 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
126 header = get_header(ptr);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
127 remove_alloc(header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
128 free(header);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
129 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
130
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
131 void * m_strdup(const char * str) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132 char* ret;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
133 unsigned int len;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
134 len = strlen(str);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
136 ret = m_malloc(len+1);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
137 if (ret == NULL) {
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
138 dropbear_exit("m_strdup failed");
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
139 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140 memcpy(ret, str, len+1);
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
141 return ret;
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
142 }
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
143
f9f930e1a516 add dbmalloc epoch cleanup
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
144