aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2019-07-16 16:00:35 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2019-07-18 20:54:55 +1200
commit385ea910fc28f0e46c72669a260e44d4f3f37d9e (patch)
tree7e37ba55d0be202d2ff6b2c14be2ab5818027f6a
parent4d60a5820ae2c7bc2ce5bee441b834129a3a56e1 (diff)
downloadruby-385ea910fc28f0e46c72669a260e44d4f3f37d9e.tar.gz
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.
-rw-r--r--cont.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/cont.c b/cont.c
index 938db70122..16e8d7c33d 100644
--- a/cont.c
+++ b/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