Branch: Tag:

2012-02-12

2012-02-12 02:57:46 by Arne Goedeke <el@laramies.com>

use maligned memory pages to find page without hash

1:   #include <stdlib.h>   #include <string.h>   #include <stdint.h> + #include <malloc.h>   #ifdef BA_STATS   # include <unistd.h> - # include <malloc.h> +    # include <mcheck.h>   #endif   
24:   PMOD_EXPORT char errbuf[8192];   #endif    + #ifndef BA_USE_MEMALIGN   static INLINE void ba_htable_insert(const struct block_allocator * a,    ba_page ptr);   static INLINE void ba_htable_grow(struct block_allocator * a); -  + #endif      #define BA_NBLOCK(a, p, ptr) ((uintptr_t)((char*)ptr - (char)(p+1))/(a)->block_size)   
48:   PMOD_EXPORT void ba_show_pages(const struct block_allocator * a) {    unsigned int i = 0;    + #ifndef BA_USE_MEMALIGN    fprintf(stderr, "allocated: %u\n", a->allocated); -  + #endif    fprintf(stderr, "num_pages: %u\n", a->num_pages);    fprintf(stderr, "max_empty_pages: %u\n", a->max_empty_pages);    fprintf(stderr, "empty_pages: %u\n", a->empty_pages);    fprintf(stderr, "magnitude: %u\n", a->magnitude);    PRINT_NODE(a, empty);    PRINT_NODE(a, first); -  + #ifdef BA_USE_MEMALIGN +  PRINT_NODE(a, full); + #else    PRINT_NODE(a, last_free); -  + #endif       PAGE_LOOP(a, {    ba_block_t blocks_used;
136:       page_size = block_size * blocks + BLOCK_HEADER_SIZE;    -  a->empty = a->first = a->last_free = NULL; +  a->empty = a->first = NULL; + #ifdef BA_USE_MEMALIGN +  a->full = NULL; + #else +  a->last_free = NULL; + #endif      #ifdef BA_DEBUG    fprintf(stderr, "blocks: %u block_size: %u page_size: %u\n",
164:    a->max_empty_pages = BA_MAX_EMPTY;       // we start with management structures for 16 pages + #ifndef BA_USE_MEMALIGN    a->allocated = BA_ALLOC_INITIAL;    a->pages = (ba_page*)malloc(BA_ALLOC_INITIAL * sizeof(ba_page));    if (!a->pages) Pike_error("nomem");    memset(a->pages, 0, BA_ALLOC_INITIAL * sizeof(ba_page)); -  + #endif   }      static INLINE void ba_free_page(struct block_allocator * a, ba_page p) {
211:   PMOD_EXPORT INLINE void ba_free_all(struct block_allocator * a) {    unsigned int i;    + #ifdef BA_USE_MEMALIGN +  if (!a->num_pages) return; + #else    if (!a->allocated) return; -  + #endif       PAGE_LOOP(a, {    PIKE_MEM_RW_RANGE(p, BA_PAGESIZE(a));
220:       a->num_pages = 0;    a->empty_pages = 0; -  a->empty = a->first = a->last_free = NULL; +  a->empty = a->first = NULL; + #ifdef BA_USE_MEMALIGN +  a->full = NULL; + #else +  a->last_free = NULL;    a->allocated = BA_ALLOC_INITIAL;    memset(a->pages, 0, a->allocated * sizeof(ba_page)); -  + #endif   }      PMOD_EXPORT INLINE void ba_count_all(struct block_allocator * a, size_t *num, size_t *size) {
230:    size_t n = 0;       //fprintf(stderr, "page_size: %u, pages: %u\n", BA_PAGESIZE(a), a->num_pages); + #ifdef BA_USE_MEMALIGN +  *size = a->num_pages * BA_PAGESIZE(a); + #else    *size = BA_BYTES(a) + a->num_pages * BA_PAGESIZE(a); -  + #endif    PAGE_LOOP(a, {    n += p->used;    });
246:    free(p);    });    + #ifdef BA_USE_MEMALIGN +  a->full = NULL; + #else    PIKE_MEM_RW_RANGE(a->pages, BA_BYTES(a));    free(a->pages);    a->last_free = NULL; -  a->empty = a->first = NULL; +  a->allocated = 0;    a->pages = NULL; -  + #endif +  a->empty = a->first = NULL;    a->empty_pages = 0; -  a->allocated = 0; +     a->num_pages = 0;   #ifdef BA_STATS    a->stats.st_max = a->stats.st_used = 0;   #endif   }    -  + #ifndef BA_USE_MEMALIGN   static INLINE void ba_grow(struct block_allocator * a) {    if (a->allocated) {    // try to detect 32bit overrun?
465:    c = !c;    if (!(b++)) goto LOOKUP;   } + #endif      #ifdef BA_DEBUG   PMOD_EXPORT INLINE void ba_check_allocator(struct block_allocator * a,
478: Inside #if defined(BA_DEBUG)
   bad = 1;    }    + #ifndef BA_USE_MEMALIGN    for (n = 0; n < a->allocated; n++) {    ba_page_t hval;    int found = 0;
