lttng: move session_list to the lttng::cli namespace
[lttng-tools.git] / src / vendor / msgpack / zone.c
CommitLineData
116a02e3
JG
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
14struct msgpack_zone_chunk {
15 struct msgpack_zone_chunk* next;
16 /* data ... */
17};
18
19static 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
35static 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
49static 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
67void* 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
100static 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
107static 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
115static inline void destroy_finalizer_array(msgpack_zone_finalizer_array* fa)
116{
117 call_finalizer_array(fa);
118 free(fa->array);
119}
120
121static inline void clear_finalizer_array(msgpack_zone_finalizer_array* fa)
122{
123 call_finalizer_array(fa);
124 fa->tail = fa->array;
125}
126
127bool 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
163bool 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
172void msgpack_zone_destroy(msgpack_zone* zone)
173{
174 destroy_finalizer_array(&zone->finalizer_array);
175 destroy_chunk_list(&zone->chunk_list);
176}
177
178void 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
184bool 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
197msgpack_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
217void 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.060552 seconds and 4 git commands to generate.