/** * \brief Cleans the MSG data of a process. * \param smx_proc a SIMIX process */ void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc) { simdata_process_t msg_proc; // get the MSG process from the SIMIX process if (smx_proc == SIMIX_process_self()) { /* avoid a SIMIX request if this function is called by the process itself */ msg_proc = SIMIX_process_self_get_data(smx_proc); SIMIX_process_self_set_data(smx_proc, NULL); } else { msg_proc = simcall_process_get_data(smx_proc); simcall_process_set_data(smx_proc, NULL); } #ifdef HAVE_TRACING TRACE_msg_process_end(smx_proc); #endif // free the data if a function was provided if (msg_proc->data && msg_global->process_data_cleanup) { msg_global->process_data_cleanup(msg_proc->data); } // remove the process from its virtual machine if (msg_proc->vm) { int pos = xbt_dynar_search(msg_proc->vm->processes,&smx_proc); xbt_dynar_remove_at(msg_proc->vm->processes,pos, NULL); } // free the MSG process xbt_free(msg_proc); }
/** * \brief Cleans the MSG data of a process. * \param smx_proc a SIMIX process */ void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc) { simdata_process_t msg_proc; // get the MSG process from the SIMIX process if (smx_proc == SIMIX_process_self()) { /* avoid a SIMIX request if this function is called by the process itself */ msg_proc = SIMIX_process_self_get_data(smx_proc); SIMIX_process_self_set_data(smx_proc, NULL); } else { msg_proc = simcall_process_get_data(smx_proc); simcall_process_set_data(smx_proc, NULL); } TRACE_msg_process_end(smx_proc); // free the data if a function was provided if (msg_proc && msg_proc->data && msg_global->process_data_cleanup) { msg_global->process_data_cleanup(msg_proc->data); } // free the MSG process xbt_free(msg_proc); SIMIX_process_cleanup(smx_proc); }
/* Internal function used to factorize code between * MSG_task_isend_with_matching() and MSG_task_dsend(). */ static XBT_INLINE msg_comm_t MSG_task_isend_internal(msg_task_t task, const char *alias, int (*match_fun)(void*,void*, smx_synchro_t), void *match_data, void_f_pvoid_t cleanup, int detached) { simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias); int call_end = TRACE_msg_task_put_start(task); /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; if (t_simdata->isused != 0) { if (msg_global->debug_multiple_use){ XBT_ERROR("This task is already used in there:"); xbt_backtrace_display(t_simdata->isused); XBT_ERROR("And you try to reuse it from here:"); xbt_backtrace_display_current(); } else { xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code! (use --cfg=msg/debug_multiple_use:on to get the backtrace of the other process)"); } } if (msg_global->debug_multiple_use) MSG_BT(t_simdata->isused, "Using Backtrace"); else t_simdata->isused = (void*)1; t_simdata->comm = NULL; msg_global->sent_msg++; /* Send it by calling SIMIX network layer */ smx_synchro_t act = simcall_comm_isend(SIMIX_process_self(), mailbox, t_simdata->bytes_amount, t_simdata->rate, task, sizeof(void *), match_fun, cleanup, NULL, match_data,detached); t_simdata->comm = act; /* FIXME: is the field t_simdata->comm still useful? */ msg_comm_t comm; if (detached) { comm = NULL; } else { comm = xbt_new0(s_msg_comm_t, 1); comm->task_sent = task; comm->task_received = NULL; comm->status = MSG_OK; comm->s_comm = act; } if (TRACE_is_enabled()) simcall_set_category(act, task->category); if (call_end) TRACE_msg_task_put_end(); return comm; }
/** \ingroup m_process_management * \brief Return the location on which a process is running. * \param process a process (NULL means the current one) * \return the msg_host_t corresponding to the location on which \a * process is running. */ msg_host_t MSG_process_get_host(msg_process_t process) { simdata_process_t simdata; if (process == NULL) { simdata = SIMIX_process_self_get_data(SIMIX_process_self()); } else { simdata = simcall_process_get_data(process); } return simdata->m_host; }
/** \ingroup m_process_management * \brief Return the location on which a process is running. * \param process a process (nullptr means the current one) * \return the msg_host_t corresponding to the location on which \a process is running. */ msg_host_t MSG_process_get_host(msg_process_t process) { simdata_process_t simdata; if (process == nullptr) { simdata = (simdata_process_t) SIMIX_process_self_get_data(); } else { simdata = (simdata_process_t) simcall_process_get_data(process); } return simdata ? simdata->m_host : nullptr; }
/** * \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. * \param process SIMIX process * \return A void pointer to the user data */ void* SIMIX_req_process_get_data(smx_process_t process) { if (process == SIMIX_process_self()) { /* avoid a request if this function is called by the process itself */ return SIMIX_process_self_get_data(); } smx_req_t req = SIMIX_req_mine(); req->call = REQ_PROCESS_GET_DATA; req->process_get_data.process = process; SIMIX_request_push(); return req->process_get_data.result; }
/** \ingroup msg_task_usage * \brief Sends a task on a mailbox, with support for matching requests * * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test() * to end the communication. * * \param task a #msg_task_t to send on another location. * \param alias name of the mailbox to sent the task to * \param match_fun boolean function which parameters are: * - match_data_provided_here * - match_data_provided_by_other_side_if_any * - the_smx_action_describing_the_other_side * \param match_data user provided data passed to match_fun * \return the msg_comm_t communication created */ XBT_INLINE msg_comm_t MSG_task_isend_with_matching(msg_task_t task, const char *alias, int (*match_fun)(void*,void*, smx_action_t), void *match_data) { simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias); #ifdef HAVE_TRACING int call_end = TRACE_msg_task_put_start(task); #endif /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code!"); t_simdata->isused = 1; t_simdata->comm = NULL; msg_global->sent_msg++; /* Send it by calling SIMIX network layer */ msg_comm_t comm = xbt_new0(s_msg_comm_t, 1); comm->task_sent = task; comm->task_received = NULL; comm->status = MSG_OK; comm->s_comm = simcall_comm_isend(mailbox, t_simdata->message_size, t_simdata->rate, task, sizeof(void *), match_fun, NULL, match_data, 0); t_simdata->comm = comm->s_comm; /* FIXME: is the field t_simdata->comm still useful? */ #ifdef HAVE_TRACING if (TRACE_is_enabled()) { simcall_set_category(comm->s_comm, task->category); } #endif #ifdef HAVE_TRACING if (call_end) TRACE_msg_task_put_end(); #endif return comm; }
/******************************** Process ************************************/ void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc) { simdata_process_t msg_proc; if (smx_proc == SIMIX_process_self()) { /* avoid a SIMIX request if this function is called by the process itself */ msg_proc = SIMIX_process_self_get_data(); } else { msg_proc = SIMIX_req_process_get_data(smx_proc); } #ifdef HAVE_TRACING TRACE_msg_process_end(smx_proc); #endif xbt_free(msg_proc); }
static int xbt_thread_create_wrapper(int argc, char *argv[]) { smx_process_t self = SIMIX_process_self(); xbt_thread_t t = (xbt_thread_t) SIMIX_process_self_get_data(self); simcall_process_set_data(self, t->father_data); t->code(t->userparam); if (t->joinable) { t->done = 1; xbt_mutex_acquire(t->mutex); xbt_cond_broadcast(t->cond); xbt_mutex_release(t->mutex); } else { xbt_mutex_destroy(t->mutex); xbt_cond_destroy(t->cond); free(t->name); free(t); } return 0; }
xbt_thread_t xbt_thread_create(const char *name, void_f_pvoid_t code, void *param, int joinable) { xbt_thread_t res = xbt_new0(s_xbt_thread_t, 1); res->name = xbt_strdup(name); res->userparam = param; res->code = code; res->father_data = SIMIX_process_self_get_data(SIMIX_process_self()); /* char*name = bprintf("%s#%p",SIMIX_process_self_get_name(), param); */ simcall_process_create(&res->s_process, name, xbt_thread_create_wrapper, res, SIMIX_host_self_get_name(), -1.0, 0, NULL, /*props */ NULL,0); res->joinable = joinable; res->done = 0; res->cond = xbt_cond_init(); res->mutex = xbt_mutex_init(); // free(name); return res; }
/* Internal function used to factorize code between MSG_task_isend_with_matching() and MSG_task_dsend(). */ static inline msg_comm_t MSG_task_isend_internal(msg_task_t task, const char *alias, int (*match_fun)(void*,void*, smx_synchro_t), void *match_data, void_f_pvoid_t cleanup, int detached) { simdata_task_t t_simdata = nullptr; msg_process_t process = MSG_process_self(); msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias); int call_end = TRACE_msg_task_put_start(task); /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data())->m_host; t_simdata->setUsed(); t_simdata->comm = nullptr; msg_global->sent_msg++; /* Send it by calling SIMIX network layer */ smx_synchro_t act = simcall_comm_isend(SIMIX_process_self(), mailbox, t_simdata->bytes_amount, t_simdata->rate, task, sizeof(void *), match_fun, cleanup, nullptr, match_data,detached); t_simdata->comm = static_cast<simgrid::simix::Comm*>(act); /* FIXME: is the field t_simdata->comm still useful? */ msg_comm_t comm; if (detached) { comm = nullptr; } else { comm = xbt_new0(s_msg_comm_t, 1); comm->task_sent = task; comm->task_received = nullptr; comm->status = MSG_OK; comm->s_comm = act; } if (TRACE_is_enabled()) simcall_set_category(act, task->category); if (call_end) TRACE_msg_task_put_end(); return comm; }
/** \ingroup msg_task_usage * \brief Sends a task on a mailbox with a maximal rate. * * This is a non blocking detached send function. * Think of it as a best effort send. Keep in mind that the third parameter * is only called if the communication fails. If the communication does work, * it is responsibility of the receiver code to free anything related to * the task, as usual. More details on this can be obtained on * <a href="http://lists.gforge.inria.fr/pipermail/simgrid-user/2011-November/002649.html">this thread</a> * in the SimGrid-user mailing list archive. * * \param task a #msg_task_t to send on another location. * \param alias name of the mailbox to sent the task to * \param cleanup a function to destroy the task if the * communication fails, e.g. MSG_task_destroy * (if NULL, no function will be called) * \param maxrate the maximum communication rate for sending this task * */ void MSG_task_dsend_bounded(msg_task_t task, const char *alias, void_f_pvoid_t cleanup, double maxrate) { task->simdata->rate = maxrate; simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias); /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code!"); t_simdata->isused = 1; t_simdata->comm = NULL; msg_global->sent_msg++; #ifdef HAVE_TRACING int call_end = TRACE_msg_task_put_start(task); #endif /* Send it by calling SIMIX network layer */ smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size, t_simdata->rate, task, sizeof(void *), NULL, cleanup, NULL, 1); t_simdata->comm = comm; #ifdef HAVE_TRACING if (TRACE_is_enabled()) { simcall_set_category(comm, task->category); } #endif #ifdef HAVE_TRACING if (call_end) TRACE_msg_task_put_end(); #endif }
/** * \brief Cleans the MSG data of a process. * \param smx_proc a SIMIX process */ void MSG_process_cleanup_from_SIMIX(smx_actor_t smx_proc) { simdata_process_t msg_proc; // get the MSG process from the SIMIX process if (smx_proc == SIMIX_process_self()) { /* avoid a SIMIX request if this function is called by the process itself */ msg_proc = (simdata_process_t) SIMIX_process_self_get_data(); SIMIX_process_self_set_data(nullptr); } else { msg_proc = (simdata_process_t) simcall_process_get_data(smx_proc); simcall_process_set_data(smx_proc, nullptr); } TRACE_msg_process_destroy(smx_proc->name.c_str(), smx_proc->pid); // free the data if a function was provided if (msg_proc && msg_proc->data && msg_global->process_data_cleanup) { msg_global->process_data_cleanup(msg_proc->data); } // free the MSG process xbt_free(msg_proc); SIMIX_process_cleanup(smx_proc); }
xbt_thread_t xbt_thread_self(void) { return SIMIX_process_self_get_data(SIMIX_process_self()); }
msg_error_t MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task, double timeout) { xbt_ex_t e; msg_error_t ret = MSG_OK; simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(process); #ifdef HAVE_TRACING int call_end = TRACE_msg_task_put_start(task); //must be after CHECK_HOST() #endif /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code!"); t_simdata->isused=1; t_simdata->comm = NULL; msg_global->sent_msg++; p_simdata->waiting_task = task; /* Try to send it by calling SIMIX network layer */ TRY { smx_action_t comm = simcall_comm_isend(mailbox, t_simdata->message_size, t_simdata->rate, task, sizeof(void *), NULL, NULL, task, 0); #ifdef HAVE_TRACING if (TRACE_is_enabled()) { simcall_set_category(comm, task->category); } #endif t_simdata->comm = comm; simcall_comm_wait(comm, timeout); } CATCH(e) { switch (e.category) { case network_error: ret = MSG_TRANSFER_FAILURE; break; case timeout_error: ret = MSG_TIMEOUT; break; default: RETHROW; } xbt_ex_free(e); /* If the send failed, it is not used anymore */ t_simdata->isused = 0; } p_simdata->waiting_task = NULL; #ifdef HAVE_TRACING if (call_end) TRACE_msg_task_put_end(); #endif MSG_RETURN(ret); }
smpi_process_data_t smpi_process_data(void) { simdata_process_t simdata = static_cast<simdata_process_t>(SIMIX_process_self_get_data()); return static_cast<smpi_process_data_t>(simdata->data); }
/** \ingroup msg_task_usage * \brief Executes a parallel task and waits for its termination. * * \param task a #msg_task_t to execute on the location on which the process is running. * * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED * or #MSG_HOST_FAILURE otherwise */ msg_error_t MSG_parallel_task_execute(msg_task_t task) { xbt_ex_t e; simdata_task_t simdata = task->simdata; msg_process_t self = SIMIX_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(self); e_smx_state_t comp_state; msg_error_t status = MSG_OK; TRACE_msg_task_execute_start(task); xbt_assert((!simdata->compute) && (task->simdata->isused == 0), "This task is executed somewhere else. Go fix your code! %d", task->simdata->isused!=NULL); XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self())); if (simdata->flops_amount == 0 && !simdata->host_nb) { TRACE_msg_task_execute_end(task); return MSG_OK; } TRY { if (msg_global->debug_multiple_use) MSG_BT(simdata->isused, "Using Backtrace"); else simdata->isused = (void*)1; if (simdata->host_nb > 0) { simdata->compute = simcall_process_parallel_execute(task->name, simdata->host_nb, simdata->host_list, simdata->flops_parallel_amount, simdata->bytes_parallel_amount, 1.0, -1.0); XBT_DEBUG("Parallel execution action created: %p", simdata->compute); } else { unsigned long affinity_mask = (unsigned long) xbt_dict_get_or_null_ext(simdata->affinity_mask_db, (char *) p_simdata->m_host, sizeof(msg_host_t)); XBT_DEBUG("execute %s@%s with affinity(0x%04lx)", MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask); simdata->compute = simcall_process_execute(task->name, simdata->flops_amount, simdata->priority, simdata->bound, affinity_mask ); } simcall_set_category(simdata->compute, task->category); p_simdata->waiting_action = simdata->compute; comp_state = simcall_process_execution_wait(simdata->compute); p_simdata->waiting_action = NULL; if (msg_global->debug_multiple_use && simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)simdata->isused); simdata->isused = 0; XBT_DEBUG("Execution task '%s' finished in state %d", task->name, (int)comp_state); } CATCH(e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; case host_error: status = MSG_HOST_FAILURE; break; default: RETHROW; } xbt_ex_free(e); } /* action ended, set comm and compute = NULL, the actions is already destroyed * in the main function */ simdata->flops_amount = 0.0; simdata->comm = NULL; simdata->compute = NULL; TRACE_msg_task_execute_end(task); MSG_RETURN(status); }
/** \ingroup msg_task_usage * \brief Executes a parallel task and waits for its termination. * * \param task a #msg_task_t to execute on the location on which the process is running. * * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED * or #MSG_HOST_FAILURE otherwise */ msg_error_t MSG_parallel_task_execute(msg_task_t task) { simdata_task_t simdata = task->simdata; simdata_process_t p_simdata = (simdata_process_t) SIMIX_process_self_get_data(); e_smx_state_t comp_state; msg_error_t status = MSG_OK; TRACE_msg_task_execute_start(task); xbt_assert((!simdata->compute) && !task->simdata->isused, "This task is executed somewhere else. Go fix your code!"); XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self())); if (simdata->flops_amount == 0 && !simdata->host_nb) { TRACE_msg_task_execute_end(task); return MSG_OK; } try { simdata->setUsed(); if (simdata->host_nb > 0) { simdata->compute = static_cast<simgrid::simix::Exec*>( simcall_execution_parallel_start(task->name, simdata->host_nb,simdata->host_list, simdata->flops_parallel_amount, simdata->bytes_parallel_amount, 1.0, -1.0)); XBT_DEBUG("Parallel execution action created: %p", simdata->compute); } else { unsigned long affinity_mask = (unsigned long)(uintptr_t) xbt_dict_get_or_null_ext(simdata->affinity_mask_db, (char *) p_simdata->m_host, sizeof(msg_host_t)); XBT_DEBUG("execute %s@%s with affinity(0x%04lx)", MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask); simdata->compute = static_cast<simgrid::simix::Exec*>( simcall_execution_start(task->name, simdata->flops_amount, simdata->priority, simdata->bound, affinity_mask)); } simcall_set_category(simdata->compute, task->category); p_simdata->waiting_action = simdata->compute; comp_state = simcall_execution_wait(simdata->compute); p_simdata->waiting_action = nullptr; simdata->setNotUsed(); XBT_DEBUG("Execution task '%s' finished in state %d", task->name, (int)comp_state); } catch (xbt_ex& e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; case host_error: status = MSG_HOST_FAILURE; break; default: throw; } } /* action ended, set comm and compute = nullptr, the actions is already destroyed in the main function */ simdata->flops_amount = 0.0; simdata->comm = nullptr; simdata->compute = nullptr; TRACE_msg_task_execute_end(task); MSG_RETURN(status); }
msg_error_t MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task, double timeout) { msg_error_t ret = MSG_OK; simdata_task_t t_simdata = NULL; msg_process_t process = MSG_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(process); int call_end = TRACE_msg_task_put_start(task); //must be after CHECK_HOST() /* Prepare the task to send */ t_simdata = task->simdata; t_simdata->sender = process; t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host; if (t_simdata->isused != 0) { if (msg_global->debug_multiple_use){ XBT_ERROR("This task is already used in there:"); xbt_backtrace_display(t_simdata->isused); XBT_ERROR("And you try to reuse it from here:"); xbt_backtrace_display_current(); } else { xbt_assert(t_simdata->isused == 0, "This task is still being used somewhere else. You cannot send it now. Go fix your code! (use --cfg=msg/debug_multiple_use:on to get the backtrace of the other process)"); } } if (msg_global->debug_multiple_use) MSG_BT(t_simdata->isused, "Using Backtrace"); else t_simdata->isused = (void*)1; t_simdata->comm = NULL; msg_global->sent_msg++; p_simdata->waiting_task = task; xbt_ex_t e; /* Try to send it by calling SIMIX network layer */ TRY { smx_synchro_t comm = NULL; /* MC needs the comm to be set to NULL during the simix call */ comm = simcall_comm_isend(SIMIX_process_self(), mailbox,t_simdata->bytes_amount, t_simdata->rate, task, sizeof(void *), NULL, NULL, NULL, task, 0); if (TRACE_is_enabled()) simcall_set_category(comm, task->category); t_simdata->comm = comm; simcall_comm_wait(comm, timeout); } CATCH(e) { switch (e.category) { case cancel_error: ret = MSG_HOST_FAILURE; break; case network_error: ret = MSG_TRANSFER_FAILURE; break; case timeout_error: ret = MSG_TIMEOUT; break; default: RETHROW; } xbt_ex_free(e); /* If the send failed, it is not used anymore */ if (msg_global->debug_multiple_use && t_simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)t_simdata->isused); t_simdata->isused = 0; } p_simdata->waiting_task = NULL; if (call_end) TRACE_msg_task_put_end(); MSG_RETURN(ret); }
smpi_process_data_t smpi_process_data(void) { return SIMIX_process_self_get_data(SIMIX_process_self()); }
/** \ingroup msg_task_usage * \brief Executes a parallel task and waits for its termination. * * \param task a #msg_task_t to execute on the location on which the process is running. * * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED * or #MSG_HOST_FAILURE otherwise */ msg_error_t MSG_parallel_task_execute(msg_task_t task) { xbt_ex_t e; simdata_task_t simdata = task->simdata; msg_process_t self = SIMIX_process_self(); simdata_process_t p_simdata = SIMIX_process_self_get_data(self); e_smx_state_t comp_state; msg_error_t status = MSG_OK; #ifdef HAVE_TRACING TRACE_msg_task_execute_start(task); #endif xbt_assert((!simdata->compute) && (task->simdata->isused == 0), "This task is executed somewhere else. Go fix your code! %d", task->simdata->isused); XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self())); if (simdata->computation_amount == 0 && !simdata->host_nb) { #ifdef HAVE_TRACING TRACE_msg_task_execute_end(task); #endif return MSG_OK; } TRY { simdata->isused=1; if (simdata->host_nb > 0) { simdata->compute = simcall_host_parallel_execute(task->name, simdata->host_nb, simdata->host_list, simdata->comp_amount, simdata->comm_amount, 1.0, -1.0); XBT_DEBUG("Parallel execution action created: %p", simdata->compute); } else { simdata->compute = simcall_host_execute(task->name, p_simdata->m_host, simdata->computation_amount, simdata->priority); } #ifdef HAVE_TRACING simcall_set_category(simdata->compute, task->category); #endif p_simdata->waiting_action = simdata->compute; comp_state = simcall_host_execution_wait(simdata->compute); p_simdata->waiting_action = NULL; simdata->isused=0; XBT_DEBUG("Execution task '%s' finished in state %d", task->name, (int)comp_state); } CATCH(e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; default: RETHROW; } xbt_ex_free(e); } /* action ended, set comm and compute = NULL, the actions is already destroyed * in the main function */ simdata->computation_amount = 0.0; simdata->comm = NULL; simdata->compute = NULL; #ifdef HAVE_TRACING TRACE_msg_task_execute_end(task); #endif MSG_RETURN(status); }