int slab_arena_create(struct slab_arena *arena, struct quota *quota, size_t prealloc, uint32_t slab_size, int flags) { assert(flags & (MAP_PRIVATE | MAP_SHARED)); lf_lifo_init(&arena->cache); /* * Round up the user supplied data - it can come in * directly from the configuration file. Allow * zero-size arena for testing purposes. */ arena->slab_size = small_round(MAX(slab_size, SLAB_MIN_SIZE)); arena->quota = quota; /** Prealloc can not be greater than the quota */ prealloc = MIN(prealloc, quota_total(quota)); /** Extremely large sizes can not be aligned properly */ prealloc = MIN(prealloc, SIZE_MAX - arena->slab_size); /* Align prealloc around a fixed number of slabs. */ arena->prealloc = small_align(prealloc, arena->slab_size); arena->used = 0; arena->flags = flags; if (arena->prealloc) { arena->arena = mmap_checked(arena->prealloc, arena->slab_size, arena->flags); } else { arena->arena = NULL; } return arena->prealloc && !arena->arena ? -1 : 0; }
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; }
int slab_arena_create(struct slab_arena *arena, size_t prealloc, size_t maxalloc, uint32_t slab_size, int flags) { assert(flags & (MAP_PRIVATE | MAP_SHARED)); lf_lifo_init(&arena->cache); /* * Round up the user supplied data - it can come in * directly from the configuration file. Allow * zero-size arena for testing purposes. */ arena->slab_size = small_round(MAX(slab_size, SLAB_MIN_SIZE)); if (maxalloc) { arena->maxalloc = small_round(MAX(maxalloc, arena->slab_size)); } else { arena->maxalloc = 0; } /* Align arena around a fixed number of slabs. */ arena->prealloc = small_align(small_round(prealloc), arena->slab_size); if (arena->maxalloc < arena->prealloc) arena->prealloc = arena->maxalloc; arena->used = 0; arena->flags = flags; if (arena->prealloc) { arena->arena = mmap_checked(arena->prealloc, arena->slab_size, arena->flags); } else { arena->arena = NULL; } return arena->prealloc && !arena->arena ? -1 : 0; }