Add `struct fiber_pool {int free_stacks;}` to control usage of madvise.

`madvise(free)` and similar operations are good because they avoid swap
usage by clearing the dirty bit on memory pages which are mapped but no
longer needed. However, there is some performance penalty if there is no
memory pressure. Therefore, we do it by default, but it can be avoided.
This commit is contained in:
Samuel Williams 2019-07-16 16:00:35 +12:00
Родитель 4d60a5820a
Коммит 385ea910fc
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: A0765423A44728FB
1 изменённых файлов: 10 добавлений и 1 удалений

11
cont.c
Просмотреть файл

@ -157,6 +157,9 @@ struct fiber_pool {
// The initial number of stacks to allocate.
size_t initial_count;
// Whether to madvise(free) the stack or not:
int free_stacks;
// The number of stacks that have been used in this pool.
size_t used;
@ -479,6 +482,7 @@ fiber_pool_initialize(struct fiber_pool * fiber_pool, size_t size, size_t count,
fiber_pool->size = ((size / RB_PAGE_SIZE) + 1) * RB_PAGE_SIZE;
fiber_pool->count = 0;
fiber_pool->initial_count = count;
fiber_pool->free_stacks = 1;
fiber_pool->used = 0;
fiber_pool->vm_stack_size = vm_stack_size;
@ -612,7 +616,12 @@ fiber_pool_stack_release(struct fiber_pool_stack * stack) {
// Release address space and/or dirty memory:
if (stack->allocation->used == 0) {
fiber_pool_allocation_free(stack->allocation);
} else {
} else if (stack->pool->free_stacks) {
fiber_pool_stack_free(stack);
}
#else
// This is entirely optional, but clears the dirty flag from the stack memory, so it won't get swapped to disk when there is memory pressure:
if (stack->pool->free_stacks) {
fiber_pool_stack_free(stack);
}
#endif