+void SIMIX_pre_process_join(smx_simcall_t simcall, smx_process_t process, double timeout)
+{
+ smx_action_t action = SIMIX_process_join(simcall->issuer, process, timeout);
+ xbt_fifo_push(action->simcalls, simcall);
+ simcall->issuer->waiting_action = action;
+}
+
+static int SIMIX_process_join_finish(smx_process_exit_status_t status, smx_action_t action){
+ if (action->sleep.surf_sleep) {
+ surf_action_cancel(action->sleep.surf_sleep);
+
+ smx_simcall_t simcall;
+ while ((simcall = xbt_fifo_shift(action->simcalls))) {
+ simcall_process_sleep__set__result(simcall, SIMIX_DONE);
+ simcall->issuer->waiting_action = NULL;
+ if (simcall->issuer->suspended) {
+ XBT_DEBUG("Wait! This process is suspended and can't wake up now.");
+ simcall->issuer->suspended = 0;
+ SIMIX_pre_process_suspend(simcall, simcall->issuer);
+ } else {
+ SIMIX_simcall_answer(simcall);
+ }
+ }
+ surf_action_unref(action->sleep.surf_sleep);
+ action->sleep.surf_sleep = NULL;
+ }
+ xbt_mallocator_release(simix_global->action_mallocator, action);
+ return 0;
+}
+
+smx_action_t SIMIX_process_join(smx_process_t issuer, smx_process_t process, double timeout)
+{
+ smx_action_t res = SIMIX_process_sleep(issuer, timeout);
+ res->type = SIMIX_ACTION_JOIN;
+ SIMIX_process_on_exit(process, (int_f_pvoid_pvoid_t)SIMIX_process_join_finish, res);
+ return res;
+}
+
+void SIMIX_pre_process_sleep(smx_simcall_t simcall, double duration)