[PATCH] libgcc: allocate extra space for morestack expansion

Rain Mark rain.by.zhou@gmail.com
Wed Feb 10 06:36:54 GMT 2021


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)



More information about the Gcc-patches mailing list