diff options
author | Robert Hensing <robert@roberthensing.nl> | 2021-06-24 18:02:51 +0200 |
---|---|---|
committer | Robert Hensing <robert@roberthensing.nl> | 2021-06-24 18:17:03 +0200 |
commit | 57409244ec8f568ce6b4ecb1bde0e509942ac05f (patch) | |
tree | 33ef78c2d7e918c2387a8e013a91cfa5a25d4776 /boehmgc-coroutine-sp-fallback.diff | |
parent | bec83a6f953ab045e85d50b0cab9de176cd00bc0 (diff) |
boehmgc: Crude support for coroutines
Fixes the problem where a stack pointer outside the original
thread causes the collector to crash.
It could be made more accurate by recording the stack pointer
every time we switch to a coroutine. We can use this information
to update our own coroutine stacks like normal data. When the
stack pointer is on a thread, we can add a field to GC_thread
"fallback_sp" to be used when the thread sp is outside the original
thread range.
Diffstat (limited to 'boehmgc-coroutine-sp-fallback.diff')
-rw-r--r-- | boehmgc-coroutine-sp-fallback.diff | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/boehmgc-coroutine-sp-fallback.diff b/boehmgc-coroutine-sp-fallback.diff new file mode 100644 index 000000000..c618718a7 --- /dev/null +++ b/boehmgc-coroutine-sp-fallback.diff @@ -0,0 +1,44 @@ +diff --git a/pthread_stop_world.c b/pthread_stop_world.c +index 1cee6a0b..8977b0dd 100644 +--- a/pthread_stop_world.c ++++ b/pthread_stop_world.c +@@ -674,6 +674,8 @@ GC_INNER void GC_push_all_stacks(void) + struct GC_traced_stack_sect_s *traced_stack_sect; + pthread_t self = pthread_self(); + word total_size = 0; ++ size_t stack_limit; ++ pthread_attr_t pattr; + + if (!EXPECT(GC_thr_initialized, TRUE)) + GC_thr_init(); +@@ -723,6 +725,30 @@ GC_INNER void GC_push_all_stacks(void) + hi = p->altstack + p->altstack_size; + /* FIXME: Need to scan the normal stack too, but how ? */ + /* FIXME: Assume stack grows down */ ++ } else { ++ if (pthread_getattr_np(p->id, &pattr)) { ++ ABORT("GC_push_all_stacks: pthread_getattr_np failed!"); ++ } ++ if (pthread_attr_getstacksize(&pattr, &stack_limit)) { ++ ABORT("GC_push_all_stacks: pthread_attr_getstacksize failed!"); ++ } ++ // When a thread goes into a coroutine, we lose its original sp until ++ // control flow returns to the thread. ++ // While in the coroutine, the sp points outside the thread stack, ++ // so we can detect this and push the entire thread stack instead, ++ // as an approximation. ++ // We assume that the coroutine has similarly added its entire stack. ++ // This could be made accurate by cooperating with the application ++ // via new functions and/or callbacks. ++ #ifndef STACK_GROWS_UP ++ if (lo >= hi || lo < hi - stack_limit) { // sp outside stack ++ lo = hi - stack_limit; ++ } ++ #else ++ if (lo < hi || lo >= hi + stack_limit) { // sp outside stack ++ lo = hi + stack_limit; ++ } ++ #endif + } + GC_push_all_stack_sections(lo, hi, traced_stack_sect); + # ifdef STACK_GROWS_UP |