-/* Copyright (c) 2009-2017. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2009-2018. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
/* \file UContext.cpp Context switching with ucontexts from System V */
#include "ContextUnix.hpp"
+#include "context_private.hpp"
#include "mc/mc.h"
-#include "src/mc/mc_ignore.h"
+#include "src/mc/mc_ignore.hpp"
#include "src/simix/ActorImpl.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
static_assert(sizeof(simgrid::kernel::context::UContext*) <= CTX_ADDR_LEN * sizeof(int),
"Ucontexts are not supported on this arch yet");
-// The name of this function is currently hardcoded in the code (as string).
-// Do not change it without fixing those references as well.
-static void smx_ctx_sysv_wrapper(int i1, int i2)
-{
- // Rebuild the Context* pointer from the integers:
- int ctx_addr[CTX_ADDR_LEN] = {i1, i2};
- simgrid::kernel::context::UContext* context;
- memcpy(&context, ctx_addr, sizeof context);
-
- try {
- (*context)();
- context->Context::stop();
- } catch (simgrid::kernel::context::Context::StopRequest const&) {
- XBT_DEBUG("Caught a StopRequest");
- }
- context->suspend();
-}
-
namespace simgrid {
namespace kernel {
namespace context {
this->uc_.uc_link = nullptr;
this->uc_.uc_stack.ss_sp = sg_makecontext_stack_addr(this->stack_);
this->uc_.uc_stack.ss_size = sg_makecontext_stack_size(smx_context_usable_stack_size);
- UContext::make_ctx(&this->uc_, UContext::wrapper, this);
+#if PTH_STACKGROWTH == -1
+ ASAN_EVAL(this->asan_stack_ = static_cast<char*>(this->stack_) + smx_context_usable_stack_size);
+#else
+ ASAN_EVAL(this->asan_stack_ = this->stack_);
+#endif
+ UContext::make_ctx(&this->uc_, UContext::smx_ctx_sysv_wrapper, this);
} else {
if (process != nullptr && maestro_context_ == nullptr)
maestro_context_ = this;
SIMIX_context_stack_delete(this->stack_);
}
-void UContext::wrapper(int i1, int i2)
+// The name of this function is currently hardcoded in the code (as string).
+// Do not change it without fixing those references as well.
+void UContext::smx_ctx_sysv_wrapper(int i1, int i2)
{
- smx_ctx_sysv_wrapper(i1, i2);
+ // Rebuild the Context* pointer from the integers:
+ int ctx_addr[CTX_ADDR_LEN] = {i1, i2};
+ simgrid::kernel::context::UContext* context;
+ memcpy(&context, ctx_addr, sizeof context);
+
+ ASAN_FINISH_SWITCH(nullptr, &context->asan_ctx_->asan_stack_, &context->asan_ctx_->asan_stack_size_);
+ try {
+ (*context)();
+ context->Context::stop();
+ } catch (simgrid::kernel::context::Context::StopRequest const&) {
+ XBT_DEBUG("Caught a StopRequest");
+ }
+ ASAN_EVAL(context->asan_stop_ = true);
+ context->suspend();
}
/** A better makecontext
makecontext(ucp, (void (*)())func, 2, ctx_addr[0], ctx_addr[1]);
}
+inline void UContext::swap(UContext* from, UContext* to)
+{
+ void* fake_stack = nullptr;
+ ASAN_EVAL(to->asan_ctx_ = from);
+ ASAN_START_SWITCH(from->asan_stop_ ? nullptr : &fake_stack, to->asan_stack_, to->asan_stack_size_);
+ swapcontext(&from->uc_, &to->uc_);
+ ASAN_FINISH_SWITCH(fake_stack, &from->asan_ctx_->asan_stack_, &from->asan_ctx_->asan_stack_size_);
+}
+
void UContext::stop()
{
Context::stop();
#if HAVE_THREAD_CONTEXTS
simgrid::xbt::Parmap<smx_actor_t>* ParallelUContext::parmap_;
-uintptr_t ParallelUContext::threads_working_; /* number of threads that have started their work */
+std::atomic<uintptr_t> ParallelUContext::threads_working_; /* number of threads that have started their work */
xbt_os_thread_key_t ParallelUContext::worker_id_key_; /* thread-specific storage for the thread id */
std::vector<ParallelUContext*> ParallelUContext::workers_context_; /* space to save the worker's context
* in each thread */
void ParallelUContext::resume()
{
// What is my containing body?
- uintptr_t worker_id = __sync_fetch_and_add(&threads_working_, 1);
+ uintptr_t worker_id = threads_working_.fetch_add(1, std::memory_order_relaxed);
// Store the number of my containing body in os-thread-specific area :
xbt_os_thread_set_specific(worker_id_key_, reinterpret_cast<void*>(worker_id));
// Get my current soul: