Advertisement
Guest User

Chris M Thomasson

a guest
Mar 11th, 2009
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.63 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stddef.h>
  3. #include <assert.h>
  4.  
  5.  
  6.  
  7.  
  8. #if defined (_MSC_VER)
  9. /* warning C4116: unnamed type definition in parentheses */
  10. #  pragma warning (disable : 4116)
  11. #endif
  12.  
  13.  
  14.  
  15.  
  16. #if ! defined (NDEBUG)
  17. #  include <stdio.h>
  18. #  define DBG_PRINTF(mp_exp) printf mp_exp
  19. #else
  20. #  define DBG_PRINTF(mp_exp) ((void)0)
  21. #endif
  22.  
  23.  
  24.  
  25.  
  26. typedef size_t uintptr_type;
  27.  
  28.  
  29. typedef char static_assert[
  30.   sizeof(uintptr_type) == sizeof(void*) ? 1 : -1
  31. ];
  32.  
  33.  
  34.  
  35.  
  36. enum align_enum {
  37.   ALIGN_ENUM
  38. };
  39.  
  40.  
  41. struct align_struct {
  42.   char pad;
  43.   double type;
  44. };
  45.  
  46.  
  47. union align_max {
  48.   char char_;
  49.   short int short_;
  50.   int int_;
  51.   long int long_;
  52.   float float_;
  53.   double double_;
  54.   long double long_double_;
  55.   void* ptr_;
  56.   void* (*fptr_) (void*);
  57.   enum align_enum enum_;
  58.   struct align_struct struct_;
  59.   size_t size_t_;
  60.   ptrdiff_t ptrdiff_t;
  61. };
  62.  
  63.  
  64. #define ALIGN_OF(mp_type) \
  65.   offsetof( \
  66.     struct { \
  67.       char pad_ALIGN_OF; \
  68.       mp_type type_ALIGN_OF; \
  69.     }, \
  70.     type_ALIGN_OF \
  71.   )
  72.  
  73.  
  74. #define ALIGN_MAX ALIGN_OF(union align_max)
  75.  
  76.  
  77. #define ALIGN_UP(mp_ptr, mp_align) \
  78.   ((void*)( \
  79.     (((uintptr_type)(mp_ptr)) + ((mp_align) - 1)) \
  80.     & ~(((mp_align) - 1)) \
  81.   ))
  82.  
  83.  
  84. #define ALIGN_ASSERT(mp_ptr, mp_align) \
  85.   (((void*)(mp_ptr)) == ALIGN_UP(mp_ptr, mp_align))
  86.  
  87.  
  88.  
  89.  
  90. struct region {
  91.   unsigned char* buffer;
  92.   size_t size;
  93.   size_t offset;
  94. };
  95.  
  96.  
  97. void
  98. region_init(
  99.  struct region* const self,
  100.  void* buffer,
  101.  size_t size
  102. ) {
  103.   self->buffer = buffer;
  104.   self->size = size;
  105.   self->offset = 0;
  106.  
  107.   DBG_PRINTF((
  108.     "region_init(%p) {\n"
  109.     "  buffer          = %p\n"
  110.     "  size            = %lu\n"
  111.     "}\n\n\n",
  112.     (void*)self,
  113.     buffer,
  114.     (unsigned long int)size
  115.   ));
  116. }
  117.  
  118.  
  119. void*
  120. region_alloc_ex(
  121.  struct region* const self,
  122.  size_t size,
  123.  size_t align
  124. ) {
  125.   unsigned char* align_buffer;
  126.   size_t offset = self->offset;
  127.   unsigned char* raw_buffer = self->buffer + offset;
  128.  
  129.   if (! size) {
  130.     size = 1;
  131.   }
  132.  
  133.   if (! align) {
  134.     align = ALIGN_MAX;
  135.   }
  136.  
  137.   assert(align == 1 || ALIGN_ASSERT(align, 2));
  138.  
  139.   align_buffer = ALIGN_UP(raw_buffer, align);
  140.  
  141.   assert(ALIGN_ASSERT(align_buffer, align));
  142.  
  143.   size += align_buffer - raw_buffer;
  144.  
  145.   if (offset + size > self->size) {
  146.     return NULL;
  147.   }
  148.  
  149.   self->offset = offset + size;
  150.  
  151.   DBG_PRINTF((
  152.     "region_alloc_ex(%p) {\n"
  153.     "  size            = %lu\n"
  154.     "  alignment       = %lu\n"
  155.     "  origin offset   = %lu\n"
  156.     "  final offset    = %lu\n"
  157.     "  raw_buffer      = %p\n"
  158.     "  align_buffer    = %p\n"
  159.     "  size adjustment = %lu\n"
  160.     "  final size      = %lu\n"
  161.     "}\n\n\n",
  162.     (void*)self,
  163.     (unsigned long int)size - (align_buffer - raw_buffer),
  164.     (unsigned long int)align,
  165.     (unsigned long int)offset,
  166.     (unsigned long int)self->offset,
  167.     (void*)raw_buffer,
  168.     (void*)align_buffer,
  169.     (unsigned long int)(align_buffer - raw_buffer),
  170.     (unsigned long int)size
  171.   ));
  172.  
  173.   return align_buffer;
  174. }
  175.  
  176.  
  177. #define region_alloc(mp_self, mp_size) \
  178.   region_alloc_ex((mp_self), (mp_size), ALIGN_MAX)
  179.  
  180. #define region_alloc_type(mp_self, mp_count, mp_type) \
  181.   region_alloc_ex( \
  182.     (mp_self), \
  183.     sizeof(mp_type) * (mp_count),\
  184.     ALIGN_OF(mp_type) \
  185.   )
  186.  
  187.  
  188. void
  189. region_flush(
  190.  struct region* const self
  191. ) {
  192.   self->offset = 0;
  193.  
  194.   DBG_PRINTF((
  195.     "region_flush(%p) {}\n\n\n",
  196.     (void*)self
  197.   ));  
  198. }
  199.  
  200.  
  201.  
  202.  
  203. /* condensed API */
  204. #define rinit region_init
  205. #define ralloc region_alloc
  206. #define ralloct region_alloc_type
  207. #define rallocex region_alloc_ex
  208. #define rflush region_flush
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217. #include <stdio.h>
  218.  
  219.  
  220. struct foo {
  221.   char a;
  222.   double b;
  223. };
  224.  
  225.  
  226. int main(void) {
  227.   size_t i;
  228.   struct region region;
  229.   unsigned char buffer[8192] = { '\0' };
  230.  
  231.   region_init(&region, buffer, sizeof(buffer));
  232.  
  233.   for (i = 0; i < 32; ++i) {
  234.     region_alloc(&region, i);
  235.     region_alloc_type(&region, i, char);
  236.     region_alloc_type(&region, i, short int);
  237.     region_alloc_type(&region, i, int);
  238.     region_alloc_type(&region, i, long int);
  239.     region_alloc_type(&region, i, float);
  240.     region_alloc_type(&region, i, double);
  241.     region_alloc_type(&region, i, struct foo);
  242.     region_alloc_ex(&region, i, (size_t)ALIGN_UP(i, 2));
  243.     region_flush(&region);
  244.   }
  245.  
  246.   for (i = 0; i < 32; ++i) {
  247.     ralloc(&region, i);
  248.     ralloct(&region, i, char);
  249.     ralloct(&region, i, short int);
  250.     ralloct(&region, i, int);
  251.     ralloct(&region, i, long int);
  252.     ralloct(&region, i, float);
  253.     ralloct(&region, i, double);
  254.     ralloct(&region, i, struct foo);
  255.     rallocex(&region, i, (size_t)ALIGN_UP(i, 2));
  256.     rflush(&region);
  257.   }
  258.  
  259.   return 0;
  260. }
  261.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement