Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
73c91df5340a3b5cc54d4636e6483f360722d8a7
[simgrid.git] / src / msg / msg_gos.c
1 /* Copyright (c) 2004-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "msg_private.h"
8 #include "msg_mailbox.h"
9 #include "mc/mc.h"
10 #include "xbt/log.h"
11 #include "xbt/sysdep.h"
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_gos, msg,
14                                 "Logging specific to MSG (gos)");
15
16 /** \ingroup msg_task_usage
17  * \brief Executes a task and waits for its termination.
18  *
19  * This function is used for describing the behavior of a process. It
20  * takes only one parameter.
21  * \param task a #msg_task_t to execute on the location on which the process is running.
22  * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED
23  * or #MSG_HOST_FAILURE otherwise
24  */
25 msg_error_t MSG_task_execute(msg_task_t task)
26 {
27   /* TODO: add this to other locations */
28   msg_host_t host = MSG_process_get_host(MSG_process_self());
29   MSG_host_add_task(host, task);
30
31   msg_error_t ret = MSG_parallel_task_execute(task);
32
33   MSG_host_del_task(host, task);
34
35   return ret;
36 }
37
38 /** \ingroup msg_task_usage
39  * \brief Executes a parallel task and waits for its termination.
40  *
41  * \param task a #msg_task_t to execute on the location on which the process is running.
42  *
43  * \return #MSG_OK if the task was successfully completed, #MSG_TASK_CANCELED
44  * or #MSG_HOST_FAILURE otherwise
45  */
46 msg_error_t MSG_parallel_task_execute(msg_task_t task)
47 {
48   xbt_ex_t e;
49   simdata_task_t simdata = task->simdata;
50   msg_process_t self = SIMIX_process_self();
51   simdata_process_t p_simdata = SIMIX_process_self_get_data(self);
52   e_smx_state_t comp_state;
53   msg_error_t status = MSG_OK;
54
55 #ifdef HAVE_TRACING
56   TRACE_msg_task_execute_start(task);
57 #endif
58
59   xbt_assert((!simdata->compute) && (task->simdata->isused == 0),
60              "This task is executed somewhere else. Go fix your code! %d",
61              task->simdata->isused!=NULL);
62
63   XBT_DEBUG("Computing on %s", MSG_process_get_name(MSG_process_self()));
64
65   if (simdata->computation_amount == 0 && !simdata->host_nb) {
66 #ifdef HAVE_TRACING
67     TRACE_msg_task_execute_end(task);
68 #endif
69     return MSG_OK;
70   }
71
72
73   TRY {
74     if (msg_global->debug_multiple_use)
75       MSG_BT(simdata->isused, "Using Backtrace");
76     else
77       simdata->isused = (void*)1;
78
79     if (simdata->host_nb > 0) {
80       simdata->compute = simcall_host_parallel_execute(task->name,
81                                                        simdata->host_nb,
82                                                        simdata->host_list,
83                                                        simdata->comp_amount,
84                                                        simdata->comm_amount,
85                                                        1.0, -1.0);
86       XBT_DEBUG("Parallel execution action created: %p", simdata->compute);
87     } else {
88       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));
89       XBT_DEBUG("execute %s@%s with affinity(0x%04lx)", MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask);
90
91       simdata->compute = simcall_host_execute(task->name,
92                                               p_simdata->m_host,
93                                               simdata->computation_amount,
94                                               simdata->priority,
95                                               simdata->bound,
96                                               affinity_mask
97                                               );
98
99     }
100 #ifdef HAVE_TRACING
101     simcall_set_category(simdata->compute, task->category);
102 #endif
103     p_simdata->waiting_action = simdata->compute;
104     comp_state = simcall_host_execution_wait(simdata->compute);
105
106     p_simdata->waiting_action = NULL;
107
108     if (msg_global->debug_multiple_use && simdata->isused!=0)
109       xbt_ex_free(*(xbt_ex_t*)simdata->isused);
110     simdata->isused = 0;
111
112     XBT_DEBUG("Execution task '%s' finished in state %d",
113               task->name, (int)comp_state);
114   }
115   CATCH(e) {
116     switch (e.category) {
117     case cancel_error:
118       status = MSG_TASK_CANCELED;
119       break;
120     case host_error:
121       status = MSG_HOST_FAILURE;
122       break;
123     default:
124       RETHROW;
125     }
126     xbt_ex_free(e);
127   }
128   /* action ended, set comm and compute = NULL, the actions is already destroyed
129    * in the main function */
130   simdata->computation_amount = 0.0;
131   simdata->comm = NULL;
132   simdata->compute = NULL;
133 #ifdef HAVE_TRACING
134   TRACE_msg_task_execute_end(task);
135 #endif
136
137   MSG_RETURN(status);
138 }
139
140
141 /** \ingroup msg_task_usage
142  * \brief Sleep for the specified number of seconds
143  *
144  * Makes the current process sleep until \a time seconds have elapsed.
145  *
146  * \param nb_sec a number of second
147  */
148 msg_error_t MSG_process_sleep(double nb_sec)
149 {
150   xbt_ex_t e;
151   msg_error_t status = MSG_OK;
152   /*msg_process_t proc = MSG_process_self();*/
153
154 #ifdef HAVE_TRACING
155   TRACE_msg_process_sleep_in(MSG_process_self());
156 #endif
157
158   /* create action to sleep */
159
160   /*proc->simdata->waiting_action = act_sleep;
161
162   FIXME: check if not setting the waiting_action breaks something on msg
163
164   proc->simdata->waiting_action = NULL;*/
165
166   TRY {
167     simcall_process_sleep(nb_sec);
168   }
169   CATCH(e) {
170     switch (e.category) {
171     case cancel_error:
172       XBT_DEBUG("According to the JAVA API, a sleep call should only deal with HostFailureException, WTF here ?"); 
173       // adsein: MSG_TASK_CANCELED is assigned when someone kills the process that made the sleep, this is not
174       // correct. For instance, when the node is turned off, the error should be MSG_HOST_FAILURE, which is by the way
175       // and according to the JAVA document, the only exception that can be triggered by MSG_Process_sleep call.
176       // To avoid possible impacts in the code, I just raised a host_failure exception for the moment in the JAVA code
177       // and did not change anythings at the C level.
178       // 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) 
179       status = MSG_TASK_CANCELED;
180       break;
181     default:
182       RETHROW;
183     }
184     xbt_ex_free(e);
185   }
186
187   #ifdef HAVE_TRACING
188     TRACE_msg_process_sleep_out(MSG_process_self());
189   #endif
190   MSG_RETURN(status);
191 }
192
193 /** \ingroup msg_task_usage
194  * \brief Deprecated function that used to receive a task from a mailbox from a specific host.
195  *
196  * Sorry, this function is not supported anymore. That wouldn't be
197  * impossible to reimplement it, but we are lacking the time to do so ourselves.
198  * If you need this functionality, you can either:
199  *
200  *  - implement the buffering mechanism on the user-level by queuing all messages
201  *    received in the mailbox that do not match your expectation
202  *  - change your application logic to leverage the mailboxes features. For example,
203  *    if you have A receiving messages from B and C, you could have A waiting on
204  *    mailbox "A" most of the time, but on "A#B" when it's waiting for specific
205  *    messages from B and "A#C" when waiting for messages from C. You could even get A
206  *    sometime waiting on all these mailboxes using @ref MSG_comm_waitany. You can find
207  *    an example of use of this function in the @ref MSG_examples section.
208  *  - Provide a proper patch to implement this functionality back in MSG. That wouldn't be
209  *    very difficult actually. Check the function @ref MSG_mailbox_get_task_ext. During its call to
210  *    simcall_comm_recv(), the 5th argument, match_fun, is NULL. Create a function that filters
211  *    messages according to the host (that you will pass as sixth argument to simcall_comm_recv()
212  *    and that your filtering function will receive as first parameter, and then, the filter could
213  *    simply compare the host names, for example. After sufficient testing, provide an example that
214  *    we could add to the distribution, and your first contribution to SimGrid is ready. Thanks in advance.
215  *
216  * \param task a memory location for storing a #msg_task_t.
217  * \param alias name of the mailbox to receive the task from
218  * \param host a #msg_host_t host from where the task was sent
219  *
220  * \return Returns
221  * #MSG_OK if the task was successfully received,
222  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
223  */
224 msg_error_t
225 MSG_task_receive_from_host(msg_task_t * task, const char *alias,
226                            msg_host_t host)
227 {
228   return MSG_task_receive_ext(task, alias, -1, host);
229 }
230
231 /** msg_task_usage
232  *\brief Deprecated function that used to receive a task from a mailbox from a specific host
233  *\brief at a given rate
234  *
235  * \param task a memory location for storing a #msg_task_t.
236  * \param alias name of the mailbox to receive the task from
237  * \param host a #msg_host_t host from where the task was sent
238  * \param rate limit the reception to rate bandwidth
239  *
240  * \return Returns
241  * #MSG_OK if the task was successfully received,
242  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
243  */
244 msg_error_t
245 MSG_task_receive_from_host_bounded(msg_task_t * task, const char *alias,
246                                    msg_host_t host, double rate)
247 {
248   return MSG_task_receive_ext_bounded(task, alias, -1, host, rate);
249 }
250
251 /** \ingroup msg_task_usage
252  * \brief Receives a task from a mailbox.
253  *
254  * This is a blocking function, the execution flow will be blocked
255  * until the task is received. See #MSG_task_irecv
256  * for receiving tasks asynchronously.
257  *
258  * \param task a memory location for storing a #msg_task_t.
259  * \param alias name of the mailbox to receive the task from
260  *
261  * \return Returns
262  * #MSG_OK if the task was successfully received,
263  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
264  */
265 msg_error_t MSG_task_receive(msg_task_t * task, const char *alias)
266 {
267   return MSG_task_receive_with_timeout(task, alias, -1);
268 }
269
270 /** \ingroup msg_task_usage
271  * \brief Receives a task from a mailbox at a given rate.
272  *
273  * \param task a memory location for storing a #msg_task_t.
274  * \param alias name of the mailbox to receive the task from
275  *  \param rate limit the reception to rate bandwidth
276  *
277  * \return Returns
278  * #MSG_OK if the task was successfully received,
279  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
280  */
281 msg_error_t MSG_task_receive_bounded(msg_task_t * task, const char *alias,
282                                      double rate)
283 {
284   return MSG_task_receive_with_timeout_bounded(task, alias, -1, rate);
285 }
286
287 /** \ingroup msg_task_usage
288  * \brief Receives a task from a mailbox with a given timeout.
289  *
290  * This is a blocking function with a timeout, the execution flow will be blocked
291  * until the task is received or the timeout is achieved. See #MSG_task_irecv
292  * for receiving tasks asynchronously.  You can provide a -1 timeout
293  * to obtain an infinite timeout.
294  *
295  * \param task a memory location for storing a #msg_task_t.
296  * \param alias name of the mailbox to receive the task from
297  * \param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_receive)
298  *
299  * \return Returns
300  * #MSG_OK if the task was successfully received,
301  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
302  */
303 msg_error_t
304 MSG_task_receive_with_timeout(msg_task_t * task, const char *alias,
305                               double timeout)
306 {
307   return MSG_task_receive_ext(task, alias, timeout, NULL);
308 }
309
310 /** \ingroup msg_task_usage
311  * \brief Receives a task from a mailbox with a given timeout and at a given rate.
312  *
313  * \param task a memory location for storing a #msg_task_t.
314  * \param alias name of the mailbox to receive the task from
315  * \param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_receive)
316  *  \param rate limit the reception to rate bandwidth
317  *
318  * \return Returns
319  * #MSG_OK if the task was successfully received,
320  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
321  */
322 msg_error_t
323 MSG_task_receive_with_timeout_bounded(msg_task_t * task, const char *alias,
324                                       double timeout,double rate)
325 {
326   return MSG_task_receive_ext_bounded(task, alias, timeout, NULL, rate);
327 }
328
329 /** \ingroup msg_task_usage
330  * \brief Receives a task from a mailbox from a specific host with a given timeout.
331  *
332  * This is a blocking function with a timeout, the execution flow will be blocked
333  * until the task is received or the timeout is achieved. See #MSG_task_irecv
334  * for receiving tasks asynchronously. You can provide a -1 timeout
335  * to obtain an infinite timeout.
336  *
337  * \param task a memory location for storing a #msg_task_t.
338  * \param alias name of the mailbox to receive the task from
339  * \param timeout is the maximum wait time for completion (provide -1 for no timeout)
340  * \param host a #msg_host_t host from where the task was sent
341  *
342  * \return Returns
343  * #MSG_OK if the task was successfully received,
344 * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
345  */
346 msg_error_t
347 MSG_task_receive_ext(msg_task_t * task, const char *alias, double timeout,
348                      msg_host_t host)
349 {
350   xbt_ex_t e;
351   msg_error_t ret = MSG_OK;
352   XBT_DEBUG
353       ("MSG_task_receive_ext: Trying to receive a message on mailbox '%s'",
354        alias);
355   TRY {
356     ret = MSG_mailbox_get_task_ext(MSG_mailbox_get_by_alias(alias), task,
357                                    host, timeout);
358   }
359   CATCH(e) {
360     switch (e.category) {
361     case cancel_error:          /* may be thrown by MSG_mailbox_get_by_alias */
362       ret = MSG_HOST_FAILURE;
363       break;
364     default:
365       RETHROW;
366     }
367     xbt_ex_free(e);
368   }
369   return ret;
370 }
371
372 /** \ingroup msg_task_usage
373  * \brief Receives a task from a mailbox from a specific host with a given timeout
374  *  and at a given rate.
375  *
376  * \param task a memory location for storing a #msg_task_t.
377  * \param alias name of the mailbox to receive the task from
378  * \param timeout is the maximum wait time for completion (provide -1 for no timeout)
379  * \param host a #msg_host_t host from where the task was sent
380  * \param rate limit the reception to rate bandwidth
381  *
382  * \return Returns
383  * #MSG_OK if the task was successfully received,
384 * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
385  */
386 msg_error_t
387 MSG_task_receive_ext_bounded(msg_task_t * task, const char *alias, double timeout,
388                              msg_host_t host, double rate)
389 {
390   XBT_DEBUG
391       ("MSG_task_receive_ext: Trying to receive a message on mailbox '%s'",
392        alias);
393   return MSG_mailbox_get_task_ext_bounded(MSG_mailbox_get_by_alias(alias), task,
394                                           host, timeout, rate);
395 }
396
397 /* Internal function used to factorize code between
398  * MSG_task_isend_with_matching() and MSG_task_dsend().
399  */
400 static XBT_INLINE
401 msg_comm_t MSG_task_isend_internal(msg_task_t task, const char *alias,
402                                    int (*match_fun)(void*,void*, smx_action_t),
403                                    void *match_data, void_f_pvoid_t cleanup,
404                                    int detached)
405 {
406   simdata_task_t t_simdata = NULL;
407   msg_process_t process = MSG_process_self();
408   msg_mailbox_t mailbox = MSG_mailbox_get_by_alias(alias);
409
410 #ifdef HAVE_TRACING
411   int call_end = TRACE_msg_task_put_start(task);
412 #endif
413
414   /* Prepare the task to send */
415   t_simdata = task->simdata;
416   t_simdata->sender = process;
417   t_simdata->source = ((simdata_process_t) SIMIX_process_self_get_data(process))->m_host;
418
419   if (t_simdata->isused != 0) {
420     if (msg_global->debug_multiple_use){
421       XBT_ERROR("This task is already used in there:");
422       xbt_backtrace_display(t_simdata->isused);
423       XBT_ERROR("And you try to reuse it from here:");
424       xbt_backtrace_display_current();
425     } else {
426       xbt_assert(t_simdata->isused == 0,
427                  "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)");
428     }
429   }
430
431   if (msg_global->debug_multiple_use)
432     MSG_BT(t_simdata->isused, "Using Backtrace");
433   else
434     t_simdata->isused = (void*)1;
435   t_simdata->comm = NULL;
436   msg_global->sent_msg++;
437
438   /* Send it by calling SIMIX network layer */
439   smx_action_t act = simcall_comm_isend(SIMIX_process_self(), mailbox, t_simdata->message_size,
440                                         t_simdata->rate, task, sizeof(void *),
441                                         match_fun, cleanup, NULL, match_data,detached);
442   t_simdata->comm = act; /* FIXME: is the field t_simdata->comm still useful? */
443
444   msg_comm_t comm;
445   if (detached) {
446     comm = NULL;
447   } else {
448     comm = xbt_new0(s_msg_comm_t, 1);
449     comm->task_sent = task;
450     comm->task_received = NULL;
451     comm->status = MSG_OK;
452     comm->s_comm = act;
453   }
454
455 #ifdef HAVE_TRACING
456   if (TRACE_is_enabled()) {
457     simcall_set_category(act, task->category);
458   }
459
460   if (call_end)
461     TRACE_msg_task_put_end();
462 #endif
463
464   return comm;
465 }
466
467
468 /** \ingroup msg_task_usage
469  * \brief Sends a task on a mailbox.
470  *
471  * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test()
472  * to end the communication.
473  *
474  * \param task a #msg_task_t to send on another location.
475  * \param alias name of the mailbox to sent the task to
476  * \return the msg_comm_t communication created
477  */
478 msg_comm_t MSG_task_isend(msg_task_t task, const char *alias)
479 {
480   return MSG_task_isend_internal(task, alias, NULL, NULL, NULL, 0);
481 }
482
483 /** \ingroup msg_task_usage
484  * \brief Sends a task on a mailbox with a maximum rate
485  *
486  * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test()
487  * to end the communication. The maxrate parameter allows the application
488  * to limit the bandwidth utilization of network links when sending the task.
489  *
490  * \param task a #msg_task_t to send on another location.
491  * \param alias name of the mailbox to sent the task to
492  * \param maxrate the maximum communication rate for sending this task .
493  * \return the msg_comm_t communication created
494  */
495 msg_comm_t MSG_task_isend_bounded(msg_task_t task, const char *alias,
496                                   double maxrate)
497 {
498   task->simdata->rate = maxrate;
499   return MSG_task_isend_internal(task, alias, NULL, NULL, NULL, 0);
500 }
501
502
503 /** \ingroup msg_task_usage
504  * \brief Sends a task on a mailbox, with support for matching requests
505  *
506  * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test()
507  * to end the communication.
508  *
509  * \param task a #msg_task_t to send on another location.
510  * \param alias name of the mailbox to sent the task to
511  * \param match_fun boolean function which parameters are:
512  *        - match_data_provided_here
513  *        - match_data_provided_by_other_side_if_any
514  *        - the_smx_action_describing_the_other_side
515  * \param match_data user provided data passed to match_fun
516  * \return the msg_comm_t communication created
517  */
518 msg_comm_t MSG_task_isend_with_matching(msg_task_t task, const char *alias,
519                                         int (*match_fun)(void*, void*,
520                                                          smx_action_t),
521                                         void *match_data)
522 {
523   return MSG_task_isend_internal(task, alias, match_fun, match_data, NULL, 0);
524 }
525
526 /** \ingroup msg_task_usage
527  * \brief Sends a task on a mailbox.
528  *
529  * This is a non blocking detached send function.
530  * Think of it as a best effort send. Keep in mind that the third parameter
531  * is only called if the communication fails. If the communication does work,
532  * it is responsibility of the receiver code to free anything related to
533  * the task, as usual. More details on this can be obtained on
534  * <a href="http://lists.gforge.inria.fr/pipermail/simgrid-user/2011-November/002649.html">this thread</a>
535  * in the SimGrid-user mailing list archive.
536  *
537  * \param task a #msg_task_t to send on another location.
538  * \param alias name of the mailbox to sent the task to
539  * \param cleanup a function to destroy the task if the
540  * communication fails, e.g. MSG_task_destroy
541  * (if NULL, no function will be called)
542  */
543 void MSG_task_dsend(msg_task_t task, const char *alias, void_f_pvoid_t cleanup)
544 {
545   MSG_task_isend_internal(task, alias, NULL, NULL, cleanup, 1);
546 }
547
548 /** \ingroup msg_task_usage
549  * \brief Sends a task on a mailbox with a maximal rate.
550  *
551  * This is a non blocking detached send function.
552  * Think of it as a best effort send. Keep in mind that the third parameter
553  * is only called if the communication fails. If the communication does work,
554  * it is responsibility of the receiver code to free anything related to
555  * the task, as usual. More details on this can be obtained on
556  * <a href="http://lists.gforge.inria.fr/pipermail/simgrid-user/2011-November/002649.html">this thread</a>
557  * in the SimGrid-user mailing list archive.
558  *
559  * \param task a #msg_task_t to send on another location.
560  * \param alias name of the mailbox to sent the task to
561  * \param cleanup a function to destroy the task if the
562  * communication fails, e.g. MSG_task_destroy
563  * (if NULL, no function will be called)
564  * \param maxrate the maximum communication rate for sending this task
565  *
566  */
567 void MSG_task_dsend_bounded(msg_task_t task, const char *alias,
568                             void_f_pvoid_t cleanup, double maxrate)
569 {
570   task->simdata->rate = maxrate;
571   MSG_task_dsend(task, alias, cleanup);
572 }
573
574 /** \ingroup msg_task_usage
575  * \brief Starts listening for receiving a task from an asynchronous communication.
576  *
577  * This is a non blocking function: use MSG_comm_wait() or MSG_comm_test()
578  * to end the communication.
579  *
580  * \param task a memory location for storing a #msg_task_t. has to be valid until the end of the communication.
581  * \param name of the mailbox to receive the task on
582  * \return the msg_comm_t communication created
583  */
584 msg_comm_t MSG_task_irecv(msg_task_t *task, const char *name)
585 {
586   return MSG_task_irecv_bounded(task, name, -1.0);
587 }
588
589 /** \ingroup msg_task_usage
590  * \brief Starts listening for receiving a task from an asynchronous communication
591  * at a given rate.
592  *
593  * \param task a memory location for storing a #msg_task_t. has to be valid until the end of the communication.
594  * \param name of the mailbox to receive the task on
595  * \param rate limit the bandwidth to the given rate
596  * \return the msg_comm_t communication created
597  */
598 msg_comm_t MSG_task_irecv_bounded(msg_task_t *task, const char *name,
599                                   double rate)
600 {
601   smx_rdv_t rdv = MSG_mailbox_get_by_alias(name);
602
603   /* FIXME: these functions are not traceable */
604
605   /* Sanity check */
606   xbt_assert(task, "Null pointer for the task storage");
607
608   if (*task)
609     XBT_CRITICAL
610         ("MSG_task_irecv() was asked to write in a non empty task struct.");
611
612   /* Try to receive it by calling SIMIX network layer */
613   msg_comm_t comm = xbt_new0(s_msg_comm_t, 1);
614   comm->task_sent = NULL;
615   comm->task_received = task;
616   comm->status = MSG_OK;
617   comm->s_comm = simcall_comm_irecv(rdv, task, NULL, NULL, NULL, NULL, rate);
618
619   return comm;
620 }
621
622 /** \ingroup msg_task_usage
623  * \brief Checks whether a communication is done, and if yes, finalizes it.
624  * \param comm the communication to test
625  * \return TRUE if the communication is finished
626  * (but it may have failed, use MSG_comm_get_status() to know its status)
627  * or FALSE if the communication is not finished yet
628  * If the status is FALSE, don't forget to use MSG_process_sleep() after the test.
629  */
630 int MSG_comm_test(msg_comm_t comm)
631 {
632   xbt_ex_t e;
633   int finished = 0;
634
635   TRY {
636     finished = simcall_comm_test(comm->s_comm);
637
638     if (finished && comm->task_received != NULL) {
639       /* I am the receiver */
640       if (msg_global->debug_multiple_use && (*comm->task_received)->simdata->isused!=0)
641         xbt_ex_free(*(xbt_ex_t*)(*comm->task_received)->simdata->isused);
642       (*comm->task_received)->simdata->isused = 0;
643     }
644   }
645   CATCH(e) {
646     switch (e.category) {
647       case network_error:
648         comm->status = MSG_TRANSFER_FAILURE;
649         finished = 1;
650         break;
651
652       case timeout_error:
653         comm->status = MSG_TIMEOUT;
654         finished = 1;
655         break;
656
657       default:
658         RETHROW;
659     }
660     xbt_ex_free(e);
661   }
662
663   return finished;
664 }
665
666 /** \ingroup msg_task_usage
667  * \brief This function checks if a communication is finished.
668  * \param comms a vector of communications
669  * \return the position of the finished communication if any
670  * (but it may have failed, use MSG_comm_get_status() to know its status),
671  * or -1 if none is finished
672  */
673 int MSG_comm_testany(xbt_dynar_t comms)
674 {
675   xbt_ex_t e;
676   int finished_index = -1;
677
678   /* create the equivalent dynar with SIMIX objects */
679   xbt_dynar_t s_comms = xbt_dynar_new(sizeof(smx_action_t), NULL);
680   msg_comm_t comm;
681   unsigned int cursor;
682   xbt_dynar_foreach(comms, cursor, comm) {
683     xbt_dynar_push(s_comms, &comm->s_comm);
684   }
685
686   msg_error_t status = MSG_OK;
687   TRY {
688     finished_index = simcall_comm_testany(s_comms);
689   }
690   CATCH(e) {
691     switch (e.category) {
692       case network_error:
693         finished_index = e.value;
694         status = MSG_TRANSFER_FAILURE;
695         break;
696
697       case timeout_error:
698         finished_index = e.value;
699         status = MSG_TIMEOUT;
700         break;
701
702       default:
703         RETHROW;
704     }
705     xbt_ex_free(e);
706   }
707   xbt_dynar_free(&s_comms);
708
709   if (finished_index != -1) {
710     comm = xbt_dynar_get_as(comms, finished_index, msg_comm_t);
711     /* the communication is finished */
712     comm->status = status;
713
714     if (status == MSG_OK && comm->task_received != NULL) {
715       /* I am the receiver */
716       if (msg_global->debug_multiple_use && (*comm->task_received)->simdata->isused!=0)
717         xbt_ex_free(*(xbt_ex_t*)(*comm->task_received)->simdata->isused);
718       (*comm->task_received)->simdata->isused = 0;
719     }
720   }
721
722   return finished_index;
723 }
724
725 /** \ingroup msg_task_usage
726  * \brief Destroys a communication.
727  * \param comm the communication to destroy.
728  */
729 void MSG_comm_destroy(msg_comm_t comm)
730 {
731   xbt_free(comm);
732 }
733
734 /** \ingroup msg_task_usage
735  * \brief Wait for the completion of a communication.
736  *
737  * It takes two parameters.
738  * \param comm the communication to wait.
739  * \param timeout Wait until the communication terminates or the timeout
740  * occurs. You can provide a -1 timeout to obtain an infinite timeout.
741  * \return msg_error_t
742  */
743 msg_error_t MSG_comm_wait(msg_comm_t comm, double timeout)
744 {
745   xbt_ex_t e;
746   TRY {
747     simcall_comm_wait(comm->s_comm, timeout);
748
749     if (comm->task_received != NULL) {
750       /* I am the receiver */
751       if (msg_global->debug_multiple_use && (*comm->task_received)->simdata->isused!=0)
752         xbt_ex_free(*(xbt_ex_t*)(*comm->task_received)->simdata->isused);
753       (*comm->task_received)->simdata->isused = 0;
754     }
755
756     /* FIXME: these functions are not traceable */
757   }
758   CATCH(e) {
759     switch (e.category) {
760     case network_error:
761       comm->status = MSG_TRANSFER_FAILURE;
762       break;
763     case timeout_error:
764       comm->status = MSG_TIMEOUT;
765       break;
766     default:
767       RETHROW;
768     }
769     xbt_ex_free(e);
770   }
771
772   return comm->status;
773 }
774
775 /** \ingroup msg_task_usage
776 * \brief This function is called by a sender and permit to wait for each communication
777 *
778 * \param comm a vector of communication
779 * \param nb_elem is the size of the comm vector
780 * \param timeout for each call of MSG_comm_wait
781 */
782 void MSG_comm_waitall(msg_comm_t * comm, int nb_elem, double timeout)
783 {
784   int i = 0;
785   for (i = 0; i < nb_elem; i++) {
786     MSG_comm_wait(comm[i], timeout);
787   }
788 }
789
790 /** \ingroup msg_task_usage
791  * \brief This function waits for the first communication finished in a list.
792  * \param comms a vector of communications
793  * \return the position of the first finished communication
794  * (but it may have failed, use MSG_comm_get_status() to know its status)
795  */
796 int MSG_comm_waitany(xbt_dynar_t comms)
797 {
798   xbt_ex_t e;
799   int finished_index = -1;
800
801   /* create the equivalent dynar with SIMIX objects */
802   xbt_dynar_t s_comms = xbt_dynar_new(sizeof(smx_action_t), NULL);
803   msg_comm_t comm;
804   unsigned int cursor;
805   xbt_dynar_foreach(comms, cursor, comm) {
806     xbt_dynar_push(s_comms, &comm->s_comm);
807   }
808
809   msg_error_t status = MSG_OK;
810   TRY {
811     finished_index = simcall_comm_waitany(s_comms);
812   }
813   CATCH(e) {
814     switch (e.category) {
815       case network_error:
816         finished_index = e.value;
817         status = MSG_TRANSFER_FAILURE;
818         break;
819
820       case timeout_error:
821         finished_index = e.value;
822         status = MSG_TIMEOUT;
823         break;
824
825       default:
826         RETHROW;
827     }
828     xbt_ex_free(e);
829   }
830
831   xbt_assert(finished_index != -1, "WaitAny returned -1");
832   xbt_dynar_free(&s_comms);
833
834   comm = xbt_dynar_get_as(comms, finished_index, msg_comm_t);
835   /* the communication is finished */
836   comm->status = status;
837
838   if (comm->task_received != NULL) {
839     /* I am the receiver */
840     if (msg_global->debug_multiple_use && (*comm->task_received)->simdata->isused!=0)
841       xbt_ex_free(*(xbt_ex_t*)(*comm->task_received)->simdata->isused);
842     (*comm->task_received)->simdata->isused = 0;
843   }
844
845   return finished_index;
846 }
847
848 /**
849  * \ingroup msg_task_usage
850  * \brief Returns the error (if any) that occured during a finished communication.
851  * \param comm a finished communication
852  * \return the status of the communication, or #MSG_OK if no error occured
853  * during the communication
854  */
855 msg_error_t MSG_comm_get_status(msg_comm_t comm) {
856
857   return comm->status;
858 }
859
860 /** \ingroup msg_task_usage
861  * \brief Get a task (#msg_task_t) from a communication
862  *
863  * \param comm the communication where to get the task
864  * \return the task from the communication
865  */
866 msg_task_t MSG_comm_get_task(msg_comm_t comm)
867 {
868   xbt_assert(comm, "Invalid parameter");
869
870   return comm->task_received ? *comm->task_received : comm->task_sent;
871 }
872
873 /**
874  * \brief This function is called by SIMIX in kernel mode to copy the data of a comm.
875  * \param comm the comm
876  * \param buff the data copied
877  * \param buff_size size of the buffer
878  */
879 void MSG_comm_copy_data_from_SIMIX(smx_action_t comm, void* buff, size_t buff_size) {
880
881   // copy the task
882   SIMIX_comm_copy_pointer_callback(comm, buff, buff_size);
883
884   // notify the user callback if any
885   if (msg_global->task_copy_callback) {
886     msg_task_t task = buff;
887     msg_global->task_copy_callback(task,
888         simcall_comm_get_src_proc(comm), simcall_comm_get_dst_proc(comm));
889   }
890 }
891
892 /** \ingroup msg_task_usage
893  * \brief Sends a task to a mailbox
894  *
895  * This is a blocking function, the execution flow will be blocked
896  * until the task is sent (and received in the other side if #MSG_task_receive is used).
897  * See #MSG_task_isend for sending tasks asynchronously.
898  *
899  * \param task the task to be sent
900  * \param alias the mailbox name to where the task is sent
901  *
902  * \return Returns #MSG_OK if the task was successfully sent,
903  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
904  */
905 msg_error_t MSG_task_send(msg_task_t task, const char *alias)
906 {
907   XBT_DEBUG("MSG_task_send: Trying to send a message on mailbox '%s'", alias);
908   return MSG_task_send_with_timeout(task, alias, -1);
909 }
910
911 /** \ingroup msg_task_usage
912  * \brief Sends a task to a mailbox with a maximum rate
913  *
914  * This is a blocking function, the execution flow will be blocked
915  * until the task is sent. The maxrate parameter allows the application
916  * to limit the bandwidth utilization of network links when sending the task.
917  *
918  * \param task the task to be sent
919  * \param alias the mailbox name to where the task is sent
920  * \param maxrate the maximum communication rate for sending this task
921  *
922  * \return Returns #MSG_OK if the task was successfully sent,
923  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE otherwise.
924  */
925 msg_error_t
926 MSG_task_send_bounded(msg_task_t task, const char *alias, double maxrate)
927 {
928   task->simdata->rate = maxrate;
929   return MSG_task_send(task, alias);
930 }
931
932 /** \ingroup msg_task_usage
933  * \brief Sends a task to a mailbox with a timeout
934  *
935  * This is a blocking function, the execution flow will be blocked
936  * until the task is sent or the timeout is achieved.
937  *
938  * \param task the task to be sent
939  * \param alias the mailbox name to where the task is sent
940  * \param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_send)
941  *
942  * \return Returns #MSG_OK if the task was successfully sent,
943  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
944  */
945 msg_error_t
946 MSG_task_send_with_timeout(msg_task_t task, const char *alias,
947                            double timeout)
948 {
949   return MSG_mailbox_put_with_timeout(MSG_mailbox_get_by_alias(alias),
950                                       task, timeout);
951 }
952
953 /** \ingroup msg_task_usage
954  * \brief Sends a task to a mailbox with a timeout and with a maximum rate
955  *
956  * This is a blocking function, the execution flow will be blocked
957  * until the task is sent or the timeout is achieved.
958  *
959  * \param task the task to be sent
960  * \param alias the mailbox name to where the task is sent
961  * \param timeout is the maximum wait time for completion (if -1, this call is the same as #MSG_task_send)
962  * \param maxrate the maximum communication rate for sending this task
963  *
964  * \return Returns #MSG_OK if the task was successfully sent,
965  * #MSG_HOST_FAILURE, or #MSG_TRANSFER_FAILURE, or #MSG_TIMEOUT otherwise.
966  */
967 msg_error_t
968 MSG_task_send_with_timeout_bounded(msg_task_t task, const char *alias,
969                            double timeout, double maxrate)
970 {
971   task->simdata->rate = maxrate;
972   return MSG_mailbox_put_with_timeout(MSG_mailbox_get_by_alias(alias),
973                                       task, timeout);
974 }
975
976 /** \ingroup msg_task_usage
977  * \brief Check if there is a communication going on in a mailbox.
978  *
979  * \param alias the name of the mailbox to be considered
980  *
981  * \return Returns 1 if there is a communication, 0 otherwise
982  */
983 int MSG_task_listen(const char *alias)
984 {
985   return !MSG_mailbox_is_empty(MSG_mailbox_get_by_alias(alias));
986 }
987
988 /** \ingroup msg_task_usage
989  * \brief Check the number of communication actions of a given host pending in a mailbox.
990  *
991  * \param alias the name of the mailbox to be considered
992  * \param host the host to check for communication
993  *
994  * \return Returns the number of pending communication actions of the host in the
995  * given mailbox, 0 if there is no pending communication actions.
996  *
997  */
998 int MSG_task_listen_from_host(const char *alias, msg_host_t host)
999 {
1000   return
1001       MSG_mailbox_get_count_host_waiting_tasks(MSG_mailbox_get_by_alias
1002                                                (alias), host);
1003 }
1004
1005 /** \ingroup msg_task_usage
1006  * \brief Look if there is a communication on a mailbox and return the
1007  * PID of the sender process.
1008  *
1009  * \param alias the name of the mailbox to be considered
1010  *
1011  * \return Returns the PID of sender process,
1012  * -1 if there is no communication in the mailbox.
1013  */
1014 int MSG_task_listen_from(const char *alias)
1015 {
1016   msg_task_t task;
1017
1018   if (NULL ==
1019       (task = MSG_mailbox_get_head(MSG_mailbox_get_by_alias(alias))))
1020     return -1;
1021
1022   return MSG_process_get_PID(task->simdata->sender);
1023 }
1024
1025 /** \ingroup msg_task_usage
1026  * \brief Sets the tracing category of a task.
1027  *
1028  * This function should be called after the creation of
1029  * a MSG task, to define the category of that task. The
1030  * first parameter task must contain a task that was
1031  * created with the function #MSG_task_create. The second
1032  * parameter category must contain a category that was
1033  * previously declared with the function #TRACE_category
1034  * (or with #TRACE_category_with_color).
1035  *
1036  * See \ref tracing for details on how to trace
1037  * the (categorized) resource utilization.
1038  *
1039  * \param task the task that is going to be categorized
1040  * \param category the name of the category to be associated to the task
1041  *
1042  * \see MSG_task_get_category, TRACE_category, TRACE_category_with_color
1043  */
1044 void MSG_task_set_category (msg_task_t task, const char *category)
1045 {
1046 #ifdef HAVE_TRACING
1047   TRACE_msg_set_task_category (task, category);
1048 #endif
1049 }
1050
1051 /** \ingroup msg_task_usage
1052  *
1053  * \brief Gets the current tracing category of a task.
1054  *
1055  * \param task the task to be considered
1056  *
1057  * \see MSG_task_set_category
1058  *
1059  * \return Returns the name of the tracing category of the given task, NULL otherwise
1060  */
1061 const char *MSG_task_get_category (msg_task_t task)
1062 {
1063 #ifdef HAVE_TRACING
1064   return task->category;
1065 #else
1066   return NULL;
1067 #endif
1068 }
1069
1070 /**
1071  * \brief Returns the value of a given AS or router property
1072  *
1073  * \param asr the name of a router or AS
1074  * \param name a property name
1075  * \return value of a property (or NULL if property not set)
1076  */
1077 const char *MSG_as_router_get_property_value(const char* asr, const char *name)
1078 {
1079   return xbt_dict_get_or_null(MSG_as_router_get_properties(asr), name);
1080 }
1081
1082 /**
1083  * \brief Returns a xbt_dict_t consisting of the list of properties assigned to
1084  * a the AS or router
1085  *
1086  * \param asr the name of a router or AS
1087  * \return a dict containing the properties
1088  */
1089 xbt_dict_t MSG_as_router_get_properties(const char* asr)
1090 {
1091   return (simcall_asr_get_properties(asr));
1092 }
1093
1094 /**
1095  * \brief Change the value of a given AS or router
1096  *
1097  * \param asr the name of a router or AS
1098  * \param name a property name
1099  * \param value what to change the property to
1100  * \param free_ctn the freeing function to use to kill the value on need
1101  */
1102 void MSG_as_router_set_property_value(const char* asr, const char *name, char *value,void_f_pvoid_t free_ctn) {
1103   xbt_dict_set(MSG_as_router_get_properties(asr), name, value,free_ctn);
1104 }
1105
1106 #ifdef MSG_USE_DEPRECATED
1107 /** \ingroup msg_deprecated_functions
1108  *
1109  * \brief Return the last value returned by a MSG function (except
1110  * MSG_get_errno...).
1111  */
1112 msg_error_t MSG_get_errno(void)
1113 {
1114   return PROCESS_GET_ERRNO();
1115 }
1116
1117 /** \ingroup msg_deprecated_functions
1118  * \brief Put a task on a channel of an host and waits for the end of the
1119  * transmission.
1120  *
1121  * This function is used for describing the behavior of a process. It
1122  * takes three parameter.
1123  * \param task a #msg_task_t to send on another location. This task
1124  will not be usable anymore when the function will return. There is
1125  no automatic task duplication and you have to save your parameters
1126  before calling this function. Tasks are unique and once it has been
1127  sent to another location, you should not access it anymore. You do
1128  not need to call MSG_task_destroy() but to avoid using, as an
1129  effect of inattention, this task anymore, you definitely should
1130  renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
1131  can be transfered iff it has been correctly created with
1132  MSG_task_create().
1133  * \param dest the destination of the message
1134  * \param channel the channel on which the process should put this
1135  task. This value has to be >=0 and < than the maximal number of
1136  channels fixed with MSG_set_channel_number().
1137  * \return #MSG_HOST_FAILURE if the host on which
1138  * this function was called was shut down,
1139  * #MSG_TRANSFER_FAILURE if the transfer could not be properly done
1140  * (network failure, dest failure) or #MSG_OK if it succeeded.
1141  */
1142 msg_error_t MSG_task_put(msg_task_t task, msg_host_t dest, m_channel_t channel)
1143 {
1144   XBT_WARN("DEPRECATED! Now use MSG_task_send");
1145   return MSG_task_put_with_timeout(task, dest, channel, -1.0);
1146 }
1147
1148 /** \ingroup msg_deprecated_functions
1149  * \brief Does exactly the same as MSG_task_put but with a bounded transmition
1150  * rate.
1151  *
1152  * \sa MSG_task_put
1153  */
1154 msg_error_t
1155 MSG_task_put_bounded(msg_task_t task, msg_host_t dest, m_channel_t channel,
1156                      double maxrate)
1157 {
1158   XBT_WARN("DEPRECATED! Now use MSG_task_send_bounded");
1159   task->simdata->rate = maxrate;
1160   return MSG_task_put(task, dest, channel);
1161 }
1162
1163 /** \ingroup msg_deprecated_functions
1164  *
1165  * \brief Put a task on a channel of an
1166  * host (with a timeout on the waiting of the destination host) and
1167  * waits for the end of the transmission.
1168  *
1169  * This function is used for describing the behavior of a process. It
1170  * takes four parameter.
1171  * \param task a #msg_task_t to send on another location. This task
1172  will not be usable anymore when the function will return. There is
1173  no automatic task duplication and you have to save your parameters
1174  before calling this function. Tasks are unique and once it has been
1175  sent to another location, you should not access it anymore. You do
1176  not need to call MSG_task_destroy() but to avoid using, as an
1177  effect of inattention, this task anymore, you definitely should
1178  renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
1179  can be transfered iff it has been correctly created with
1180  MSG_task_create().
1181  * \param dest the destination of the message
1182  * \param channel the channel on which the process should put this
1183  task. This value has to be >=0 and < than the maximal number of
1184  channels fixed with MSG_set_channel_number().
1185  * \param timeout the maximum time to wait for a task before giving
1186  up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task
1187  will not be modified
1188  * \return #MSG_HOST_FAILURE if the host on which
1189 this function was called was shut down,
1190 #MSG_TRANSFER_FAILURE if the transfer could not be properly done
1191 (network failure, dest failure, timeout...) or #MSG_OK if the communication succeeded.
1192  */
1193 msg_error_t
1194 MSG_task_put_with_timeout(msg_task_t task, msg_host_t dest,
1195                           m_channel_t channel, double timeout)
1196 {
1197   XBT_WARN("DEPRECATED! Now use MSG_task_send_with_timeout");
1198   xbt_assert((channel >= 0)
1199               && (channel < msg_global->max_channel), "Invalid channel %d",
1200               channel);
1201
1202   XBT_DEBUG("MSG_task_put_with_timout: Trying to send a task to '%s'", MSG_host_get_name(dest));
1203   return
1204       MSG_mailbox_put_with_timeout(MSG_mailbox_get_by_channel
1205                                    (dest, channel), task, timeout);
1206 }
1207
1208 /** \ingroup msg_deprecated_functions
1209  * \brief Test whether there is a pending communication on a channel, and who sent it.
1210  *
1211  * It takes one parameter.
1212  * \param channel the channel on which the process should be
1213  listening. This value has to be >=0 and < than the maximal
1214  number of channels fixed with MSG_set_channel_number().
1215  * \return -1 if there is no pending communication and the PID of the process who sent it otherwise
1216  */
1217 int MSG_task_probe_from(m_channel_t channel)
1218 {
1219   XBT_WARN("DEPRECATED! Now use MSG_task_listen_from");
1220   msg_task_t task;
1221
1222   xbt_assert((channel >= 0)
1223               && (channel < msg_global->max_channel), "Invalid channel %d",
1224               channel);
1225
1226   if (NULL ==
1227       (task =
1228        MSG_mailbox_get_head(MSG_mailbox_get_by_channel
1229                             (MSG_host_self(), channel))))
1230     return -1;
1231
1232   return MSG_process_get_PID(task->simdata->sender);
1233 }
1234
1235 /** \ingroup msg_deprecated_functions
1236  * \brief Test whether there is a pending communication on a channel.
1237  *
1238  * It takes one parameter.
1239  * \param channel the channel on which the process should be
1240  listening. This value has to be >=0 and < than the maximal
1241  number of channels fixed with MSG_set_channel_number().
1242  * \return 1 if there is a pending communication and 0 otherwise
1243  */
1244 int MSG_task_Iprobe(m_channel_t channel)
1245 {
1246   XBT_WARN("DEPRECATED!");
1247   xbt_assert((channel >= 0)
1248               && (channel < msg_global->max_channel), "Invalid channel %d",
1249               channel);
1250
1251   return
1252       !MSG_mailbox_is_empty(MSG_mailbox_get_by_channel
1253                             (MSG_host_self(), channel));
1254 }
1255
1256 /** \ingroup msg_deprecated_functions
1257
1258  * \brief Return the number of tasks waiting to be received on a \a
1259  channel and sent by \a host.
1260  *
1261  * It takes two parameters.
1262  * \param channel the channel on which the process should be
1263  listening. This value has to be >=0 and < than the maximal
1264  number of channels fixed with MSG_set_channel_number().
1265  * \param host the host that is to be watched.
1266  * \return the number of tasks waiting to be received on \a channel
1267  and sent by \a host.
1268  */
1269 int MSG_task_probe_from_host(int channel, msg_host_t host)
1270 {
1271   XBT_WARN("DEPRECATED! Now use MSG_task_listen_from_host");
1272   xbt_assert((channel >= 0)
1273               && (channel < msg_global->max_channel), "Invalid channel %d",
1274               channel);
1275
1276   return
1277       MSG_mailbox_get_count_host_waiting_tasks(MSG_mailbox_get_by_channel
1278                                                (MSG_host_self(), channel),
1279                                                host);
1280
1281 }
1282
1283 /** \ingroup msg_deprecated_functions
1284  * \brief Listen on \a channel and waits for receiving a task from \a host.
1285  *
1286  * It takes three parameters.
1287  * \param task a memory location for storing a #msg_task_t. It will
1288  hold a task when this function will return. Thus \a task should not
1289  be equal to \c NULL and \a *task should be equal to \c NULL. If one of
1290  those two condition does not hold, there will be a warning message.
1291  * \param channel the channel on which the process should be
1292  listening. This value has to be >=0 and < than the maximal
1293  number of channels fixed with MSG_set_channel_number().
1294  * \param host the host that is to be watched.
1295  * \return a #msg_error_t indicating whether the operation was successful (#MSG_OK), or why it failed otherwise.
1296  */
1297 msg_error_t
1298 MSG_task_get_from_host(msg_task_t * task, m_channel_t channel, msg_host_t host)
1299 {
1300   XBT_WARN("DEPRECATED! Now use MSG_task_receive_from_host");
1301   return MSG_task_get_ext(task, channel, -1, host);
1302 }
1303
1304 /** \ingroup msg_deprecated_functions
1305  * \brief Listen on a channel and wait for receiving a task.
1306  *
1307  * It takes two parameters.
1308  * \param task a memory location for storing a #msg_task_t. It will
1309  hold a task when this function will return. Thus \a task should not
1310  be equal to \c NULL and \a *task should be equal to \c NULL. If one of
1311  those two condition does not hold, there will be a warning message.
1312  * \param channel the channel on which the process should be
1313  listening. This value has to be >=0 and < than the maximal
1314  number of channels fixed with MSG_set_channel_number().
1315  * \return a #msg_error_t indicating whether the operation was successful (#MSG_OK), or why it failed otherwise.
1316  */
1317 msg_error_t MSG_task_get(msg_task_t * task, m_channel_t channel)
1318 {
1319   XBT_WARN("DEPRECATED! Now use MSG_task_receive");
1320   return MSG_task_get_with_timeout(task, channel, -1);
1321 }
1322
1323 /** \ingroup msg_deprecated_functions
1324  * \brief Listen on a channel and wait for receiving a task with a timeout.
1325  *
1326  * It takes three parameters.
1327  * \param task a memory location for storing a #msg_task_t. It will
1328  hold a task when this function will return. Thus \a task should not
1329  be equal to \c NULL and \a *task should be equal to \c NULL. If one of
1330  those two condition does not hold, there will be a warning message.
1331  * \param channel the channel on which the process should be
1332  listening. This value has to be >=0 and < than the maximal
1333  number of channels fixed with MSG_set_channel_number().
1334  * \param max_duration the maximum time to wait for a task before giving
1335  up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task
1336  will not be modified and will still be
1337  equal to \c NULL when returning.
1338  * \return a #msg_error_t indicating whether the operation was successful (#MSG_OK), or why it failed otherwise.
1339  */
1340 msg_error_t
1341 MSG_task_get_with_timeout(msg_task_t * task, m_channel_t channel,
1342                           double max_duration)
1343 {
1344   XBT_WARN("DEPRECATED! Now use MSG_task_receive_with_timeout");
1345   return MSG_task_get_ext(task, channel, max_duration, NULL);
1346 }
1347
1348 msg_error_t
1349 MSG_task_get_ext(msg_task_t * task, m_channel_t channel, double timeout,
1350                  msg_host_t host)
1351 {
1352   XBT_WARN("DEPRECATED! Now use MSG_task_receive_ext");
1353   xbt_assert((channel >= 0)
1354               && (channel < msg_global->max_channel), "Invalid channel %d",
1355               channel);
1356
1357   return
1358       MSG_mailbox_get_task_ext(MSG_mailbox_get_by_channel
1359                                (MSG_host_self(), channel), task, host,
1360                                timeout);
1361 }
1362
1363 #endif