Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use a fifo instead of a swag of sleeping processes on a semaphore (so that waitany...
[simgrid.git] / src / simix / smx_process.c
index 25c5801..3d080f2 100644 (file)
@@ -1,6 +1,5 @@
-/*     $Id$     */
-
-/* Copyright (c) 2002,2003,2004 Arnaud Legrand. All rights reserved.        */
+/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ * 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 "private.h"
 #include "xbt/sysdep.h"
 #include "xbt/log.h"
+#include "xbt/dict.h"
+#include "msg/mailbox.h"
+
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix,
-                               "Logging specific to SIMIX (process)");
-/** \defgroup m_process_management Management Functions of Agents
- *  \brief This section describes the agent structure of MSG
- *  (#m_process_t) and the functions for managing it.
- *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Agents" --> \endhtmlonly
- * 
- *  We need to simulate many independent scheduling decisions, so
- *  the concept of <em>process</em> is at the heart of the
- *  simulator. A process may be defined as a <em>code</em>, with
- *  some <em>private data</em>, executing in a <em>location</em>.
- *  \see m_process_t
+                                "Logging specific to SIMIX (process)");
+
+/**
+ * \brief Move a process to the list of process to destroy. *
  */
+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, ((smx_process_t) arg)->smx_host->process_list);
+  xbt_swag_insert(arg, simix_global->process_to_destroy);
+}
 
-/******************************** Process ************************************/
-/** \ingroup m_process_management
- * \brief Creates and runs a new #m_process_t.
+/** 
+ * Garbage collection
  *
- * Does exactly the same as #MSG_process_create_with_arguments but without 
-   providing standard arguments (\a argc, \a argv, \a start_time, \a kill_time).
- * \sa MSG_process_create_with_arguments
+ * Should be called some time to time to free the memory allocated for processes
+ * that have finished (or killed).
  */
-smx_process_t SIMIX_process_create(const char *name,
-                              smx_process_code_t code, void *data,
-                              smx_host_t host)
+void SIMIX_process_empty_trash(void)
 {
-  return SIMIX_process_create_with_arguments(name, code, data, host, -1, NULL);
+  smx_process_t process = NULL;
+
+  while ((process = xbt_swag_extract(simix_global->process_to_destroy))) {
+    SIMIX_context_free(process->context);
+
+    /* Free the exception allocated at creation time */
+    if (process->exception)
+      free(process->exception);
+    if (process->properties)
+      xbt_dict_free(&process->properties);
+
+    free(process->name);
+    process->name = NULL;
+    free(process);
+  }
 }
 
-static void SIMIX_process_cleanup(void *arg)
+/**
+ * \brief Creates and runs the maestro process
+ */
+void SIMIX_create_maestro_process()
 {
-  xbt_swag_remove(arg, simix_global->process_list);
-  xbt_swag_remove(arg, simix_global->process_to_run);
-  xbt_swag_remove(arg, ((smx_process_t) arg)->simdata->host->simdata->process_list);
-  free(((smx_process_t) arg)->name);
-  ((smx_process_t) arg)->name = NULL;
-  free(((smx_process_t) arg)->simdata);
-  ((smx_process_t) arg)->simdata = NULL;
-  free(arg);
+  smx_process_t process = NULL;
+  process = xbt_new0(s_smx_process_t, 1);
+
+  /* Process data */
+  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);
+
+  /* Set it as the maestro process */
+  simix_global->maestro_process = process;
+  simix_global->current_process = process;
+
+  return;
 }
 
-/** \ingroup m_process_management
- * \brief Creates and runs a new #m_process_t.
-
- * A constructor for #m_process_t taking four arguments and returning the 
- * corresponding object. The structure (and the corresponding thread) is
- * created, and put in the list of ready process.
- * \param name a name for the object. It is for user-level information
-   and can be NULL.
- * \param code is a function describing the behavior of the agent. It
-   should then only use functions described in \ref
-   m_process_management (to create a new #m_process_t for example),
-   in \ref m_host_management (only the read-only functions i.e. whose
-   name contains the word get), in \ref m_task_management (to create
-   or destroy some #m_task_t for example) and in \ref
-   msg_gos_functions (to handle file transfers and task processing).
- * \param data a pointer to any data one may want to attach to the new
-   object.  It is for user-level information and can be NULL. It can
-   be retrieved with the function \ref MSG_process_get_data.
+/**
+ * \brief Creates and runs a new #smx_process_t.
+ *
+ * A constructor for #m_process_t taking four arguments and returning the corresponding object. The structure (and the corresponding thread) is created, and put in the list of ready process.
+ *
+ * \param name a name for the object. It is for user-level information and can be NULL.
+ * \param data a pointer to any data one may want to attach to the new object.  It is for user-level information and can be NULL. It can be retrieved with the function \ref MSG_process_get_data.
  * \param host the location where the new agent is executed.
  * \param argc first argument passed to \a code
  * \param argv second argument passed to \a code
- * \see m_process_t
+ * \param clean_process_function The cleanup function of user process. It will be called when the process finish. This function have to call the SIMIX_process_cleanup.
+ * \see smx_process_t
  * \return The new corresponding object.
  */
-smx_process_t SIMIX_process_create_with_arguments(const char *name,
-                                             smx_process_code_t code, void *data,
-                                             smx_host_t host, int argc, char **argv)
+smx_process_t SIMIX_process_create(const char *name,
+                                   xbt_main_func_t code, void *data,
+                                   const char *hostname, int argc,
+                                   char **argv, xbt_dict_t properties)
 {
-  simdata_process_t simdata = xbt_new0(s_simdata_process_t,1);
-  smx_process_t process = xbt_new0(s_smx_process_t,1);
-  smx_process_t self = NULL;
+  smx_process_t process = NULL;
+  smx_host_t host = SIMIX_host_get_by_name(hostname);
 
-  xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
-  /* Simulator Data */
+  DEBUG2("Start process %s on host %s", name, hostname);
 
-  simdata->host = host;
-  simdata->argc = argc;
-  simdata->argv = argv;
-  simdata->context = xbt_context_new(code, NULL, NULL, 
-                                    SIMIX_process_cleanup, process, 
-                                    simdata->argc, simdata->argv);
-
-  simdata->last_errno=SIMIX_OK;
+  if (!SIMIX_host_get_state(host)) {
+    WARN2("Cannot launch process '%s' on failed host '%s'", name, hostname);
+    return NULL;
+  }
+  process = xbt_new0(s_smx_process_t, 1);
 
+  xbt_assert0(((code != NULL) && (host != NULL)), "Invalid parameters");
 
-  /* Process structure */
+  /* Process data */
   process->name = xbt_strdup(name);
-  process->simdata = simdata;
+  process->smx_host = host;
+  process->mutex = NULL;
+  process->cond = NULL;
+  process->iwannadie = 0;
   process->data = data;
 
-  xbt_swag_insert(process, host->simdata->process_list);
+  VERB1("Create context %s", process->name);
+  process->context = SIMIX_context_new(code, argc, argv,
+                                       simix_global->cleanup_process_function,
+                                       process);
 
-  /* *************** FIX du current_process !!! *************** */
-  self = simix_global->current_process;
-  xbt_context_start(process->simdata->context);
-  simix_global->current_process = self;
+  process->exception = xbt_new(ex_ctx_t, 1);
+  XBT_CTX_INITIALIZE(process->exception);
 
- // xbt_swag_insert(process,simix_global->process_list);
-  DEBUG2("Inserting %s(%s) in the to_run list",process->name,
-        host->name);
-  xbt_swag_insert(process,simix_global->process_to_run);
+  /* Add properties */
+  process->properties = properties;
+
+  /* Add the process to it's host process list */
+  xbt_swag_insert(process, host->process_list);
+
+  DEBUG1("Start context '%s'", process->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);
+  xbt_swag_insert(process, simix_global->process_to_run);
 
   return process;
 }
 
