Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
More informative error message
[simgrid.git] / src / simix / smx_process.c
index f90dcdb..b2ec5c1 100644 (file)
@@ -21,7 +21,7 @@ void SIMIX_process_cleanup(void *arg)
 {
   xbt_swag_remove(arg, simix_global->process_to_run);
   xbt_swag_remove(arg, simix_global->process_list);
 {
   xbt_swag_remove(arg, simix_global->process_to_run);
   xbt_swag_remove(arg, simix_global->process_list);
-  xbt_swag_remove(arg, ((smx_process_t)arg)->smx_host->process_list);
+  xbt_swag_remove(arg, ((smx_process_t) arg)->smx_host->process_list);
   xbt_swag_insert(arg, simix_global->process_to_destroy);
 }
 
   xbt_swag_insert(arg, simix_global->process_to_destroy);
 }
 
@@ -32,11 +32,16 @@ void SIMIX_process_cleanup(void *arg)
  * that have finished (or killed).
  */
 void SIMIX_process_empty_trash(void)
  * that have finished (or killed).
  */
 void SIMIX_process_empty_trash(void)
-{ 
+{
   smx_process_t process = NULL;
 
   smx_process_t process = NULL;
 
-  while ((process = xbt_swag_extract(simix_global->process_to_destroy))){
+  while ((process = xbt_swag_extract(simix_global->process_to_destroy))) {
     SIMIX_context_free(process->context);
     SIMIX_context_free(process->context);
+
+    /* Free the exception allocated at creation time */
+    if (process->exception)
+      free(process->exception);
+
     free(process->name);
     process->name = NULL;
     free(process);
     free(process->name);
     process->name = NULL;
     free(process);
@@ -46,13 +51,16 @@ void SIMIX_process_empty_trash(void)
 /**
  * \brief Creates and runs the maestro process
  */
 /**
  * \brief Creates and runs the maestro process
  */
-void __SIMIX_create_maestro_process()
+void SIMIX_create_maestro_process()
 {
   smx_process_t process = NULL;
   process = xbt_new0(s_smx_process_t, 1);
 
   /* Process data */
 {
   smx_process_t process = NULL;
   process = xbt_new0(s_smx_process_t, 1);
 
   /* Process data */
-  process->name = (char *)"";
+  process->name = (char *) "";
+
+  process->exception = xbt_new(ex_ctx_t, 1);
+  XBT_CTX_INITIALIZE(process->exception);
 
   /* Create a dummy context for maestro */
   process->context = SIMIX_context_new(NULL, 0, NULL, NULL, NULL);
 
   /* Create a dummy context for maestro */
   process->context = SIMIX_context_new(NULL, 0, NULL, NULL, NULL);
@@ -102,13 +110,15 @@ smx_process_t SIMIX_process_create(const char *name,
   process->mutex = NULL;
   process->cond = NULL;
   process->iwannadie = 0;
   process->mutex = NULL;
   process->cond = NULL;
   process->iwannadie = 0;
+  process->data = data;
 
   VERB1("Create context %s", process->name);
 
   VERB1("Create context %s", process->name);
-  process->context = SIMIX_context_new(code, argc, argv, 
+  process->context = SIMIX_context_new(code, argc, argv,
                                        simix_global->cleanup_process_function,
                                        process);
                                        simix_global->cleanup_process_function,
                                        process);
-  
-  process->data = data;
+
+  process->exception = xbt_new(ex_ctx_t, 1);
+  XBT_CTX_INITIALIZE(process->exception);
 
   /* Add properties */
   process->properties = properties;
 
   /* Add properties */
   process->properties = properties;
@@ -118,7 +128,7 @@ smx_process_t SIMIX_process_create(const char *name,
 
   DEBUG1("Start context '%s'", process->name);
   SIMIX_context_start(process->context);
 
   DEBUG1("Start context '%s'", process->name);
   SIMIX_context_start(process->context);
-   
+
   /* Now insert it in the global process list and in the process to run list */
   xbt_swag_insert(process, simix_global->process_list);
   DEBUG2("Inserting %s(%s) in the to_run list", process->name, host->name);
   /* Now insert it in the global process list and in the process to run list */
   xbt_swag_insert(process, simix_global->process_list);
   DEBUG2("Inserting %s(%s) in the to_run list", process->name, host->name);
@@ -137,23 +147,37 @@ void SIMIX_process_kill(smx_process_t process)
 {
   DEBUG2("Killing process %s on %s", process->name, process->smx_host->name);
 
 {
   DEBUG2("Killing process %s on %s", process->name, process->smx_host->name);
 
-  /* Cleanup if we were waiting for something */
-  if (process->mutex)
-    xbt_swag_remove(process, process->mutex->sleeping);
-
-  if (process->cond)
-    xbt_swag_remove(process, process->cond->sleeping);
-
-  DEBUG2("%p here! killing %p", simix_global->current_process, process);
-
   process->iwannadie = 1;
 
   process->iwannadie = 1;
 
-  /* If I'm killing myself then stop otherwise schedule the process to kill */
-  if (process == SIMIX_process_self())
+  /* If I'm killing myself then stop otherwise schedule the process to kill
+   * Two different behaviors, if I'm killing my self, remove from mutex and condition and stop. Otherwise, first we must schedule the process, wait its ending and after remove it from mutex and condition */
+  if (process == SIMIX_process_self()) {
+    /* Cleanup if we were waiting for something */
+    if (process->mutex)
+      xbt_swag_remove(process, process->mutex->sleeping);
+
+    if (process->cond)
+      xbt_swag_remove(process, process->cond->sleeping);
+    if (process->waiting_action) {
+      SIMIX_unregister_action_to_condition(process->waiting_action, process->cond);
+      SIMIX_action_destroy(process->waiting_action);
+    }
     SIMIX_context_stop(process->context);
     SIMIX_context_stop(process->context);
-  else
-    __SIMIX_process_schedule(process);
-  
+  } else {
+    DEBUG2("%p here! killing %p", simix_global->current_process, process);
+    SIMIX_process_schedule(process);
+    /* Cleanup if we were waiting for something */
+    if (process->mutex)
+      xbt_swag_remove(process, process->mutex->sleeping);
+
+    if (process->cond)
+      xbt_swag_remove(process, process->cond->sleeping);
+
+    if (process->waiting_action) {
+      SIMIX_unregister_action_to_condition(process->waiting_action, process->cond);
+      SIMIX_action_destroy(process->waiting_action);
+    }
+  }
 }
 
 /**
 }
 
 /**
@@ -272,7 +296,7 @@ void SIMIX_process_suspend(smx_process_t process)
       process->suspended = 1;
       c = process->cond;
       xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
       process->suspended = 1;
       c = process->cond;
       xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
-        surf_workstation_model->suspend(act->surf_action);
+        surf_workstation_model->suspend(act->surf_action);
       }
     } else {
       process->suspended = 1;
       }
     } else {
       process->suspended = 1;
@@ -286,9 +310,11 @@ void SIMIX_process_suspend(smx_process_t process)
 
     cond = SIMIX_cond_init();
     dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0);
 
     cond = SIMIX_cond_init();
     dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0);
+    SIMIX_process_self()->waiting_action = dummy;
     surf_workstation_model->suspend(dummy->surf_action);
     SIMIX_register_action_to_condition(dummy, cond);
     __SIMIX_cond_wait(cond);
     surf_workstation_model->suspend(dummy->surf_action);
     SIMIX_register_action_to_condition(dummy, cond);
     __SIMIX_cond_wait(cond);
+    SIMIX_process_self()->waiting_action = NULL;
     SIMIX_unregister_action_to_condition(dummy, cond);
     SIMIX_action_destroy(dummy);
     SIMIX_cond_destroy(cond);
     SIMIX_unregister_action_to_condition(dummy, cond);
     SIMIX_action_destroy(dummy);
     SIMIX_cond_destroy(cond);
@@ -338,7 +364,8 @@ void SIMIX_process_resume(smx_process_t process)
  *
  * This function changes the value of the host on which \a process is running.
  */
  *
  * This function changes the value of the host on which \a process is running.
  */
-void SIMIX_process_change_host(smx_process_t process, char *source, char *dest)
+void SIMIX_process_change_host(smx_process_t process, char *source,
+                               char *dest)
 {
   xbt_assert0((process != NULL), "Invalid parameters");
   smx_host_t h1 = SIMIX_host_get_by_name(source);
 {
   xbt_assert0((process != NULL), "Invalid parameters");
   smx_host_t h1 = SIMIX_host_get_by_name(source);
@@ -380,11 +407,12 @@ int SIMIX_process_count()
  * Only the processes can call this function, giving back the control
  * to the maestro
  */
  * Only the processes can call this function, giving back the control
  * to the maestro
  */
-void __SIMIX_process_yield(void)
+void SIMIX_process_yield(void)
 {
   DEBUG1("Yield process '%s'", simix_global->current_process->name);
 {
   DEBUG1("Yield process '%s'", simix_global->current_process->name);
-  xbt_assert0((simix_global->current_process != simix_global->maestro_process),
-              "You are not supposed to run this function here!");
+  xbt_assert0((simix_global->current_process !=
+               simix_global->maestro_process),
+              "You are not supposed to run this function in maestro context!");
 
   SIMIX_context_suspend(simix_global->current_process->context);
 
 
   SIMIX_context_suspend(simix_global->current_process->context);
 
@@ -392,7 +420,7 @@ void __SIMIX_process_yield(void)
     SIMIX_context_stop(simix_global->current_process->context);
 }
 
     SIMIX_context_stop(simix_global->current_process->context);
 }
 
-void __SIMIX_process_schedule(smx_process_t new_process)
+void SIMIX_process_schedule(smx_process_t new_process)
 {
   DEBUG1("Scheduling context: '%s'", new_process->name);
 
 {
   DEBUG1("Scheduling context: '%s'", new_process->name);
 
@@ -408,3 +436,16 @@ void __SIMIX_process_schedule(smx_process_t new_process)
   /* restore the current process to the previously saved process */
   simix_global->current_process = old_process;
 }
   /* restore the current process to the previously saved process */
   simix_global->current_process = old_process;
 }
+
+/* callback: context fetching */
+ex_ctx_t *SIMIX_process_get_exception(void)
+{
+  return simix_global->current_process->exception;
+}
+
+/* callback: termination */
+void SIMIX_process_exception_terminate(xbt_ex_t * e)
+{
+  xbt_ex_display(e);
+  abort();
+}