pike.git / src / block_allocator.c

version» Context lines:

pike.git/src/block_allocator.c:80:    fprintf(stderr, "empty_pages: %u\n", a->empty_pages);    fprintf(stderr, "magnitude: %u\n", a->magnitude);    PRINT_NODE(a, empty);    PRINT_NODE(a, first);    PRINT_NODE(a, last_free);       for (i = 1; i <= a->num_pages; i++) {    ba_page p = BA_PAGE(a, i);    ba_block_t blocks_used;    if (p == a->first) { -  if (!a->first_blk) blocks_used = a->blocks; -  else blocks_used = a->blocks - a->first_blk->left; +  blocks_used = 0;    } else { -  if (!p->first) blocks_used = a->blocks; -  else blocks_used = a->blocks - p->first->left; +  blocks_used = p->used;    }    fprintf(stderr, "%d(%p[%u])\t%f\t(%u %d) --> (prev: %p[%u] | next: %p[%u])\n",    i, p, p->n, blocks_used/(double)a->blocks * 100,    blocks_used,    blocks_used,    p->prev, BA_NUM(p->prev), p->next, BA_NUM(p->next));       }   }   
pike.git/src/block_allocator.c:129:    a->num_pages = 0;    a->empty_pages = 0;    a->max_empty_pages = BA_MAX_EMPTY;       // we start with management structures for 16 pages    a->allocated = BA_ALLOC_INITIAL;    a->pages = NULL;    ba_realloc(a);   }    + static INLINE void ba_free_page(struct block_allocator * a, ba_page p) { +  p->first = BA_BLOCKN(a, p, 0); +  p->used = 0; +  if (a->blueprint) { +  //xmemset(p+1, a->blueprint, a->block_size, a->blocks); +  size_t len = (a->blocks - 1) * a->block_size, clen = a->block_size; +  p++; +  memcpy(p, a->blueprint, a->block_size); +  +  while (len > clen) { +  memcpy(((char*)(p)) + clen, p, clen); +  len -= clen; +  clen <<= 1; +  } +  +  if (len) memcpy(((char*)(p)) + clen, p, len); +  p--; +  } +  +  do { +  char * ptr = (char*)(p+1); +  +  while (ptr < BA_LASTBLOCK(a, p)) { + #ifdef BA_DEBUG +  PIKE_MEM_RW(((ba_block_header)ptr)->magic); +  ((ba_block_header)ptr)->magic = BA_MARK_FREE; + #endif +  ((ba_block_header)ptr)->next = (ba_block_header)(ptr+a->block_size); +  ptr+=a->block_size; +  } +  BA_LASTBLOCK(a, p)->next = NULL; +  } while (0); + } +    PMOD_EXPORT INLINE void ba_free_all(struct block_allocator * a) {    unsigned int i;       if (!a->allocated) return;       for (i = 0; i < a->num_pages; i++) {    ba_page p = BA_PAGE(a, i+1);    PIKE_MEM_RW_RANGE(BA_BLOCKN(a, 0), BA_PAGESIZE(a));    free(p);    BA_PAGE(a, i+1) = NULL;
pike.git/src/block_allocator.c:159:   }      PMOD_EXPORT INLINE void ba_count_all(struct block_allocator * a, size_t *num, size_t *size) {    unsigned int i;    size_t n = 0;       //fprintf(stderr, "page_size: %u, pages: %u\n", BA_PAGESIZE(a), a->num_pages);    *size = BA_BYTES(a) + a->num_pages * BA_PAGESIZE(a);    for (i = 0; i < a->num_pages; i++) {    ba_page p = a->pages[i]; -  if (p == a->first) { -  if (a->first_blk) n += a->first_blk->left; -  else n += a->blocks; -  } else { -  if (p->first) n+= p->first->left; -  else n += a->blocks; +  n+= p->used;    } -  } +        *num = n;   }      PMOD_EXPORT INLINE void ba_destroy(struct block_allocator * a) {    ba_free_all(a);    PIKE_MEM_RW_RANGE(a->pages, BA_BYTES(a));    free(a->pages);    a->allocated = 0;    a->htable = NULL;
pike.git/src/block_allocator.c:436: Inside #if defined(BA_DEBUG)
   fprintf(stderr, "\nCalled from %s:%d:%s\n", fun, line, file);    fprintf(stderr, "pages: %u\n", a->num_pages);    BA_ERROR("bad");    }   }   #endif      static INLINE void ba_alloc_page(struct block_allocator * a) {    ba_page p;    unsigned int i; +  void * ptr;       if (unlikely(a->num_pages == a->allocated)) {    ba_grow(a);    }       a->num_pages++; -  +  ptr = malloc(BA_PAGESIZE(a)); +  if (!ptr) BA_ERROR("no mem. alloc returned zero.");   #ifdef BA_DEBUG    if (BA_PAGE(a, a->num_pages)) { -  void * new = malloc(BA_PAGESIZE(a)); +     fprintf(stderr, "reusing unfreed page %d, data: %p -> %p\n", a->num_pages, -  p+1, new); +  p+1, ptr);    a->num_pages--;    ba_show_pages(a);    a->num_pages++; -  BA_PAGE(a, a->num_pages) = p = new; -  BA_ERROR("dont continue\n"); +     } else   #endif -  BA_PAGE(a, a->num_pages) = p = (ba_page)malloc(sizeof(struct ba_page) + BA_PAGESIZE(a)); -  if (!p) { -  BA_ERROR("no mem. alloc returned zero."); -  } +  BA_PAGE(a, a->num_pages) = p = (ba_page)ptr;    p->n = a->num_pages;   #ifdef BA_DEBUG    if (!p->n) BA_ERROR("num pages cannot be zero\n");   #endif -  +  ba_free_page(a, p);    p->next = p->prev = NULL;    a->last = a->first = p;    IF_HASH(    ba_htable_insert(a, BA_LASTBLOCK(a, p), a->num_pages);   #ifdef BA_DEBUG    ba_check_allocator(a, "ba_alloc after insert", __FILE__, __LINE__);   #endif    ); -  p->first = BA_BLOCKN(a, p, 0); -  -  if (a->blueprint) { -  size_t len = (a->blocks - 1) * a->block_size, clen = a->block_size; -  memcpy(p+1, a->blueprint, a->block_size); -  -  while (len > clen) { -  memcpy(((char*)(p+1)) + clen, p+1, clen); -  len -= clen; -  clen <<= 1; -  } -  -  if (len) memcpy(((char*)(p+1)) + clen, p+1, len); -  } -  -  for (i = 0; i < a->blocks; i++) { +    #ifdef BA_DEBUG -  PIKE_MEM_RW(BA_BLOCKN(a, p, i)->magic); -  BA_BLOCKN(a, p, i)->magic = BA_MARK_FREE; - #endif -  BA_BLOCKN(a, p, i)->next = BA_BLOCKN(a, p, i+1); -  BA_BLOCKN(a, p, i)->left = a->blocks - (i); -  } -  BA_LASTBLOCK(a, p)->next = NULL; - #ifdef BA_DEBUG +     PIKE_MEM_RW(BA_LASTBLOCK(a, p)->magic);    BA_LASTBLOCK(a, p)->magic = BA_MARK_FREE;    PIKE_MEM_RW(BA_BLOCKN(a, p, 0)->magic);    BA_BLOCKN(a, p, 0)->magic = BA_MARK_ALLOC;    ba_check_allocator(a, "ba_alloc after insert", __FILE__, __LINE__);   #endif   }      PMOD_EXPORT void ba_low_alloc(struct block_allocator * a) {    //fprintf(stderr, "ba_alloc(%p)\n", a);
