Bug 1888590 - Mark some subtests on trusted-types-event-handlers.html as failing...
[gecko.git] / third_party / msgpack / src / zone.c
blob372a1f5b80b8edce47dec2e600bb24311e9164ec
1 /*
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)
9 */
10 #include "msgpack/zone.h"
11 #include <stdlib.h>
12 #include <string.h>
14 struct msgpack_zone_chunk {
15 struct msgpack_zone_chunk* next;
16 /* data ... */
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);
23 if(chunk == NULL) {
24 return false;
27 cl->head = chunk;
28 cl->free = chunk_size;
29 cl->ptr = ((char*)chunk) + sizeof(msgpack_zone_chunk);
30 chunk->next = NULL;
32 return true;
35 static inline void destroy_chunk_list(msgpack_zone_chunk_list* cl)
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;
49 static inline void clear_chunk_list(msgpack_zone_chunk_list* cl, size_t chunk_size)
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;
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;
74 while(sz < size) {
75 size_t tmp_sz = sz * 2;
76 if (tmp_sz <= sz) {
77 sz = size;
78 break;
80 sz = tmp_sz;
83 chunk = (msgpack_zone_chunk*)malloc(
84 sizeof(msgpack_zone_chunk) + sz);
85 if (chunk == NULL) {
86 return NULL;
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;
95 return ptr;
100 static inline void init_finalizer_array(msgpack_zone_finalizer_array* fa)
102 fa->tail = NULL;
103 fa->end = NULL;
104 fa->array = NULL;
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);
118 free(fa->array);
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);
135 size_t nnext;
136 if(nused == 0) {
137 nnext = (sizeof(msgpack_zone_finalizer) < 72/2) ?
138 72 / sizeof(msgpack_zone_finalizer) : 8;
140 } else {
141 nnext = nused * 2;
144 tmp = (msgpack_zone_finalizer*)realloc(fa->array,
145 sizeof(msgpack_zone_finalizer) * nnext);
146 if(tmp == NULL) {
147 return false;
150 fa->array = tmp;
151 fa->end = tmp + nnext;
152 fa->tail = tmp + nused;
154 fa->tail->func = func;
155 fa->tail->data = data;
157 ++fa->tail;
159 return true;
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)) {
189 return false;
192 init_finalizer_array(&zone->finalizer_array);
194 return true;
197 msgpack_zone* msgpack_zone_new(size_t chunk_size)
199 msgpack_zone* zone = (msgpack_zone*)malloc(
200 sizeof(msgpack_zone));
201 if(zone == NULL) {
202 return NULL;
205 zone->chunk_size = chunk_size;
207 if(!init_chunk_list(&zone->chunk_list, chunk_size)) {
208 free(zone);
209 return NULL;
212 init_finalizer_array(&zone->finalizer_array);
214 return zone;
217 void msgpack_zone_free(msgpack_zone* zone)
219 if(zone == NULL) { return; }
220 msgpack_zone_destroy(zone);
221 free(zone);