-/** \ingroup m_process_management
+/** \brief Kill a SIMIX process
+ *
+ * This function simply kills a \a process... scarry isn't it ? :).
  * \param process poor victim
  *
- * This function simply kills a \a process... scarry isn't it ? :)
  */
 void SIMIX_process_kill(smx_process_t process)
 {
-  //int i;
-  simdata_process_t p_simdata = process->simdata;
-  //simdata_host_t h_simdata= p_simdata->host->simdata;
-  //int _cursor;
-  //smx_process_t proc = NULL;
-
-  DEBUG2("Killing %s on %s",process->name, p_simdata->host->name);
-  
-  /*
-  
-  if(p_simdata->waiting_task) {
-    xbt_dynar_foreach(p_simdata->waiting_task->simdata->sleeping,_cursor,proc) {
-      if(proc==process) 
-       xbt_dynar_remove_at(p_simdata->waiting_task->simdata->sleeping,_cursor,&proc);
+  DEBUG2("Killing process %s on %s", process->name, process->smx_host->name);
+
+  process->iwannadie = 1;
+
+  /* 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);
     }
-    if(p_simdata->waiting_task->simdata->compute)
-      surf_workstation_resource->common_public->
-       action_free(p_simdata->waiting_task->simdata->compute);
-    else if (p_simdata->waiting_task->simdata->comm) {
-      surf_workstation_resource->common_public->
-       action_change_state(p_simdata->waiting_task->simdata->comm,SURF_ACTION_FAILED);
-      surf_workstation_resource->common_public->
-       action_free(p_simdata->waiting_task->simdata->comm);
-    } else {
-      xbt_die("UNKNOWN STATUS. Please report this bug.");
+
+    if (process->sem) {
+      xbt_fifo_remove(process->sem->sleeping, process);
+
+      if (process->waiting_action) {
+        SIMIX_unregister_action_to_semaphore(process->waiting_action, process->sem);
+        SIMIX_action_destroy(process->waiting_action);
+      }
     }
-  }
 
-  if ((i==msg_global->max_channel) && (process!=MSG_process_self()) && 
-      (!p_simdata->waiting_task)) {
-    xbt_die("UNKNOWN STATUS. Please report this bug.");
-  }
-*/
-  xbt_swag_remove(process,simix_global->process_to_run);
-  xbt_swag_remove(process,simix_global->process_list);
-  xbt_context_free(process->simdata->context);
-
-  if(process==SIMIX_process_self()) {
-    /* I just killed myself */
-    xbt_context_yield();
-  }
-}
+    SIMIX_context_stop(process->context);
 
-/** \ingroup m_process_management
- * \brief Migrates an agent to another location.
- *
- * This functions checks whether \a process and \a host are valid pointers
-   and change the value of the #m_host_t on which \a process is running.
- */
-SIMIX_error_t SIMIX_process_change_host(smx_process_t process, smx_host_t host)
-{
-  simdata_process_t simdata = NULL;
+  } else {
+    DEBUG4("%s(%p) here! killing %s(%p)",
+        simix_global->current_process->name,simix_global->current_process,
+        process->name,process);
+
+    /* Cleanup if it were waiting for something */
+    if (process->mutex) {
+      xbt_swag_remove(process, process->mutex->sleeping);
+      process->mutex = NULL;
+    }
 
-  /* Sanity check */
+    if (process->cond) {
+      xbt_swag_remove(process, process->cond->sleeping);
 
-  xbt_assert0(((process) && (process->simdata)
-         && (host)), "Invalid parameters");
-  simdata = process->simdata;
+      if (process->waiting_action) {
+        SIMIX_unregister_action_to_condition(process->waiting_action, process->cond);
+        SIMIX_action_destroy(process->waiting_action);
+      }
+      process->cond = NULL;
+    }
+
+    if (process->sem) {
+      xbt_fifo_remove(process->sem->sleeping, process);
 
-  xbt_swag_remove(process,simdata->host->simdata->process_list);
-  simdata->host = host;
-  xbt_swag_insert(process,host->simdata->process_list);
+      if (process->waiting_action) {
+       SIMIX_unregister_action_to_semaphore(process->waiting_action, process->sem);
+       SIMIX_action_destroy(process->waiting_action);
+      }
+      process->sem = NULL;
+    }
 
-  return SIMIX_OK;
+    /* make sure that the process gets awake soon enough, now that we've set its iwannadie to 1 */
+    process->blocked = 0;
+    process->suspended = 0;
+    xbt_swag_insert(process, simix_global->process_to_run);
+  }
 }
 
-/** \ingroup m_process_management
- * \brief Return the user data of a #m_process_t.
+/**
+ * \brief Return the user data of a #smx_process_t.
  *
- * This functions checks whether \a process is a valid pointer or not 
-   and return the user data associated to \a process if it is possible.
+ * This functions checks whether \a process is a valid pointer or not and return the user data associated to \a process if it is possible.
+ * \param process SIMIX process
+ * \return A void pointer to the user data
  */
-void *SIMIX_process_get_data(smx_process_t process)
+XBT_INLINE void *SIMIX_process_get_data(smx_process_t process)
 {
   xbt_assert0((process != NULL), "Invalid parameters");
-
   return (process->data);
 }
 
-/** \ingroup m_process_management
+/**
  * \brief Set the user data of a #m_process_t.
  *
- * This functions checks whether \a process is a valid pointer or not 
-   and set the user data associated to \a process if it is possible.
+ * This functions checks whether \a process is a valid pointer or not and set the user data associated to \a process if it is possible.
+ * \param process SIMIX process
+ * \param data User data
  */
-SIMIX_error_t SIMIX_process_set_data(smx_process_t process,void *data)
+XBT_INLINE void SIMIX_process_set_data(smx_process_t process, void *data)
 {
   xbt_assert0((process != NULL), "Invalid parameters");
-  xbt_assert0((process->data == NULL), "Data already set");
-  
+
   process->data = data;
-   
-  return SIMIX_OK;
+  return;
 }
 
-/** \ingroup m_process_management
+/**
  * \brief Return the location on which an agent is running.
  *
- * This functions checks whether \a process is a valid pointer or not 
-   and return the m_host_t corresponding to the location on which \a 
-   process is running.
+ * This functions checks whether \a process is a valid pointer or not and return the m_host_t corresponding to the location on which \a process is running.
+ * \param process SIMIX process
+ * \return SIMIX host
  */
-smx_host_t SIMIX_process_get_host(smx_process_t process)
+XBT_INLINE smx_host_t SIMIX_process_get_host(smx_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
-
-  return (((simdata_process_t) process->simdata)->host);
+  xbt_assert0((process != NULL), "Invalid parameters");
+  return (process->smx_host);
 }
 
-/** \ingroup m_process_management
+/**
  * \brief Return the name of an agent.
  *
- * This functions checks whether \a process is a valid pointer or not 
-   and return its name.
+ * This functions checks whether \a process is a valid pointer or not and return its name.
+ * \param process SIMIX process
+ * \return The process name
  */
-const char *SIMIX_process_get_name(smx_process_t process)
+XBT_INLINE const char *SIMIX_process_get_name(smx_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
-
+  xbt_assert0((process != NULL), "Invalid parameters");
   return (process->name);
 }
 
-/** \ingroup m_process_management
- * \brief Return the current agent.
+/**
+ * \brief Changes the name of an agent.
  *
- * This functions returns the currently running #m_process_t.
+ * This functions checks whether \a process is a valid pointer or not and return its name.
+ * \param process SIMIX process
+ * \param name The new process name
  */
-smx_process_t SIMIX_process_self(void)
+XBT_INLINE void SIMIX_process_set_name(smx_process_t process, char *name)
 {
-  return simix_global ? simix_global->current_process : NULL;
+  xbt_assert0((process != NULL), "Invalid parameters");
+  process->name = name;
 }
 
 /** \ingroup m_process_management
- * \brief Suspend the process.
+ * \brief Return the properties
  *
- * This functions suspend the process by suspending the task on which
- * it was waiting for the completion.
+ * This functions returns the properties associated with this process
  */
-SIMIX_error_t SIMIX_process_suspend(smx_process_t process)
+XBT_INLINE xbt_dict_t SIMIX_process_get_properties(smx_process_t process)
 {
-  simdata_process_t simdata = NULL;
-       smx_action_t dummy;
-       char name[] = "dummy";
-       
-  xbt_assert0(((process) && (process->simdata)), "Invalid parameters");
-
-  if(process!=SIMIX_process_self()) {
-    simdata = process->simdata;
-    
-               if ( (simdata->mutex == NULL) && (simdata->cond == NULL) ) {
-                       /* Ops, I don't know what to do yet. */
-
-               }
-               else if (simdata->mutex) {
-                       /* process blocked on a mutex, only set suspend=1 */
-                       simdata->suspended = 1;
-               }
-               else if (simdata->cond){
-                       /* process blocked cond, suspend all actions */
-                       
-                       /* temporaries variables */ 
-                       smx_cond_t c;
-                       xbt_fifo_item_t i;
-                       smx_action_t act;
-
-                       simdata->suspended = 1;
-                       c = simdata->cond;
-                       xbt_fifo_foreach(c->actions,i,act, smx_action_t) {
-                                surf_workstation_resource->common_public->suspend(act->simdata->surf_action);
-                       }
-               }
-               else xbt_assert0(0, "Unknown process status");
+  return process->properties;
+}
 
-  }
-       else {
-               /* process executing, I can create an action and suspend it */
-               dummy = SIMIX_execute(SIMIX_process_get_host(process)->simdata->host, name, 0);
-               process->simdata->block_action = dummy;
-
-               process->simdata->suspended = 1;
-               surf_workstation_resource->common_public->suspend(dummy->simdata->surf_action);
-               __SIMIX_wait_for_action(process,dummy);
-               SIMIX_action_destroy(dummy);
-               process->simdata->suspended = 0;
-
-       }
-  return SIMIX_OK;
+/**
+ * \brief Return the current agent.
+ *
+ * This functions returns the currently running #smx_process_t.
+ * \return The SIMIX process
+ */
+XBT_INLINE smx_process_t SIMIX_process_self(void)
+{
+ if(simix_global)
+        return simix_global->current_process;
+ return NULL;
 }
 
-/** \ingroup m_process_management
- * \brief Resume a suspended process.
+/**
+ * \brief Suspend the process.
  *
- * This functions resume a suspended process by resuming the task on
+ * This functions suspend the process by suspending the action on
  * which it was waiting for the completion.
+ *
+ * \param process SIMIX process
  */
-SIMIX_error_t SIMIX_process_resume(smx_process_t process)
+void SIMIX_process_suspend(smx_process_t process)
 {
-  simdata_process_t simdata = NULL;
-
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
-  CHECK_HOST();
-
-  if(process == SIMIX_process_self()) {
-    SIMIX_RETURN(SIMIX_OK);
+  xbt_assert0(process, "Invalid parameters");
+
+  if (process != SIMIX_process_self()) {
+
+    if (process->mutex) {
+      /* process blocked on a mutex or sem, only set suspend=1 */
+      process->suspended = 1;
+    } else if (process->cond) {
+      /* process blocked cond, suspend all actions */
+
+      /* temporaries variables */
+      smx_cond_t c;
+      xbt_fifo_item_t i;
+      smx_action_t act;
+
+      process->suspended = 1;
+      c = process->cond;
+      xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
+        SIMIX_action_suspend(act);
+      }
+    } else if (process->sem) {
+      smx_sem_t s;
+      xbt_fifo_item_t i;
+      smx_action_t act;
+
+      process->suspended = 1;
+      s = process->sem;
+      xbt_fifo_foreach(s->actions, i, act, smx_action_t) {
+        SIMIX_action_suspend(act);
+      }
+    } else {
+      process->suspended = 1;
+    }
+  } else {
+    /* process executing, I can create an action and suspend it */
+    smx_action_t dummy;
+    smx_cond_t cond;
+    char name[] = "dummy";
+    process->suspended = 1;
+
+    cond = SIMIX_cond_init();
+    dummy = SIMIX_action_execute(SIMIX_process_get_host(process), name, 0);
+    SIMIX_process_self()->waiting_action = dummy;
+    SIMIX_action_suspend(dummy);
+    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);
   }
+  return;
+}
 
-  simdata = process->simdata;
-
-  if(simdata->mutex) {
-    simdata->suspended = 0; /* He'll wake up by itself */
-    SIMIX_RETURN(SIMIX_OK);
+/**
+ * \brief Resume a suspended process.
+ *
+ * This functions resume a suspended process by resuming the task on which it was waiting for the completion.
+ * \param process SIMIX process
+ */
+void SIMIX_process_resume(smx_process_t process)
+{
+  xbt_assert0((process != NULL), "Invalid parameters");
+  SIMIX_CHECK_HOST();
+
+  if (process == SIMIX_process_self())
+    return;
+
+  if (process->mutex) {
+    DEBUG0("Resume process blocked on a mutex or semaphore");
+    process->suspended = 0;     /* It'll wake up by itself when mutex releases */
+    return;
+  } else if (process->cond) {
+    /* temporaries variables */
+    smx_cond_t c;
+    xbt_fifo_item_t i;
+    smx_action_t act;
+    DEBUG0("Resume process blocked on a conditional");
+    process->suspended = 0;
+    c = process->cond;
+    xbt_fifo_foreach(c->actions, i, act, smx_action_t) {
+      SIMIX_action_resume(act);
+    }
+    SIMIX_cond_signal(c);
+    return;
+  } else if (process->sem) {
+    /* temporaries variables */
+    smx_sem_t s;
+    xbt_fifo_item_t i;
+    smx_action_t act;
+    DEBUG0("Resume process blocked on a semaphore");
+    process->suspended = 0;
+    s = process->sem;
+    xbt_fifo_foreach(s->actions, i, act, smx_action_t) {
+      SIMIX_action_resume(act);
+    }
+    return;
+  } else {
+    process->suspended = 0;
+    xbt_swag_insert(process, simix_global->process_to_run);
   }
-       else if (simdata->cond) {
-               /* temporaries variables */ 
-               smx_cond_t c;
-               xbt_fifo_item_t i;
-               smx_action_t act;
-
-               simdata->suspended = 0;
-               c = simdata->cond;
-               xbt_fifo_foreach(c->actions,i,act, smx_action_t) {
-                       surf_workstation_resource->common_public->resume(act->simdata->surf_action);
-               }
-    SIMIX_RETURN(SIMIX_OK);
-       }
-       else if (simdata->block_action){
-               simdata->suspended = 0;
-               surf_workstation_resource->common_public->resume(simdata->block_action->simdata->surf_action);
-    SIMIX_RETURN(SIMIX_OK);
-       }
-       else xbt_assert0(0, "Unknown process status");
+}
 
+/**
+ * \brief Migrates an agent to another location.
+ *
+ * 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)
+{
+  smx_host_t h1 = NULL;
+  smx_host_t h2 = NULL;
+  xbt_assert0((process != NULL), "Invalid parameters");
+  h1 = SIMIX_host_get_by_name(source);
+  h2 = SIMIX_host_get_by_name(dest);
+  process->smx_host = h2;
+  xbt_swag_remove(process, h1->process_list);
+  xbt_swag_insert(process, h2->process_list);
 }
 
-/** \ingroup m_process_management
+/**
  * \brief Returns true if the process is suspended .
  *
- * This checks whether a process is suspended or not by inspecting the
- * task on which it was waiting for the completion.
+ * This checks whether a process is suspended or not by inspecting the task on which it was waiting for the completion.
+ * \param process SIMIX process
+ * \return 1, if the process is suspended, else 0.
  */
-int SIMIX_process_is_suspended(smx_process_t process)
+XBT_INLINE int SIMIX_process_is_suspended(smx_process_t process)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  xbt_assert0((process != NULL), "Invalid parameters");
 
-  return (process->simdata->suspended);
+  return (process->suspended);
 }
 
-int __SIMIX_process_block(double max_duration)
+/**
+ * \brief Returns the amount of SIMIX processes in the system
+ *
+ * Maestro internal process is not counted, only user code processes are
+ */
+XBT_INLINE int SIMIX_process_count()
 {
-
-  smx_process_t process = SIMIX_process_self();
-  smx_action_t dummy = NULL;
-  char name[] = "dummy";
-
-  dummy = SIMIX_execute(SIMIX_process_get_host(process)->simdata->host, name, 0);
-       process->simdata->block_action = dummy;
-
-  process->simdata->blocked=1;
-
-  surf_workstation_resource->common_public->suspend(dummy->simdata->surf_action);
-  if(max_duration>=0)
-    surf_workstation_resource->common_public->set_max_duration(dummy->simdata->surf_action, 
-                                                              max_duration);
-       __SIMIX_wait_for_action(process,dummy);
-       SIMIX_action_destroy(dummy);
-       process->simdata->blocked=0;
-
-  if(process->simdata->suspended) {
-    DEBUG0("I've been suspended in the meantime");    
-    SIMIX_process_suspend(process);
-    DEBUG0("I've been resumed, let's keep going");    
-  }
-
-/*
-  m_task_t dummy = SIMIX_TASK_UNINITIALIZED;
-  char blocked_name[512];
-  snprintf(blocked_name,512,"blocked [%s] (%s:%s)",
-         info, process->name, process->simdata->host->name);
-
-  XBT_IN1(": max_duration=%g",max_duration);
-
-  dummy = MSG_task_create(blocked_name, 0.0, 0, NULL);
-  
-  PAJE_PROCESS_PUSH_STATE(process,"B",NULL);
-
-  process->simdata->blocked=1;
-  __MSG_task_execute(process,dummy);
-  surf_workstation_resource->common_public->suspend(dummy->simdata->compute);
-  if(max_duration>=0)
-    surf_workstation_resource->common_public->set_max_duration(dummy->simdata->compute, 
-                                                              max_duration);
-  __MSG_wait_for_computation(process,dummy);
-  MSG_task_destroy(dummy);
-  process->simdata->blocked=0;
-
-  if(process->simdata->suspended) {
-    DEBUG0("I've been suspended in the meantime");    
-    SIMIX_process_suspend(process);
-    DEBUG0("I've been resumed, let's keep going");    
-  }
-
-  PAJE_PROCESS_POP_STATE(process);
-
-  XBT_OUT;
-  */
-  return 1;
+  return xbt_swag_size(simix_global->process_list);
 }
 
