pike.git / src / block_allocator.c

version» Context lines:

pike.git/src/block_allocator.c:1:   #include "global.h"   #include "pike_error.h"   #include "pike_memory.h"      #include "block_allocator.h"   #include "bitvector.h"      #include <stdlib.h>    - #define BA_BLOCKN(l, p, n) ((struct ba_block_header *)((char*)(p) + (l).doffset + (n)*((l).block_size))) - #define BA_LASTBLOCK(l, p) ((struct ba_block_header*)((char*)(p) + (l).doffset + (l).offset)) - #define BA_CHECK_PTR(l, p, ptr) ((size_t)((char*)(ptr) - (char*)(p)) <= (l).offset + (l).doffset) + #define BA_BLOCKN(l, p, n) ((struct ba_block_header *)((char*)(p) + sizeof(struct ba_page) + (n)*((l).block_size))) + #define BA_LASTBLOCK(l, p) ((struct ba_block_header*)((char*)(p) + sizeof(struct ba_page) + (l).offset)) + #define BA_CHECK_PTR(l, p, ptr) ((size_t)((char*)(ptr) - (char*)(p)) <= (l).offset + sizeof(struct ba_page))      #define BA_ONE ((struct ba_block_header *)1)   #define BA_FLAG_SORTED 1u      #ifdef PIKE_DEBUG   static void print_allocator(const struct block_allocator * a);   #endif      #ifdef PIKE_DEBUG   static void ba_check_ptr(struct block_allocator * a, int page, void * ptr, struct ba_block_header *loc,
pike.git/src/block_allocator.c:64:    p->h.used = 0;    p->h.flags = BA_FLAG_SORTED;    p->h.first = BA_BLOCKN(*l, p, 0);    PIKE_MEMPOOL_ALLOC(a, p->h.first, l->block_size);    p->h.first->next = BA_ONE;    PIKE_MEMPOOL_FREE(a, p->h.first, l->block_size);   }      static struct ba_page * ba_alloc_page(struct block_allocator * a, int i) {    struct ba_layout l = ba_get_layout(a, i); -  size_t n = l.offset + l.block_size + l.doffset; +  size_t n = l.offset + l.block_size + sizeof(struct ba_page);    struct ba_page * p;       /*    * note that i is always positive, so this only    * happens if ba_get_layout overflows    */    if (a->l.offset > l.offset || n < l.offset) {    Pike_error("Overflow.\n");    }    -  if (l.alignment) { -  p = xalloc_aligned(n, l.alignment); -  } else { +  {   #ifdef DEBUG_MALLOC    /* In debug malloc mode, calling xalloc from the block alloc may result    * in a deadlock, since xalloc will call ba_alloc, which in turn may call xalloc.    */    p = system_malloc(n);    if (!p) {    fprintf(stderr, "Fatal: Out of memory.\n");    exit(17);    }   #else    p = xalloc(n);   #endif    }    ba_clear_page(a, p, &a->l); -  PIKE_MEM_NA_RANGE((char*)p + l.doffset, n - l.doffset); +  PIKE_MEM_NA_RANGE((char*)p + sizeof(struct ba_page), n - sizeof(struct ba_page));    return p;   }      static void ba_free_empty_pages(struct block_allocator * a) {    int i;       for (i = a->size - 1; i >= 0; i--) {    struct ba_page * p = a->pages[i];    if (p->h.used) break;   #ifdef DEBUG_MALLOC
pike.git/src/block_allocator.c:116:   #endif    a->pages[i] = NULL;    }       if (a->size != i+1) {    a->size = i+1;    a->alloc = a->last_free = MAXIMUM(0, i);    }   }    - PMOD_EXPORT void ba_low_init_aligned(struct block_allocator * a) { + static void ba_low_init(struct block_allocator * a) {    unsigned INT32 block_size = MAXIMUM(a->l.block_size, sizeof(struct ba_block_header));       PIKE_MEMPOOL_CREATE(a);    -  if (a->l.alignment) { -  if (a->l.alignment & (a->l.alignment - 1)) -  Pike_fatal("Block allocator a->l.alignment is not a power of 2.\n"); -  if (block_size & (a->l.alignment-1)) -  Pike_fatal("Block allocator block size is not aligned.\n"); -  a->l.doffset = PIKE_ALIGNTO(sizeof(struct ba_page), a->l.alignment); -  } else { -  a->l.doffset = sizeof(struct ba_page); -  } -  +     if (a->l.blocks & (a->l.blocks - 1)) {    unsigned INT32 tmp = round_up32(a->l.blocks);    if (tmp) a->l.blocks = tmp;    } else if (!a->l.blocks) a->l.blocks = 1;    a->l.block_size = block_size;    a->l.offset = block_size * (a->l.blocks-1);   }    - PMOD_EXPORT void ba_init_aligned(struct block_allocator * a, unsigned INT32 block_size, -  unsigned INT32 blocks, unsigned INT32 alignment) { + PMOD_EXPORT void ba_init(struct block_allocator * a, unsigned INT32 block_size, +  unsigned INT32 blocks) {    a->l.blocks = blocks;    a->l.block_size = block_size; -  a->l.alignment = alignment; -  ba_low_init_aligned(a); +  ba_low_init(a);    a->alloc = a->last_free = a->size = 0;    memset(a->pages, 0, sizeof(a->pages));   }      PMOD_EXPORT void ba_destroy(struct block_allocator * a) {    int i;       if (!a->l.offset) return;       for (i = 0; i < a->size; i++) {
pike.git/src/block_allocator.c:199:       return c;   }      PMOD_EXPORT void ba_count_all(const struct block_allocator * a, size_t * num, size_t * size) {    size_t n = 0, b = sizeof( struct block_allocator );    unsigned int i;    for( i=0; i<a->size; i++ )    {    struct ba_layout l = ba_get_layout( a, i ); -  b += l.offset + l.block_size + l.doffset; +  b += l.offset + l.block_size + sizeof(struct ba_page);    n += a->pages[i]->h.used;    }    *num = n;    *size = b;   }      static void ba_low_alloc(struct block_allocator * a) {    int i;       if (!a->l.offset) { -  ba_low_init_aligned(a); +  ba_low_init(a);    }       /*    * The biggest page is full, lets try to find some space in the previous ones    */    for (i = a->size - 1; i >= 0; i--) {    struct ba_page * p = a->pages[i];       if (p->h.first) {    a->alloc = i;
pike.git/src/block_allocator.c:268:    PIKE_MEMPOOL_FREE(a, p->h.first, a->l.block_size);    } else {   #ifdef PIKE_DEBUG    if (ptr->next)    ba_check_ptr(a, a->alloc, ptr->next, ptr, __LINE__);   #endif    p->h.first = ptr->next;    }    PIKE_MEM_WO_RANGE(ptr, sizeof(struct ba_block_header));    - #if PIKE_DEBUG -  if (a->l.alignment && (size_t)ptr & (a->l.alignment - 1)) { -  print_allocator(a); -  Pike_fatal("Returning unaligned pointer.\n"); -  } - #endif -  +     return ptr;   }      PMOD_EXPORT void ba_free(struct block_allocator * a, void * ptr) {    int i = a->last_free;    struct ba_page * p = a->pages[i];    struct ba_layout l = ba_get_layout(a, i);    - #if PIKE_DEBUG -  if (a->l.alignment && (size_t)ptr & (a->l.alignment - 1)) { -  print_allocator(a); -  Pike_fatal("Returning unaligned pointer.\n"); -  } - #endif -  +     if (BA_CHECK_PTR(l, p, ptr)) goto found;      #ifdef PIKE_DEBUG    p = NULL;   #endif       for (i = a->size-1, l = ba_get_layout(a, i); i >= 0; i--, ba_half_layout(&l)) {    if (BA_CHECK_PTR(l, a->pages[i], ptr)) {    a->last_free = i;    p = a->pages[i];