summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Williams <[email protected]>2023-05-25 11:17:49 +0900
committer<[email protected]>2023-05-25 11:17:49 +0900
commit492e0025fd1221681beafe28f1947b4dd1aefd9a ()
treefc9fa1d7b41d1d1c8763d5b6bbf86dee309fe7e6
parent31b28b31fa5a0452cb9d5f7eee88eebfebe5b4d1 (diff)
Allow environment variable to control madvise advice. (#7855)
Introduce experimental support for explicitly specifying the `advice` value provided to `madvise` when releasing the fiber stack.
Notes: Merged-By: ioquatix <[email protected]>
-rw-r--r--cont.c38
1 files changed, 28 insertions, 10 deletions
@@ -179,7 +179,7 @@ struct fiber_pool {
// A singly-linked list of allocations which contain 1 or more stacks each.
struct fiber_pool_allocation * allocations;
- // Provides O(1) stack "allocation":
struct fiber_pool_vacancy * vacancies;
// The size of the stack allocations (excluding any guard page).
@@ -191,13 +191,15 @@ 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;
- // The amount to allocate for the vm_stack:
size_t vm_stack_size;
};
@@ -695,7 +697,9 @@ fiber_pool_stack_free(struct fiber_pool_stack * stack)
// If this is not true, the vacancy information will almost certainly be destroyed:
VM_ASSERT(size <= (stack->size - RB_PAGE_SIZE));
- if (DEBUG) fprintf(stderr, "fiber_pool_stack_free: %p+%"PRIuSIZE" [base=%p, size=%"PRIuSIZE"]\n", base, size, stack->base, stack->size);
// The pages being used by the stack can be returned back to the system.
// That doesn't change the page mapping, but it does allow the system to
@@ -709,24 +713,29 @@ fiber_pool_stack_free(struct fiber_pool_stack * stack)
#ifdef __wasi__
// WebAssembly doesn't support madvise, so we just don't do anything.
#elif VM_CHECK_MODE > 0 && defined(MADV_DONTNEED)
// This immediately discards the pages and the memory is reset to zero.
- madvise(base, size, MADV_DONTNEED);
#elif defined(MADV_FREE_REUSABLE)
// Darwin / macOS / iOS.
// Acknowledge the kernel down to the task info api we make this
// page reusable for future use.
- // As for MADV_FREE_REUSE below we ensure in the rare occasions the task was not
// completed at the time of the call to re-iterate.
- while (madvise(base, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN);
#elif defined(MADV_FREE)
// Recent Linux.
- madvise(base, size, MADV_FREE);
#elif defined(MADV_DONTNEED)
// Old Linux.
- madvise(base, size, MADV_DONTNEED);
#elif defined(POSIX_MADV_DONTNEED)
// Solaris?
- posix_madvise(base, size, POSIX_MADV_DONTNEED);
#elif defined(_WIN32)
VirtualAlloc(base, size, MEM_RESET, PAGE_READWRITE);
// Not available in all versions of Windows.
@@ -3439,6 +3448,15 @@ Init_Cont(void)
const char *fiber_shared_fiber_pool_free_stacks = getenv("RUBY_SHARED_FIBER_POOL_FREE_STACKS");
if (fiber_shared_fiber_pool_free_stacks) {
shared_fiber_pool.free_stacks = atoi(fiber_shared_fiber_pool_free_stacks);
}
rb_cFiber = rb_define_class("Fiber", rb_cObject);