diff --git a/config.h b/config.h index 3258aa3..4a4212b 100644 --- a/config.h +++ b/config.h @@ -9,7 +9,8 @@ #define SLAB_CANARY true #define GUARD_SLABS_INTERVAL 1 #define GUARD_SIZE_DIVISOR 2 -#define REGION_QUARANTINE_SIZE 1024 +#define REGION_QUARANTINE_RANDOM_SIZE 128 +#define REGION_QUARANTINE_QUEUE_SIZE 1024 #define REGION_QUARANTINE_SKIP_THRESHOLD (32 * 1024 * 1024) #endif diff --git a/malloc.c b/malloc.c index 8fcbc3f..e478349 100644 --- a/malloc.c +++ b/malloc.c @@ -527,7 +527,8 @@ static struct region_info *regions; static size_t regions_total = INITIAL_REGION_TABLE_SIZE; static size_t regions_free = INITIAL_REGION_TABLE_SIZE; static struct mutex regions_lock = MUTEX_INITIALIZER; -static struct quarantine_info regions_quarantine[REGION_QUARANTINE_SIZE]; +static struct quarantine_info regions_quarantine_random[REGION_QUARANTINE_RANDOM_SIZE]; +static struct quarantine_info regions_quarantine_queue[REGION_QUARANTINE_QUEUE_SIZE]; static size_t regions_quarantine_index; static void regions_quarantine_deallocate_pages(void *p, size_t size, size_t guard_size) { @@ -541,13 +542,27 @@ static void regions_quarantine_deallocate_pages(void *p, size_t size, size_t gua return; } - struct quarantine_info old = regions_quarantine[regions_quarantine_index]; - if (old.p != NULL) { - memory_unmap(old.p, old.size); - } - regions_quarantine[regions_quarantine_index] = + struct quarantine_info a = (struct quarantine_info){(char *)p - guard_size, size + guard_size * 2}; - regions_quarantine_index = (regions_quarantine_index + 1) % REGION_QUARANTINE_SIZE; + + mutex_lock(®ions_lock); + + size_t index = get_random_u64_uniform(®ions_rng, REGION_QUARANTINE_RANDOM_SIZE); + struct quarantine_info b = regions_quarantine_random[index]; + regions_quarantine_random[index] = a; + if (b.p == NULL) { + mutex_unlock(®ions_lock); + return; + } + + a = regions_quarantine_queue[regions_quarantine_index]; + if (a.p != NULL) { + memory_unmap(a.p, a.size); + } + regions_quarantine_queue[regions_quarantine_index] = b; + regions_quarantine_index = (regions_quarantine_index + 1) % REGION_QUARANTINE_QUEUE_SIZE; + + mutex_unlock(®ions_lock); } static size_t hash_page(void *p) {