Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
allow to specify the stack size on a per-actor basis
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Thu, 5 Mar 2020 09:03:59 +0000 (10:03 +0100)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Thu, 5 Mar 2020 10:18:47 +0000 (11:18 +0100)
12 files changed:
include/simgrid/s4u/Actor.hpp
src/kernel/actor/ActorImpl.cpp
src/kernel/actor/ActorImpl.hpp
src/kernel/context/Context.hpp
src/kernel/context/ContextBoost.cpp
src/kernel/context/ContextRaw.cpp
src/kernel/context/ContextSwapped.cpp
src/kernel/context/ContextSwapped.hpp
src/kernel/context/ContextUnix.cpp
src/s4u/s4u_Actor.cpp
teshsuite/kernel/context-stacksize/context-stacksize.cpp
teshsuite/kernel/context-stacksize/context-stacksize.tesh

index a040274..6d8ef15 100644 (file)
@@ -107,6 +107,7 @@ public:
    *
    * This is usefull to set some properties or extension before actually starting it */
   static ActorPtr init(const std::string& name, s4u::Host* host);
+  ActorPtr set_stacksize(unsigned stacksize);
   /** Start a previously initialized actor */
   ActorPtr start(const std::function<void()>& code);
 
index b890a8e..7c801df 100644 (file)
@@ -54,8 +54,9 @@ ActorImpl* ActorImpl::self()
 
 ActorImpl::ActorImpl(xbt::string name, s4u::Host* host) : host_(host), name_(std::move(name)), piface_(this)
 {
-  pid_           = maxpid++;
+  pid_            = maxpid++;
   simcall.issuer_ = this;
+  stacksize_      = smx_context_stack_size;
 }
 
 ActorImpl::~ActorImpl()
