zone.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. #include "sysdep.h"
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. /**
  17. * @defgroup msgpack_zone Memory zone
  18. * @ingroup msgpack
  19. * @{
  20. */
  21. typedef struct msgpack_zone_finalizer {
  22. void (*func)(void* data);
  23. void* data;
  24. } msgpack_zone_finalizer;
  25. typedef struct msgpack_zone_finalizer_array {
  26. msgpack_zone_finalizer* tail;
  27. msgpack_zone_finalizer* end;
  28. msgpack_zone_finalizer* array;
  29. } msgpack_zone_finalizer_array;
  30. struct msgpack_zone_chunk;
  31. typedef struct msgpack_zone_chunk msgpack_zone_chunk;
  32. typedef struct msgpack_zone_chunk_list {
  33. size_t free;
  34. char* ptr;
  35. msgpack_zone_chunk* head;
  36. } msgpack_zone_chunk_list;
  37. typedef struct msgpack_zone {
  38. msgpack_zone_chunk_list chunk_list;
  39. msgpack_zone_finalizer_array finalizer_array;
  40. size_t chunk_size;
  41. } msgpack_zone;
  42. #ifndef MSGPACK_ZONE_CHUNK_SIZE
  43. #define MSGPACK_ZONE_CHUNK_SIZE 8192
  44. #endif
  45. MSGPACK_DLLEXPORT
  46. bool msgpack_zone_init(msgpack_zone* zone, size_t chunk_size);
  47. MSGPACK_DLLEXPORT
  48. void msgpack_zone_destroy(msgpack_zone* zone);
  49. MSGPACK_DLLEXPORT
  50. msgpack_zone* msgpack_zone_new(size_t chunk_size);
  51. MSGPACK_DLLEXPORT
  52. void msgpack_zone_free(msgpack_zone* zone);
  53. static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size);
  54. static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size);
  55. static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
  56. void (*func)(void* data), void* data);
  57. static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b);
  58. MSGPACK_DLLEXPORT
  59. bool msgpack_zone_is_empty(msgpack_zone* zone);
  60. MSGPACK_DLLEXPORT
  61. void msgpack_zone_clear(msgpack_zone* zone);
  62. /** @} */
  63. #ifndef MSGPACK_ZONE_ALIGN
  64. #define MSGPACK_ZONE_ALIGN sizeof(void*)
  65. #endif
  66. MSGPACK_DLLEXPORT
  67. void* msgpack_zone_malloc_expand(msgpack_zone* zone, size_t size);
  68. static inline void* msgpack_zone_malloc_no_align(msgpack_zone* zone, size_t size)
  69. {
  70. char* ptr;
  71. msgpack_zone_chunk_list* cl = &zone->chunk_list;
  72. if(zone->chunk_list.free < size) {
  73. return msgpack_zone_malloc_expand(zone, size);
  74. }
  75. ptr = cl->ptr;
  76. cl->free -= size;
  77. cl->ptr += size;
  78. return ptr;
  79. }
  80. static inline void* msgpack_zone_malloc(msgpack_zone* zone, size_t size)
  81. {
  82. char* aligned =
  83. (char*)(
  84. (size_t)(
  85. zone->chunk_list.ptr + (MSGPACK_ZONE_ALIGN - 1)
  86. ) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN
  87. );
  88. size_t adjusted_size = size + (aligned - zone->chunk_list.ptr);
  89. if(zone->chunk_list.free >= adjusted_size) {
  90. zone->chunk_list.free -= adjusted_size;
  91. zone->chunk_list.ptr += adjusted_size;
  92. return aligned;
  93. }
  94. {
  95. void* ptr = msgpack_zone_malloc_expand(zone, size + (MSGPACK_ZONE_ALIGN - 1));
  96. if (ptr) {
  97. return (char*)((size_t)(ptr) / MSGPACK_ZONE_ALIGN * MSGPACK_ZONE_ALIGN);
  98. }
  99. }
  100. return NULL;
  101. }
  102. bool msgpack_zone_push_finalizer_expand(msgpack_zone* zone,
  103. void (*func)(void* data), void* data);
  104. static inline bool msgpack_zone_push_finalizer(msgpack_zone* zone,
  105. void (*func)(void* data), void* data)
  106. {
  107. msgpack_zone_finalizer_array* const fa = &zone->finalizer_array;
  108. msgpack_zone_finalizer* fin = fa->tail;
  109. if(fin == fa->end) {
  110. return msgpack_zone_push_finalizer_expand(zone, func, data);
  111. }
  112. fin->func = func;
  113. fin->data = data;
  114. ++fa->tail;
  115. return true;
  116. }
  117. static inline void msgpack_zone_swap(msgpack_zone* a, msgpack_zone* b)
  118. {
  119. msgpack_zone tmp = *a;
  120. *a = *b;
  121. *b = tmp;
  122. }
  123. #ifdef __cplusplus
  124. }
  125. #endif
  126. #endif /* msgpack/zone.h */