randomize slab slot choice
parent
965c3202b4
commit
f08d4d31db
22
malloc.c
22
malloc.c
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue