Browse Source

add split stack

main cops_v4
Rain Mark 4 years ago
parent
commit
9b2906f9ff
  1. 4
      build.sh
  2. 6
      coroutine.cpp
  3. 54
      coroutine.h
  4. 26
      gcc-split-stack-extra-space.patch
  5. 14
      splitstack.cpp

4
build.sh

@ -12,3 +12,7 @@ $CXX $FLAGS future_test.cpp -o bin/future_test
$CXX $FLAGS -O0 loop_test.cpp coroutine.cpp *.S -o bin/loop_test
$CXX $FLAGS -O0 httpd/httpd.cpp coroutine.cpp *.S -o bin/httpd
$CXX $FLAGS -fsplit-stack -O0 splitstack.cpp -o bin/splitstack
$CXX $FLAGS -fsplit-stack -DSPLIT_STACK loop_test.cpp coroutine.cpp *.S -o bin/loop_split_stack_test

6
coroutine.cpp

@ -15,6 +15,9 @@ void main(coro_t* coro, context from) {
void coro_t::switch_out() {
current = next_;
#ifdef SPLIT_STACK
switch_split_stack_context(stack_.ss_ctx_, stack_.next_);
#endif
context from = switch_context(next_, next_->ctx_);
next_ = static_cast<coro_t*>(from);
next_->ctx_ = from;
@ -23,6 +26,9 @@ void coro_t::switch_out() {
void coro_t::switch_in() {
next_ = current;
current = this;
#ifdef SPLIT_STACK
switch_split_stack_context(stack_.next_, stack_.ss_ctx_);
#endif
ctx_ = switch_context(this, ctx_);
}

54
coroutine.h

@ -6,6 +6,36 @@
#include <future.h>
#ifdef SPLIT_STACK
///////////////////////////
// forward declaration for splitstack-functions defined in libgcc
// https://github.com/gcc-mirror/gcc/blob/master/libgcc/generic-morestack.c
// https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/i386/morestack.S
enum splitstack_context_offsets {
MORESTACK_SEGMENTS = 0,
CURRENT_SEGMENT = 1,
CURRENT_STACK = 2,
STACK_GUARD = 3,
INITIAL_SP = 4,
INITIAL_SP_LEN = 5,
BLOCK_SIGNALS = 6,
NUMBER_OFFSETS = 10
};
extern "C" {
void *__splitstack_makecontext(std::size_t, void* [NUMBER_OFFSETS], std::size_t*);
void __splitstack_setcontext(void* [NUMBER_OFFSETS]);
void __splitstack_getcontext(void* [NUMBER_OFFSETS]);
void __splitstack_releasecontext(void* [NUMBER_OFFSETS]);
void __splitstack_resetcontext(void* [NUMBER_OFFSETS]);
void __splitstack_block_signals_context(void* [NUMBER_OFFSETS], int* new_value, int* old_value);
}
#endif
namespace cops {
class coro_t;
class event_loop_t;
@ -23,10 +53,20 @@ namespace cops {
class stack_t {
public:
stack_t(size_t size = 64 * 1024) : size_(size) {
#ifdef SPLIT_STACK
sp_ = static_cast<char*>(__splitstack_makecontext(size_, ss_ctx_, &size_));
static int off = 0;
__splitstack_block_signals_context(ss_ctx_, &off, 0);
#else
sp_ = new char[size_];
#endif
}
~stack_t() {
#ifdef SPLIT_STACK
__splitstack_releasecontext(ss_ctx_);
#else
delete[] sp_;
#endif
}
void* sp() {
@ -36,8 +76,22 @@ public:
private:
char* sp_;
size_t size_;
#ifdef SPLIT_STACK
public:
using split_stack_context = void* [NUMBER_OFFSETS];
split_stack_context ss_ctx_{0};
split_stack_context next_{0};
#endif
};
#ifdef SPLIT_STACK
inline void switch_split_stack_context(stack_t::split_stack_context from,
stack_t::split_stack_context to) {
__splitstack_getcontext(from);
__splitstack_setcontext(to);
}
#endif
class coro_t {
public:
using Fn = std::function<void(void)>;

26
gcc-split-stack-extra-space.patch

@ -0,0 +1,26 @@
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 59101d8..4cbad01 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -9488,7 +9488,7 @@ ix86_expand_split_stack_prologue (void)
ix86_finalize_stack_frame_flags ();
struct ix86_frame &frame = cfun->machine->frame;
- allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
+ allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET + 64 * 1024;
/* This is the label we will branch to if we have enough stack
space. We expect the basic block reordering pass to reverse this
diff --git a/libgcc/config/i386/morestack.S b/libgcc/config/i386/morestack.S
index 519bbbc..0f0a79e 100644
--- a/libgcc/config/i386/morestack.S
+++ b/libgcc/config/i386/morestack.S
@@ -84,7 +84,7 @@
# The amount of space we ask for when calling non-split-stack code.
-#define NON_SPLIT_STACK 0x100000
+#define NON_SPLIT_STACK 0x8000
# This entry point is for split-stack code which calls non-split-stack
# code. When the linker sees this case, it converts the call to

14
splitstack.cpp

@ -0,0 +1,14 @@
#include <stdio.h>
int foo(int x1) {
printf("%d\n", x1);
return 0;
}
int bar(int x2) {
return foo(x2);
}
int main() {
return bar(0);
}
Loading…
Cancel
Save