Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alloc with MMAP #138

Merged
merged 1 commit into from
Nov 23, 2020
Merged

Alloc with MMAP #138

merged 1 commit into from
Nov 23, 2020

Conversation

accelerated
Copy link
Contributor

Describe your changes

  • Use MMAP instead of heap for coroutine allocations
  • Moved header block at the end of the stack

The motivation behind using mmap() on Linux (and the equivalent feature on Windows - not yet supported) is to allow for immediate memory reclaiming of the coroutine stack (quite large). If heap allocations are used, although the allocated memory is freed, the dynamic memory management algorithm will not return immediately these blocks to the system as they may be reused at a later date (for obvious performance reasons). If the system is very busy, these blocks may become fragmented and new coroutine stack allocations will again require further expansion from system memory (via sbrk() or mmap()) as large contiguous areas won't be necessarily available. The result is that the application's RSS keeps increasing even through all coroutines may have finished processing.

mmap() is just as fast as a call to new() without the drawbacks of memory leakage. An alternative to using mmap() is to tinker with mallopt() M_MMAP_THRESHOLD and M_TRIM_THRESHOLD but it's not as reliable as mmap(). Furthermore, with mmap() we can now protect the lowest page of the coroutine stack (only for pre-allocated blocks) so that we may catch any stack overflows. These overflows are hard to debug and fail in very different (often confusing) ways.
One reason for not pre-allocating one, single large contiguous block for all pre-allocated coroutines (rather than piece-meal) is to prevent trampling from one stack to another. Even with page protection, a function may somehow write beyond the 4096 byte range of protection and hit the next stack. This is easily reproducible.

Testing performed
Ran entire test suite. Any coroutine allocation issues are sure to fail immediately.

Signed-off-by: Alexander Damian adamian@bloomberg.net

- Use MMAP instead of heap for coroutine allocations
- Moved header block at the end of the stack

Signed-off-by: Alexander Damian <adamian@bloomberg.net>
Copy link
Contributor

@arosenzweig3 arosenzweig3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@accelerated accelerated merged commit 92a4a06 into bloomberg:master Nov 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants