sessiond: Add msgpack-c 3.3.0 to the tree
[lttng-tools.git] / src / vendor / msgpack / zone.c
1 /*
2 * MessagePack for C memory pool implementation
3 *
4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
5 *
6 * Distributed under the Boost Software License, Version 1.0.
7 * (See accompanying file LICENSE_1_0.txt or copy at
8 * http://www.boost.org/LICENSE_1_0.txt)
9 */
10 #include "vendor/msgpack/zone.h"
11 #include <stdlib.h>
12 #include <string.h>
13
14 struct msgpack_zone_chunk {
15 struct msgpack_zone_chunk* next;
16 /* data ... */
17 };
18
19 static inline bool init_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
20 {
21 msgpack_zone_chunk* chunk = (msgpack_zone_chunk*)malloc(
22 sizeof(msgpack_zone_chunk) + chunk_size);
23 if(chunk == NULL) {
24 return false;
25 }
26
27 cl->head = chunk;
28 cl->free = chunk_size;
29 cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
30 chunk->next = NULL;
31
32 return true;
33 }
34
35 static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
36 {
37 msgpack_zone_chunk* c = cl->head;
38 while(true) {
39 msgpack_zone_chunk* n = c->next;
40 free(c);
41 if(n != NULL) {
42 c = n;
43 } else {
44 break;
45 }
46 }
47 }
48
49 static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
50 {
51 msgpack_zone_chunk* c = cl->head;
52 while(true) {
53 msgpack_zone_chunk* n = c->next;
54 if(n != NULL) {
55 free(c);
56 c = n;
57 } else {
58 cl->head = c;
59 break;
60 }
61 }
62 cl->head->next = NULL;
63 cl->free = chunk_size;
64 cl->ptr = ((char*)cl->head) + sizeof(msgpack_zone_chunk);
65 }
66
67 void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size)
68 {
69 msgpack_zone_chunk_list* const cl = &zone->chunk_list;
70 msgpack_zone_chunk* chunk;
71
72 size_t sz = zone->chunk_size;
73
74 while(sz < size) {
75 size_t tmp_sz = sz * 2;
76 if (tmp_sz <= sz) {
77 sz = size;
78 break;
79 }
80 sz = tmp_sz;
81 }
82
83 chunk = (msgpack_zone_chunk*)malloc(
84 sizeof(msgpack_zone_chunk) + sz);
85 if (chunk == NULL) {
86 return NULL;
87 }
88 else {
89 char* ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
90 chunk->next = cl->head;
91 cl->head = chunk;
92 cl->free = sz - size;
93 cl->ptr = ptr + size;
94
95 return ptr;
96 }
97 }
98
99
100 static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
101 {
102 fa->tail = NULL;
103 fa->end = NULL;
104 fa->array = NULL;
105 }
106
107 static inline void call_finalizer_array(msgpack_zone_finalizer_array* fa)
108 {
109 msgpack_zone_finalizer* fin = fa->tail;
110 for(; fin != fa->array; --fin) {
111 (*(fin-1)->func)((fin-1)->data);
112 }
113 }
114
115 static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
116 {
117 call_finalizer_array(fa);
118 free(fa->array);
119 }
120
121 static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
122 {
123 call_finalizer_array(fa);
124 fa->tail = fa->array;
125 }
126
127 bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
128 void (*func)(void* data), void* data)
129 {
130 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
131 msgpack_zone_finalizer* tmp;
132
133 const size_t nused = (size_t)(fa->end - fa->array);
134
135 size_t nnext;
136 if(nused == 0) {
137 nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
138 72 / sizeof(msgpack_zone_finalizer) : 8;
139
140 } else {
141 nnext = nused * 2;
142 }
143
144 tmp = (msgpack_zone_finalizer*)realloc(fa->array,
145 sizeof(msgpack_zone_finalizer) * nnext);
146 if(tmp == NULL) {
147 return false;
148 }
149
150 fa->array = tmp;
151 fa->end = tmp + nnext;
152 fa->tail = tmp + nused;
153
154 fa->tail->func = func;
155 fa->tail->data = data;
156
157 ++fa->tail;
158
159 return true;
160 }
161
162
163 bool msgpack_zone_is_empty(msgpack_zone* zone)
164 {
165 msgpack_zone_chunk_list* const cl = &zone->chunk_list;
166 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
167 return cl->free == zone->chunk_size && cl->head->next == NULL &&
168 fa->tail == fa->array;
169 }
170
171
172 void msgpack_zone_destroy(msgpack_zone* zone)
173 {
174 destroy_finalizer_array(&zone->finalizer_array);
175 destroy_chunk_list(&zone->chunk_list);
176 }
177
178 void msgpack_zone_clear(msgpack_zone* zone)
179 {
180 clear_finalizer_array(&zone->finalizer_array);
181 clear_chunk_list(&zone->chunk_list, zone->chunk_size);
182 }
183
184 bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size)
185 {
186 zone->chunk_size = chunk_size;
187
188 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
189 return false;
190 }
191
192 init_finalizer_array(&zone->finalizer_array);
193
194 return true;
195 }
196
197 msgpack_zone* msgpack_zone_new(size_t chunk_size)
198 {
199 msgpack_zone* zone = (msgpack_zone*)malloc(
200 sizeof(msgpack_zone));
201 if(zone == NULL) {
202 return NULL;
203 }
204
205 zone->chunk_size = chunk_size;
206
207 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
208 free(zone);
209 return NULL;
210 }
211
212 init_finalizer_array(&zone->finalizer_array);
213
214 return zone;
215 }
216
217 void msgpack_zone_free(msgpack_zone* zone)
218 {
219 if(zone == NULL) { return; }
220 msgpack_zone_destroy(zone);
221 free(zone);
222 }
This page took 0.048664 seconds and 4 git commands to generate.