2 * MessagePack for C memory pool implementation
4 * Copyright (C) 2008-2009 FURUHASHI Sadayuki
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)
10 #include "msgpack/zone.h"
14 struct msgpack_zone_chunk
{
15 struct msgpack_zone_chunk
* next
;
19 static inline bool init_chunk_list(msgpack_zone_chunk_list
* cl
, size_t chunk_size
)
21 msgpack_zone_chunk
* chunk
= (msgpack_zone_chunk
*)malloc(
22 sizeof(msgpack_zone_chunk
) + chunk_size
);
28 cl
->free
= chunk_size
;
29 cl
->ptr
= ((char*)chunk
) + sizeof(msgpack_zone_chunk
);
35 static inline void destroy_chunk_list(msgpack_zone_chunk_list
* cl
)
37 msgpack_zone_chunk
* c
= cl
->head
;
39 msgpack_zone_chunk
* n
= c
->next
;
49 static inline void clear_chunk_list(msgpack_zone_chunk_list
* cl
, size_t chunk_size
)
51 msgpack_zone_chunk
* c
= cl
->head
;
53 msgpack_zone_chunk
* n
= c
->next
;
62 cl
->head
->next
= NULL
;
63 cl
->free
= chunk_size
;
64 cl
->ptr
= ((char*)cl
->head
) + sizeof(msgpack_zone_chunk
);
67 void* msgpack_zone_malloc_expand(msgpack_zone
* zone
, size_t size
)
69 msgpack_zone_chunk_list
* const cl
= &zone
->chunk_list
;
70 msgpack_zone_chunk
* chunk
;
72 size_t sz
= zone
->chunk_size
;
75 size_t tmp_sz
= sz
* 2;
83 chunk
= (msgpack_zone_chunk
*)malloc(
84 sizeof(msgpack_zone_chunk
) + sz
);
89 char* ptr
= ((char*)chunk
) + sizeof(msgpack_zone_chunk
);
90 chunk
->next
= cl
->head
;
100 static inline void init_finalizer_array(msgpack_zone_finalizer_array
* fa
)
107 static inline void call_finalizer_array(msgpack_zone_finalizer_array
* fa
)
109 msgpack_zone_finalizer
* fin
= fa
->tail
;
110 for(; fin
!= fa
->array
; --fin
) {
111 (*(fin
-1)->func
)((fin
-1)->data
);
115 static inline void destroy_finalizer_array(msgpack_zone_finalizer_array
* fa
)
117 call_finalizer_array(fa
);
121 static inline void clear_finalizer_array(msgpack_zone_finalizer_array
* fa
)
123 call_finalizer_array(fa
);
124 fa
->tail
= fa
->array
;
127 bool msgpack_zone_push_finalizer_expand(msgpack_zone
* zone
,
128 void (*func
)(void* data
), void* data
)
130 msgpack_zone_finalizer_array
* const fa
= &zone
->finalizer_array
;
131 msgpack_zone_finalizer
* tmp
;
133 const size_t nused
= (size_t)(fa
->end
- fa
->array
);
137 nnext
= (sizeof(msgpack_zone_finalizer
) < 72/2) ?
138 72 / sizeof(msgpack_zone_finalizer
) : 8;
144 tmp
= (msgpack_zone_finalizer
*)realloc(fa
->array
,
145 sizeof(msgpack_zone_finalizer
) * nnext
);
151 fa
->end
= tmp
+ nnext
;
152 fa
->tail
= tmp
+ nused
;
154 fa
->tail
->func
= func
;
155 fa
->tail
->data
= data
;
163 bool msgpack_zone_is_empty(msgpack_zone
* zone
)
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
;
172 void msgpack_zone_destroy(msgpack_zone
* zone
)
174 destroy_finalizer_array(&zone
->finalizer_array
);
175 destroy_chunk_list(&zone
->chunk_list
);
178 void msgpack_zone_clear(msgpack_zone
* zone
)
180 clear_finalizer_array(&zone
->finalizer_array
);
181 clear_chunk_list(&zone
->chunk_list
, zone
->chunk_size
);
184 bool msgpack_zone_init(msgpack_zone
* zone
, size_t chunk_size
)
186 zone
->chunk_size
= chunk_size
;
188 if(!init_chunk_list(&zone
->chunk_list
, chunk_size
)) {
192 init_finalizer_array(&zone
->finalizer_array
);
197 msgpack_zone
* msgpack_zone_new(size_t chunk_size
)
199 msgpack_zone
* zone
= (msgpack_zone
*)malloc(
200 sizeof(msgpack_zone
));
205 zone
->chunk_size
= chunk_size
;
207 if(!init_chunk_list(&zone
->chunk_list
, chunk_size
)) {
212 init_finalizer_array(&zone
->finalizer_array
);
217 void msgpack_zone_free(msgpack_zone
* zone
)
219 if(zone
== NULL
) { return; }
220 msgpack_zone_destroy(zone
);