-SIMIX_error_t __SIMIX_process_unblock(smx_process_t process)
+/** 
+ * Calling this function makes the process process to yield. The process
+ * that scheduled it returns from __SIMIX_process_schedule as if nothing
+ * had happened.
+ * 
+ * Only the processes can call this function, giving back the control
+ * to the maestro
+ */
+void SIMIX_process_yield(void)
 {
-  simdata_process_t simdata = NULL;
-  simdata_action_t simdata_action = NULL;
+  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 in maestro context!");
 
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
-  CHECK_HOST();
 
-       simdata = process->simdata;
-  if(!(simdata->block_action)) {
-    xbt_assert0(0,"Process is not blocked !");
-    return SIMIX_WARNING;
-  }
-       simdata_action = simdata->block_action->simdata;
-  xbt_assert0(simdata->blocked,"Process not blocked");
-  surf_workstation_resource->common_public->resume(simdata_action->surf_action);
-  SIMIX_RETURN(SIMIX_OK);
+  /* Go into sleep and return control to maestro */
+  SIMIX_context_suspend(simix_global->current_process->context);
+  /* Ok, maestro returned control to us */
 
-/*
-  simdata_process_t simdata = NULL;
-  simdata_task_t simdata_task = NULL;
-
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
-  CHECK_HOST();
-
-  XBT_IN2(": %s unblocking %s", SIMIX_process_self()->name,process->name);
+  if (simix_global->current_process->iwannadie)
+    SIMIX_context_stop(simix_global->current_process->context);
+}
 
-  simdata = process->simdata;
-  if(!(simdata->waiting_task)) {
-    xbt_assert0(0,"Process not waiting for anything else. Weird !");
-    XBT_OUT;
-    return SIMIX_WARNING;
-  }
-  simdata_task = simdata->waiting_task->simdata;
+void SIMIX_process_schedule(smx_process_t new_process)
+{
+  xbt_assert0(simix_global->current_process == simix_global->maestro_process,
+      "This function can only be called from maestro context");
+  DEBUG1("Scheduling context: '%s'", new_process->name);
 
-  xbt_assert0(simdata->blocked,"Process not blocked");
+  /* update the current process */
+  simix_global->current_process = new_process;
 
-  surf_workstation_resource->common_public->resume(simdata_task->compute);
+  /* schedule the context */
+  SIMIX_context_resume(new_process->context);
+  DEBUG1("Resumed from scheduling context: '%s'", new_process->name);
 
-  XBT_OUT;
-*/
+  /* restore the current process to the previously saved process */
+  simix_global->current_process = simix_global->maestro_process;
 }
 
-int __SIMIX_process_isBlocked(smx_process_t process)
+/* callback: context fetching */
+ex_ctx_t *SIMIX_process_get_exception(void)
 {
-  xbt_assert0(((process != NULL) && (process->simdata)), "Invalid parameters");
+  return simix_global->current_process->exception;
+}
 
-  return (process->simdata->blocked);
+/* callback: termination */
+void SIMIX_process_exception_terminate(xbt_ex_t * e)
+{
+  xbt_ex_display(e);
+  abort();
 }