Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
dos2unix + indent
[simgrid.git] / src / xbt / xbt_context_sysv.c
index 2a36b6e..bf05588 100644 (file)
-\r
-#include "xbt/ex_interface.h"\r
-#include "xbt/xbt_context_private.h"\r
-\r
-#include "context_sysv_config.h"       /* loads context system definitions                             */\r
-#include "portable.h" \r
-#include <ucontext.h>                  /* context relative declarations                                */                              \r
-#define STACK_SIZE 128*1024            /* lower this if you want to reduce the memory consumption      */\r
-\r
-typedef struct s_xbt_ctx_sysv {\r
-   XBT_CTX_BASE_T;\r
-       ucontext_t uc;                  /* the thread that execute the code                             */\r
-       char stack[STACK_SIZE];         /* the thread stack size                                        */\r
-       struct s_xbt_ctx_sysv* prev;/* the previous thread                                              */\r
-} s_xbt_ctx_sysv_t,* xbt_ctx_sysv_t;\r
-\r
-\r
-/* callback: context fetching */\r
-static ex_ctx_t*\r
-xbt_jcontext_ex_ctx(void);\r
-\r
-/* callback: termination */\r
-static void \r
-xbt_jcontext_ex_terminate(xbt_ex_t *e);\r
-\r
-static xbt_context_t \r
-xbt_ctx_sysv_factory_create_context(const char* name, xbt_main_func_t code, void_f_pvoid_t startup_func, void* startup_arg, void_f_pvoid_t cleanup_func, void* cleanup_arg, int argc, char** argv);\r
-\r
-static int\r
-xbt_ctx_sysv_factory_finalize(xbt_context_factory_t* factory);\r
-\r
-static int \r
-xbt_ctx_sysv_factory_create_maestro_context(xbt_context_t* maestro);\r
-\r
-static void \r
-xbt_ctx_sysv_free(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_sysv_kill(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_sysv_schedule(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_sysv_yield(void);\r
-\r
-static void \r
-xbt_ctx_sysv_start(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_sysv_stop(int exit_code);\r
-\r
-static void \r
-xbt_ctx_sysv_swap(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_sysv_schedule(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_sysv_yield(void);\r
-\r
-static void\r
-xbt_ctx_sysv_suspend(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_sysv_resume(xbt_context_t context);\r
-\r
-static void xbt_ctx_sysv_wrapper(void);\r
-\r
-/* callback: context fetching */\r
-static ex_ctx_t*\r
-xbt_ctx_sysv_ex_ctx(void) \r
-{\r
-       return current_context->exception;\r
-}\r
-\r
-/* callback: termination */\r
-static void \r
-xbt_ctx_sysv_ex_terminate(xbt_ex_t *e) \r
-{\r
-       xbt_ex_display(e);\r
-       abort();\r
-}\r
-\r
-\r
-void\r
-xbt_ctx_sysv_factory_init(xbt_context_factory_t* factory)\r
-{\r
-       /* context exception */\r
-       *factory = xbt_new0(s_xbt_context_factory_t,1);\r
-       \r
-       (*factory)->create_context = xbt_ctx_sysv_factory_create_context;\r
-       (*factory)->finalize = xbt_ctx_sysv_factory_finalize;\r
-       (*factory)->create_maestro_context = xbt_ctx_sysv_factory_create_maestro_context;\r
-       (*factory)->name = "ctx_sysv_context_factory";\r
-       \r
-       /* context exception handlers */\r
-       __xbt_ex_ctx       = xbt_ctx_sysv_ex_ctx;\r
-    __xbt_ex_terminate = xbt_ctx_sysv_ex_terminate;    \r
-}\r
-\r
-static int \r
-xbt_ctx_sysv_factory_create_maestro_context(xbt_context_t* maestro)\r
-{\r
-               \r
-       xbt_ctx_sysv_t context = xbt_new0(s_xbt_ctx_sysv_t, 1);\r
-       \r
-       context->exception = xbt_new(ex_ctx_t,1);\r
-    XBT_CTX_INITIALIZE(context->exception);\r
-    \r
-    *maestro = (xbt_context_t)context;\r
-    \r
-    return 0;\r
-    \r
-}\r
-\r
-\r
-static int\r
-xbt_ctx_sysv_factory_finalize(xbt_context_factory_t* factory)\r
-{\r
-       free(maestro_context->exception);\r
-       free(*factory);\r
-       *factory = NULL;\r
-       return 0;\r
-}\r
-\r
-static xbt_context_t \r
-xbt_ctx_sysv_factory_create_context(const char* name, xbt_main_func_t code, void_f_pvoid_t startup_func, void* startup_arg, void_f_pvoid_t cleanup_func, void* cleanup_arg, int argc, char** argv)\r
-{\r
-       xbt_ctx_sysv_t context = xbt_new0(s_xbt_ctx_sysv_t, 1);\r
-       \r
-       context->code = code;\r
-       context->name = xbt_strdup(name);\r
-       \r
-       xbt_assert2(getcontext(&(context->uc)) == 0,"Error in context saving: %d (%s)", errno, strerror(errno));\r
-       context->uc.uc_link = NULL;\r
-       context->uc.uc_stack.ss_sp = pth_skaddr_makecontext(context->stack, STACK_SIZE);\r
-       context->uc.uc_stack.ss_size = pth_sksize_makecontext(context->stack, STACK_SIZE);\r
-       \r
-       context->exception = xbt_new(ex_ctx_t, 1);\r
-       XBT_CTX_INITIALIZE(context->exception);\r
-       context->iwannadie = 0;           /* useless but makes valgrind happy */\r
-       context->argc = argc;\r
-       context->argv = argv;\r
-       context->startup_func = startup_func;\r
-       context->startup_arg = startup_arg;\r
-       context->cleanup_func = cleanup_func;\r
-       context->cleanup_arg = cleanup_arg;\r
-       \r
-       \r
-       context->free = xbt_ctx_sysv_free;                      \r
-       context->kill = xbt_ctx_sysv_kill;                      \r
-       context->schedule = xbt_ctx_sysv_schedule;\r
-       context->yield = xbt_ctx_sysv_yield;                    \r
-       context->start = xbt_ctx_sysv_start;                    \r
-       context->stop = xbt_ctx_sysv_stop;                      \r
-       \r
-       return (xbt_context_t)context;\r
-}\r
-\r
-static void \r
-xbt_ctx_sysv_free(xbt_context_t context)\r
-{\r
-       if(context)\r
-       {\r
-               free(context->name);\r
-               \r
-               if(context->argv)\r
-               {\r
-                       int i;\r
-                       \r
-                       for(i = 0; i < context->argc; i++)\r
-                               if(context->argv[i])\r
-                                       free(context->argv[i]);\r
-                                       \r
-                       free(context->argv);\r
-               }\r
-               \r
-               if(context->exception) \r
-                       free(context->exception);\r
-               \r
-               /* finally destroy the context */\r
-               free(context);\r
-       }\r
-}\r
-\r
-static void \r
-xbt_ctx_sysv_kill(xbt_context_t context)\r
-{\r
-       context->iwannadie = 1;\r
-       xbt_ctx_sysv_swap(context);\r
-}\r
-\r
-/** \r
- * \param context the winner\r
- *\r
- * Calling this function blocks the current context and schedule \a context.  \r
- * When \a context will call xbt_context_yield, it will return\r
- * to this function as if nothing had happened.\r
- * \r
- * Only the maestro can call this function to run a given process.\r
- */\r
-static void \r
-xbt_ctx_sysv_schedule(xbt_context_t context)\r
-{\r
-       xbt_assert0((current_context == maestro_context),"You are not supposed to run this function here!");\r
-       xbt_ctx_sysv_swap(context);\r
-}\r
-\r
-/** \r
- * Calling this function makes the current context yield. The context\r
- * that scheduled it returns from xbt_context_schedule as if nothing\r
- * had happened.\r
- * \r
- * Only the processes can call this function, giving back the control\r
- * to the maestro\r
- */\r
-static void \r
-xbt_ctx_sysv_yield(void)\r
-{\r
-       xbt_assert0((current_context != maestro_context),"You are not supposed to run this function here!");\r
-       xbt_ctx_sysv_swap(current_context);\r
-}\r
-\r
-static void \r
-xbt_ctx_sysv_start(xbt_context_t context)\r
-{\r
-       makecontext(&(((xbt_ctx_sysv_t)context)->uc), xbt_ctx_sysv_wrapper, 0);\r
-}\r
-\r
-static void \r
-xbt_ctx_sysv_stop(int exit_code)\r
-{\r
-       if(current_context->cleanup_func) \r
-               ((*current_context->cleanup_func))(current_context->cleanup_arg);\r
-       \r
-       xbt_swag_remove(current_context, context_living);\r
-       xbt_swag_insert(current_context, context_to_destroy);   \r
-       \r
-       xbt_ctx_sysv_swap(current_context);\r
-}\r
-\r
-static void \r
-xbt_ctx_sysv_swap(xbt_context_t context)\r
-{\r
-       xbt_assert0(current_context, "You have to call context_init() first.");\r
-       xbt_assert0(context, "Invalid argument");\r
-       \r
-       if(((xbt_ctx_sysv_t)context)->prev == NULL) \r
-               xbt_ctx_sysv_resume(context);\r
-       else \r
-               xbt_ctx_sysv_suspend(context);\r
-       \r
-       if(current_context->iwannadie)\r
-               xbt_ctx_sysv_stop(1);\r
-}\r
-\r
-static void\r
-xbt_ctx_sysv_wrapper(void)\r
-{\r
-       if (current_context->startup_func)\r
-               (*current_context->startup_func)(current_context->startup_arg);\r
-       \r
-       xbt_ctx_sysv_stop((*(current_context->code))(current_context->argc, current_context->argv));\r
-}\r
-\r
-static void\r
-xbt_ctx_sysv_suspend(xbt_context_t context)\r
-{\r
-       int rv;\r
-       \r
-       xbt_ctx_sysv_t prev_context = ((xbt_ctx_sysv_t)context)->prev;\r
-       \r
-       current_context = (xbt_context_t)(((xbt_ctx_sysv_t)context)->prev);\r
-       \r
-       ((xbt_ctx_sysv_t)context)->prev = NULL;\r
-       \r
-       rv = swapcontext(&(((xbt_ctx_sysv_t)context)->uc), &(prev_context->uc));\r
-               \r
-       xbt_assert0((rv == 0), "Context swapping failure");\r
-}\r
-\r
-static void\r
-xbt_ctx_sysv_resume(xbt_context_t context)\r
-{\r
-       int rv;\r
-       \r
-       ((xbt_ctx_sysv_t)context)->prev = (xbt_ctx_sysv_t)current_context;\r
-       \r
-       current_context = context;\r
-       \r
-       rv = swapcontext(&(((xbt_ctx_sysv_t)context)->prev->uc), &(((xbt_ctx_sysv_t)context)->uc));\r
-               \r
-       xbt_assert0((rv == 0), "Context swapping failure");\r
-}\r
-\r
-\r
-\r
+
+#include "xbt/ex_interface.h"
+#include "xbt/xbt_context_private.h"
+
+#include "context_sysv_config.h"        /* loads context system definitions                             */
+#include "portable.h"
+#include <ucontext.h>           /* context relative declarations                                */
+#define STACK_SIZE 128*1024     /* lower this if you want to reduce the memory consumption      */
+
+typedef struct s_xbt_ctx_sysv {
+  XBT_CTX_BASE_T;
+  ucontext_t uc;                /* the thread that execute the code                             */
+  char stack[STACK_SIZE];       /* the thread stack size                                        */
+  struct s_xbt_ctx_sysv *prev;  /* the previous thread                                              */
+} s_xbt_ctx_sysv_t, *xbt_ctx_sysv_t;
+
+
+/* callback: context fetching */
+static ex_ctx_t *xbt_jcontext_ex_ctx(void);
+
+/* callback: termination */
+static void xbt_jcontext_ex_terminate(xbt_ex_t * e);
+
+static xbt_context_t
+xbt_ctx_sysv_factory_create_context(const char *name, xbt_main_func_t code,
+                                    void_f_pvoid_t startup_func,
+                                    void *startup_arg,
+                                    void_f_pvoid_t cleanup_func,
+                                    void *cleanup_arg, int argc, char **argv);
+
+static int xbt_ctx_sysv_factory_finalize(xbt_context_factory_t * factory);
+
+static int
+xbt_ctx_sysv_factory_create_maestro_context(xbt_context_t * maestro);
+
+static void xbt_ctx_sysv_free(xbt_context_t context);
+
+static void xbt_ctx_sysv_kill(xbt_context_t context);
+
+static void xbt_ctx_sysv_schedule(xbt_context_t context);
+
+static void xbt_ctx_sysv_yield(void);
+
+static void xbt_ctx_sysv_start(xbt_context_t context);
+
+static void xbt_ctx_sysv_stop(int exit_code);
+
+static void xbt_ctx_sysv_swap(xbt_context_t context);
+
+static void xbt_ctx_sysv_schedule(xbt_context_t context);
+
+static void xbt_ctx_sysv_yield(void);
+
+static void xbt_ctx_sysv_suspend(xbt_context_t context);
+
+static void xbt_ctx_sysv_resume(xbt_context_t context);
+
+static void xbt_ctx_sysv_wrapper(void);
+
+/* callback: context fetching */
+static ex_ctx_t *xbt_ctx_sysv_ex_ctx(void)
+{
+  return current_context->exception;
+}
+
+/* callback: termination */
+static void xbt_ctx_sysv_ex_terminate(xbt_ex_t * e)
+{
+  xbt_ex_display(e);
+  abort();
+}
+
+
+void xbt_ctx_sysv_factory_init(xbt_context_factory_t * factory)
+{
+  /* context exception */
+  *factory = xbt_new0(s_xbt_context_factory_t, 1);
+
+  (*factory)->create_context = xbt_ctx_sysv_factory_create_context;
+  (*factory)->finalize = xbt_ctx_sysv_factory_finalize;
+  (*factory)->create_maestro_context =
+    xbt_ctx_sysv_factory_create_maestro_context;
+  (*factory)->name = "ctx_sysv_context_factory";
+
+  /* context exception handlers */
+  __xbt_ex_ctx = xbt_ctx_sysv_ex_ctx;
+  __xbt_ex_terminate = xbt_ctx_sysv_ex_terminate;
+}
+
+static int
+xbt_ctx_sysv_factory_create_maestro_context(xbt_context_t * maestro)
+{
+
+  xbt_ctx_sysv_t context = xbt_new0(s_xbt_ctx_sysv_t, 1);
+
+  context->exception = xbt_new(ex_ctx_t, 1);
+  XBT_CTX_INITIALIZE(context->exception);
+
+  *maestro = (xbt_context_t) context;
+
+  return 0;
+
+}
+
+
+static int xbt_ctx_sysv_factory_finalize(xbt_context_factory_t * factory)
+{
+  free(maestro_context->exception);
+  free(*factory);
+  *factory = NULL;
+  return 0;
+}
+
+static xbt_context_t
+xbt_ctx_sysv_factory_create_context(const char *name, xbt_main_func_t code,
+                                    void_f_pvoid_t startup_func,
+                                    void *startup_arg,
+                                    void_f_pvoid_t cleanup_func,
+                                    void *cleanup_arg, int argc, char **argv)
+{
+  xbt_ctx_sysv_t context = xbt_new0(s_xbt_ctx_sysv_t, 1);
+
+  context->code = code;
+  context->name = xbt_strdup(name);
+
+  xbt_assert2(getcontext(&(context->uc)) == 0,
+              "Error in context saving: %d (%s)", errno, strerror(errno));
+  context->uc.uc_link = NULL;
+  context->uc.uc_stack.ss_sp =
+    pth_skaddr_makecontext(context->stack, STACK_SIZE);
+  context->uc.uc_stack.ss_size =
+    pth_sksize_makecontext(context->stack, STACK_SIZE);
+
+  context->exception = xbt_new(ex_ctx_t, 1);
+  XBT_CTX_INITIALIZE(context->exception);
+  context->iwannadie = 0;       /* useless but makes valgrind happy */
+  context->argc = argc;
+  context->argv = argv;
+  context->startup_func = startup_func;
+  context->startup_arg = startup_arg;
+  context->cleanup_func = cleanup_func;
+  context->cleanup_arg = cleanup_arg;
+
+
+  context->free = xbt_ctx_sysv_free;
+  context->kill = xbt_ctx_sysv_kill;
+  context->schedule = xbt_ctx_sysv_schedule;
+  context->yield = xbt_ctx_sysv_yield;
+  context->start = xbt_ctx_sysv_start;
+  context->stop = xbt_ctx_sysv_stop;
+
+  return (xbt_context_t) context;
+}
+
+static void xbt_ctx_sysv_free(xbt_context_t context)
+{
+  if (context) {
+    free(context->name);
+
+    if (context->argv) {
+      int i;
+
+      for (i = 0; i < context->argc; i++)
+        if (context->argv[i])
+          free(context->argv[i]);
+
+      free(context->argv);
+    }
+
+    if (context->exception)
+      free(context->exception);
+
+    /* finally destroy the context */
+    free(context);
+  }
+}
+
+static void xbt_ctx_sysv_kill(xbt_context_t context)
+{
+  context->iwannadie = 1;
+  xbt_ctx_sysv_swap(context);
+}
+
+/** 
+ * \param context the winner
+ *
+ * Calling this function blocks the current context and schedule \a context.  
+ * When \a context will call xbt_context_yield, it will return
+ * to this function as if nothing had happened.
+ * 
+ * Only the maestro can call this function to run a given process.
+ */
+static void xbt_ctx_sysv_schedule(xbt_context_t context)
+{
+  xbt_assert0((current_context == maestro_context),
+              "You are not supposed to run this function here!");
+  xbt_ctx_sysv_swap(context);
+}
+
+/** 
+ * Calling this function makes the current context yield. The context
+ * that scheduled it returns from xbt_context_schedule as if nothing
+ * had happened.
+ * 
+ * Only the processes can call this function, giving back the control
+ * to the maestro
+ */
+static void xbt_ctx_sysv_yield(void)
+{
+  xbt_assert0((current_context != maestro_context),
+              "You are not supposed to run this function here!");
+  xbt_ctx_sysv_swap(current_context);
+}
+
+static void xbt_ctx_sysv_start(xbt_context_t context)
+{
+  makecontext(&(((xbt_ctx_sysv_t) context)->uc), xbt_ctx_sysv_wrapper, 0);
+}
+
+static void xbt_ctx_sysv_stop(int exit_code)
+{
+  if (current_context->cleanup_func)
+    ((*current_context->cleanup_func)) (current_context->cleanup_arg);
+
+  xbt_swag_remove(current_context, context_living);
+  xbt_swag_insert(current_context, context_to_destroy);
+
+  xbt_ctx_sysv_swap(current_context);
+}
+
+static void xbt_ctx_sysv_swap(xbt_context_t context)
+{
+  xbt_assert0(current_context, "You have to call context_init() first.");
+  xbt_assert0(context, "Invalid argument");
+
+  if (((xbt_ctx_sysv_t) context)->prev == NULL)
+    xbt_ctx_sysv_resume(context);
+  else
+    xbt_ctx_sysv_suspend(context);
+
+  if (current_context->iwannadie)
+    xbt_ctx_sysv_stop(1);
+}
+
+static void xbt_ctx_sysv_wrapper(void)
+{
+  if (current_context->startup_func)
+    (*current_context->startup_func) (current_context->startup_arg);
+
+  xbt_ctx_sysv_stop((*(current_context->code))
+                    (current_context->argc, current_context->argv));
+}
+
+static void xbt_ctx_sysv_suspend(xbt_context_t context)
+{
+  int rv;
+
+  xbt_ctx_sysv_t prev_context = ((xbt_ctx_sysv_t) context)->prev;
+
+  current_context = (xbt_context_t) (((xbt_ctx_sysv_t) context)->prev);
+
+  ((xbt_ctx_sysv_t) context)->prev = NULL;
+
+  rv = swapcontext(&(((xbt_ctx_sysv_t) context)->uc), &(prev_context->uc));
+
+  xbt_assert0((rv == 0), "Context swapping failure");
+}
+
+static void xbt_ctx_sysv_resume(xbt_context_t context)
+{
+  int rv;
+
+  ((xbt_ctx_sysv_t) context)->prev = (xbt_ctx_sysv_t) current_context;
+
+  current_context = context;
+
+  rv =
+    swapcontext(&(((xbt_ctx_sysv_t) context)->prev->uc),
+                &(((xbt_ctx_sysv_t) context)->uc));
+
+  xbt_assert0((rv == 0), "Context swapping failure");
+}