X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/226d3997c4e356a1935b7d51b310034b4833afb9..6de9090dd8692387ae343c587b26915f9922d7bd:/src/msg/msg_gos.c diff --git a/src/msg/msg_gos.c b/src/msg/msg_gos.c index 4623eb68a1..23911d7624 100644 --- a/src/msg/msg_gos.c +++ b/src/msg/msg_gos.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2004-2011. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2004-2012. 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. */ @@ -23,76 +23,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_gos, msg, */ MSG_error_t MSG_task_execute(m_task_t task) { - simdata_task_t simdata = NULL; - simdata_process_t p_simdata; - e_smx_state_t comp_state; - - simdata = task->simdata; - - xbt_assert(simdata->host_nb == 0, - "This is a parallel task. Go to hell."); - -#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) { -#ifdef HAVE_TRACING - TRACE_msg_task_execute_end(task); -#endif - return MSG_OK; - } - - m_process_t self = SIMIX_process_self(); - p_simdata = SIMIX_process_self_get_data(self); - simdata->isused=1; - simdata->compute = - simcall_host_execute(task->name, p_simdata->m_host->simdata->smx_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); - if (comp_state == SIMIX_DONE) { - /* 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(MSG_OK); - } else if (simcall_host_get_state(SIMIX_host_self()) == 0) { - /* action ended, set comm and compute = NULL, the actions is already destroyed in the main function */ - simdata->comm = NULL; - simdata->compute = NULL; -#ifdef HAVE_TRACING - TRACE_msg_task_execute_end(task); -#endif - MSG_RETURN(MSG_HOST_FAILURE); - } else { - /* action ended, set comm and compute = NULL, the actions is already destroyed in the main function */ - simdata->comm = NULL; - simdata->compute = NULL; -#ifdef HAVE_TRACING - TRACE_msg_task_execute_end(task); -#endif - MSG_RETURN(MSG_TASK_CANCELED); - } + return MSG_parallel_task_execute(task); } /** \ingroup m_task_management @@ -146,7 +77,7 @@ MSG_parallel_task_create(const char *name, int host_nb, simdata->comm_amount = communication_amount; for (i = 0; i < host_nb; i++) - simdata->host_list[i] = host_list[i]->simdata->smx_host; + simdata->host_list[i] = host_list[i]->smx_host; return task; } @@ -161,56 +92,89 @@ MSG_parallel_task_create(const char *name, int host_nb, */ MSG_error_t MSG_parallel_task_execute(m_task_t task) { + xbt_ex_t e; simdata_task_t simdata = NULL; - e_smx_state_t comp_state; simdata_process_t p_simdata; + e_smx_state_t comp_state; + MSG_error_t status = MSG_OK; simdata = task->simdata; - p_simdata = SIMIX_process_self_get_data(SIMIX_process_self()); + m_process_t self = SIMIX_process_self(); + p_simdata = SIMIX_process_self_get_data(self); + + #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())); - xbt_assert((!simdata->compute) - && (task->simdata->isused == 0), - "This task is executed somewhere else. Go fix your code!"); + if (simdata->computation_amount == 0 && !simdata->host_nb) { + #ifdef HAVE_TRACING + TRACE_msg_task_execute_end(task); + #endif + return MSG_OK; + } - xbt_assert(simdata->host_nb, - "This is not a parallel task. Go to hell."); - XBT_DEBUG("Parallel computing on %s", p_simdata->m_host->name); + TRY { + #ifdef HAVE_TRACING + simcall_set_category(simdata->compute, task->category); + #endif - simdata->isused=1; + simdata->isused=1; - simdata->compute = - simcall_host_parallel_execute(task->name, simdata->host_nb, + 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); - - p_simdata->waiting_action = simdata->compute; - comp_state = simcall_host_execution_wait(simdata->compute); - p_simdata->waiting_action = NULL; - - XBT_DEBUG("Finished waiting for execution of action %p, state = %d", simdata->compute, (int)comp_state); - - simdata->isused=0; - - if (comp_state == SIMIX_DONE) { - /* 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; - MSG_RETURN(MSG_OK); - } else if (simcall_host_get_state(SIMIX_host_self()) == 0) { - /* action ended, set comm and compute = NULL, the actions is already destroyed in the main function */ - simdata->comm = NULL; - simdata->compute = NULL; - MSG_RETURN(MSG_HOST_FAILURE); - } else { - /* action ended, set comm and compute = NULL, the actions is already destroyed in the main function */ - simdata->comm = NULL; - simdata->compute = NULL; - MSG_RETURN(MSG_TASK_CANCELED); + XBT_DEBUG("Parallel execution action created: %p", simdata->compute); + } + else { + simdata->compute = + simcall_host_execute(task->name, p_simdata->m_host->smx_host, + simdata->computation_amount, + simdata->priority); + + } + 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 host_error: + status = MSG_HOST_FAILURE; + break; + case cancel_error: + #ifdef HAVE_TRACING + TRACE_msg_task_execute_end(task); + #endif + 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); } @@ -223,7 +187,8 @@ MSG_error_t MSG_parallel_task_execute(m_task_t task) */ MSG_error_t MSG_process_sleep(double nb_sec) { - e_smx_state_t state; + xbt_ex_t e; + MSG_error_t status = MSG_OK; /*m_process_t proc = MSG_process_self();*/ #ifdef HAVE_TRACING @@ -231,33 +196,58 @@ MSG_error_t MSG_process_sleep(double nb_sec) #endif /* create action to sleep */ - state = simcall_process_sleep(nb_sec); /*proc->simdata->waiting_action = act_sleep; FIXME: check if not setting the waiting_action breaks something on msg proc->simdata->waiting_action = NULL;*/ - - if (state == SIMIX_DONE) { -#ifdef HAVE_TRACING - TRACE_msg_process_sleep_out(MSG_process_self()); -#endif - MSG_RETURN(MSG_OK); - } else { -#ifdef HAVE_TRACING - TRACE_msg_process_sleep_out(MSG_process_self()); -#endif - MSG_RETURN(MSG_HOST_FAILURE); + + TRY { + simcall_process_sleep(nb_sec); } + CATCH(e) { + switch (e.category) { + case host_error: + #ifdef HAVE_TRACING + TRACE_msg_process_sleep_out(MSG_process_self()); + #endif + status = MSG_HOST_FAILURE; + 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 Receives a task from a mailbox from a specific host. + * \brief Deprecated function that used to receive a task from a mailbox from a specific host. * - * This is a blocking function, the execution flow will be blocked - * until the task is received. See #MSG_task_irecv - * for receiving tasks asynchronously. + * Sorry, this function is not supported anymore. That wouldn't be + * impossible to reimplement it, but we are lacking the time to do so ourselves. + * If you need this functionality, you can either: + * + * - implement the buffering mechanism on the user-level by queuing all messages + * received in the mailbox that do not match your expectation + * - change your application logic to leverage the mailboxes features. For example, + * if you have A receiving messages from B and C, you could have A waiting on + * mailbox "A" most of the time, but on "A#B" when it's waiting for specific + * messages from B and "A#C" when waiting for messages from C. You could even get A + * sometime waiting on all these mailboxes using @ref MSG_comm_waitany. You can find + * an example of use of this function in the @ref MSG_examples section. + * - Provide a proper patch to implement this functionality back in MSG. That wouldn't be + * very difficult actually. Check the function @ref MSG_mailbox_get_task_ext. During its call to + * simcall_comm_recv(), the 5th argument, match_fun, is NULL. Create a function that filters + * messages according to the host (that you will pass as sixth argument to simcall_comm_recv() + * and that your filtering function will receive as first parameter, and then, the filter could + * simply compare the host names, for example. After sufficient testing, provide an example that + * we could add to the distribution, and your first contribution to SimGrid is ready. Thanks in advance. * * \param task a memory location for storing a #m_task_t. * \param alias name of the mailbox to receive the task from @@ -367,12 +357,15 @@ msg_comm_t MSG_task_isend(m_task_t task, const char *alias) * * \param task a #m_task_t to send on another location. * \param alias name of the mailbox to sent the task to - * \param match_fun boolean function taking the match_data provided by sender (here), and the one of the receiver (if any) and returning whether they match + * \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(m_task_t task, const char *alias, - int (*match_fun)(void*,void*), + int (*match_fun)(void*,void*, smx_action_t), void *match_data) { simdata_task_t t_simdata = NULL; @@ -454,8 +447,8 @@ void MSG_task_dsend(m_task_t task, const char *alias, void_f_pvoid_t cleanup) * * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test() * to end the communication. - * - * \param task a memory location for storing a #m_task_t. + * + * \param task a memory location for storing a #m_task_t. has to be valid until the end of the communication. * \param name of the mailbox to receive the task on * \return the msg_comm_t communication created */ @@ -606,7 +599,8 @@ void MSG_comm_destroy(msg_comm_t comm) * * It takes two parameters. * \param comm the communication to wait. - * \param timeout Wait until the communication terminates or the timeout occurs + * \param timeout Wait until the communication terminates or the timeout + * occurs. You can provide a -1 timeout to obtain an infinite timeout. * \return MSG_error_t */ MSG_error_t MSG_comm_wait(msg_comm_t comm, double timeout) @@ -1014,7 +1008,7 @@ MSG_task_put_with_timeout(m_task_t task, m_host_t dest, && (channel < msg_global->max_channel), "Invalid channel %d", channel); - XBT_DEBUG("MSG_task_put_with_timout: Trying to send a task to '%s'", dest->name); + XBT_DEBUG("MSG_task_put_with_timout: Trying to send a task to '%s'", SIMIX_host_get_name(dest->smx_host)); return MSG_mailbox_put_with_timeout(MSG_mailbox_get_by_channel (dest, channel), task, timeout);