Hello. After enabling -fsplit-stack, dynamic stack expansion of the coroutine is realized, but calling functions without -fsplit-stack will directly expand the space by 1M, which is too wasteful for a system with a large number of coroutines running under the 128K stack size. We hope to give users more control over the size of stack expansion to adapt to more complex scenarios.
Apply for more space each time the stack is expanded, which can also reduce the frequency of morestack being called. When calling the non-split function, we do not need additional checks and apply for 1M space. At this time, we can turn off the conversion of linker to __morestack_non_split. This is more friendly to a large number of small stack coroutines running below 128K. Later we need to add an option to the gold linker to turn off the __morestack_non_split conversion. Looking forward to your reply. Thanks, Rain libgcc/ChangeLog: * libgcc/generic-morestack.c (__extra_stack_size): New thread local variable. * libgcc/generic-morestack.c (__splitstack_set_extra_stack_size): New function. --- libgcc/generic-morestack.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c index acada4038a6..b22ba129b36 100644 --- a/libgcc/generic-morestack.c +++ b/libgcc/generic-morestack.c @@ -193,6 +193,10 @@ __splitstack_find_context (void *context[10], size_t *, void **, void **, void **) __attribute__ ((visibility ("default"))); +extern void +__splitstack_set_extra_stack_size (size_t) + __attribute__ ((visibility ("default"))); + /* These functions must be defined by the processor specific code. */ extern void *__morestack_get_guard (void) @@ -297,6 +301,10 @@ __thread struct stack_segment *__morestack_current_segment __thread struct initial_sp __morestack_initial_sp __attribute__ ((visibility ("default"))); +/* The extra stack space to avoid call morestack frequently, default 0. */ + +__thread size_t __extra_stack_size; + /* A static signal mask, to avoid taking up stack space. */ static sigset_t __morestack_fullmask; @@ -394,6 +402,7 @@ allocate_segment (size_t frame_size) overhead = sizeof (struct stack_segment); allocate = pagesize; + frame_size += __extra_stack_size; if (allocate < MINSIGSTKSZ) allocate = ((MINSIGSTKSZ + overhead + pagesize - 1) & ~ (pagesize - 1)); @@ -1184,6 +1193,23 @@ __splitstack_block_signals_context (void *context[NUMBER_OFFSETS], int *new, context[BLOCK_SIGNALS] = (void *) (uintptr_type) (*new ? 0 : 1); } +/* Set extra stack space to current __morestack_segments. + Apply for more space each time the stack is expanded, which + can reduce the frequency of morestack being called. + When calling the non-split function, we + do not need additional checks and apply for 1M space. + At this time, we can turn off the conversion of linker + to __morestack_non_split. + This is more friendly to a large number of small stack coroutines + running below 128K. */ + +void +__splitstack_set_extra_stack_size (size_t size) +{ + __extra_stack_size = size; +} + + /* Find the stack segments associated with a split stack context. This will return the address of the first stack segment and set *STACK_SIZE to its size. It will set next_segment, next_sp, and -- 2.17.2 (Apple Git-113)