1/* 2 * MessagePack for C memory pool implementation 3 * 4 * Copyright (C) 2008-2010 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#ifndef MSGPACK_ZONE_H 11#define MSGPACK_ZONE_H 12 13#include "sysdep.h" 14 15#ifdef __cplusplus 16extern "C" { 17#endif 18 19 20/** 21 * @defgroup msgpack_zone Memory zone 22 * @ingroup msgpack 23 * @{ 24 */ 25 26typedef struct msgpack_zone_finalizer { 27 void (*func)(void* data); 28 void* data; 29} msgpack_zone_finalizer; 30 31typedef struct msgpack_zone_finalizer_array { 32 msgpack_zone_finalizer* tail; 33 msgpack_zone_finalizer* end; 34 msgpack_zone_finalizer* array; 35} msgpack_zone_finalizer_array; 36 37struct msgpack_zone_chunk; 38typedef struct msgpack_zone_chunk msgpack_zone_chunk; 39 40typedef struct msgpack_zone_chunk_list { 41 size_t free; 42 char* ptr; 43 msgpack_zone_chunk* head; 44} msgpack_zone_chunk_list; 45 46typedef struct msgpack_zone { 47 msgpack_zone_chunk_list chunk_list; 48 msgpack_zone_finalizer_array finalizer_array; 49 size_t chunk_size; 50} msgpack_zone; 51 52#ifndef MSGPACK_ZONE_CHUNK_SIZE 53#define MSGPACK_ZONE_CHUNK_SIZE 8192 54#endif 55 56MSGPACK_DLLEXPORT 57bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size); 58MSGPACK_DLLEXPORT 59void msgpack_zone_destroy(msgpack_zone* zone); 60 61MSGPACK_DLLEXPORT 62msgpack_zone* msgpack_zone_new(size_t chunk_size); 63MSGPACK_DLLEXPORT 64void msgpack_zone_free(msgpack_zone* zone); 65 66static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size); 67static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size); 68 69static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone, 70 void (*func)(void* data), void* data); 71 72static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b); 73 74MSGPACK_DLLEXPORT 75bool msgpack_zone_is_empty(msgpack_zone* zone); 76 77MSGPACK_DLLEXPORT 78void msgpack_zone_clear(msgpack_zone* zone); 79 80/** @} */ 81 82 83#ifndef MSGPACK_ZONE_ALIGN 84#define MSGPACK_ZONE_ALIGN sizeof(void*) 85#endif 86 87MSGPACK_DLLEXPORT 88void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size); 89 90static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size) 91{ 92 char* ptr; 93 msgpack_zone_chunk_list* cl = &zone->chunk_list; 94 95 if(zone->chunk_list.free < size) { 96 return msgpack_zone_malloc_expand(zone, size); 97 } 98 99 ptr = cl->ptr; 100 cl->free -= size; 101 cl->ptr += size; 102 103 return ptr; 104} 105 106static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size) 107{ 108 char* aligned = 109 (char*)( 110 (size_t)( 111 zone->chunk_list.ptr + (MSGPACK_ZONE_ALIGN - 1) 112 ) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN 113 ); 114 size_t adjusted_size = size + (aligned - zone->chunk_list.ptr); 115 if(zone->chunk_list.free >= adjusted_size) { 116 zone->chunk_list.free -= adjusted_size; 117 zone->chunk_list.ptr += adjusted_size; 118 return aligned; 119 } 120 { 121 void* ptr = msgpack_zone_malloc_expand(zone, size + (MSGPACK_ZONE_ALIGN - 1)); 122 if (ptr) { 123 return (char*)((size_t)(ptr) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN); 124 } 125 } 126 return NULL; 127} 128 129 130bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone, 131 void (*func)(void* data), void* data); 132 133static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone, 134 void (*func)(void* data), void* data) 135{ 136 msgpack_zone_finalizer_array* const fa = &zone->finalizer_array; 137 msgpack_zone_finalizer* fin = fa->tail; 138 139 if(fin == fa->end) { 140 return msgpack_zone_push_finalizer_expand(zone, func, data); 141 } 142 143 fin->func = func; 144 fin->data = data; 145 146 ++fa->tail; 147 148 return true; 149} 150 151static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b) 152{ 153 msgpack_zone tmp = *a; 154 *a = *b; 155 *b = tmp; 156} 157 158 159#ifdef __cplusplus 160} 161#endif 162 163#endif /* msgpack/zone.h */ 164