Logo AND Algorithmique Numérique Distribuée

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