Commit 7f864131 authored by Marius Wachtler's avatar Marius Wachtler

Save current internal thread state in TLS

reduces the generator yield overhead
parent babe2f69
...@@ -131,16 +131,18 @@ public: ...@@ -131,16 +131,18 @@ public:
} }
}; };
static std::unordered_map<pthread_t, ThreadStateInternal*> current_threads; static std::unordered_map<pthread_t, ThreadStateInternal*> current_threads;
static __thread ThreadStateInternal* current_internal_thread_state = 0;
// TODO could optimize these by keeping a __thread local reference to current_threads[pthread_self()]
void pushGenerator(BoxedGenerator* g, void* new_stack_start, void* old_stack_limit) { void pushGenerator(BoxedGenerator* g, void* new_stack_start, void* old_stack_limit) {
assert(new_stack_start); assert(new_stack_start);
assert(old_stack_limit); assert(old_stack_limit);
current_threads[pthread_self()]->pushGenerator(g, new_stack_start, old_stack_limit); assert(current_internal_thread_state);
current_internal_thread_state->pushGenerator(g, new_stack_start, old_stack_limit);
} }
void popGenerator() { void popGenerator() {
current_threads[pthread_self()]->popGenerator(); assert(current_internal_thread_state);
current_internal_thread_state->popGenerator();
} }
// These are guarded by threading_lock // These are guarded by threading_lock
...@@ -179,20 +181,19 @@ static void visitLocalStack(gc::GCVisitor* v) { ...@@ -179,20 +181,19 @@ static void visitLocalStack(gc::GCVisitor* v) {
assert(sizeof(registers) % 8 == 0); assert(sizeof(registers) % 8 == 0);
v->visitPotentialRange((void**)&registers, (void**)((&registers) + 1)); v->visitPotentialRange((void**)&registers, (void**)((&registers) + 1));
ThreadStateInternal* thread_state = current_threads[pthread_self()]; assert(current_internal_thread_state);
#if STACK_GROWS_DOWN #if STACK_GROWS_DOWN
void* stack_low = getCurrentStackLimit(); void* stack_low = getCurrentStackLimit();
void* stack_high = thread_state->stack_start; void* stack_high = current_internal_thread_state->stack_start;
#else #else
void* stack_low = thread_state->stack_start; void* stack_low = current_thread_state->stack_start;
void* stack_high = getCurrentStackLimit(); void* stack_high = getCurrentStackLimit();
#endif #endif
assert(stack_low < stack_high); assert(stack_low < stack_high);
v->visitPotentialRange((void**)stack_low, (void**)stack_high); v->visitPotentialRange((void**)stack_low, (void**)stack_high);
thread_state->accept(v); current_internal_thread_state->accept(v);
} }
void visitAllStacks(gc::GCVisitor* v) { void visitAllStacks(gc::GCVisitor* v) {
...@@ -267,6 +268,7 @@ static void _thread_context_dump(int signum, siginfo_t* info, void* _context) { ...@@ -267,6 +268,7 @@ static void _thread_context_dump(int signum, siginfo_t* info, void* _context) {
printf("old rip: 0x%lx\n", (intptr_t)context->uc_mcontext.gregs[REG_RIP]); printf("old rip: 0x%lx\n", (intptr_t)context->uc_mcontext.gregs[REG_RIP]);
} }
assert(current_internal_thread_state == current_threads[tid]);
pushThreadState(current_threads[tid], context); pushThreadState(current_threads[tid], context);
signals_waiting--; signals_waiting--;
} }
...@@ -306,7 +308,8 @@ static void* _thread_start(void* _arg) { ...@@ -306,7 +308,8 @@ static void* _thread_start(void* _arg) {
#else #else
void* stack_bottom = stack_start; void* stack_bottom = stack_start;
#endif #endif
current_threads[current_thread] = new ThreadStateInternal(stack_bottom, current_thread, &cur_thread_state); current_internal_thread_state = new ThreadStateInternal(stack_bottom, current_thread, &cur_thread_state);
current_threads[current_thread] = current_internal_thread_state;
num_starting_threads--; num_starting_threads--;
...@@ -318,7 +321,7 @@ static void* _thread_start(void* _arg) { ...@@ -318,7 +321,7 @@ static void* _thread_start(void* _arg) {
assert(!PyErr_Occurred()); assert(!PyErr_Occurred());
void* rtn = start_func(arg1, arg2, arg3); void* rtn = start_func(arg1, arg2, arg3);
current_threads[current_thread]->assertNoGenerators(); current_internal_thread_state->assertNoGenerators();
{ {
LOCK_REGION(&threading_lock); LOCK_REGION(&threading_lock);
...@@ -327,6 +330,7 @@ static void* _thread_start(void* _arg) { ...@@ -327,6 +330,7 @@ static void* _thread_start(void* _arg) {
if (VERBOSITY() >= 2) if (VERBOSITY() >= 2)
printf("thread tid=%ld exited\n", current_thread); printf("thread tid=%ld exited\n", current_thread);
} }
current_internal_thread_state = 0;
return rtn; return rtn;
} }
...@@ -404,7 +408,9 @@ static void* find_stack() { ...@@ -404,7 +408,9 @@ static void* find_stack() {
void registerMainThread() { void registerMainThread() {
LOCK_REGION(&threading_lock); LOCK_REGION(&threading_lock);
current_threads[pthread_self()] = new ThreadStateInternal(find_stack(), pthread_self(), &cur_thread_state); assert(!current_internal_thread_state);
current_internal_thread_state = new ThreadStateInternal(find_stack(), pthread_self(), &cur_thread_state);
current_threads[pthread_self()] = current_internal_thread_state;
struct sigaction act; struct sigaction act;
memset(&act, 0, sizeof(act)); memset(&act, 0, sizeof(act));
...@@ -420,7 +426,8 @@ void registerMainThread() { ...@@ -420,7 +426,8 @@ void registerMainThread() {
} }
void finishMainThread() { void finishMainThread() {
current_threads[pthread_self()]->assertNoGenerators(); assert(current_internal_thread_state);
current_internal_thread_state->assertNoGenerators();
// TODO maybe this is the place to wait for non-daemon threads? // TODO maybe this is the place to wait for non-daemon threads?
} }
...@@ -440,18 +447,17 @@ extern "C" void beginAllowThreads() noexcept { ...@@ -440,18 +447,17 @@ extern "C" void beginAllowThreads() noexcept {
{ {
LOCK_REGION(&threading_lock); LOCK_REGION(&threading_lock);
ThreadStateInternal* state = current_threads[pthread_self()]; assert(current_internal_thread_state);
assert(state); current_internal_thread_state->saveCurrent();
state->saveCurrent();
} }
} }
extern "C" void endAllowThreads() noexcept { extern "C" void endAllowThreads() noexcept {
{ {
LOCK_REGION(&threading_lock); LOCK_REGION(&threading_lock);
ThreadStateInternal* state = current_threads[pthread_self()];
assert(state); assert(current_internal_thread_state);
state->popCurrent(); current_internal_thread_state->popCurrent();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment