Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
ContextUnix: add header file with class definitions.
[simgrid.git] / src / kernel / context / ContextUnix.cpp
index 2512da7..c0d29fb 100644 (file)
@@ -5,54 +5,34 @@
 
 /* \file UContext.cpp Context switching with ucontexts from System V        */
 
-#include <ucontext.h>           /* context relative declarations */
+#include "ContextUnix.hpp"
 
 #include "mc/mc.h"
 #include "src/mc/mc_ignore.h"
 #include "src/simix/ActorImpl.hpp"
-#include "src/simix/smx_private.hpp"
-#include "xbt/parmap.hpp"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
 
 /** Many integers are needed to store a pointer
  *
- * This is a bit paranoid about sizeof(smx_ctx_sysv_t) not being a multiple
- * of sizeof(int), but it doesn't harm. */
-#define CTX_ADDR_LEN                            \
-  (sizeof(void*) / sizeof(int) +       \
-   !!(sizeof(void*) % sizeof(int)))
+ * Support up to two ints. */
+constexpr int CTX_ADDR_LEN = 2;
+
+static_assert(sizeof(simgrid::kernel::context::UContext*) <= CTX_ADDR_LEN * sizeof(int),
+              "Ucontexts are not supported on this arch yet");
 
 /** A better makecontext
  *
  * Makecontext expects integer arguments, we the context
  * variable is decomposed into a serie of integers and
  * each integer is passed as argument to makecontext. */
-static void simgrid_makecontext(ucontext_t* ucp, void (*func)(int first, ...), void* arg)
+static void simgrid_makecontext(ucontext_t* ucp, void (*func)(int, int), simgrid::kernel::context::UContext* arg)
 {
-  int ctx_addr[CTX_ADDR_LEN];
-  memcpy(ctx_addr, &arg, sizeof(void*));
-  switch (CTX_ADDR_LEN) {
-  case 1:
-    makecontext(ucp, (void (*)())func, 1, ctx_addr[0]);
-    break;
-  case 2:
-    makecontext(ucp, (void (*)()) func, 2, ctx_addr[0], ctx_addr[1]);
-    break;
-  default:
-    xbt_die("Ucontexts are not supported on this arch yet (addr len = %zu/%zu = %zu)", sizeof(void*), sizeof(int), CTX_ADDR_LEN);
-  }
+  int ctx_addr[CTX_ADDR_LEN]{};
+  memcpy(ctx_addr, &arg, sizeof arg);
+  makecontext(ucp, (void (*)())func, 2, ctx_addr[0], ctx_addr[1]);
 }
 
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_context);
-
-namespace simgrid {
-namespace kernel {
-namespace context {
-  class UContext;
-  class SerialUContext;
-  class ParallelUContext;
-  class UContextFactory;
-}}}
-
 #if HAVE_THREAD_CONTEXTS
 static simgrid::xbt::Parmap<smx_actor_t>* sysv_parmap;
 static simgrid::kernel::context::UContext** sysv_workers_context; /* space to save the worker's context
@@ -67,58 +47,12 @@ static bool sysv_parallel;
 
 // 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 first, ...);
+static void smx_ctx_sysv_wrapper(int, int);
 
 namespace simgrid {
 namespace kernel {
 namespace context {
 
-class UContext : public Context {
-private:
-  ucontext_t uc_;         /* the ucontext that executes the code */
-  char *stack_ = nullptr; /* the thread stack */
-public:
-  friend UContextFactory;
-  UContext(std::function<void()>  code,
-    void_pfn_smxprocess_t cleanup_func, smx_actor_t process);
-  ~UContext() override;
-  void stop() override;
-  static void swap(UContext* from, UContext* to) { swapcontext(&from->uc_, &to->uc_); }
-};
-
-class SerialUContext : public UContext {
-public:
-  SerialUContext(std::function<void()>  code,
-      void_pfn_smxprocess_t cleanup_func, smx_actor_t process)
-    : UContext(std::move(code), cleanup_func, process)
-  {}
-  void suspend() override;
-  void resume();
-};
-
-class ParallelUContext : public UContext {
-public:
-  ParallelUContext(std::function<void()>  code,
-      void_pfn_smxprocess_t cleanup_func, smx_actor_t process)
-    : UContext(std::move(code), cleanup_func, process)
-  {}
-  void suspend() override;
-  void resume();
-};
-
-class UContextFactory : public ContextFactory {
-public:
-  friend UContext;
-  friend SerialUContext;
-  friend ParallelUContext;
-
-  UContextFactory();
-  ~UContextFactory() override;
-  Context* create_context(std::function<void()> code,
-    void_pfn_smxprocess_t cleanup, smx_actor_t process) override;
-  void run_all() override;
-};
-
 XBT_PRIVATE ContextFactory* sysv_factory()
 {
   XBT_VERB("Activating SYSV context factory");
@@ -238,20 +172,12 @@ void UContext::stop()
 }
 }}} // namespace simgrid::kernel::context
 
-static void smx_ctx_sysv_wrapper(int first, ...)
+static void smx_ctx_sysv_wrapper(int i1, int i2)
 {
   // Rebuild the Context* pointer from the integers:
-  int ctx_addr[CTX_ADDR_LEN];
+  int ctx_addr[CTX_ADDR_LEN] = {i1, i2};
   simgrid::kernel::context::UContext* context;
-  ctx_addr[0] = first;
-  if (CTX_ADDR_LEN > 1) {
-    va_list ap;
-    va_start(ap, first);
-    for (unsigned i = 1; i < CTX_ADDR_LEN; i++)
-      ctx_addr[i] = va_arg(ap, int);
-    va_end(ap);
-  }
-  memcpy(&context, ctx_addr, sizeof(simgrid::kernel::context::UContext*));
+  memcpy(&context, ctx_addr, sizeof context);
 
   try {
     (*context)();
@@ -270,7 +196,8 @@ void SerialUContext::suspend()
 {
   /* determine the next context */
   UContext* next_context = nullptr;
-  unsigned long int i = sysv_process_index++;
+  unsigned long int i    = sysv_process_index;
+  sysv_process_index++;
 
   if (i < simix_global->process_to_run.size()) {
     /* execute the next process */