507: Inside #if defined(BA_DEBUG)
   if (bad)    ba_print_htable(a);    } + #endif       if (bad) {    ba_show_pages(a);
521:    ba_page p;    unsigned int i;    + #ifdef BA_USE_MEMALIGN +  if (a->num_pages == 0) ba_init(a, a->block_size, a->blocks); + #else    if (unlikely(a->num_pages == a->allocated)) {    ba_grow(a);    } -  + #endif       a->num_pages++; -  + #ifndef BA_USE_MEMALIGN    p = (ba_page)malloc(BA_PAGESIZE(a)); -  + #else +  p = (ba_page)memalign((size_t)(1 << a->magnitude), BA_PAGESIZE(a)); + #endif    if (!p) BA_ERROR("no mem. alloc returned zero.");    ba_free_page(a, p);    p->next = p->prev = NULL;    a->first = p; -  + #ifndef BA_USE_MEMALIGN    ba_htable_insert(a, p); -  + #endif   #ifdef BA_DEBUG    ba_check_allocator(a, "ba_alloc after insert", __FILE__, __LINE__);   #endif
554:    if (a->first) {    ba_page p = a->first;    DOUBLE_SHIFT(a->first); + #ifdef BA_USE_MEMALIGN +  DOUBLE_LINK(a->full, p); + #else    p->next = NULL;    p->first = NULL; -  + #endif    }       if (a->first) return;
584:    // page was full    if (unlikely(!ptr->next)) {    INC(free_full); + #ifdef BA_USE_MEMALIGN +  DOUBLE_UNLINK(a->full, p); + #endif    DOUBLE_LINK(a->first, p);    } else if (!p->used) {    INC(free_empty);
597:    }   }    + #ifndef BA_USE_MEMALIGN   static INLINE void ba_htable_linear_lookup(struct block_allocator * a,    const void * ptr) {    PAGE_LOOP(a, {
638:   #endif    BA_ERROR("Unknown pointer (not found in hash) %lx\n", (long int)ptr);   } + #endif    -  +    PMOD_EXPORT void ba_remove_page(struct block_allocator * a,    ba_page p) {   #ifdef BA_DEBUG
662:    a->num_pages);   #endif    + #ifndef BA_USE_MEMALIGN    ba_htable_delete(a, p);    PIKE_MEM_RW_RANGE(*p, BA_PAGESIZE(a));       // we know that p == a->last_free    a->last_free = NULL; -  + #endif       DOUBLE_UNLINK(a->first, p);   
683: Inside #if defined(BA_DEBUG)
  #ifdef BA_DEBUG    ba_check_allocator(a, "ba_remove_page", __FILE__, __LINE__);   #endif + #ifndef BA_USE_MEMALIGN    if (a->allocated > BA_ALLOC_INITIAL && a->num_pages <= (a->allocated >> 2)) {    ba_htable_shrink(a);    } - #if 0//def BA_DEBUG -  ba_show_pages(a); -  ba_print_htable(a); -  fprintf(stderr, "< =================\n"); +    #endif   }