pike.git/src/block_allocator.c:517:   #endif       //fprintf(stderr, "allocating new page. was %p\n", p);    if (a->first) {    ba_page p = a->first;    if (p->next) a->first = p->next;    else a->first = a->last = NULL;    p->prev = NULL;    p->next = NULL;    p->first = NULL; - #ifdef BA_DEBUG - #endif +  p->used = a->blocks;    }       if (a->first) { - #if 1//def BA_DEBUG + #ifdef BA_DEBUG    if (!a->first->first) {    ba_show_pages(a);    BA_ERROR("no free blk in page %p[%u]\n", a->first,    BA_NUM(a->first));    }   #endif    a->first->prev = NULL;    } else if (a->empty_pages) {    a->last = a->first = a->empty;    a->empty = a->empty->next;    a->empty_pages--;    a->first->next = NULL;    } else ba_alloc_page(a);    - #if 1//def BA_DEBUG + #ifdef BA_DEBUG    if (!a->first->first) {    ba_show_pages(a);    BA_ERROR("a->first has no first block!\n");    }   #endif      #ifdef BA_DEBUG    ba_check_allocator(a, "ba_alloc after grow", __FILE__, __LINE__);   #endif       a->first_blk = a->first->first;   }    - PMOD_EXPORT void ba_free_empty(struct block_allocator * a, ba_page p) { + PMOD_EXPORT void ba_low_free(struct block_allocator * a, ba_page p, +  ba_block_header ptr) { +  // page was full +  if (unlikely(!ptr->next)) { +  +  if (a->first) { +  p->prev = a->last; +  a->last->next = p; +  a->last = p; +  p->first = ptr; +  } else { +  p->prev = p->next = NULL; +  a->first = a->last = p; +  a->first_blk = ptr; +  } +  } else if (!p->used) {    if (a->empty_pages == a->max_empty_pages) {    ba_remove_page(a, p);    return;    }    if (p->next) p->next->prev = p->prev;    else a->last = p->prev;    if (p->prev) {    p->prev->next = p->next;    p->prev = NULL;    }    a->last_free = NULL;    p->next = a->empty;    a->empty = p;    a->empty_pages ++;    } -  - PMOD_EXPORT void ba_free_full(struct block_allocator * a, -  ba_page p, ba_block_header ptr) { -  ptr->next = NULL; -  ptr->left = 1; -  -  if (a->first) { -  p->prev = a->last; -  a->last->next = p; -  a->last = p; -  p->first = ptr; -  } else { -  p->prev = p->next = NULL; -  a->first = a->last = p; -  a->first_blk = ptr; +    } - } +       PMOD_EXPORT void ba_find_page(struct block_allocator * a,    const void * ptr) {    ba_page_t n;   #ifdef BA_DEBUG    ba_check_allocator(a, "ba_low_free", __FILE__, __LINE__);   #endif   #ifdef BA_HASH_THLD    if (a->num_pages <= BA_HASH_THLD) {    for (n = 0; n < a->num_pages; n++) {