index bbbcd60..1efe8da 100644 (file)
@@ -27,6 +27,7 @@ class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder {
   aid_t ppid_        = -1;
   bool daemon_       = false; /* Daemon actors are automatically killed when the last non-daemon leaves */
   bool auto_restart_ = false;
+  unsigned stacksize_; // set to default value in constructor
 
 public:
   xbt::string name_;
@@ -58,6 +59,8 @@ public:
   bool is_daemon() { return daemon_; } /** Whether this actor has been daemonized */
   bool has_to_auto_restart() { return auto_restart_; }
   void set_auto_restart(bool autorestart) { auto_restart_ = autorestart; }
+  void set_stacksize(unsigned stacksize) { stacksize_ = stacksize; }
+  unsigned get_stacksize() { return stacksize_; }
 
   std::unique_ptr<context::Context> context_; /* the context (uctx/raw/thread) that executes the user function */
 
index 84dc108..813856f 100644 (file)
@@ -58,7 +58,7 @@ public:
   void set_wannadie(bool value = true) { iwannadie_ = value; }
   void operator()() { code_(); }
   bool has_code() const { return static_cast<bool>(code_); }
-  actor::ActorImpl* get_actor() { return this->actor_; }
+  actor::ActorImpl* get_actor() const { return this->actor_; }
 
   // Scheduling methods
   virtual void stop();
index ae9ade0..f7d76cb 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "ContextBoost.hpp"
 #include "simgrid/Exception.hpp"
+#include "src/internal_config.h"
 #include "src/simix/smx_private.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
@@ -24,14 +25,14 @@ BoostContext* BoostContextFactory::create_context(std::function<void()>&& code,
 BoostContext::BoostContext(std::function<void()>&& code, actor::ActorImpl* actor, SwappedContextFactory* factory)
     : SwappedContext(std::move(code), actor, factory)
 {
-  XBT_VERB("Creating a context of stack %uMb", smx_context_stack_size / 1024 / 1024);
+  XBT_VERB("Creating a context of stack %uMb", actor->get_stacksize() / 1024 / 1024);
   /* if the user provided a function for the process then use it, otherwise it is the context for maestro */
   if (has_code()) {
 #if BOOST_VERSION < 106100
-    this->fc_ = boost::context::make_fcontext(get_stack_bottom(), smx_context_stack_size, BoostContext::wrapper);
+    this->fc_ = boost::context::make_fcontext(get_stack_bottom(), actor->get_stacksize(), BoostContext::wrapper);
 #else
     this->fc_ =
-        boost::context::detail::make_fcontext(get_stack_bottom(), smx_context_stack_size, BoostContext::wrapper);
+        boost::context::detail::make_fcontext(get_stack_bottom(), actor->get_stacksize(), BoostContext::wrapper);
 #endif
   }
 }
index 4cc658a..3b36ada 100644 (file)
@@ -197,9 +197,9 @@ RawContext* RawContextFactory::create_context(std::function<void()>&& code, acto
 RawContext::RawContext(std::function<void()>&& code, actor::ActorImpl* actor, SwappedContextFactory* factory)
     : SwappedContext(std::move(code), actor, factory)
 {
-  XBT_VERB("Creating a context of stack %uMb", smx_context_stack_size / 1024 / 1024);
+  XBT_VERB("Creating a context of stack %uMb", actor->get_stacksize() / 1024 / 1024);
   if (has_code()) {
-    this->stack_top_ = raw_makecontext(get_stack(), smx_context_stack_size, smx_ctx_wrapper, this);
+    this->stack_top_ = raw_makecontext(get_stack(), actor->get_stacksize(), smx_ctx_wrapper, this);
   } else {
     if (MC_is_active())
       MC_ignore_heap(&stack_top_, sizeof(stack_top_));
index d64dac4..7b25012 100644 (file)
@@ -74,7 +74,7 @@ SwappedContext::SwappedContext(std::function<void()>&& code, smx_actor_t actor,
     factory_.maestro_context_ = this;
 
   if (has_code()) {
-    xbt_assert((smx_context_stack_size & 0xf) == 0, "smx_context_stack_size should be multiple of 16");
+    xbt_assert((actor->get_stacksize() & 0xf) == 0, "Actor stack size should be multiple of 16");
     if (smx_context_guard_size > 0 && not MC_is_active()) {
 #if PTH_STACKGROWTH != -1
       xbt_die(
@@ -85,7 +85,7 @@ SwappedContext::SwappedContext(std::function<void()>&& code, smx_actor_t actor,
        * Protected pages need to be put after the stack when PTH_STACKGROWTH == 1. */
 #endif
 
-      size_t size = smx_context_stack_size + smx_context_guard_size;
+      size_t size = actor->get_stacksize() + smx_context_guard_size;
 #if SIMGRID_HAVE_MC
       /* Cannot use posix_memalign when SIMGRID_HAVE_MC. Align stack by hand, and save the
        * pointer returned by xbt_malloc0. */
@@ -116,12 +116,12 @@ SwappedContext::SwappedContext(std::function<void()>&& code, smx_actor_t actor,
 #endif
       this->stack_ = this->stack_ + smx_context_guard_size;
     } else {
-      this->stack_ = static_cast<unsigned char*>(xbt_malloc0(smx_context_stack_size));
+      this->stack_ = static_cast<unsigned char*>(xbt_malloc0(actor->get_stacksize()));
     }
 
 #if HAVE_VALGRIND_H
     if (RUNNING_ON_VALGRIND)
-      this->valgrind_stack_id_ = VALGRIND_STACK_REGISTER(this->stack_, this->stack_ + smx_context_stack_size);
+      this->valgrind_stack_id_ = VALGRIND_STACK_REGISTER(this->stack_, this->stack_ + actor->get_stacksize());
 #endif
 #if HAVE_SANITIZER_ADDRESS_FIBER_SUPPORT
     this->asan_stack_ = get_stack_bottom();
@@ -167,6 +167,12 @@ SwappedContext::~SwappedContext()
   xbt_free(stack_);
 }
 
+unsigned char* SwappedContext::get_stack_bottom() const
+{
+  // Depending on the stack direction, its bottom (that make_fcontext needs) may be the lower or higher end
+  return PTH_STACKGROWTH == -1 ? stack_ + get_actor()->get_stacksize() : stack_;
+}
+
 void SwappedContext::stop()
 {
   Context::stop();
index 1b815aa..414416d 100644 (file)
@@ -40,14 +40,14 @@ private:
   SwappedContext* maestro_context_ = nullptr; // save maestro's context
 
   /* For the parallel execution, will be created lazily with the right parameters if needed (ie, in parallel) */
-  std::unique_ptr<simgrid::xbt::Parmap<smx_actor_t>> parmap_{nullptr};
+  std::unique_ptr<simgrid::xbt::Parmap<actor::ActorImpl*>> parmap_{nullptr};
 };
 
 class SwappedContext : public Context {
   friend void ::smx_ctx_wrapper(simgrid::kernel::context::SwappedContext*);
 
 public:
-  SwappedContext(std::function<void()>&& code, smx_actor_t get_actor, SwappedContextFactory* factory);
+  SwappedContext(std::function<void()>&& code, actor::ActorImpl* get_actor, SwappedContextFactory* factory);
   SwappedContext(const SwappedContext&) = delete;
   SwappedContext& operator=(const SwappedContext&) = delete;
   virtual ~SwappedContext();
@@ -58,12 +58,11 @@ public:
 
   void swap_into(SwappedContext* to);
 
+protected:
   unsigned char* get_stack() const { return stack_; }
-  // Return the address for the bottom of the stack.  Depending on the stack direction it may be the lower or higher
-  // address
-  unsigned char* get_stack_bottom() const { return PTH_STACKGROWTH == -1 ? stack_ + smx_context_stack_size : stack_; }
+  unsigned char* get_stack_bottom() const; // Depending on the stack direction, its bottom (that Boost::make_fcontext
+                                           // needs) may be the lower or higher end
 
-protected:
   // With ASan, after a context switch, check that the originating context is the expected one (see BoostContext)
   void verify_previous_context(const SwappedContext* context) const;
 
index 6e2ebe5..28a62b9 100644 (file)
@@ -49,13 +49,13 @@ UContext* UContextFactory::create_context(std::function<void()>&& code, actor::A
 UContext::UContext(std::function<void()>&& code, actor::ActorImpl* actor, SwappedContextFactory* factory)
     : SwappedContext(std::move(code), actor, factory)
 {
-  XBT_VERB("Creating a context of stack %uMb", smx_context_stack_size / 1024 / 1024);
+  XBT_VERB("Creating a context of stack %uMb", actor->get_stacksize() / 1024 / 1024);
   /* if the user provided a function for the actor then use it. If not, nothing to do for maestro. */
   if (has_code()) {
     getcontext(&this->uc_);
     this->uc_.uc_link = nullptr;
     this->uc_.uc_stack.ss_sp   = sg_makecontext_stack_addr(get_stack());
-    this->uc_.uc_stack.ss_size = sg_makecontext_stack_size(smx_context_stack_size);
+    this->uc_.uc_stack.ss_size = sg_makecontext_stack_size(actor->get_stacksize());
     // Makecontext expects integer arguments; we want to pass a pointer.
     // This context address is decomposed into a series of integers, which are passed as arguments to makecontext.
 
index 0ca43d2..b963779 100644 (file)
@@ -56,6 +56,15 @@ ActorPtr Actor::init(const std::string& name, s4u::Host* host)
   return actor->iface();
 }
 
+/** Set a non-default stack size for this context (in Kb)
+ *
+ * This must be done before starting the actor, and it won't work with the thread factory. */
+ActorPtr Actor::set_stacksize(unsigned stacksize)
+{
+  pimpl_->set_stacksize(stacksize * 1024);
+  return this;
+}
+
 ActorPtr Actor::start(const std::function<void()>& code)
 {
   simgrid::kernel::actor::simcall([this, &code] { pimpl_->start(code); });
index 49cba2e..3d9a77e 100644 (file)
@@ -19,12 +19,22 @@ int main(int argc, char* argv[])
   simgrid::s4u::Engine e(&argc, argv);
   e.load_platform(argv[1]);
 
+  // If you don't specify anything, you get the default size (8Mb) or the one passed on the command line
   simgrid::s4u::Actor::create("actor", simgrid::s4u::Host::by_name("Tremblay"), actor);
+
+  // You can use set_config(string) to pass a size that will be parsed. That value will be used for any subsequent
+  // actors
   e.set_config("contexts/stack-size:16384");
   simgrid::s4u::Actor::create("actor", simgrid::s4u::Host::by_name("Tremblay"), actor);
+  simgrid::s4u::Actor::create("actor", simgrid::s4u::Host::by_name("Tremblay"), actor);
+
+  // You can use set_config(key, value) for the same effect.
   e.set_config("contexts/stack-size", 32 * 1024);
   simgrid::s4u::Actor::create("actor", simgrid::s4u::Host::by_name("Tremblay"), actor);
-  e.set_config("contexts/stack-size", 64 * 1024);
+  simgrid::s4u::Actor::create("actor", simgrid::s4u::Host::by_name("Tremblay"), actor);
+
+  // Or you can use set_stacksize() before starting the actor to modify only this one
+  simgrid::s4u::Actor::init("actor", simgrid::s4u::Host::by_name("Tremblay"))->set_stacksize(64 * 1024)->start(actor);
   simgrid::s4u::Actor::create("actor", simgrid::s4u::Host::by_name("Tremblay"), actor);
 
   e.run();
index dd05180..f6f564f 100644 (file)
@@ -7,10 +7,16 @@ $ ./context-stacksize --log=simix_context.thresh:verbose --log=no_loc ${platfdir
 > [::(0) 0.000000] [simix_context/VERBOSE] Creating a context of stack 8Mb
 > [0.000000] [simix_context/VERBOSE] Creating a context of stack 8Mb
 > [0.000000] [simix_context/VERBOSE] Creating a context of stack 16Mb
+> [0.000000] [simix_context/VERBOSE] Creating a context of stack 16Mb
+> [0.000000] [simix_context/VERBOSE] Creating a context of stack 32Mb
 > [0.000000] [simix_context/VERBOSE] Creating a context of stack 32Mb
 > [0.000000] [simix_context/VERBOSE] Creating a context of stack 64Mb
+> [0.000000] [simix_context/VERBOSE] Creating a context of stack 32Mb
 > [Tremblay:actor:(1) 0.000000] [s4u_test/INFO] Hello
 > [Tremblay:actor:(2) 0.000000] [s4u_test/INFO] Hello
 > [Tremblay:actor:(3) 0.000000] [s4u_test/INFO] Hello
 > [Tremblay:actor:(4) 0.000000] [s4u_test/INFO] Hello
+> [Tremblay:actor:(5) 0.000000] [s4u_test/INFO] Hello
+> [Tremblay:actor:(6) 0.000000] [s4u_test/INFO] Hello
+> [Tremblay:actor:(7) 0.000000] [s4u_test/INFO] Hello
 > [0.000000] [s4u_test/INFO] Simulation time 0