0a3d34 | 2011-11-10 | Arne Goedeke | | #include <stdlib.h>
|
67795d | 2011-11-11 | Arne Goedeke | | #include <string.h>
|
385483 | 2011-11-18 | Arne Goedeke | | #include <stdint.h>
|
0a3d34 | 2011-11-10 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #include "block_allocator.h"
|
a60c24 | 2011-12-25 | Arne Goedeke | | #include "bitvector.h"
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #if defined(PIKE_CORE) || defined(DYNAMIC_MODULE) || defined(STATIC_MODULE)
#include "pike_memory.h"
#endif
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
|
f2b3bd | 2011-12-31 | Arne Goedeke | | #ifndef PMOD_EXPORT
# warning WTF
|
385483 | 2011-11-18 | Arne Goedeke | | #endif
|
fdfd28 | 2011-12-25 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #if defined(BA_DEBUG) || (!defined(PIKE_CORE) && !defined(DYNAMIC_MODULE) \
&& !defined(STATIC_MODULES))
#endif
PMOD_EXPORT char errbuf[8192];
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_htable_insert(const struct block_allocator * a,
|
f2b3bd | 2011-12-31 | Arne Goedeke | | const void * ptr, const ba_page_t n);
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
|
335e6a | 2012-01-04 | Arne Goedeke | | #define BA_NBLOCK(a, p, ptr) ((uintptr_t)((char*)ptr - (char)(p+1))/(a)->block_size)
|
e90c49 | 2011-11-27 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #define BA_DIVIDE(a, b) ((a) / (b) + (!!((a) & ((b)-1))))
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | #define BA_PAGESIZE(a) ((a)->blocks * (a)->block_size)
|
385483 | 2011-11-18 | Arne Goedeke | | #define BA_SPAGE_SIZE(a) (sizeof(struct ba_page) + (BA_DIVIDE((a)->blocks, sizeof(uintptr_t)*8) - 1)*sizeof(uintptr_t))
#define BA_HASH_MASK(a) (((a->allocated)) - 1)
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_HASH_THLD
|
335e6a | 2012-01-04 | Arne Goedeke | | # define BA_BYTES(a) ( (sizeof(ba_page) + ((a->allocated > BA_HASH_THLD) ? sizeof(ba_page_t) : 0)) * ((a)->allocated) )
|
e2499f | 2012-01-03 | Arne Goedeke | | #else
|
335e6a | 2012-01-04 | Arne Goedeke | | # define BA_BYTES(a) ( (sizeof(ba_page) + sizeof(ba_page_t)) * ((a)->allocated) )
|
e2499f | 2012-01-03 | Arne Goedeke | | #endif
|
385483 | 2011-11-18 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifndef PIKE_MEM_RW_RANGE
# define PIKE_MEM_RW_RANGE(x, y)
#endif
|
67795d | 2011-11-11 | Arne Goedeke | |
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_realloc(struct block_allocator * a) {
|
475075 | 2011-11-19 | Arne Goedeke | | unsigned int i;
|
335e6a | 2012-01-04 | Arne Goedeke | | ba_page * old;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | ba_page p;
|
335e6a | 2012-01-04 | Arne Goedeke | | a->pages = (ba_page*)realloc(old = a->pages, BA_BYTES(a));
|
6fc6ce | 2011-12-30 | Arne Goedeke | | if (unlikely(!a->pages)) {
|
e2499f | 2012-01-03 | Arne Goedeke | |
BA_ERROR("alloc of %lu bytes failed.", BA_BYTES(a));
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
f2b3bd | 2011-12-31 | Arne Goedeke | | #ifdef BA_DEBUG
|
385483 | 2011-11-18 | Arne Goedeke | | memset((void*)BA_PAGE(a, a->num_pages+1), 0, BA_BYTES(a) - sizeof(struct ba_page)*a->num_pages);
#endif
|
e2499f | 2012-01-03 | Arne Goedeke | | a->htable = NULL;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | IF_HASH(
|
335e6a | 2012-01-04 | Arne Goedeke | | a->htable = (ba_page_t*) (a->pages + a->allocated);
|
f2b3bd | 2011-12-31 | Arne Goedeke | | memset(a->htable, 0, a->allocated * sizeof(ba_page_t));
|
6fc6ce | 2011-12-30 | Arne Goedeke | | for (i = 0; i < a->num_pages; i++) {
p = BA_PAGE(a, i+1);
p->hchain = 0;
ba_htable_insert(a, BA_LASTBLOCK(a, p), i+1);
}
);
#ifdef BA_DEBUG
ba_check_allocator(a, "realloc", __FILE__, __LINE__);
#endif
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | PMOD_EXPORT void ba_show_pages(struct block_allocator * a) {
unsigned int i = 0;
fprintf(stderr, "first: %p last_free: %p\n", a->first, a->last_free);
for (i = 1; i <= a->num_pages; i++) {
ba_page p = BA_PAGE(a, i);
|
335e6a | 2012-01-04 | Arne Goedeke | | fprintf(stderr, "%d\t%f\t(%u %d) --> (prev: %p | next: %p)\n",
|
e2499f | 2012-01-03 | Arne Goedeke | | i, p->blocks_used/(double)a->blocks * 100,
p->blocks_used,
p->blocks_used,
|
335e6a | 2012-01-04 | Arne Goedeke | | p->prev, p->next);
|
e2499f | 2012-01-03 | Arne Goedeke | |
}
}
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_init(struct block_allocator * a,
|
6fc6ce | 2011-12-30 | Arne Goedeke | | uint32_t block_size, ba_page_t blocks) {
|
475075 | 2011-11-19 | Arne Goedeke | | uint32_t page_size = block_size * blocks;
|
385483 | 2011-11-18 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | a->first = NULL;
a->last_free = NULL;
|
335e6a | 2012-01-04 | Arne Goedeke | | a->last_free_num = 0;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
0a3d34 | 2011-11-10 | Arne Goedeke | | if ((page_size & (page_size - 1)) == 0)
|
67795d | 2011-11-11 | Arne Goedeke | | a->magnitude = (uint16_t)ctz32(page_size);
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | else
|
67795d | 2011-11-11 | Arne Goedeke | | a->magnitude = (uint16_t)ctz32(round_up32(page_size));
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
0a3d34 | 2011-11-10 | Arne Goedeke | | a->block_size = block_size;
|
e2499f | 2012-01-03 | Arne Goedeke | | a->blocks = (1 << a->magnitude) / block_size;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | a->num_pages = 0;
|
938726 | 2011-12-25 | Arne Goedeke | | a->empty_pages = 0;
|
e2499f | 2012-01-03 | Arne Goedeke | | a->max_empty_pages = BA_MAX_EMPTY;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
67795d | 2011-11-11 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | a->allocated = BA_ALLOC_INITIAL;
|
67795d | 2011-11-11 | Arne Goedeke | | a->pages = NULL;
ba_realloc(a);
}
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_free_all(struct block_allocator * a) {
|
475075 | 2011-11-19 | Arne Goedeke | | unsigned int i;
|
67795d | 2011-11-11 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | if (!a->allocated) return;
|
67795d | 2011-11-11 | Arne Goedeke | | for (i = 0; i < a->num_pages; i++) {
|
335e6a | 2012-01-04 | Arne Goedeke | | 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;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
67795d | 2011-11-11 | Arne Goedeke | | a->num_pages = 0;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | a->empty_pages = 0;
|
e2499f | 2012-01-03 | Arne Goedeke | | a->first = NULL;
a->last_free = NULL;
a->allocated = BA_ALLOC_INITIAL;
ba_realloc(a);
IF_HASH(
memset(a->htable, 0, sizeof(*a->htable)*a->allocated);
);
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_count_all(struct block_allocator * a, size_t *num, size_t *size) {
|
475075 | 2011-11-19 | Arne Goedeke | | unsigned int i;
|
385483 | 2011-11-18 | Arne Goedeke | | size_t n = 0;
|
f2b3bd | 2011-12-31 | Arne Goedeke | |
|
385483 | 2011-11-18 | Arne Goedeke | | *size = BA_BYTES(a) + a->num_pages * BA_PAGESIZE(a);
for (i = 0; i < a->num_pages; i++) {
|
475075 | 2011-11-19 | Arne Goedeke | | n += BA_PAGE(a, i+1)->blocks_used;
|
385483 | 2011-11-18 | Arne Goedeke | | }
*num = n;
}
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_destroy(struct block_allocator * a) {
|
67795d | 2011-11-11 | Arne Goedeke | | ba_free_all(a);
|
f2b3bd | 2011-12-31 | Arne Goedeke | | PIKE_MEM_RW_RANGE(a->pages, BA_BYTES(a));
|
67795d | 2011-11-11 | Arne Goedeke | | free(a->pages);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | a->allocated = 0;
|
e2499f | 2012-01-03 | Arne Goedeke | | a->htable = NULL;
|
67795d | 2011-11-11 | Arne Goedeke | | a->pages = NULL;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_grow(struct block_allocator * a) {
|
385483 | 2011-11-18 | Arne Goedeke | | if (a->allocated) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
if (a->allocated >= ((ba_page_t)1 << (sizeof(ba_page_t)*8-1))) {
Pike_error("too many pages.\n");
}
|
385483 | 2011-11-18 | Arne Goedeke | | a->allocated *= 2;
ba_realloc(a);
} else {
ba_init(a, a->block_size, a->blocks);
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef BA_DEBUG
ba_check_allocator(a, "ba_grow", __FILE__, __LINE__);
#endif
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_shrink(struct block_allocator * a) {
|
67795d | 2011-11-11 | Arne Goedeke | | a->allocated /= 2;
ba_realloc(a);
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #define MIX(t) do { \
t ^= (t >> 20) ^ (t >> 12); \
t ^= (t >> 7) ^ (t >> 4); \
} while(0)
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE ba_page_t hash1(const struct block_allocator * a,
|
67795d | 2011-11-11 | Arne Goedeke | | const void * ptr) {
uintptr_t t = ((uintptr_t)ptr) >> a->magnitude;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | MIX(t);
return (ba_page_t) t;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE ba_page_t hash2(const struct block_allocator * a,
|
67795d | 2011-11-11 | Arne Goedeke | | const void * ptr) {
uintptr_t t = ((uintptr_t)ptr) >> a->magnitude;
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | t++;
MIX(t);
return (ba_page_t) t;
}
|
f2b3bd | 2011-12-31 | Arne Goedeke | | #ifdef BA_DEBUG
PMOD_EXPORT void ba_print_htable(const struct block_allocator * a) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | unsigned int i;
ba_page p;
fprintf(stderr, "allocated: %u\n", a->allocated);
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);
fprintf(stderr, "block_size: %u\n", a->block_size);
|
e2499f | 2012-01-03 | Arne Goedeke | | IF_HASH(
for (i = 0; i < a->allocated; i++) {
ba_page_t n = a->htable[i];
ba_page_t hval;
void * ptr;
while (n) {
p = BA_PAGE(a, n);
ptr = BA_LASTBLOCK(a, p);
hval = hash1(a, ptr);
|
335e6a | 2012-01-04 | Arne Goedeke | | fprintf(stderr, "%u\t%X[%d]\t%p-%p\t%X (page %d)\n", i, hval, hval & BA_HASH_MASK(a), p+1, ptr, (unsigned int)((uintptr_t)ptr >> a->magnitude), n);
|
e2499f | 2012-01-03 | Arne Goedeke | | n = p->hchain;
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
|
e2499f | 2012-01-03 | Arne Goedeke | | );
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
f2b3bd | 2011-12-31 | Arne Goedeke | | #endif
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_htable_insert(const struct block_allocator * a,
|
6fc6ce | 2011-12-30 | Arne Goedeke | | const void * ptr, const ba_page_t n) {
ba_page_t hval = hash1(a, ptr);
ba_page_t * b = a->htable + (hval & BA_HASH_MASK(a));
#ifdef BA_DEBUG
while (*b) {
if (*b == n) {
fprintf(stderr, "inserting (%p, %d) twice\n", ptr, n);
|
335e6a | 2012-01-04 | Arne Goedeke | | fprintf(stderr, "is (%p, %d)\n", BA_PAGE(a, n)+1, n);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | Pike_error("double insert.\n");
return;
}
b = &BA_PAGE(a, *b)->hchain;
}
b = a->htable + (hval & BA_HASH_MASK(a));
#endif
|
385483 | 2011-11-18 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
fprintf(stderr, "replacing bucket %u with page %u by %u\n",
hval & BA_HASH_MASK(a), *b, n);
#endif
|
385483 | 2011-11-18 | Arne Goedeke | | BA_PAGE(a, n)->hchain = *b;
*b = n;
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_htable_replace(const struct block_allocator * a,
|
6fc6ce | 2011-12-30 | Arne Goedeke | | const void * ptr, const ba_page_t n,
const ba_page_t new) {
ba_page_t hval = hash1(a, ptr);
ba_page_t * b = a->htable + (hval & BA_HASH_MASK(a));
|
385483 | 2011-11-18 | Arne Goedeke | |
while (*b) {
if (*b == n) {
*b = new;
BA_PAGE(a, new)->hchain = BA_PAGE(a, n)->hchain;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | BA_PAGE(a, n)->hchain = 0;
|
385483 | 2011-11-18 | Arne Goedeke | | return;
}
b = &BA_PAGE(a, *b)->hchain;
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef DEBUG
fprintf(stderr, "ba_htable_replace(%p, %u, %u)\n", ptr, n, new);
fprintf(stderr, "hval: %u, %u, %u\n", hval, hval & BA_HASH_MASK(a), BA_HASH_MASK(a));
ba_print_htable(a);
Pike_error("did not find index to replace.\n")
#endif
|
385483 | 2011-11-18 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE void ba_htable_delete(const struct block_allocator * a,
|
6fc6ce | 2011-12-30 | Arne Goedeke | | const void * ptr, const ba_page_t n) {
ba_page_t hval = hash1(a, ptr);
ba_page_t * b = a->htable + (hval & BA_HASH_MASK(a));
|
385483 | 2011-11-18 | Arne Goedeke | |
while (*b) {
if (*b == n) {
*b = BA_PAGE(a, n)->hchain;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | BA_PAGE(a, n)->hchain = 0;
|
385483 | 2011-11-18 | Arne Goedeke | | return;
}
b = &BA_PAGE(a, *b)->hchain;
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef DEBUG
|
e2499f | 2012-01-03 | Arne Goedeke | | ba_print_htable(a);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | fprintf(stderr, "ba_htable_delete(%p, %u)\n", ptr, n);
Pike_error("did not find index to delete.\n")
#endif
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | static INLINE ba_page_t ba_htable_lookup(const struct block_allocator * a,
|
6fc6ce | 2011-12-30 | Arne Goedeke | | const void * ptr) {
|
316eb4 | 2012-01-04 | Arne Goedeke | | #ifdef COUNT
count_name = "hash";
#endif
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
|
6fc6ce | 2011-12-30 | Arne Goedeke | | int c = 0;
|
e2499f | 2012-01-03 | Arne Goedeke | | #endif
ba_page_t n;
|
0a3d34 | 2011-11-10 | Arne Goedeke | | ba_page p;
|
e2499f | 2012-01-03 | Arne Goedeke | | n = a->htable[hash1(a, ptr) & BA_HASH_MASK(a)];
while (n) {
p = BA_PAGE(a, n);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | if (BA_CHECK_PTR(a, p, ptr)) {
|
316eb4 | 2012-01-04 | Arne Goedeke | | INC(good);
|
e2499f | 2012-01-03 | Arne Goedeke | | return n;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
|
e2499f | 2012-01-03 | Arne Goedeke | | n = p->hchain;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
|
e2499f | 2012-01-03 | Arne Goedeke | | n = a->htable[hash2(a, ptr) & BA_HASH_MASK(a)];
while (n) {
p = BA_PAGE(a, n);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | if (BA_CHECK_PTR(a, p, ptr)) {
|
316eb4 | 2012-01-04 | Arne Goedeke | | if (a->htable[hash1(a, ptr) & BA_HASH_MASK(a)])
INC(ugly);
else INC(bad);
|
e2499f | 2012-01-03 | Arne Goedeke | | return n;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
if (c++ > a->allocated) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | Pike_error("hash chain is infinite\n");
}
|
e2499f | 2012-01-03 | Arne Goedeke | | #endif
n = p->hchain;
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | return 0;
}
|
67795d | 2011-11-11 | Arne Goedeke | |
|
f2b3bd | 2011-12-31 | Arne Goedeke | | #ifdef BA_DEBUG
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_check_allocator(struct block_allocator * a,
|
6fc6ce | 2011-12-30 | Arne Goedeke | | char *fun, char *file, int line) {
unsigned int i = 0;
int bad = 0;
|
67795d | 2011-11-11 | Arne Goedeke | | ba_page p;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | if (a->empty_pages > a->num_pages) {
fprintf(stderr, "too many empty pages.\n");
bad = 1;
}
for (i = 1; i <= a->num_pages; i++) {
ba_page_t hval;
int found = 0;
ba_page_t n;
p = BA_PAGE(a, i);
if (p->blocks_used == a->blocks) {
if (p->prev || p->next) {
|
335e6a | 2012-01-04 | Arne Goedeke | | BA_ERROR("block is full but in list. next: %p prev: %p\n",
|
6fc6ce | 2011-12-30 | Arne Goedeke | | p->next, p->prev);
bad = 1;
|
67795d | 2011-11-11 | Arne Goedeke | | }
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
IF_HASH(
hval = hash1(a, BA_LASTBLOCK(a, p));
n = a->htable[hval & BA_HASH_MASK(a)];
while (n) {
if (n == i) {
found = 1;
break;
}
n = BA_PAGE(a, n)->hchain;
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
if (!found) {
fprintf(stderr, "did not find page %d, %p (%u) in htable.\n",
i, BA_LASTBLOCK(a, BA_PAGE(a, i)), hval);
fprintf(stderr, "looking in bucket %u mask: %d\n", hval & BA_HASH_MASK(a), BA_HASH_MASK(a));
bad = 1;
}
for (i = 0; i < a->allocated; i++) {
n = a->htable[i];
while (n) {
p = BA_PAGE(a, n);
hval = hash1(a, BA_LASTBLOCK(a, p));
if (i != (hval & BA_HASH_MASK(a))) {
fprintf(stderr, "page %u found in wrong bucket %d\n",
n, i);
bad = 1;
}
n = p->hchain;
}
}
);
}
if (bad) {
ba_print_htable(a);
fprintf(stderr, "\nCalled from %s:%d:%s\n", fun, line, file);
fprintf(stderr, "pages: %u\n", a->num_pages);
Pike_error("bad");
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
}
|
f2b3bd | 2011-12-31 | Arne Goedeke | | #endif
|
a5e1b8 | 2011-11-09 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void * ba_low_alloc(struct block_allocator * a) {
|
e90c49 | 2011-11-27 | Arne Goedeke | |
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | ba_page p;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef BA_DEBUG
ba_check_allocator(a, "ba_alloc top", __FILE__, __LINE__);
#endif
|
e2499f | 2012-01-03 | Arne Goedeke | | unsigned int i;
|
d2892b | 2011-12-25 | Arne Goedeke | |
|
e90c49 | 2011-11-27 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | if (unlikely(a->num_pages == a->allocated)) {
|
385483 | 2011-11-18 | Arne Goedeke | | ba_grow(a);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
#ifdef BA_DEBUG
ba_check_allocator(a, "ba_alloc after grow", __FILE__, __LINE__);
#endif
|
385483 | 2011-11-18 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | a->num_pages++;
#ifdef BA_DEBUG
|
335e6a | 2012-01-04 | Arne Goedeke | | if (BA_PAGE(a, a->num_pages)) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | void * new = malloc(BA_PAGESIZE(a));
fprintf(stderr, "reusing unfreed page %d, data: %p -> %p\n", a->num_pages,
|
335e6a | 2012-01-04 | Arne Goedeke | | p+1, new);
|
e2499f | 2012-01-03 | Arne Goedeke | | a->num_pages--;
ba_show_pages(a);
a->num_pages++;
|
335e6a | 2012-01-04 | Arne Goedeke | | BA_PAGE(a, a->num_pages) = p = new;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | } else
#endif
|
335e6a | 2012-01-04 | Arne Goedeke | | BA_PAGE(a, a->num_pages) = p = (ba_page)malloc(sizeof(struct ba_page) + BA_PAGESIZE(a));
if (!p) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | Pike_error("no mem. alloc returned zero.");
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
335e6a | 2012-01-04 | Arne Goedeke | | p->next = p->prev = NULL;
|
e2499f | 2012-01-03 | Arne Goedeke | | a->first = p;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | 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
);
|
385483 | 2011-11-18 | Arne Goedeke | | p->blocks_used = 1;
|
f2b3bd | 2011-12-31 | Arne Goedeke | | p->first = BA_BLOCKN(a, p, 1);
|
0639aa | 2012-01-04 | Arne Goedeke | |
for (i = 1; i+1 < a->blocks; i++) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef BA_DEBUG
|
e2499f | 2012-01-03 | Arne Goedeke | | PIKE_MEM_RW(BA_BLOCKN(a, p, i)->magic);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | BA_BLOCKN(a, p, i)->magic = BA_MARK_FREE;
#endif
|
0639aa | 2012-01-04 | Arne Goedeke | | BA_BLOCKN(a, p, i)->next = BA_BLOCKN(a, p, i+1);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
|
f2b3bd | 2011-12-31 | Arne Goedeke | | BA_LASTBLOCK(a, p)->next = NULL;
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
#ifdef BA_DEBUG
|
e2499f | 2012-01-03 | Arne Goedeke | | PIKE_MEM_RW(BA_LASTBLOCK(a, p)->magic);
|
f2b3bd | 2011-12-31 | Arne Goedeke | | BA_LASTBLOCK(a, p)->magic = BA_MARK_FREE;
|
e2499f | 2012-01-03 | Arne Goedeke | | PIKE_MEM_RW(BA_BLOCKN(a, p, 0)->magic);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | BA_BLOCKN(a, p, 0)->magic = BA_MARK_ALLOC;
ba_check_allocator(a, "ba_alloc after insert", __FILE__, __LINE__);
|
385483 | 2011-11-18 | Arne Goedeke | | #endif
|
335e6a | 2012-01-04 | Arne Goedeke | | return BA_BLOCKN(a, p, 0);
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_low_free(struct block_allocator * a,
|
335e6a | 2012-01-04 | Arne Goedeke | | void * ptr, ba_page p, ba_page_t n) {
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
ba_check_allocator(a, "ba_low_free", __FILE__, __LINE__);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #endif
|
e2499f | 2012-01-03 | Arne Goedeke | | if (!p) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef BA_HASH_THLD
|
e2499f | 2012-01-03 | Arne Goedeke | | if (a->allocated <= BA_HASH_THLD)
BA_ERROR("ba_low_free(.., %p) should never be called: %d, %d\n",
ptr, a->allocated, BA_HASH_THLD);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #endif
|
335e6a | 2012-01-04 | Arne Goedeke | | n = ba_htable_lookup(a, ptr);
|
e2499f | 2012-01-03 | Arne Goedeke | | if (n) {
a->last_free = p = BA_PAGE(a, n);
|
335e6a | 2012-01-04 | Arne Goedeke | | a->last_free_num = n;
|
e2499f | 2012-01-03 | Arne Goedeke | | } else {
|
d2892b | 2011-12-25 | Arne Goedeke | | #ifdef BA_DEBUG
|
e2499f | 2012-01-03 | Arne Goedeke | | fprintf(stderr, "magnitude: %u\n", a->magnitude);
fprintf(stderr, "allocated: %u\n", a->allocated);
fprintf(stderr, "did not find %p (%X[%X] | %X[%X])\n", ptr,
hash1(a, ptr), hash1(a, ptr) & BA_HASH_MASK(a),
hash2(a, ptr), hash2(a, ptr) & BA_HASH_MASK(a)
);
ba_print_htable(a);
|
d2892b | 2011-12-25 | Arne Goedeke | | #endif
|
e2499f | 2012-01-03 | Arne Goedeke | | BA_ERROR("Unknown pointer (not found in hash) %p\n", ptr);
}
}
if (p->blocks_used == a->blocks) {
|
335e6a | 2012-01-04 | Arne Goedeke | | if (a->first) {
a->first->prev = p;
|
e2499f | 2012-01-03 | Arne Goedeke | | }
|
335e6a | 2012-01-04 | Arne Goedeke | | p->next = a->first;
p->prev = NULL;
|
e2499f | 2012-01-03 | Arne Goedeke | | a->first = p;
p->first = NULL;
} else if (p->blocks_used == 1 && a->empty_pages > a->max_empty_pages) {
a->empty_pages--;
|
335e6a | 2012-01-04 | Arne Goedeke | | ba_remove_page(a, n);
|
e2499f | 2012-01-03 | Arne Goedeke | | return;
|
67795d | 2011-11-11 | Arne Goedeke | | }
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef BA_DEBUG
|
e2499f | 2012-01-03 | Arne Goedeke | | if ((int)p->blocks_used <= 0) {
fprintf(stderr, "MEGAFAIL in page %u at %p: %d %u\n",
1 + (a->pages - p),
p,
p->blocks_used,
p->blocks_used);
ba_show_pages(a);
|
6fc6ce | 2011-12-30 | Arne Goedeke | | }
|
385483 | 2011-11-18 | Arne Goedeke | | #endif
|
e2499f | 2012-01-03 | Arne Goedeke | | p->blocks_used --;
#ifdef BA_DEBUG
if (((ba_block_header)ptr)->magic == BA_MARK_FREE) {
fprintf(stderr, "double freed somethign\n");
}
((ba_block_header)ptr)->magic = BA_MARK_FREE;
#endif
((ba_block_header)ptr)->next = p->first;
p->first = ptr;
|
385483 | 2011-11-18 | Arne Goedeke | | }
|
f2b3bd | 2011-12-31 | Arne Goedeke | |
|
c8b590 | 2012-01-04 | Arne Goedeke | | PMOD_EXPORT INLINE void ba_remove_page(struct block_allocator * a,
|
e2499f | 2012-01-03 | Arne Goedeke | | ba_page_t n) {
|
385483 | 2011-11-18 | Arne Goedeke | | ba_page tmp, p;
|
6fc6ce | 2011-12-30 | Arne Goedeke | | #ifdef BA_DEBUG
ba_check_allocator(a, "ba_remove_page", __FILE__, __LINE__);
if (a->empty_pages < a->max_empty_pages) {
Pike_error("strange things happening\n");
}
#endif
|
385483 | 2011-11-18 | Arne Goedeke | |
p = BA_PAGE(a, n);
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
fprintf(stderr, "> ===============\n");
ba_show_pages(a);
ba_print_htable(a);
fprintf(stderr, "removing page %4u[%p]\t(%p .. %p) -> %X (%X) (of %u).\n", n, p,
|
335e6a | 2012-01-04 | Arne Goedeke | | p+1, BA_LASTBLOCK(a, p), hash1(a, BA_LASTBLOCK(a,p)),
|
385483 | 2011-11-18 | Arne Goedeke | | hash1(a, BA_LASTBLOCK(a,p)) & BA_HASH_MASK(a),
a->num_pages);
|
e2499f | 2012-01-03 | Arne Goedeke | | #endif
|
385483 | 2011-11-18 | Arne Goedeke | |
|
6fc6ce | 2011-12-30 | Arne Goedeke | | IF_HASH(
ba_htable_delete(a, BA_LASTBLOCK(a, p), n);
);
|
335e6a | 2012-01-04 | Arne Goedeke | | PIKE_MEM_RW_RANGE(*p, BA_PAGESIZE(a));
|
385483 | 2011-11-18 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | if (a->last_free == p)
a->last_free = NULL;
|
385483 | 2011-11-18 | Arne Goedeke | |
if (p->prev) {
|
335e6a | 2012-01-04 | Arne Goedeke | | p->prev->next = p->next;
|
385483 | 2011-11-18 | Arne Goedeke | | } else {
|
e2499f | 2012-01-03 | Arne Goedeke | | if (p->next) {
|
335e6a | 2012-01-04 | Arne Goedeke | | a->first = p->next;
a->first->prev = NULL;
|
e2499f | 2012-01-03 | Arne Goedeke | | } else a->first = NULL;
|
385483 | 2011-11-18 | Arne Goedeke | | }
if (p->next) {
|
335e6a | 2012-01-04 | Arne Goedeke | | p->next->prev = p->prev;
|
385483 | 2011-11-18 | Arne Goedeke | | }
|
de2d07 | 2011-12-25 | Arne Goedeke | | if (a->num_pages != n) {
tmp = BA_PAGE(a, a->num_pages);
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
fprintf(stderr, "removing last from htable\n");
#endif
|
6fc6ce | 2011-12-30 | Arne Goedeke | | IF_HASH(
ba_htable_delete(a, BA_LASTBLOCK(a, tmp), a->num_pages);
);
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
ba_print_htable(a);
fprintf(stderr, "fooo\n");
fprintf(stderr, "replacing with page %4u[%p]\t(%p .. %p) -> %X (%X) (of %u).\n", a->num_pages, tmp,
tmp->data, BA_LASTBLOCK(a, tmp), hash1(a, BA_LASTBLOCK(a,tmp)),
hash1(a, BA_LASTBLOCK(a,tmp)) & BA_HASH_MASK(a),
a->num_pages);
|
de2d07 | 2011-12-25 | Arne Goedeke | |
|
e2499f | 2012-01-03 | Arne Goedeke | | #endif
|
335e6a | 2012-01-04 | Arne Goedeke | | BA_PAGE(a, n) = BA_PAGE(a, a->num_pages);
if (tmp == a->last_free) {
a->last_free_num = n;
}
|
6fc6ce | 2011-12-30 | Arne Goedeke | | IF_HASH(
ba_htable_insert(a, BA_LASTBLOCK(a, tmp), n);
);
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
ba_print_htable(a);
fprintf(stderr, "fooo\n");
#endif
|
de2d07 | 2011-12-25 | Arne Goedeke | | }
|
d2892b | 2011-12-25 | Arne Goedeke | | #ifdef BA_DEBUG
|
e2499f | 2012-01-03 | Arne Goedeke | | memset(BA_PAGE(a, a->num_pages), 0, sizeof(struct ba_page));
if (a->first == BA_PAGE(a, a->num_pages)) {
|
d2892b | 2011-12-25 | Arne Goedeke | | fprintf(stderr, "a->first will be old removed page %d\n", a->first);
|
335e6a | 2012-01-04 | Arne Goedeke | | fprintf(stderr, "page %d was not moved and prev was %p\n", n, p->prev);
|
d2892b | 2011-12-25 | Arne Goedeke | | }
#endif
|
385483 | 2011-11-18 | Arne Goedeke | | a->num_pages--;
|
335e6a | 2012-01-04 | Arne Goedeke | | free(p);
|
6fc6ce | 2011-12-30 | Arne Goedeke | |
#ifdef BA_DEBUG
ba_check_allocator(a, "ba_remove_page", __FILE__, __LINE__);
#endif
|
e2499f | 2012-01-03 | Arne Goedeke | | if (a->allocated > BA_ALLOC_INITIAL && a->num_pages <= (a->allocated >> 2)) {
|
6fc6ce | 2011-12-30 | Arne Goedeke | | ba_shrink(a);
}
|
e2499f | 2012-01-03 | Arne Goedeke | | #ifdef BA_DEBUG
ba_show_pages(a);
ba_print_htable(a);
fprintf(stderr, "< =================\n");
#endif
|
a5e1b8 | 2011-11-09 | Arne Goedeke | | }
|