From 7b7b18bf76328764ba08d088f0b589c2737ffe36 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Thu, 21 Sep 2017 23:28:31 +0200 Subject: [PATCH] Improve context termination. Throw an exception to terminate the context at upper level, and have resources freed by stack unwinding. Closes #204, since pthread_exit is not called anymore. --- src/kernel/context/Context.hpp | 2 ++ src/kernel/context/ContextBoost.cpp | 13 +++++++++---- src/kernel/context/ContextRaw.cpp | 11 ++++++++--- src/kernel/context/ContextThread.cpp | 21 +++++++++++---------- src/kernel/context/ContextThread.hpp | 2 +- src/kernel/context/ContextUnix.cpp | 13 +++++++++---- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/kernel/context/Context.hpp b/src/kernel/context/Context.hpp index 8102fb130e..41e1f8fae2 100644 --- a/src/kernel/context/Context.hpp +++ b/src/kernel/context/Context.hpp @@ -80,6 +80,8 @@ namespace context { void_pfn_smxprocess_t cleanup_func_ = nullptr; smx_actor_t process_ = nullptr; public: + class StopRequest { + }; bool iwannadie; Context(std::function code, diff --git a/src/kernel/context/ContextBoost.cpp b/src/kernel/context/ContextBoost.cpp index f39f1d5213..a4c78b34e0 100644 --- a/src/kernel/context/ContextBoost.cpp +++ b/src/kernel/context/ContextBoost.cpp @@ -135,8 +135,13 @@ void BoostContext::smx_ctx_boost_wrapper(BoostContext::ctx_arg_type arg) static_cast(arg.data)[0]->fc_ = arg.fctx; BoostContext* context = static_cast(arg.data)[1]; #endif - (*context)(); - context->stop(); + try { + (*context)(); + context->stop(); + } catch (StopRequest) { + XBT_DEBUG("Caught a StopRequest"); + } + context->suspend(); } inline void BoostContext::smx_ctx_boost_jump_fcontext(BoostContext* from, BoostContext* to) @@ -223,7 +228,7 @@ void BoostSerialContext::suspend() void BoostSerialContext::stop() { BoostContext::stop(); - this->suspend(); + throw StopRequest(); } // BoostParallelContext @@ -250,7 +255,7 @@ void BoostParallelContext::suspend() void BoostParallelContext::stop() { BoostContext::stop(); - this->suspend(); + throw StopRequest(); } void BoostParallelContext::resume() diff --git a/src/kernel/context/ContextRaw.cpp b/src/kernel/context/ContextRaw.cpp index 53726aa300..00c60085b6 100644 --- a/src/kernel/context/ContextRaw.cpp +++ b/src/kernel/context/ContextRaw.cpp @@ -291,8 +291,13 @@ RawContext* RawContextFactory::create_context(std::function code, void RawContext::wrapper(void* arg) { RawContext* context = static_cast(arg); - (*context)(); - context->stop(); + try { + (*context)(); + context->stop(); + } catch (StopRequest) { + XBT_DEBUG("Caught a StopRequest"); + } + context->suspend(); } RawContext::RawContext(std::function code, @@ -323,7 +328,7 @@ RawContext::~RawContext() void RawContext::stop() { Context::stop(); - this->suspend(); + throw StopRequest(); } void RawContextFactory::run_all() diff --git a/src/kernel/context/ContextThread.cpp b/src/kernel/context/ContextThread.cpp index 3cbb7d5ddb..322d0e1f77 100644 --- a/src/kernel/context/ContextThread.cpp +++ b/src/kernel/context/ContextThread.cpp @@ -151,9 +151,17 @@ void *ThreadContext::wrapper(void *param) if (smx_ctx_thread_sem) /* parallel run */ xbt_os_sem_acquire(smx_ctx_thread_sem); - (*context)(); - context->stop(); + try { + (*context)(); + context->stop(); + } catch (StopRequest) { + XBT_DEBUG("Caught a StopRequest"); + } +#ifndef WIN32 + stack.ss_flags = SS_DISABLE; + sigaltstack(&stack, nullptr); +#endif return nullptr; } @@ -202,14 +210,7 @@ void ThreadContext::stop() // Signal to the maestro that it has finished: xbt_os_sem_release(this->end_); -#ifndef WIN32 - stack_t stack; - stack.ss_sp = nullptr; - stack.ss_size = 0; - stack.ss_flags = SS_DISABLE; - sigaltstack(&stack, nullptr); -#endif - xbt_os_thread_exit(nullptr); + throw StopRequest(); } void ThreadContext::suspend() diff --git a/src/kernel/context/ContextThread.hpp b/src/kernel/context/ContextThread.hpp index 096a01ccd3..3449f88a59 100644 --- a/src/kernel/context/ContextThread.hpp +++ b/src/kernel/context/ContextThread.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2015. The SimGrid Team. +/* Copyright (c) 2009-2017. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it diff --git a/src/kernel/context/ContextUnix.cpp b/src/kernel/context/ContextUnix.cpp index ec26e437ce..5a7148d2de 100644 --- a/src/kernel/context/ContextUnix.cpp +++ b/src/kernel/context/ContextUnix.cpp @@ -247,8 +247,13 @@ static void smx_ctx_sysv_wrapper(int first, ...) } memcpy(&context, ctx_addr, sizeof(simgrid::kernel::context::UContext*)); - (*context)(); - context->stop(); + try { + (*context)(); + context->stop(); + } catch (simgrid::kernel::context::Context::StopRequest) { + XBT_DEBUG("Caught a StopRequest"); + } + context->suspend(); } namespace simgrid { @@ -258,7 +263,7 @@ namespace context { void SerialUContext::stop() { Context::stop(); - this->suspend(); + throw StopRequest(); } void SerialUContext::suspend() @@ -291,7 +296,7 @@ void SerialUContext::resume() void ParallelUContext::stop() { UContext::stop(); - this->suspend(); + throw StopRequest(); } /** Run one particular simulated process on the current thread. */ -- 2.20.1