Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stddef.h>
- #include <assert.h>
- #if defined (_MSC_VER)
- /* warning C4116: unnamed type definition in parentheses */
- # pragma warning (disable : 4116)
- #endif
- #if ! defined (NDEBUG)
- # include <stdio.h>
- # define DBG_PRINTF(mp_exp) printf mp_exp
- #else
- # define DBG_PRINTF(mp_exp) ((void)0)
- #endif
- typedef size_t uintptr_type;
- typedef char static_assert[
- sizeof(uintptr_type) == sizeof(void*) ? 1 : -1
- ];
- enum align_enum {
- ALIGN_ENUM
- };
- struct align_struct {
- char pad;
- double type;
- };
- union align_max {
- char char_;
- short int short_;
- int int_;
- long int long_;
- float float_;
- double double_;
- long double long_double_;
- void* ptr_;
- void* (*fptr_) (void*);
- enum align_enum enum_;
- struct align_struct struct_;
- size_t size_t_;
- ptrdiff_t ptrdiff_t;
- };
- #define ALIGN_OF(mp_type) \
- offsetof( \
- struct { \
- char pad_ALIGN_OF; \
- mp_type type_ALIGN_OF; \
- }, \
- type_ALIGN_OF \
- )
- #define ALIGN_MAX ALIGN_OF(union align_max)
- #define ALIGN_UP(mp_ptr, mp_align) \
- ((void*)( \
- (((uintptr_type)(mp_ptr)) + ((mp_align) - 1)) \
- & ~(((mp_align) - 1)) \
- ))
- #define ALIGN_ASSERT(mp_ptr, mp_align) \
- (((void*)(mp_ptr)) == ALIGN_UP(mp_ptr, mp_align))
- struct region {
- unsigned char* buffer;
- size_t size;
- size_t offset;
- };
- void
- region_init(
- struct region* const self,
- void* buffer,
- size_t size
- ) {
- self->buffer = buffer;
- self->size = size;
- self->offset = 0;
- DBG_PRINTF((
- "region_init(%p) {\n"
- " buffer = %p\n"
- " size = %lu\n"
- "}\n\n\n",
- (void*)self,
- buffer,
- (unsigned long int)size
- ));
- }
- void*
- region_alloc_ex(
- struct region* const self,
- size_t size,
- size_t align
- ) {
- size_t offset = self->offset;
- unsigned char* raw_buffer = self->buffer + offset;
- unsigned char* align_buffer;
- if (! size) {
- size = 1;
- }
- if (! align) {
- align = ALIGN_MAX;
- }
- assert(align == 1 || ALIGN_ASSERT(align, 2));
- align_buffer = ALIGN_UP(raw_buffer, align);
- assert(ALIGN_ASSERT(align_buffer, align));
- size += align_buffer - raw_buffer;
- if (offset + size > self->size) {
- return NULL;
- }
- self->offset = offset + size;
- DBG_PRINTF((
- "region_alloc_ex(%p) {\n"
- " size = %lu\n"
- " alignment = %lu\n"
- " origin offset = %lu\n"
- " final offset = %lu\n"
- " raw_buffer = %p\n"
- " align_buffer = %p\n"
- " size adjustment = %lu\n"
- " final size = %lu\n"
- "}\n\n\n",
- (void*)self,
- (unsigned long int)size - (align_buffer - raw_buffer),
- (unsigned long int)align,
- (unsigned long int)offset,
- (unsigned long int)self->offset,
- (void*)raw_buffer,
- (void*)align_buffer,
- (unsigned long int)(align_buffer - raw_buffer),
- (unsigned long int)size
- ));
- return align_buffer;
- }
- #define region_alloc(mp_self, mp_size) \
- region_alloc_ex((mp_self), (mp_size), ALIGN_MAX)
- #define region_alloc_type(mp_self, mp_type) \
- region_alloc_ex((mp_self), sizeof(mp_type), ALIGN_OF(mp_type))
- void
- region_flush(
- struct region* const self
- ) {
- self->offset = 0;
- DBG_PRINTF((
- "region_flush(%p) {}\n\n\n",
- (void*)self
- ));
- }
- #include <stdio.h>
- struct foo {
- char a;
- double b;
- };
- int main(void) {
- size_t i;
- struct region region;
- unsigned char buffer[8192] = { '\0' };
- region_init(®ion, buffer, sizeof(buffer));
- for (i = 0; i < 32; ++i) {
- region_alloc(®ion, i);
- region_alloc_type(®ion, char);
- region_alloc_type(®ion, short int);
- region_alloc_type(®ion, int);
- region_alloc_type(®ion, long int);
- region_alloc_type(®ion, float);
- region_alloc_type(®ion, double);
- region_alloc_type(®ion, struct foo);
- region_alloc_ex(®ion, i, (size_t)ALIGN_UP(i, 2));
- region_flush(®ion);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement