void slab_arena_destroy(struct slab_arena *arena) { void *ptr; size_t total = 0; while ((ptr = lf_lifo_pop(&arena->cache))) { if (arena->arena == NULL || ptr < arena->arena || ptr >= arena->arena + arena->prealloc) { munmap_checked(ptr, arena->slab_size); } total += arena->slab_size; } if (arena->arena) munmap_checked(arena->arena, arena->prealloc); assert(total == arena->used); }
int main() { struct lf_lifo head; void *val1 = mmap_aligned(MAP_SIZE); void *val2 = mmap_aligned(MAP_SIZE); void *val3 = mmap_aligned(MAP_SIZE); lf_lifo_init(&head); fail_unless(lf_lifo_pop(&head) == NULL); fail_unless(lf_lifo_pop(lf_lifo_push(&head, val1)) == val1); fail_unless(lf_lifo_pop(lf_lifo_push(&head, val1)) == val1); lf_lifo_push(lf_lifo_push(lf_lifo_push(&head, val1), val2), val3); fail_unless(lf_lifo_pop(&head) == val3); fail_unless(lf_lifo_pop(&head) == val2); fail_unless(lf_lifo_pop(&head) == val1); fail_unless(lf_lifo_pop(&head) == NULL); lf_lifo_init(&head); /* Test overflow of ABA counter. */ int i = 0; do { lf_lifo_push(&head, val1); fail_unless(lf_lifo_pop(&head) == val1); fail_unless(lf_lifo_pop(&head) == NULL); i++; } while (head.next != 0); munmap(val1, MAP_SIZE); munmap(val2, MAP_SIZE); munmap(val3, MAP_SIZE); printf("success\n"); return 0; }
void * slab_map(struct slab_arena *arena) { void *ptr; if ((ptr = lf_lifo_pop(&arena->cache))) return ptr; /** Need to allocate a new slab. */ size_t used = __sync_add_and_fetch(&arena->used, arena->slab_size); if (used <= arena->prealloc) return arena->arena + used - arena->slab_size; if (used > arena->maxalloc) { __sync_sub_and_fetch(&arena->used, arena->slab_size); return NULL; } return mmap_checked(arena->slab_size, arena->slab_size, arena->flags); }
void * slab_map(struct slab_arena *arena) { void *ptr; if ((ptr = lf_lifo_pop(&arena->cache))) return ptr; if (quota_use(arena->quota, arena->slab_size) < 0) return NULL; /** Need to allocate a new slab. */ size_t used = __sync_add_and_fetch(&arena->used, arena->slab_size); if (used <= arena->prealloc) return arena->arena + used - arena->slab_size; ptr = mmap_checked(arena->slab_size, arena->slab_size, arena->flags); if (!ptr) { __sync_sub_and_fetch(&arena->used, arena->slab_size); quota_release(arena->quota, arena->slab_size); } return ptr; }