randomize slab slot choice

pull/50/head
Daniel Micay 2018-08-25 03:02:39 -04:00
parent 965c3202b4
commit f08d4d31db
1 changed files with 20 additions and 4 deletions

View File

@ -248,19 +248,35 @@ static bool get_slot(struct slab_metadata *metadata, size_t index) {
} }
static uint64_t get_mask(size_t slots) { static uint64_t get_mask(size_t slots) {
if (slots > 64) return 0; // TODO: implement multi-word bitmaps
return slots < 64 ? ~0UL << slots : 0; return slots < 64 ? ~0UL << slots : 0;
} }
static size_t first_free_slot(size_t slots, struct slab_metadata *metadata) { static size_t get_free_slot(struct random_state *rng, size_t slots, struct slab_metadata *metadata) {
if (slots > 64) {
slots = 64;
}
uint64_t masked = metadata->bitmap | get_mask(slots); uint64_t masked = metadata->bitmap | get_mask(slots);
if (masked == ~0UL) { if (masked == ~0UL) {
fatal_error("no zero bits"); fatal_error("no zero bits");
} }
// randomize start location for linear search (uniform random choice is too slow)
uint64_t random_split = ~0UL >> get_random_size_uniform(rng, slots);
size_t slot = __builtin_ffsl(~(masked | random_split));
if (slot) {
return slot - 1;
} else {
return __builtin_ffsl(~masked) - 1; return __builtin_ffsl(~masked) - 1;
} }
}
static bool has_free_slots(size_t slots, struct slab_metadata *metadata) { static bool has_free_slots(size_t slots, struct slab_metadata *metadata) {
if (slots > 64) {
slots = 64;
}
uint64_t masked = metadata->bitmap | get_mask(slots); uint64_t masked = metadata->bitmap | get_mask(slots);
return masked != ~0UL; return masked != ~0UL;
} }
@ -348,7 +364,7 @@ static void *slab_allocate(size_t requested_size) {
} }
struct slab_metadata *metadata = c->partial_slabs; struct slab_metadata *metadata = c->partial_slabs;
size_t slot = first_free_slot(slots, metadata); size_t slot = get_free_slot(&c->rng, slots, metadata);
set_slot(metadata, slot); set_slot(metadata, slot);
if (!has_free_slots(slots, metadata)) { if (!has_free_slots(slots, metadata)) {