Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
dos2unix + indent
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Tue, 27 May 2008 10:13:00 +0000 (10:13 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Tue, 27 May 2008 10:13:00 +0000 (10:13 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@5501 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/xbt/xbt_context.c
src/xbt/xbt_context_java.c
src/xbt/xbt_context_java.h
src/xbt/xbt_context_private.h
src/xbt/xbt_context_sysv.c
src/xbt/xbt_context_thread.c

index 8774486..a1b719e 100644 (file)
-/* a fast and simple context switching library                              */\r
-\r
-/* Copyright (c) 2004 Arnaud Legrand.                                       */\r
-/* Copyright (c) 2004, 2005 Martin Quinson.                                 */\r
-/* All rights reserved.                                                     */\r
-\r
-/* This program is free software; you can redistribute it and/or modify it\r
- * under the terms of the license (GNU LGPL) which comes with this package. */\r
-\r
-#include "portable.h"\r
-#include "xbt/log.h"\r
-#include "xbt/swag.h"\r
-#include "xbt_context_private.h"\r
-\r
-/* the context associated with the current process                             */\r
-xbt_context_t current_context = NULL;\r
-\r
-/* the context associated with the maestro                                             */\r
-xbt_context_t  maestro_context = NULL;\r
-\r
-\r
-/* this list contains the contexts to destroy                                  */\r
-xbt_swag_t context_to_destroy = NULL;\r
-\r
-/* this list contains the contexts in use                                              */\r
-xbt_swag_t context_living = NULL;\r
-\r
-/* the context factory used to create the appropriate context  \r
- * each context implementation define its own context factory\r
- * a context factory is responsable of the creation of the context\r
- * associated with the maestro and of all the context based on\r
- * the selected implementation.\r
- *\r
- * for example, the context switch based on java thread use the\r
- * java implementation of the context and the java factory build\r
- * the context depending of this implementation.\r
- */\r
-static xbt_context_factory_t\r
-context_factory = NULL;\r
-\r
-/**\r
- * This function is call by the xbt_init() function to initialize the context module.\r
- */\r
-void\r
-xbt_context_mod_init(void)\r
-{\r
-       if(!context_factory)\r
-       {\r
-               /* select context factory to use to create the context(depends of the macro definitions) */\r
-\r
-               #ifdef CONTEXT_THREADS\r
-                       /* context switch based os thread */\r
-                       xbt_ctx_thread_factory_init(&context_factory);\r
-               #elif !defined(WIN32)\r
-                       /* context switch based ucontext */\r
-                       xbt_ctx_sysv_factory_init(&context_factory);\r
-               #else\r
-                       /* context switch is not allowed on Windows */\r
-                       #error ERROR [__FILE__, line __LINE__]: no context based implementation specified.\r
-               #endif\r
-               \r
-               /* maestro context specialisation (this create the maestro with the good implementation */\r
-               (*(context_factory->create_maestro_context))(&maestro_context);\r
-               \r
-               /* the current context is the context of the maestro */\r
-               current_context = maestro_context;\r
-               \r
-               /* the current context doesn't want to die */\r
-               current_context->iwannadie = 0;\r
-               \r
-               /* intantiation of the lists containing the contexts to destroy and the contexts in use */  \r
-               context_to_destroy = xbt_swag_new(xbt_swag_offset(*current_context, hookup));\r
-               context_living = xbt_swag_new(xbt_swag_offset(*current_context, hookup));\r
-               \r
-               /* insert the current context in the list of the contexts in use */\r
-               xbt_swag_insert(current_context, context_living);\r
-               \r
-       }                \r
-} \r
-\r
-/**\r
- * This function is call by the xbt_exit() function to finalize the context module.\r
- */\r
-void\r
-xbt_context_mod_exit(void)\r
-{\r
-       if(context_factory)\r
-       {\r
-               xbt_context_t context = NULL;\r
-               xbt_pfn_context_factory_finalize_t finalize_factory;\r
-               \r
-               /* finalize the context factory */\r
-               finalize_factory = context_factory->finalize;\r
-               \r
-               (*finalize_factory)(&context_factory);\r
-               \r
-               /* destroy all contexts in the list of contexts to destroy */\r
-               xbt_context_empty_trash();\r
-               \r
-               /* remove the context of the scheduler from the list of the contexts in use */\r
-               xbt_swag_remove(maestro_context, context_living);\r
-               \r
-               /*  \r
-                * kill all the contexts in use :\r
-                * the killed contexts are added in the list of the contexts to destroy\r
-                */\r
-               while((context = xbt_swag_extract(context_living))) \r
-                               (*(context->kill))(context);    \r
-       \r
-               \r
-               /* destroy all contexts in the list of contexts to destroy */\r
-               xbt_context_empty_trash();\r
-               \r
-               free(maestro_context);\r
-               maestro_context = current_context = NULL;\r
-               \r
-               /* destroy the lists */\r
-               xbt_swag_free(context_to_destroy);\r
-               xbt_swag_free(context_living);\r
-       }\r
-}\r
-\r
-/*******************************/\r
-/* Object creation/destruction */\r
-/*******************************/\r
-/** \r
- * \param code a main function\r
- * \param startup_func a function to call when running the context for\r
- *      the first time and just before the main function \a code\r
- * \param startup_arg the argument passed to the previous function (\a startup_func)\r
- * \param cleanup_func a function to call when running the context, just after \r
-        the termination of the main function \a code\r
- * \param cleanup_arg the argument passed to the previous function (\a cleanup_func)\r
- * \param argc first argument of function \a code\r
- * \param argv seconde argument of function \a code\r
- */\r
-xbt_context_t\r
-xbt_context_new(const char *name,\r
-                xbt_main_func_t code,\r
-                void_f_pvoid_t startup_func,\r
-                void *startup_arg,\r
-                void_f_pvoid_t cleanup_func,\r
-                void *cleanup_arg, int argc, char *argv[]\r
-)\r
-{\r
-       /* use the appropriate context factory to create the appropriate context */\r
-       xbt_context_t context = (*(context_factory->create_context))(name, code, startup_func, startup_arg, cleanup_func, cleanup_arg, argc, argv);\r
-       \r
-       /* add the context in the list of the contexts in use */\r
-       xbt_swag_insert(context, context_living);\r
-\r
-       return context;\r
-}\r
-\r
-/* Scenario for the end of a context:\r
- * \r
- * CASE 1: death after end of function\r
- *   __context_wrapper, called by os thread, calls xbt_context_stop after user code stops\r
- *   xbt_context_stop calls user cleanup_func if any (in context settings),\r
- *                    add current to trashbin\r
- *                    yields back to maestro (destroy os thread on need)\r
- *   From time to time, maestro calls xbt_context_empty_trash, \r
- *       which maps xbt_context_free on the content\r
- *   xbt_context_free frees some more memory, \r
- *                    joins os thread\r
- * \r
- * CASE 2: brutal death\r
- *   xbt_context_kill (from any context)\r
- *                    set context->wannadie to 1\r
- *                    yields to the context\r
- *   the context is awaken in the middle of __yield. \r
- *   At the end of it, it checks that wannadie == 1, and call xbt_context_stop\r
- *   (same than first case afterward)\r
- */\r
-\r
-\r
-/* Argument must be stopped first -- runs in maestro context */\r
-void\r
-xbt_context_free(xbt_context_t context)\r
-{\r
-       (*(context->free))(context);    \r
-}\r
-\r
-\r
-void\r
-xbt_context_kill(xbt_context_t context)\r
-{\r
-       (*(context->kill))(context);    \r
-}\r
-\r
-/** \r
- * \param context the context to start\r
- * \r
- * Calling this function prepares \a context to be run. It will \r
-   however run effectively only when calling #xbt_context_schedule\r
- */\r
-void\r
-xbt_context_start(xbt_context_t context)\r
-{\r
-       (*(context->start))(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
-void\r
-xbt_context_yield(void)\r
-{\r
-       (*(current_context->yield))();  \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
-void\r
-xbt_context_schedule(xbt_context_t context)\r
-{\r
-       (*(context->schedule))(context);        \r
-}\r
-\r
-void\r
-xbt_context_stop(int exit_code)\r
-{\r
-\r
-       (*(current_context->stop))(exit_code);\r
-}\r
-\r
-int\r
-xbt_context_select_factory(const char* name)\r
-{\r
-       /* if a factory is already instantiated (xbt_context_mod_init() was called) */\r
-       if(NULL != context_factory)\r
-       {\r
-               /* if the desired factory is different of the current factory, call xbt_context_mod_exit() */\r
-               if(strcmp(context_factory->name,name))\r
-                       xbt_context_mod_exit();\r
-               else\r
-                       /* the same context factory is requested return directly */\r
-                       return 0;\r
-       }\r
-       \r
-       /* get the desired factory */\r
-       xbt_context_init_factory_by_name(&context_factory,name);\r
-       \r
-       /* maestro context specialisation */\r
-       (*(context_factory->create_maestro_context))(&maestro_context);\r
-       \r
-       /* the current context is the context of the maestro */\r
-       current_context = maestro_context;\r
-       \r
-       /* the current context doesn't want to die */\r
-       current_context->iwannadie = 0;\r
-       \r
-       /* intantiation of the lists containing the contexts to destroy and the contexts in use */  \r
-       context_to_destroy = xbt_swag_new(xbt_swag_offset(*current_context, hookup));\r
-       context_living = xbt_swag_new(xbt_swag_offset(*current_context, hookup));\r
-       \r
-       /* insert the current context in the list of the contexts in use */\r
-       xbt_swag_insert(current_context, context_living);       \r
-       \r
-       return 0;       \r
-}\r
-\r
-void\r
-xbt_context_init_factory_by_name(xbt_context_factory_t* factory, const char* name)\r
-{\r
-   if(!strcmp(name,"java")) \r
-      xbt_ctx_java_factory_init(factory);\r
-#ifdef CONTEXT_THREADS\r
-   else if(!strcmp(name,"thread"))     \r
-     xbt_ctx_thread_factory_init(factory);     \r
-#elif !defined(WIN32)\r
-   else if(!strcmp(name,"sysv"))\r
-     xbt_ctx_sysv_factory_init(factory);       \r
-#endif\r
-   else\r
-     THROW1(not_found_error, 0,"Factory '%s' does not exist",name);\r
-}\r
-\r
-/** Garbage collection\r
- *\r
- * Should be called some time to time to free the memory allocated for contexts\r
- * that have finished executing their main functions.\r
- */\r
-void \r
-xbt_context_empty_trash(void)\r
-{\r
-       xbt_context_t context = NULL;\r
-       \r
-       while((context = xbt_swag_extract(context_to_destroy)))\r
-               (*(context->free))(context);\r
-}\r
-\r
-\r
-\r
+/* a fast and simple context switching library                              */
+
+/* Copyright (c) 2004 Arnaud Legrand.                                       */
+/* Copyright (c) 2004, 2005 Martin Quinson.                                 */
+/* 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. */
+
+#include "portable.h"
+#include "xbt/log.h"
+#include "xbt/swag.h"
+#include "xbt_context_private.h"
+
+/* the context associated with the current process                             */
+xbt_context_t current_context = NULL;
+
+/* the context associated with the maestro                                             */
+xbt_context_t maestro_context = NULL;
+
+
+/* this list contains the contexts to destroy                                  */
+xbt_swag_t context_to_destroy = NULL;
+
+/* this list contains the contexts in use                                              */
+xbt_swag_t context_living = NULL;
+
+/* the context factory used to create the appropriate context  
+ * each context implementation define its own context factory
+ * a context factory is responsable of the creation of the context
+ * associated with the maestro and of all the context based on
+ * the selected implementation.
+ *
+ * for example, the context switch based on java thread use the
+ * java implementation of the context and the java factory build
+ * the context depending of this implementation.
+ */
+static xbt_context_factory_t context_factory = NULL;
+
+/**
+ * This function is call by the xbt_init() function to initialize the context module.
+ */
+void xbt_context_mod_init(void)
+{
+  if (!context_factory) {
+    /* select context factory to use to create the context(depends of the macro definitions) */
+
+#ifdef CONTEXT_THREADS
+    /* context switch based os thread */
+    xbt_ctx_thread_factory_init(&context_factory);
+#elif !defined(WIN32)
+    /* context switch based ucontext */
+    xbt_ctx_sysv_factory_init(&context_factory);
+#else
+    /* context switch is not allowed on Windows */
+#error ERROR [__FILE__, line __LINE__]: no context based implementation specified.
+#endif
+
+    /* maestro context specialisation (this create the maestro with the good implementation */
+    (*(context_factory->create_maestro_context)) (&maestro_context);
+
+    /* the current context is the context of the maestro */
+    current_context = maestro_context;
+
+    /* the current context doesn't want to die */
+    current_context->iwannadie = 0;
+
+    /* intantiation of the lists containing the contexts to destroy and the contexts in use */
+    context_to_destroy =
+      xbt_swag_new(xbt_swag_offset(*current_context, hookup));
+    context_living = xbt_swag_new(xbt_swag_offset(*current_context, hookup));
+
+    /* insert the current context in the list of the contexts in use */
+    xbt_swag_insert(current_context, context_living);
+
+  }
+}
+
+/**
+ * This function is call by the xbt_exit() function to finalize the context module.
+ */
+void xbt_context_mod_exit(void)
+{
+  if (context_factory) {
+    xbt_context_t context = NULL;
+    xbt_pfn_context_factory_finalize_t finalize_factory;
+
+    /* finalize the context factory */
+    finalize_factory = context_factory->finalize;
+
+    (*finalize_factory) (&context_factory);
+
+    /* destroy all contexts in the list of contexts to destroy */
+    xbt_context_empty_trash();
+
+    /* remove the context of the scheduler from the list of the contexts in use */
+    xbt_swag_remove(maestro_context, context_living);
+
+    /*  
+     * kill all the contexts in use :
+     * the killed contexts are added in the list of the contexts to destroy
+     */
+    while ((context = xbt_swag_extract(context_living)))
+      (*(context->kill)) (context);
+
+
+    /* destroy all contexts in the list of contexts to destroy */
+    xbt_context_empty_trash();
+
+    free(maestro_context);
+    maestro_context = current_context = NULL;
+
+    /* destroy the lists */
+    xbt_swag_free(context_to_destroy);
+    xbt_swag_free(context_living);
+  }
+}
+
+/*******************************/
+/* Object creation/destruction */
+/*******************************/
+/** 
+ * \param code a main function
+ * \param startup_func a function to call when running the context for
+ *      the first time and just before the main function \a code
+ * \param startup_arg the argument passed to the previous function (\a startup_func)
+ * \param cleanup_func a function to call when running the context, just after 
+        the termination of the main function \a code
+ * \param cleanup_arg the argument passed to the previous function (\a cleanup_func)
+ * \param argc first argument of function \a code
+ * \param argv seconde argument of function \a code
+ */
+xbt_context_t
+xbt_context_new(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[]
+  )
+{
+  /* use the appropriate context factory to create the appropriate context */
+  xbt_context_t context =
+    (*(context_factory->create_context)) (name, code, startup_func,
+                                          startup_arg, cleanup_func,
+                                          cleanup_arg, argc, argv);
+
+  /* add the context in the list of the contexts in use */
+  xbt_swag_insert(context, context_living);
+
+  return context;
+}
+
+/* Scenario for the end of a context:
+ * 
+ * CASE 1: death after end of function
+ *   __context_wrapper, called by os thread, calls xbt_context_stop after user code stops
+ *   xbt_context_stop calls user cleanup_func if any (in context settings),
+ *                    add current to trashbin
+ *                    yields back to maestro (destroy os thread on need)
+ *   From time to time, maestro calls xbt_context_empty_trash, 
+ *       which maps xbt_context_free on the content
+ *   xbt_context_free frees some more memory, 
+ *                    joins os thread
+ * 
+ * CASE 2: brutal death
+ *   xbt_context_kill (from any context)
+ *                    set context->wannadie to 1
+ *                    yields to the context
+ *   the context is awaken in the middle of __yield. 
+ *   At the end of it, it checks that wannadie == 1, and call xbt_context_stop
+ *   (same than first case afterward)
+ */
+
+
+/* Argument must be stopped first -- runs in maestro context */
+void xbt_context_free(xbt_context_t context)
+{
+  (*(context->free)) (context);
+}
+
+
+void xbt_context_kill(xbt_context_t context)
+{
+  (*(context->kill)) (context);
+}
+
+/** 
+ * \param context the context to start
+ * 
+ * Calling this function prepares \a context to be run. It will 
+   however run effectively only when calling #xbt_context_schedule
+ */
+void xbt_context_start(xbt_context_t context)
+{
+  (*(context->start)) (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
+ */
+void xbt_context_yield(void)
+{
+  (*(current_context->yield)) ();
+}
+
+/** 
+ * \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.
+ */
+void xbt_context_schedule(xbt_context_t context)
+{
+  (*(context->schedule)) (context);
+}
+
+void xbt_context_stop(int exit_code)
+{
+
+  (*(current_context->stop)) (exit_code);
+}
+
+int xbt_context_select_factory(const char *name)
+{
+  /* if a factory is already instantiated (xbt_context_mod_init() was called) */
+  if (NULL != context_factory) {
+    /* if the desired factory is different of the current factory, call xbt_context_mod_exit() */
+    if (strcmp(context_factory->name, name))
+      xbt_context_mod_exit();
+    else
+      /* the same context factory is requested return directly */
+      return 0;
+  }
+
+  /* get the desired factory */
+  xbt_context_init_factory_by_name(&context_factory, name);
+
+  /* maestro context specialisation */
+  (*(context_factory->create_maestro_context)) (&maestro_context);
+
+  /* the current context is the context of the maestro */
+  current_context = maestro_context;
+
+  /* the current context doesn't want to die */
+  current_context->iwannadie = 0;
+
+  /* intantiation of the lists containing the contexts to destroy and the contexts in use */
+  context_to_destroy =
+    xbt_swag_new(xbt_swag_offset(*current_context, hookup));
+  context_living = xbt_swag_new(xbt_swag_offset(*current_context, hookup));
+
+  /* insert the current context in the list of the contexts in use */
+  xbt_swag_insert(current_context, context_living);
+
+  return 0;
+}
+
+void
+xbt_context_init_factory_by_name(xbt_context_factory_t * factory,
+                                 const char *name)
+{
+  if (!strcmp(name, "java"))
+    xbt_ctx_java_factory_init(factory);
+#ifdef CONTEXT_THREADS
+  else if (!strcmp(name, "thread"))
+    xbt_ctx_thread_factory_init(factory);
+#elif !defined(WIN32)
+  else if (!strcmp(name, "sysv"))
+    xbt_ctx_sysv_factory_init(factory);
+#endif
+  else
+    THROW1(not_found_error, 0, "Factory '%s' does not exist", name);
+}
+
+/** Garbage collection
+ *
+ * Should be called some time to time to free the memory allocated for contexts
+ * that have finished executing their main functions.
+ */
+void xbt_context_empty_trash(void)
+{
+  xbt_context_t context = NULL;
+
+  while ((context = xbt_swag_extract(context_to_destroy)))
+    (*(context->free)) (context);
+}
index 156fba3..7089548 100644 (file)
-\r
-\r
-#include "xbt/function_types.h"\r
-#include "xbt/ex_interface.h"\r
-#include "xbt/xbt_context_private.h"\r
-#include "xbt/xbt_context_java.h"\r
-\r
-XBT_LOG_NEW_DEFAULT_CATEGORY(jmsg,"MSG for Java(TM)");\r
-\r
-/* callback: context fetching */\r
-static ex_ctx_t*\r
-xbt_ctx_java_ex_ctx(void);\r
-\r
-/* callback: termination */\r
-static void \r
-xbt_ctx_java_ex_terminate(xbt_ex_t *e);\r
-\r
-static xbt_context_t \r
-xbt_ctx_java_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_java_factory_create_maestro_context(xbt_context_t* maestro);\r
-\r
-static int\r
-xbt_ctx_java_factory_finalize(xbt_context_factory_t* factory);\r
-\r
-static void \r
-xbt_ctx_java_free(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_java_kill(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_java_schedule(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_java_yield(void);\r
-\r
-static void \r
-xbt_ctx_java_start(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_java_stop(int exit_code);\r
-\r
-static void \r
-xbt_ctx_java_swap(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_java_schedule(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_java_yield(void);\r
-\r
-static void\r
-xbt_ctx_java_suspend(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_java_resume(xbt_context_t context);\r
-\r
-\r
-/* callback: context fetching */\r
-static ex_ctx_t*\r
-xbt_ctx_java_ex_ctx(void) \r
-{\r
-       return current_context->exception;\r
-}\r
-\r
-/* callback: termination */\r
-static void \r
-xbt_ctx_java_ex_terminate(xbt_ex_t *e) \r
-{\r
-       xbt_ex_display(e);\r
-       abort();\r
-}\r
-\r
-void\r
-xbt_ctx_java_factory_init(xbt_context_factory_t* factory)\r
-{\r
-       /* context exception handlers */\r
-    __xbt_ex_ctx       = xbt_ctx_java_ex_ctx;\r
-    __xbt_ex_terminate = xbt_ctx_java_ex_terminate;    \r
-    \r
-    /* instantiate the context factory */\r
-       *factory = xbt_new0(s_xbt_context_factory_t,1);\r
-       \r
-       (*factory)->create_context = xbt_ctx_java_factory_create_context;\r
-       (*factory)->finalize = xbt_ctx_java_factory_finalize;\r
-       (*factory)->create_maestro_context = xbt_ctx_java_factory_create_maestro_context;\r
-       (*factory)->name = "ctx_java_factory";\r
-}\r
-\r
-static int \r
-xbt_ctx_java_factory_create_maestro_context(xbt_context_t* maestro)\r
-{\r
-       xbt_ctx_java_t context = xbt_new0(s_xbt_ctx_java_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
-static int\r
-xbt_ctx_java_factory_finalize(xbt_context_factory_t* factory)\r
-{\r
-       free(maestro_context->exception);\r
-       free(*factory);\r
-       *factory = NULL;\r
-\r
-       return 0;\r
-}\r
-\r
-static xbt_context_t \r
-xbt_ctx_java_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_java_t context = xbt_new0(s_xbt_ctx_java_t,1);\r
-\r
-       context->name = xbt_strdup(name);\r
-\r
-       context->cleanup_func = cleanup_func;\r
-       context->cleanup_arg = cleanup_arg;\r
-\r
-       context->exception = xbt_new(ex_ctx_t,1);\r
-       XBT_CTX_INITIALIZE(context->exception);\r
-\r
-       context->free = xbt_ctx_java_free;                      \r
-       context->kill = xbt_ctx_java_kill;                      \r
-       context->schedule = xbt_ctx_java_schedule;\r
-       context->yield = xbt_ctx_java_yield;                    \r
-       context->start = xbt_ctx_java_start;                    \r
-       context->stop = xbt_ctx_java_stop;      \r
-       context->jprocess = (jobject)startup_arg;\r
-       context->jenv = get_current_thread_env();\r
-\r
-       return (xbt_context_t)context;\r
-}\r
-\r
-static void \r
-xbt_ctx_java_free(xbt_context_t context)\r
-{\r
-       if(context) \r
-       {\r
-               xbt_ctx_java_t ctx_java = (xbt_ctx_java_t)context;\r
-               \r
-               free(ctx_java->name);\r
-               \r
-               if(ctx_java->jprocess) \r
-               {\r
-                       jobject jprocess = ctx_java->jprocess;\r
-                       ctx_java->jprocess = NULL;\r
-\r
-                       /* if the java process is alive join it */\r
-                       if(jprocess_is_alive(jprocess,get_current_thread_env())) \r
-                               jprocess_join(jprocess,get_current_thread_env());\r
-               }\r
-\r
-               if(ctx_java->exception) \r
-                       free(ctx_java->exception);\r
-\r
-               free(context);\r
-               context = NULL;\r
-       }\r
-}\r
-\r
-static void \r
-xbt_ctx_java_kill(xbt_context_t context)\r
-{\r
-       context->iwannadie = 1;\r
-       xbt_ctx_java_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_java_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_java_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_java_yield(void)\r
-{\r
-       xbt_assert0((current_context != maestro_context),"You are not supposed to run this function here!");\r
-       jprocess_unschedule(current_context);\r
-}\r
-\r
-static void \r
-xbt_ctx_java_start(xbt_context_t context)\r
-{\r
-       jprocess_start(((xbt_ctx_java_t)context)->jprocess,get_current_thread_env());\r
-}\r
-\r
-static void \r
-xbt_ctx_java_stop(int exit_code)\r
-{\r
-       jobject jprocess = NULL;\r
-       xbt_ctx_java_t ctx_java;\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
-       ctx_java = (xbt_ctx_java_t)current_context;\r
-       \r
-       if(ctx_java->iwannadie)\r
-       {\r
-               /* The maestro call xbt_context_stop() with an exit code set to one */\r
-               if(ctx_java->jprocess) \r
-               {\r
-                       /* if the java process is alive schedule it */\r
-                       if(jprocess_is_alive(ctx_java->jprocess,get_current_thread_env())) \r
-                       {\r
-                               jprocess_schedule(current_context);\r
-                               jprocess = ctx_java->jprocess;\r
-                               ctx_java->jprocess = NULL;\r
-                               \r
-                               /* interrupt the java process */\r
-                               jprocess_exit(jprocess,get_current_thread_env());\r
-\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               /* the java process exits */\r
-               jprocess = ctx_java->jprocess;\r
-               ctx_java->jprocess = NULL;\r
-       }\r
-\r
-       /* delete the global reference associated with the java process */\r
-       jprocess_delete_global_ref(jprocess,get_current_thread_env());  \r
-}\r
-\r
-static void \r
-xbt_ctx_java_swap(xbt_context_t context)\r
-{\r
-       if(context) \r
-       {\r
-               xbt_context_t self = current_context;\r
-               \r
-               current_context = context;\r
-               \r
-               jprocess_schedule(context);\r
-               \r
-               current_context = self;\r
-       }\r
-       \r
-       if(current_context->iwannadie)\r
-               xbt_ctx_java_stop(1);\r
-}\r
+
+
+#include "xbt/function_types.h"
+#include "xbt/ex_interface.h"
+#include "xbt/xbt_context_private.h"
+#include "xbt/xbt_context_java.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(jmsg, "MSG for Java(TM)");
+
+/* callback: context fetching */
+static ex_ctx_t *xbt_ctx_java_ex_ctx(void);
+
+/* callback: termination */
+static void xbt_ctx_java_ex_terminate(xbt_ex_t * e);
+
+static xbt_context_t
+xbt_ctx_java_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_java_factory_create_maestro_context(xbt_context_t * maestro);
+
+static int xbt_ctx_java_factory_finalize(xbt_context_factory_t * factory);
+
+static void xbt_ctx_java_free(xbt_context_t context);
+
+static void xbt_ctx_java_kill(xbt_context_t context);
+
+static void xbt_ctx_java_schedule(xbt_context_t context);
+
+static void xbt_ctx_java_yield(void);
+
+static void xbt_ctx_java_start(xbt_context_t context);
+
+static void xbt_ctx_java_stop(int exit_code);
+
+static void xbt_ctx_java_swap(xbt_context_t context);
+
+static void xbt_ctx_java_schedule(xbt_context_t context);
+
+static void xbt_ctx_java_yield(void);
+
+static void xbt_ctx_java_suspend(xbt_context_t context);
+
+static void xbt_ctx_java_resume(xbt_context_t context);
+
+
+/* callback: context fetching */
+static ex_ctx_t *xbt_ctx_java_ex_ctx(void)
+{
+  return current_context->exception;
+}
+
+/* callback: termination */
+static void xbt_ctx_java_ex_terminate(xbt_ex_t * e)
+{
+  xbt_ex_display(e);
+  abort();
+}
+
+void xbt_ctx_java_factory_init(xbt_context_factory_t * factory)
+{
+  /* context exception handlers */
+  __xbt_ex_ctx = xbt_ctx_java_ex_ctx;
+  __xbt_ex_terminate = xbt_ctx_java_ex_terminate;
+
+  /* instantiate the context factory */
+  *factory = xbt_new0(s_xbt_context_factory_t, 1);
+
+  (*factory)->create_context = xbt_ctx_java_factory_create_context;
+  (*factory)->finalize = xbt_ctx_java_factory_finalize;
+  (*factory)->create_maestro_context =
+    xbt_ctx_java_factory_create_maestro_context;
+  (*factory)->name = "ctx_java_factory";
+}
+
+static int
+xbt_ctx_java_factory_create_maestro_context(xbt_context_t * maestro)
+{
+  xbt_ctx_java_t context = xbt_new0(s_xbt_ctx_java_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_java_factory_finalize(xbt_context_factory_t * factory)
+{
+  free(maestro_context->exception);
+  free(*factory);
+  *factory = NULL;
+
+  return 0;
+}
+
+static xbt_context_t
+xbt_ctx_java_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_java_t context = xbt_new0(s_xbt_ctx_java_t, 1);
+
+  context->name = xbt_strdup(name);
+
+  context->cleanup_func = cleanup_func;
+  context->cleanup_arg = cleanup_arg;
+
+  context->exception = xbt_new(ex_ctx_t, 1);
+  XBT_CTX_INITIALIZE(context->exception);
+
+  context->free = xbt_ctx_java_free;
+  context->kill = xbt_ctx_java_kill;
+  context->schedule = xbt_ctx_java_schedule;
+  context->yield = xbt_ctx_java_yield;
+  context->start = xbt_ctx_java_start;
+  context->stop = xbt_ctx_java_stop;
+  context->jprocess = (jobject) startup_arg;
+  context->jenv = get_current_thread_env();
+
+  return (xbt_context_t) context;
+}
+
+static void xbt_ctx_java_free(xbt_context_t context)
+{
+  if (context) {
+    xbt_ctx_java_t ctx_java = (xbt_ctx_java_t) context;
+
+    free(ctx_java->name);
+
+    if (ctx_java->jprocess) {
+      jobject jprocess = ctx_java->jprocess;
+
+      ctx_java->jprocess = NULL;
+
+      /* if the java process is alive join it */
+      if (jprocess_is_alive(jprocess, get_current_thread_env()))
+        jprocess_join(jprocess, get_current_thread_env());
+    }
+
+    if (ctx_java->exception)
+      free(ctx_java->exception);
+
+    free(context);
+    context = NULL;
+  }
+}
+
+static void xbt_ctx_java_kill(xbt_context_t context)
+{
+  context->iwannadie = 1;
+  xbt_ctx_java_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_java_schedule(xbt_context_t context)
+{
+  xbt_assert0((current_context == maestro_context),
+              "You are not supposed to run this function here!");
+  xbt_ctx_java_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_java_yield(void)
+{
+  xbt_assert0((current_context != maestro_context),
+              "You are not supposed to run this function here!");
+  jprocess_unschedule(current_context);
+}
+
+static void xbt_ctx_java_start(xbt_context_t context)
+{
+  jprocess_start(((xbt_ctx_java_t) context)->jprocess,
+                 get_current_thread_env());
+}
+
+static void xbt_ctx_java_stop(int exit_code)
+{
+  jobject jprocess = NULL;
+  xbt_ctx_java_t ctx_java;
+
+  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);
+
+  ctx_java = (xbt_ctx_java_t) current_context;
+
+  if (ctx_java->iwannadie) {
+    /* The maestro call xbt_context_stop() with an exit code set to one */
+    if (ctx_java->jprocess) {
+      /* if the java process is alive schedule it */
+      if (jprocess_is_alive(ctx_java->jprocess, get_current_thread_env())) {
+        jprocess_schedule(current_context);
+        jprocess = ctx_java->jprocess;
+        ctx_java->jprocess = NULL;
+
+        /* interrupt the java process */
+        jprocess_exit(jprocess, get_current_thread_env());
+
+      }
+    }
+  } else {
+    /* the java process exits */
+    jprocess = ctx_java->jprocess;
+    ctx_java->jprocess = NULL;
+  }
+
+  /* delete the global reference associated with the java process */
+  jprocess_delete_global_ref(jprocess, get_current_thread_env());
+}
+
+static void xbt_ctx_java_swap(xbt_context_t context)
+{
+  if (context) {
+    xbt_context_t self = current_context;
+
+    current_context = context;
+
+    jprocess_schedule(context);
+
+    current_context = self;
+  }
+
+  if (current_context->iwannadie)
+    xbt_ctx_java_stop(1);
+}
index 9760e04..7c75315 100644 (file)
@@ -1,22 +1,20 @@
-#ifndef _XBT_CONTEXT_JAVA_H\r
-#define _XBT_CONTEXT_JAVA_H\r
-\r
-#include "portable.h"\r
-#include "xbt/misc.h"\r
-\r
-#include "xbt/xbt_context_private.h"\r
-#include "java/jmsg.h"\r
-#include "java/jmsg_process.h"\r
-\r
-SG_BEGIN_DECL()\r
-\r
-typedef struct s_xbt_ctx_java\r
-{\r
-       XBT_CTX_BASE_T;\r
-       jobject jprocess;                               /* the java process instance binded with the msg process structure                                                      */\r
-       JNIEnv* jenv;                                   /* jni interface pointer associated to this thread                                                                                      */\r
-}s_xbt_ctx_java_t,* xbt_ctx_java_t;\r
-\r
-SG_END_DECL()\r
-\r
-#endif /* !_XBT_CONTEXT_JAVA_H */\r
+#ifndef _XBT_CONTEXT_JAVA_H
+#define _XBT_CONTEXT_JAVA_H
+
+#include "portable.h"
+#include "xbt/misc.h"
+
+#include "xbt/xbt_context_private.h"
+#include "java/jmsg.h"
+#include "java/jmsg_process.h"
+
+SG_BEGIN_DECL()
+
+     typedef struct s_xbt_ctx_java {
+       XBT_CTX_BASE_T;
+       jobject jprocess;        /* the java process instance binded with the msg process structure                                                      */
+       JNIEnv *jenv;            /* jni interface pointer associated to this thread                                                                                      */
+     } s_xbt_ctx_java_t, *xbt_ctx_java_t;
+
+SG_END_DECL()
+#endif /* !_XBT_CONTEXT_JAVA_H */
index 54155e9..d6ba31a 100644 (file)
-#ifndef _XBT_CONTEXT_PRIVATE_H\r
-#define _XBT_CONTEXT_PRIVATE_H\r
-\r
-#include "xbt/sysdep.h"\r
-#include "xbt/context.h"\r
-#include "xbt/swag.h"\r
-\r
-SG_BEGIN_DECL()\r
-\r
-/* *********************** */\r
-/* Context type definition */\r
-/* *********************** */\r
-  \r
-/* the following function pointers describe the interface that all context concepts must implement */\r
-typedef void (*xbt_pfn_context_free_t)(xbt_context_t);         /* pointer type to the function used to destroy the specified context   */\r
-typedef void (*xbt_pfn_context_kill_t)(xbt_context_t);         /* pointer type to the function used to kill the specified context              */\r
-typedef void (*xbt_pfn_context_schedule_t)(xbt_context_t);     /* pointer type to the function used to resume the specified context    */\r
-typedef void (*xbt_pfn_context_yield_t)(void);                 /* pointer type to the function used to yield the specified context             */\r
-typedef void (*xbt_pfn_context_start_t)(xbt_context_t);                /* pointer type to the function used to start the specified context             */\r
-typedef void (*xbt_pfn_context_stop_t)(int);                   /* pointer type to the function used to stop the current context                */\r
-\r
-/* each context type must contain this macro at its begining -- OOP in C :/ */\r
-#define XBT_CTX_BASE_T \\r
-       s_xbt_swag_hookup_t hookup; \\r
-       char *name; \\r
-       void_f_pvoid_t cleanup_func; \\r
-       void *cleanup_arg; \\r
-       ex_ctx_t *exception; \\r
-       int iwannadie; \\r
-       xbt_main_func_t code; \\r
-       int argc; \\r
-       char **argv; \\r
-       void_f_pvoid_t startup_func; \\r
-       void *startup_arg; \\r
-       xbt_pfn_context_free_t free; \\r
-       xbt_pfn_context_kill_t kill; \\r
-       xbt_pfn_context_schedule_t schedule; \\r
-       xbt_pfn_context_yield_t yield; \\r
-       xbt_pfn_context_start_t start; \\r
-       xbt_pfn_context_stop_t stop                             \r
-\r
-/* all other context types derive from this structure */\r
-typedef struct s_xbt_context {\r
-       XBT_CTX_BASE_T;\r
-} s_xbt_context_t;\r
-\r
-/* ****************** */\r
-/* Globals definition */\r
-/* ****************** */\r
-\r
-/* Important guys */\r
-extern xbt_context_t current_context;\r
-extern xbt_context_t maestro_context;\r
-/* All dudes lists */\r
-extern xbt_swag_t context_living;\r
-extern xbt_swag_t context_to_destroy;\r
-\r
-/* *********************** */\r
-/* factory type definition */\r
-/* *********************** */\r
-typedef struct s_xbt_context_factory * xbt_context_factory_t;\r
-\r
-/* this function describes the interface that all context factory must implement */\r
-typedef xbt_context_t (*xbt_pfn_context_factory_create_context_t)(const char*, xbt_main_func_t, void_f_pvoid_t, void*, void_f_pvoid_t, void*, int, char**);\r
-typedef int (*xbt_pfn_context_factory_create_maestro_context_t)(xbt_context_t*);\r
-\r
-/* this function finalize the specified context factory */\r
-typedef int (*xbt_pfn_context_factory_finalize_t)(xbt_context_factory_t*);\r
-\r
-/* this interface is used by the xbt context module to create the appropriate concept */\r
-typedef struct s_xbt_context_factory {\r
-       xbt_pfn_context_factory_create_maestro_context_t create_maestro_context;        /* create the context of the maestro    */\r
-       xbt_pfn_context_factory_create_context_t create_context;                        /* create a new context                 */\r
-       xbt_pfn_context_factory_finalize_t finalize;                                    /* finalize the context factory         */\r
-       const char* name;                                                               /* the name of the context factory      */\r
-       \r
-} s_xbt_context_factory_t;\r
-\r
-/**\r
- * This function select a context factory associated with the name specified by\r
- * the parameter name.\r
- * If successful the function returns 0. Otherwise the function returns the error\r
- * code.\r
- */\r
-int\r
-xbt_context_select_factory(const char* name);\r
-\r
-/**\r
- * This function initialize a context factory from the name specified by the parameter\r
- * name.\r
- * If the factory cannot be found, an exception is raised.\r
- */\r
-void\r
-xbt_context_init_factory_by_name(xbt_context_factory_t* factory, const char* name);\r
-\r
-\r
-/* All factories init */\r
-void xbt_ctx_thread_factory_init(xbt_context_factory_t* factory);\r
-void xbt_ctx_sysv_factory_init(xbt_context_factory_t* factory);\r
-void xbt_ctx_java_factory_init(xbt_context_factory_t* factory);\r
-\r
-\r
-\r
-\r
-\r
-SG_END_DECL()\r
-\r
-#endif /* !_XBT_CONTEXT_PRIVATE_H */\r
+#ifndef _XBT_CONTEXT_PRIVATE_H
+#define _XBT_CONTEXT_PRIVATE_H
+
+#include "xbt/sysdep.h"
+#include "xbt/context.h"
+#include "xbt/swag.h"
+
+SG_BEGIN_DECL()
+
+/* *********************** */
+/* Context type definition */
+/* *********************** */
+/* the following function pointers describe the interface that all context concepts must implement */
+     typedef void (*xbt_pfn_context_free_t) (xbt_context_t);    /* pointer type to the function used to destroy the specified context   */
+     typedef void (*xbt_pfn_context_kill_t) (xbt_context_t);    /* pointer type to the function used to kill the specified context              */
+     typedef void (*xbt_pfn_context_schedule_t) (xbt_context_t);        /* pointer type to the function used to resume the specified context    */
+     typedef void (*xbt_pfn_context_yield_t) (void);    /* pointer type to the function used to yield the specified context             */
+     typedef void (*xbt_pfn_context_start_t) (xbt_context_t);   /* pointer type to the function used to start the specified context             */
+     typedef void (*xbt_pfn_context_stop_t) (int);      /* pointer type to the function used to stop the current context                */
+
+/* each context type must contain this macro at its begining -- OOP in C :/ */
+#define XBT_CTX_BASE_T \
+       s_xbt_swag_hookup_t hookup; \
+       char *name; \
+       void_f_pvoid_t cleanup_func; \
+       void *cleanup_arg; \
+       ex_ctx_t *exception; \
+       int iwannadie; \
+       xbt_main_func_t code; \
+       int argc; \
+       char **argv; \
+       void_f_pvoid_t startup_func; \
+       void *startup_arg; \
+       xbt_pfn_context_free_t free; \
+       xbt_pfn_context_kill_t kill; \
+       xbt_pfn_context_schedule_t schedule; \
+       xbt_pfn_context_yield_t yield; \
+       xbt_pfn_context_start_t start; \
+       xbt_pfn_context_stop_t stop
+
+/* all other context types derive from this structure */
+     typedef struct s_xbt_context {
+       XBT_CTX_BASE_T;
+     } s_xbt_context_t;
+
+/* ****************** */
+/* Globals definition */
+/* ****************** */
+
+/* Important guys */
+     extern xbt_context_t current_context;
+     extern xbt_context_t maestro_context;
+
+/* All dudes lists */
+     extern xbt_swag_t context_living;
+     extern xbt_swag_t context_to_destroy;
+
+/* *********************** */
+/* factory type definition */
+/* *********************** */
+     typedef struct s_xbt_context_factory *xbt_context_factory_t;
+
+/* this function describes the interface that all context factory must implement */
+     typedef xbt_context_t(*xbt_pfn_context_factory_create_context_t) (const
+                                                                       char *,
+                                                                       xbt_main_func_t,
+                                                                       void_f_pvoid_t,
+                                                                       void *,
+                                                                       void_f_pvoid_t,
+                                                                       void *,
+                                                                       int,
+                                                                       char
+                                                                       **);
+     typedef
+       int (*xbt_pfn_context_factory_create_maestro_context_t) (xbt_context_t
+                                                                *);
+
+/* this function finalize the specified context factory */
+     typedef int (*xbt_pfn_context_factory_finalize_t) (xbt_context_factory_t
+                                                        *);
+
+/* this interface is used by the xbt context module to create the appropriate concept */
+     typedef struct s_xbt_context_factory {
+       xbt_pfn_context_factory_create_maestro_context_t create_maestro_context; /* create the context of the maestro    */
+       xbt_pfn_context_factory_create_context_t create_context; /* create a new context                 */
+       xbt_pfn_context_factory_finalize_t finalize;     /* finalize the context factory         */
+       const char *name;        /* the name of the context factory      */
+
+     } s_xbt_context_factory_t;
+
+/**
+ * This function select a context factory associated with the name specified by
+ * the parameter name.
+ * If successful the function returns 0. Otherwise the function returns the error
+ * code.
+ */
+     int
+       xbt_context_select_factory(const char *name);
+
+/**
+ * This function initialize a context factory from the name specified by the parameter
+ * name.
+ * If the factory cannot be found, an exception is raised.
+ */
+     void
+      
+       xbt_context_init_factory_by_name(xbt_context_factory_t * factory,
+                                        const char *name);
+
+
+/* All factories init */
+     void xbt_ctx_thread_factory_init(xbt_context_factory_t * factory);
+     void xbt_ctx_sysv_factory_init(xbt_context_factory_t * factory);
+     void xbt_ctx_java_factory_init(xbt_context_factory_t * factory);
+
+
+
+
+
+SG_END_DECL()
+#endif /* !_XBT_CONTEXT_PRIVATE_H */
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");
+}
index ae325cf..b4a2e8b 100644 (file)
-\r
-#include "xbt/function_types.h"\r
-#include "xbt/xbt_context_private.h"\r
-\r
-#include "portable.h"                  /* loads context system definitions */\r
-#include "xbt/swag.h"\r
-#include "xbt/xbt_os_thread.h"\r
-\r
-\r
-typedef struct s_xbt_ctx_thread {\r
-       XBT_CTX_BASE_T;\r
-       xbt_os_thread_t thread;                 /* a plain dumb thread (portable to posix or windows) */\r
-       xbt_os_sem_t begin;                             /* this semaphore is used to schedule/yield the process  */\r
-       xbt_os_sem_t end;                               /* this semaphore is used to schedule/unschedule the process   */\r
-} s_xbt_ctx_thread_t,* xbt_ctx_thread_t;\r
-\r
-static xbt_context_t \r
-xbt_ctx_thread_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
-\r
-static int\r
-xbt_ctx_thread_factory_create_master_context(xbt_context_t* maestro);\r
-\r
-static int\r
-xbt_ctx_thread_factory_finalize(xbt_context_factory_t* factory);\r
-\r
-static void \r
-xbt_ctx_thread_free(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_thread_kill(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_thread_schedule(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_thread_yield(void);\r
-\r
-static void \r
-xbt_ctx_thread_start(xbt_context_t context);\r
-\r
-static void \r
-xbt_ctx_thread_stop(int exit_code);\r
-\r
-static void \r
-xbt_ctx_thread_swap(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_thread_schedule(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_thread_yield(void);\r
-\r
-static void\r
-xbt_ctx_thread_suspend(xbt_context_t context);\r
-\r
-static void\r
-xbt_ctx_thread_resume(xbt_context_t context);\r
-\r
-static void* \r
-xbt_ctx_thread_wrapper(void* param);\r
-\r
-void\r
-xbt_ctx_thread_factory_init(xbt_context_factory_t* factory)\r
-{\r
-       *factory = xbt_new0(s_xbt_context_factory_t,1);\r
-       \r
-       (*factory)->create_context = xbt_ctx_thread_factory_create_context;\r
-       (*factory)->finalize = xbt_ctx_thread_factory_finalize;\r
-       (*factory)->create_maestro_context = xbt_ctx_thread_factory_create_master_context;\r
-       (*factory)->name = "ctx_thread_factory";\r
-}\r
-\r
-static int\r
-xbt_ctx_thread_factory_create_master_context(xbt_context_t* maestro)\r
-{\r
-       *maestro = (xbt_context_t)xbt_new0(s_xbt_ctx_thread_t, 1);\r
-    return 0;\r
-}\r
-\r
-static int\r
-xbt_ctx_thread_factory_finalize(xbt_context_factory_t* factory)\r
-{\r
-       free(*factory);\r
-       *factory = NULL;\r
-       return 0;\r
-}\r
-\r
-static xbt_context_t \r
-xbt_ctx_thread_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_thread_t context = xbt_new0(s_xbt_ctx_thread_t, 1);\r
-       \r
-       context->code = code;\r
-       context->name = xbt_strdup(name);\r
-       context->begin = xbt_os_sem_init(0);\r
-       context->end = xbt_os_sem_init(0);\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
-       context->free = xbt_ctx_thread_free;                    \r
-       context->kill = xbt_ctx_thread_kill;                    \r
-       context->schedule = xbt_ctx_thread_schedule;\r
-       context->yield = xbt_ctx_thread_yield;                  \r
-       context->start = xbt_ctx_thread_start;                  \r
-       context->stop = xbt_ctx_thread_stop;                    \r
-       \r
-       return (xbt_context_t)context;\r
-}\r
-\r
-static void \r
-xbt_ctx_thread_free(xbt_context_t context)\r
-{\r
-       if(context)\r
-       {\r
-               xbt_ctx_thread_t ctx_thread = (xbt_ctx_thread_t)context;\r
-               \r
-               free(ctx_thread->name);\r
-               \r
-               if(ctx_thread->argv)\r
-               {\r
-                       int i;\r
-                       \r
-                       for(i = 0; i < ctx_thread->argc; i++)\r
-                               if(ctx_thread->argv[i])\r
-                                       free(ctx_thread->argv[i]);\r
-                                       \r
-                       free(ctx_thread->argv);\r
-               }\r
-               \r
-               /* wait about the thread terminason */\r
-               xbt_os_thread_join(ctx_thread->thread, NULL);\r
-               \r
-               /* destroy the synchronisation objects */\r
-               xbt_os_sem_destroy(ctx_thread->begin);\r
-               xbt_os_sem_destroy(ctx_thread->end);\r
-               \r
-               /* finally destroy the context */\r
-               free(context);\r
-       }\r
-}\r
-\r
-static void \r
-xbt_ctx_thread_kill(xbt_context_t context)\r
-{\r
-       context->iwannadie = 1;\r
-       xbt_ctx_thread_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_thread_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_thread_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_thread_yield(void)\r
-{\r
-       xbt_assert0((current_context != maestro_context),"You are not supposed to run this function here!");\r
-       xbt_ctx_thread_swap(current_context);\r
-}\r
-\r
-static void \r
-xbt_ctx_thread_start(xbt_context_t context)\r
-{\r
-       xbt_ctx_thread_t ctx_thread = (xbt_ctx_thread_t)context;\r
-       \r
-       /* create and start the process */\r
-       ctx_thread->thread = xbt_os_thread_create(ctx_thread->name,xbt_ctx_thread_wrapper,ctx_thread);\r
-       \r
-       /* wait the starting of the newly created process */\r
-       xbt_os_sem_acquire(ctx_thread->end);\r
-}\r
-\r
-static void \r
-xbt_ctx_thread_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
-       /* signal to the maestro that it has finished */\r
-       xbt_os_sem_release(((xbt_ctx_thread_t)current_context)->end);\r
-       \r
-       /* exit*/\r
-       xbt_os_thread_exit(NULL);       /* We should provide return value in case other wants it */\r
-}\r
-\r
-static void \r
-xbt_ctx_thread_swap(xbt_context_t context)\r
-{\r
-       if((current_context != maestro_context) && !context->iwannadie)\r
-       {\r
-               /* (0) it's not the scheduler and the process doesn't want to die, it just wants to yield */\r
-               \r
-               /* yield itself, resume the maestro */\r
-               xbt_ctx_thread_suspend(context);\r
-       }\r
-       else\r
-       {\r
-               /* (1) the current process is the scheduler and the process doesn't want to die\r
-                *      <-> the maestro wants to schedule the process\r
-                *              -> the maestro schedules the process and waits\r
-                *\r
-                * (2) the current process is the scheduler and the process wants to die\r
-                *      <-> the maestro wants to kill the process (has called the function xbt_context_kill())\r
-                *              -> the maestro schedule the process and waits (xbt_os_sem_acquire(context->end))\r
-                *              -> if the process stops (xbt_context_stop())\r
-                *                      -> the process resumes the maestro (xbt_os_sem_release(current_context->end)) and exit (xbt_os_thread_exit())\r
-                *              -> else the process call xbt_context_yield()\r
-                *                      -> goto (3.1)\r
-                *\r
-                * (3) the current process is not the scheduler and the process wants to die\r
-                *              -> (3.1) if the current process is the process who wants to die\r
-                *                      -> (resume not need) goto (4)\r
-                *              -> (3.2) else the current process is not the process who wants to die\r
-                *                      <-> the current process wants to kill an other process\r
-                *                              -> the current process resumes the process to die and waits\r
-                *                              -> if the process to kill stops\r
-                *                                      -> it resumes the process who kill it and exit\r
-                *                              -> else if the process to kill calls to xbt_context_yield()\r
-                *                                      -> goto (3.1)\r
-                */\r
-               /* schedule the process associated with this context */\r
-               xbt_ctx_thread_resume(context);\r
-       \r
-       }\r
-       \r
-       /* (4) the current process wants to die */\r
-       if(current_context->iwannadie)\r
-               xbt_ctx_thread_stop(1);\r
-}\r
-\r
-static void* \r
-xbt_ctx_thread_wrapper(void* param)\r
-{\r
-       xbt_ctx_thread_t context = (xbt_ctx_thread_t)param;\r
-       \r
-       /* Tell the maestro we are starting, and wait for its green light */\r
-       xbt_os_sem_release(context->end);               \r
-       xbt_os_sem_acquire(context->begin);\r
-       \r
-       if (context->startup_func)\r
-               (*(context->startup_func))(context->startup_arg);\r
-       \r
-       \r
-       xbt_ctx_thread_stop((context->code) (context->argc, context->argv));\r
-       return NULL;\r
-}\r
-\r
-static void\r
-xbt_ctx_thread_suspend(xbt_context_t context)\r
-{\r
-       /* save the current context */\r
-       xbt_context_t self = current_context;\r
-       \r
-       /* update the current context to this context */\r
-       current_context = context;\r
-       \r
-       xbt_os_sem_release(((xbt_ctx_thread_t)context)->end);   \r
-       xbt_os_sem_acquire(((xbt_ctx_thread_t)context)->begin);\r
-       \r
-       /* restore the current context to the previously saved context */\r
-       current_context = self;         \r
-}\r
-\r
-static void\r
-xbt_ctx_thread_resume(xbt_context_t context)\r
-{\r
-       /* save the current context */\r
-       xbt_context_t self = current_context;\r
-       \r
-       /* update the current context */\r
-       current_context = context;\r
-       \r
-       xbt_os_sem_release(((xbt_ctx_thread_t)context)->begin);         \r
-       xbt_os_sem_acquire(((xbt_ctx_thread_t)context)->end);\r
-       \r
-       /* restore the current context to the previously saved context */\r
-       current_context = self;\r
-}\r
-\r
-\r
-\r
+
+#include "xbt/function_types.h"
+#include "xbt/xbt_context_private.h"
+
+#include "portable.h"           /* loads context system definitions */
+#include "xbt/swag.h"
+#include "xbt/xbt_os_thread.h"
+
+
+typedef struct s_xbt_ctx_thread {
+  XBT_CTX_BASE_T;
+  xbt_os_thread_t thread;       /* a plain dumb thread (portable to posix or windows) */
+  xbt_os_sem_t begin;           /* this semaphore is used to schedule/yield the process  */
+  xbt_os_sem_t end;             /* this semaphore is used to schedule/unschedule the process   */
+} s_xbt_ctx_thread_t, *xbt_ctx_thread_t;
+
+static xbt_context_t
+xbt_ctx_thread_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_thread_factory_create_master_context(xbt_context_t * maestro);
+
+static int xbt_ctx_thread_factory_finalize(xbt_context_factory_t * factory);
+
+static void xbt_ctx_thread_free(xbt_context_t context);
+
+static void xbt_ctx_thread_kill(xbt_context_t context);
+
+static void xbt_ctx_thread_schedule(xbt_context_t context);
+
+static void xbt_ctx_thread_yield(void);
+
+static void xbt_ctx_thread_start(xbt_context_t context);
+
+static void xbt_ctx_thread_stop(int exit_code);
+
+static void xbt_ctx_thread_swap(xbt_context_t context);
+
+static void xbt_ctx_thread_schedule(xbt_context_t context);
+
+static void xbt_ctx_thread_yield(void);
+
+static void xbt_ctx_thread_suspend(xbt_context_t context);
+
+static void xbt_ctx_thread_resume(xbt_context_t context);
+
+static void *xbt_ctx_thread_wrapper(void *param);
+
+void xbt_ctx_thread_factory_init(xbt_context_factory_t * factory)
+{
+  *factory = xbt_new0(s_xbt_context_factory_t, 1);
+
+  (*factory)->create_context = xbt_ctx_thread_factory_create_context;
+  (*factory)->finalize = xbt_ctx_thread_factory_finalize;
+  (*factory)->create_maestro_context =
+    xbt_ctx_thread_factory_create_master_context;
+  (*factory)->name = "ctx_thread_factory";
+}
+
+static int
+xbt_ctx_thread_factory_create_master_context(xbt_context_t * maestro)
+{
+  *maestro = (xbt_context_t) xbt_new0(s_xbt_ctx_thread_t, 1);
+  return 0;
+}
+
+static int xbt_ctx_thread_factory_finalize(xbt_context_factory_t * factory)
+{
+  free(*factory);
+  *factory = NULL;
+  return 0;
+}
+
+static xbt_context_t
+xbt_ctx_thread_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_thread_t context = xbt_new0(s_xbt_ctx_thread_t, 1);
+
+  context->code = code;
+  context->name = xbt_strdup(name);
+  context->begin = xbt_os_sem_init(0);
+  context->end = xbt_os_sem_init(0);
+  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_thread_free;
+  context->kill = xbt_ctx_thread_kill;
+  context->schedule = xbt_ctx_thread_schedule;
+  context->yield = xbt_ctx_thread_yield;
+  context->start = xbt_ctx_thread_start;
+  context->stop = xbt_ctx_thread_stop;
+
+  return (xbt_context_t) context;
+}
+
+static void xbt_ctx_thread_free(xbt_context_t context)
+{
+  if (context) {
+    xbt_ctx_thread_t ctx_thread = (xbt_ctx_thread_t) context;
+
+    free(ctx_thread->name);
+
+    if (ctx_thread->argv) {
+      int i;
+
+      for (i = 0; i < ctx_thread->argc; i++)
+        if (ctx_thread->argv[i])
+          free(ctx_thread->argv[i]);
+
+      free(ctx_thread->argv);
+    }
+
+    /* wait about the thread terminason */
+    xbt_os_thread_join(ctx_thread->thread, NULL);
+
+    /* destroy the synchronisation objects */
+    xbt_os_sem_destroy(ctx_thread->begin);
+    xbt_os_sem_destroy(ctx_thread->end);
+
+    /* finally destroy the context */
+    free(context);
+  }
+}
+
+static void xbt_ctx_thread_kill(xbt_context_t context)
+{
+  context->iwannadie = 1;
+  xbt_ctx_thread_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_thread_schedule(xbt_context_t context)
+{
+  xbt_assert0((current_context == maestro_context),
+              "You are not supposed to run this function here!");
+  xbt_ctx_thread_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_thread_yield(void)
+{
+  xbt_assert0((current_context != maestro_context),
+              "You are not supposed to run this function here!");
+  xbt_ctx_thread_swap(current_context);
+}
+
+static void xbt_ctx_thread_start(xbt_context_t context)
+{
+  xbt_ctx_thread_t ctx_thread = (xbt_ctx_thread_t) context;
+
+  /* create and start the process */
+  ctx_thread->thread =
+    xbt_os_thread_create(ctx_thread->name, xbt_ctx_thread_wrapper,
+                         ctx_thread);
+
+  /* wait the starting of the newly created process */
+  xbt_os_sem_acquire(ctx_thread->end);
+}
+
+static void xbt_ctx_thread_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);
+
+  /* signal to the maestro that it has finished */
+  xbt_os_sem_release(((xbt_ctx_thread_t) current_context)->end);
+
+  /* exit */
+  xbt_os_thread_exit(NULL);     /* We should provide return value in case other wants it */
+}
+
+static void xbt_ctx_thread_swap(xbt_context_t context)
+{
+  if ((current_context != maestro_context) && !context->iwannadie) {
+    /* (0) it's not the scheduler and the process doesn't want to die, it just wants to yield */
+
+    /* yield itself, resume the maestro */
+    xbt_ctx_thread_suspend(context);
+  } else {
+    /* (1) the current process is the scheduler and the process doesn't want to die
+     *      <-> the maestro wants to schedule the process
+     *              -> the maestro schedules the process and waits
+     *
+     * (2) the current process is the scheduler and the process wants to die
+     *      <-> the maestro wants to kill the process (has called the function xbt_context_kill())
+     *              -> the maestro schedule the process and waits (xbt_os_sem_acquire(context->end))
+     *              -> if the process stops (xbt_context_stop())
+     *                      -> the process resumes the maestro (xbt_os_sem_release(current_context->end)) and exit (xbt_os_thread_exit())
+     *              -> else the process call xbt_context_yield()
+     *                      -> goto (3.1)
+     *
+     * (3) the current process is not the scheduler and the process wants to die
+     *              -> (3.1) if the current process is the process who wants to die
+     *                      -> (resume not need) goto (4)
+     *              -> (3.2) else the current process is not the process who wants to die
+     *                      <-> the current process wants to kill an other process
+     *                              -> the current process resumes the process to die and waits
+     *                              -> if the process to kill stops
+     *                                      -> it resumes the process who kill it and exit
+     *                              -> else if the process to kill calls to xbt_context_yield()
+     *                                      -> goto (3.1)
+     */
+    /* schedule the process associated with this context */
+    xbt_ctx_thread_resume(context);
+
+  }
+
+  /* (4) the current process wants to die */
+  if (current_context->iwannadie)
+    xbt_ctx_thread_stop(1);
+}
+
+static void *xbt_ctx_thread_wrapper(void *param)
+{
+  xbt_ctx_thread_t context = (xbt_ctx_thread_t) param;
+
+  /* Tell the maestro we are starting, and wait for its green light */
+  xbt_os_sem_release(context->end);
+  xbt_os_sem_acquire(context->begin);
+
+  if (context->startup_func)
+    (*(context->startup_func)) (context->startup_arg);
+
+
+  xbt_ctx_thread_stop((context->code) (context->argc, context->argv));
+  return NULL;
+}
+
+static void xbt_ctx_thread_suspend(xbt_context_t context)
+{
+  /* save the current context */
+  xbt_context_t self = current_context;
+
+  /* update the current context to this context */
+  current_context = context;
+
+  xbt_os_sem_release(((xbt_ctx_thread_t) context)->end);
+  xbt_os_sem_acquire(((xbt_ctx_thread_t) context)->begin);
+
+  /* restore the current context to the previously saved context */
+  current_context = self;
+}
+
+static void xbt_ctx_thread_resume(xbt_context_t context)
+{
+  /* save the current context */
+  xbt_context_t self = current_context;
+
+  /* update the current context */
+  current_context = context;
+
+  xbt_os_sem_release(((xbt_ctx_thread_t) context)->begin);
+  xbt_os_sem_acquire(((xbt_ctx_thread_t) context)->end);
+
+  /* restore the current context to the previously saved context */
+  current_context = self;
+}