/** \ingroup msg_task_usage * \brief Sleep for the specified number of seconds * * Makes the current process sleep until \a time seconds have elapsed. * * \param nb_sec a number of second */ msg_error_t MSG_process_sleep(double nb_sec) { xbt_ex_t e; msg_error_t status = MSG_OK; /*msg_process_t proc = MSG_process_self();*/ TRACE_msg_process_sleep_in(MSG_process_self()); TRY { simcall_process_sleep(nb_sec); } CATCH(e) { switch (e.category) { case cancel_error: XBT_DEBUG("According to the JAVA API, a sleep call should only deal with HostFailureException, WTF here ?"); // adsein: MSG_TASK_CANCELED is assigned when someone kills the process that made the sleep, this is not // correct. For instance, when the node is turned off, the error should be MSG_HOST_FAILURE, which is by the way // and according to the JAVA document, the only exception that can be triggered by MSG_Process_sleep call. // To avoid possible impacts in the code, I just raised a host_failure exception for the moment in the JAVA code // and did not change anythings at the C level. // See comment in the jmsg_process.c file, function JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_sleep(JNIEnv *env, jclass cls, jlong jmillis, jint jnanos) status = MSG_TASK_CANCELED; break; default: RETHROW; } xbt_ex_free(e); } TRACE_msg_process_sleep_out(MSG_process_self()); MSG_RETURN(status); }
/** \ingroup m_process_management * \brief Resume a suspended process. * * This function resumes a suspended process by resuming the task on * which it was waiting for the completion. */ msg_error_t MSG_process_resume(msg_process_t process) { xbt_assert(process != NULL, "Invalid parameter: First argument must not be NULL"); TRACE_msg_process_resume(process); simcall_process_resume(process); MSG_RETURN(MSG_OK); }
/** \ingroup msg_mailbox_management * \brief Get a task from a mailbox on a given host at a given rate * * \param mailbox The mailbox where the task was sent * \param task a memory location for storing a #msg_task_t. * \param host a #msg_host_t host from where the task was sent * \param timeout a timeout * \param rate a rate * \return Returns * #MSG_OK if the task was successfully received, * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise. */ msg_error_t MSG_mailbox_get_task_ext_bounded(msg_mailbox_t mailbox, msg_task_t * task, msg_host_t host, double timeout, double rate) { xbt_ex_t e; msg_error_t ret = MSG_OK; /* We no longer support getting a task from a specific host */ if (host) THROW_UNIMPLEMENTED; TRACE_msg_task_get_start(); double start_time = MSG_get_clock(); /* Sanity check */ xbt_assert(task, "Null pointer for the task storage"); if (*task) XBT_WARN ("Asked to write the received task in a non empty struct -- proceeding."); /* Try to receive it by calling SIMIX network layer */ TRY { simcall_comm_recv(mailbox, task, NULL, NULL, NULL, NULL, timeout, rate); XBT_DEBUG("Got task %s from %p",(*task)->name,mailbox); if (msg_global->debug_multiple_use && (*task)->simdata->isused!=0) xbt_ex_free(*(xbt_ex_t*)(*task)->simdata->isused); (*task)->simdata->isused = 0; } 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; case host_error: ret = MSG_HOST_FAILURE; break; default: RETHROW; } xbt_ex_free(e); } if (ret != MSG_HOST_FAILURE && ret != MSG_TRANSFER_FAILURE && ret != MSG_TIMEOUT) { TRACE_msg_task_get_end(start_time, *task); } MSG_RETURN(ret); }
/** \ingroup m_process_management * \brief Resume a suspended process. * * This function resumes a suspended process by resuming the task on * which it was waiting for the completion. */ msg_error_t MSG_process_resume(msg_process_t process) { xbt_assert(process != NULL, "Invalid parameter"); #ifdef HAVE_TRACING TRACE_msg_process_resume(process); #endif simcall_process_resume(process); MSG_RETURN(MSG_OK); }
/** \ingroup m_process_management * \brief Resume a suspended process. * * This function resumes a suspended process by resuming the task on * which it was waiting for the completion. */ MSG_error_t MSG_process_resume(m_process_t process) { xbt_assert(process != NULL, "Invalid parameter"); CHECK_HOST(); #ifdef HAVE_TRACING TRACE_msg_process_resume(process); #endif SIMIX_req_process_resume(process); MSG_RETURN(MSG_OK); }
/** \ingroup msg_task_usage * \brief Sleep for the specified number of seconds * * Makes the current process sleep until \a time seconds have elapsed. * * \param nb_sec a number of second */ msg_error_t MSG_process_sleep(double nb_sec) { xbt_ex_t e; msg_error_t status = MSG_OK; /*msg_process_t proc = MSG_process_self();*/ #ifdef HAVE_TRACING TRACE_msg_process_sleep_in(MSG_process_self()); #endif /* create action to sleep */ /*proc->simdata->waiting_action = act_sleep; FIXME: check if not setting the waiting_action breaks something on msg proc->simdata->waiting_action = NULL;*/ TRY { simcall_process_sleep(nb_sec); } CATCH(e) { switch (e.category) { case cancel_error: status = MSG_TASK_CANCELED; break; default: RETHROW; } xbt_ex_free(e); } #ifdef HAVE_TRACING TRACE_msg_process_sleep_out(MSG_process_self()); #endif MSG_RETURN(status); }
/** \ingroup msg_task_usage * \brief Sleep for the specified number of seconds * * Makes the current process sleep until \a time seconds have elapsed. * * \param nb_sec a number of second */ msg_error_t MSG_process_sleep(double nb_sec) { msg_error_t status = MSG_OK; /*msg_process_t proc = MSG_process_self();*/ #ifdef HAVE_TRACING TRACE_msg_process_sleep_in(MSG_process_self()); #endif /* create action to sleep */ /*proc->simdata->waiting_action = act_sleep; FIXME: check if not setting the waiting_action breaks something on msg proc->simdata->waiting_action = NULL;*/ simcall_process_sleep(nb_sec); #ifdef HAVE_TRACING TRACE_msg_process_sleep_out(MSG_process_self()); #endif MSG_RETURN(status); }
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); }
/** \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); }
/** \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); }