Hideaki Tai / msgpack-embedded

Dependents:   hello_message_pack

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers zone.h Source File

zone.h

00001 /*
00002  * MessagePack for C memory pool implementation
00003  *
00004  * Copyright (C) 2008-2010 FURUHASHI Sadayuki
00005  *
00006  *    Distributed under the Boost Software License, Version 1.0.
00007  *    (See accompanying file LICENSE_1_0.txt or copy at
00008  *    http://www.boost.org/LICENSE_1_0.txt)
00009  */
00010 #ifndef MSGPACK_ZONE_H
00011 #define MSGPACK_ZONE_H
00012 
00013 #include "sysdep.h"
00014 
00015 #ifdef __cplusplus
00016 extern "C" {
00017 #endif
00018 
00019 
00020 /**
00021  * @defgroup msgpack_zone Memory zone
00022  * @ingroup msgpack
00023  * @{
00024  */
00025 
00026 typedef struct msgpack_zone_finalizer {
00027     void (*func)(void* data);
00028     void* data;
00029 } msgpack_zone_finalizer;
00030 
00031 typedef struct msgpack_zone_finalizer_array {
00032     msgpack_zone_finalizer* tail;
00033     msgpack_zone_finalizer* end;
00034     msgpack_zone_finalizer* array;
00035 } msgpack_zone_finalizer_array;
00036 
00037 struct msgpack_zone_chunk;
00038 typedef struct msgpack_zone_chunk msgpack_zone_chunk;
00039 
00040 typedef struct msgpack_zone_chunk_list {
00041     size_t free;
00042     char* ptr;
00043     msgpack_zone_chunk* head;
00044 } msgpack_zone_chunk_list;
00045 
00046 typedef struct msgpack_zone {
00047     msgpack_zone_chunk_list chunk_list;
00048     msgpack_zone_finalizer_array finalizer_array;
00049     size_t chunk_size;
00050 } msgpack_zone;
00051 
00052 #ifndef MSGPACK_ZONE_CHUNK_SIZE
00053     #if defined(__MBED__)
00054         #define MSGPACK_ZONE_CHUNK_SIZE 512
00055     #elif defined(__AVR__)
00056         #define MSGPACK_ZONE_CHUNK_SIZE 128
00057     #else
00058         #define MSGPACK_ZONE_CHUNK_SIZE 8192
00059     #endif
00060 #endif
00061 
00062 MSGPACK_DLLEXPORT
00063 bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size);
00064 MSGPACK_DLLEXPORT
00065 void msgpack_zone_destroy(msgpack_zone* zone);
00066 
00067 MSGPACK_DLLEXPORT
00068 msgpack_zone* msgpack_zone_new(size_t chunk_size);
00069 MSGPACK_DLLEXPORT
00070 void msgpack_zone_free(msgpack_zone* zone);
00071 
00072 static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size);
00073 static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size);
00074 
00075 static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
00076         void (*func)(void* data), void* data);
00077 
00078 static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b);
00079 
00080 MSGPACK_DLLEXPORT
00081 bool msgpack_zone_is_empty(msgpack_zone* zone);
00082 
00083 MSGPACK_DLLEXPORT
00084 void msgpack_zone_clear(msgpack_zone* zone);
00085 
00086 /** @} */
00087 
00088 
00089 #ifndef MSGPACK_ZONE_ALIGN
00090 #define MSGPACK_ZONE_ALIGN sizeof(void*)
00091 #endif
00092 
00093 MSGPACK_DLLEXPORT
00094 void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size);
00095 
00096 static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size)
00097 {
00098     char* ptr;
00099     msgpack_zone_chunk_list* cl = &zone->chunk_list;
00100 
00101     if(zone->chunk_list.free < size) {
00102         return msgpack_zone_malloc_expand(zone, size);
00103     }
00104 
00105     ptr = cl->ptr;
00106     cl->free -= size;
00107     cl->ptr  += size;
00108 
00109     return ptr;
00110 }
00111 
00112 static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
00113 {
00114     char* aligned =
00115         (char*)(
00116             (size_t)(
00117                 zone->chunk_list.ptr + (MSGPACK_ZONE_ALIGN - 1)
00118             ) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN
00119         );
00120     size_t adjusted_size = size + (aligned - zone->chunk_list.ptr);
00121     if(zone->chunk_list.free >= adjusted_size) {
00122         zone->chunk_list.free -= adjusted_size;
00123         zone->chunk_list.ptr  += adjusted_size;
00124         return aligned;
00125     }
00126     {
00127         void* ptr = msgpack_zone_malloc_expand(zone, size + (MSGPACK_ZONE_ALIGN - 1));
00128         if (ptr) {
00129             return (char*)((size_t)(ptr) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN);
00130         }
00131     }
00132     return NULL;
00133 }
00134 
00135 
00136 bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
00137         void (*func)(void* data), void* data);
00138 
00139 static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
00140         void (*func)(void* data), void* data)
00141 {
00142     msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
00143     msgpack_zone_finalizer* fin = fa->tail;
00144 
00145     if(fin == fa->end) {
00146         return msgpack_zone_push_finalizer_expand(zone, func, data);
00147     }
00148 
00149     fin->func = func;
00150     fin->data = data;
00151 
00152     ++fa->tail;
00153 
00154     return true;
00155 }
00156 
00157 static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b)
00158 {
00159     msgpack_zone tmp = *a;
00160     *a = *b;
00161     *b = tmp;
00162 }
00163 
00164 
00165 #ifdef __cplusplus
00166 }
00167 #endif
00168 
00169 #endif /* msgpack/zone.h */