File Coverage

deps/msgpack-c/src/zone.c
Criterion Covered Total %
statement 58 116 50.0
branch 10 32 31.2
condition n/a
subroutine n/a
pod n/a
total 68 148 45.9


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