3 /* Copyright (c) 2002,2003,2004 Arnaud Legrand. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
9 #include "xbt/sysdep.h"
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_gos, msg,
12 "Logging specific to MSG (gos)");
14 /** \defgroup msg_gos_functions MSG Operating System Functions
15 * \brief This section describes the functions that can be used
16 * by an agent for handling some task.
19 static MSG_error_t __MSG_task_get_with_time_out_from_host(m_task_t * task,
24 m_process_t process = MSG_process_self();
27 m_task_t task_to_wait_for;
28 simdata_task_t t_simdata = NULL;
29 simdata_host_t h_simdata = NULL;
31 e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM;
32 xbt_fifo_item_t item = NULL;
35 xbt_assert1((channel>=0) && (channel < msg_global->max_channel),"Invalid channel %d",channel);
37 xbt_assert0(task,"Null pointer for the task\n");
40 CRITICAL0("MSG_task_get() was asked to write in a non empty task struct.");
44 h_simdata = h->simdata;
46 DEBUG2("Waiting for a task on channel %d (%s)", channel,h->name);
49 if(xbt_fifo_size(h_simdata->mbox[channel])>0) {
51 t = xbt_fifo_shift(h_simdata->mbox[channel]);
54 xbt_fifo_foreach(h->simdata->mbox[channel],item,t,m_task_t) {
55 if(t->simdata->source==host) break;
58 xbt_fifo_remove_item(h->simdata->mbox[channel],item);
66 PAJE_PROCESS_POP_STATE(process);
67 MSG_RETURN(MSG_TRANSFER_FAILURE);
70 xbt_assert3(!(h_simdata->sleeping[channel]),
71 "A process (%s(%d)) is already blocked on channel %d",
72 h_simdata->sleeping[channel]->name,
73 h_simdata->sleeping[channel]->simdata->PID,
75 h_simdata->sleeping[channel] = process; /* I'm waiting. Wake me up when you're ready */
77 __MSG_process_block(max_duration,"");
79 __MSG_process_block(-1,"");
81 h_simdata->sleeping[channel] = NULL;
83 if(surf_workstation_resource->extension_public->get_state(h_simdata->host)
85 MSG_RETURN(MSG_HOST_FAILURE);
86 /* OK, we should both be ready now. Are you there ? */
89 DEBUG1("OK, got a task (%s)", t->name);
91 t_simdata = t->simdata;
92 /* *task = __MSG_task_copy(t); */
98 while(MSG_process_is_suspended(t_simdata->sender)) {
99 DEBUG1("Oooups, the sender (%s) has been suspended in the meantime. Let's wait for him",
100 t_simdata->sender->name);
101 task_to_wait_for = t_simdata->sender->simdata->waiting_task;
102 if(__MSG_process_isBlocked(t_simdata->sender)) {
103 DEBUG0("He's blocked. Let's wait for him to go in the suspended state");
104 __MSG_process_unblock(t_simdata->sender);
105 task_to_wait_for->simdata->using++;
106 __MSG_task_wait_event(process, task_to_wait_for);
107 MSG_task_destroy(task_to_wait_for);
109 DEBUG0("He's suspended. Let's wait for him to go in the resumed state");
110 task_to_wait_for->simdata->using++;
111 __MSG_task_wait_event(process, task_to_wait_for);
112 MSG_task_destroy(task_to_wait_for);
113 DEBUG0("He's resumed. He should block again. So let's free him.");
114 __MSG_process_unblock(t_simdata->sender);
118 DEBUG0("Calling SURF for communication creation");
119 t_simdata->comm = surf_workstation_resource->extension_public->
120 communicate(MSG_process_get_host(t_simdata->sender)->simdata->host,
121 h->simdata->host, t_simdata->message_size,t_simdata->rate);
123 surf_workstation_resource->common_public->action_set_data(t_simdata->comm,t);
125 if(__MSG_process_isBlocked(t_simdata->sender)) {
126 DEBUG1("Unblocking %s",t_simdata->sender->name);
127 __MSG_process_unblock(t_simdata->sender);
130 PAJE_PROCESS_PUSH_STATE(process,"C",t);
133 DEBUG0("Waiting for action termination");
134 __MSG_task_wait_event(process, t);
135 state=surf_workstation_resource->common_public->action_get_state(t_simdata->comm);
136 } while (state==SURF_ACTION_RUNNING);
137 DEBUG0("Action terminated");
139 if(t->simdata->using>1) {
140 xbt_fifo_unshift(msg_global->process_to_run,process);
144 PAJE_PROCESS_POP_STATE(process);
145 PAJE_COMM_STOP(process,t,channel);
147 if(state == SURF_ACTION_DONE) {
148 if(surf_workstation_resource->common_public->action_free(t_simdata->comm))
149 t_simdata->comm = NULL;
151 } else if(surf_workstation_resource->extension_public->get_state(h_simdata->host)
153 if(surf_workstation_resource->common_public->action_free(t_simdata->comm))
154 t_simdata->comm = NULL;
155 MSG_RETURN(MSG_HOST_FAILURE);
157 if(surf_workstation_resource->common_public->action_free(t_simdata->comm))
158 t_simdata->comm = NULL;
159 MSG_RETURN(MSG_TRANSFER_FAILURE);
163 /** \ingroup msg_gos_functions
164 * \brief Listen on a channel and wait for receiving a task.
166 * It takes two parameters.
167 * \param task a memory location for storing a #m_task_t. It will
168 hold a task when this function will return. Thus \a task should not
169 be equal to \c NULL and \a *task should be equal to \c NULL. If one of
170 those two condition does not hold, there will be a warning message.
171 * \param channel the channel on which the agent should be
172 listening. This value has to be >=0 and < than the maximal
173 number of channels fixed with MSG_set_channel_number().
174 * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
175 * if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
177 MSG_error_t MSG_task_get(m_task_t * task,
180 return MSG_task_get_with_time_out(task, channel, -1);
183 /** \ingroup msg_gos_functions
184 * \brief Listen on a channel and wait for receiving a task with a timeout.
186 * It takes three parameters.
187 * \param task a memory location for storing a #m_task_t. It will
188 hold a task when this function will return. Thus \a task should not
189 be equal to \c NULL and \a *task should be equal to \c NULL. If one of
190 those two condition does not hold, there will be a warning message.
191 * \param channel the channel on which the agent should be
192 listening. This value has to be >=0 and < than the maximal
193 number of channels fixed with MSG_set_channel_number().
194 * \param max_duration the maximum time to wait for a task before giving
195 up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task
196 will not be modified and will still be
197 equal to \c NULL when returning.
198 * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
199 if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
201 MSG_error_t MSG_task_get_with_time_out(m_task_t * task,
205 return __MSG_task_get_with_time_out_from_host(task, channel, max_duration, NULL);
208 /** \ingroup msg_gos_functions
209 * \brief Listen on \a channel and waits for receiving a task from \a host.
211 * It takes three parameters.
212 * \param task a memory location for storing a #m_task_t. It will
213 hold a task when this function will return. Thus \a task should not
214 be equal to \c NULL and \a *task should be equal to \c NULL. If one of
215 those two condition does not hold, there will be a warning message.
216 * \param channel the channel on which the agent should be
217 listening. This value has to be >=0 and < than the maximal
218 number of channels fixed with MSG_set_channel_number().
219 * \param host the host that is to be watched.
220 * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
221 if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
223 MSG_error_t MSG_task_get_from_host(m_task_t * task, int channel,
226 return __MSG_task_get_with_time_out_from_host(task, channel, -1, host);
229 /** \ingroup msg_gos_functions
230 * \brief Test whether there is a pending communication on a channel.
232 * It takes one parameter.
233 * \param channel the channel on which the agent should be
234 listening. This value has to be >=0 and < than the maximal
235 number of channels fixed with MSG_set_channel_number().
236 * \return 1 if there is a pending communication and 0 otherwise
238 int MSG_task_Iprobe(m_channel_t channel)
242 xbt_assert1((channel>=0) && (channel < msg_global->max_channel),"Invalid channel %d",channel);
243 DEBUG2("Probing on channel %d (%s)", channel,h->name);
246 return(xbt_fifo_get_first_item(h->simdata->mbox[channel])!=NULL);
249 /** \ingroup msg_gos_functions
250 * \brief Test whether there is a pending communication on a channel, and who sent it.
252 * It takes one parameter.
253 * \param channel the channel on which the agent should be
254 listening. This value has to be >=0 and < than the maximal
255 number of channels fixed with MSG_set_channel_number().
256 * \return -1 if there is no pending communication and the PID of the process who sent it otherwise
258 int MSG_task_probe_from(m_channel_t channel)
261 xbt_fifo_item_t item;
264 xbt_assert1((channel>=0) && (channel < msg_global->max_channel),"Invalid channel %d",channel);
268 DEBUG2("Probing on channel %d (%s)", channel,h->name);
270 item = xbt_fifo_get_first_item(h->simdata->mbox[channel]);
271 if (!item || !(t = xbt_fifo_get_item_content(item)))
274 return MSG_process_get_PID(t->simdata->sender);
277 /** \ingroup msg_gos_functions
278 * \brief Wait for at most \a max_duration second for a task reception
279 on \a channel. *\a PID is updated with the PID of the first process
280 that triggered this event if any.
282 * It takes three parameters:
283 * \param channel the channel on which the agent should be
284 listening. This value has to be >=0 and < than the maximal.
285 number of channels fixed with MSG_set_channel_number().
286 * \param PID a memory location for storing an int.
287 * \param max_duration the maximum time to wait for a task before
288 giving up. In the case of a reception, *\a PID will be updated
289 with the PID of the first process to send a task.
290 * \return #MSG_HOST_FAILURE if the host is shut down in the meantime
291 and #MSG_OK otherwise.
293 MSG_error_t MSG_channel_select_from(m_channel_t channel, double max_duration,
297 simdata_host_t h_simdata = NULL;
298 xbt_fifo_item_t item;
301 m_process_t process = MSG_process_self();
303 xbt_assert1((channel>=0) && (channel < msg_global->max_channel),"Invalid channel %d",channel);
308 if(max_duration==0.0) {
309 *PID = MSG_task_probe_from(channel);
314 h_simdata = h->simdata;
316 DEBUG2("Probing on channel %d (%s)", channel,h->name);
317 while(!(item = xbt_fifo_get_first_item(h->simdata->mbox[channel]))) {
323 xbt_assert2(!(h_simdata->sleeping[channel]),
324 "A process (%s(%d)) is already blocked on this channel",
325 h_simdata->sleeping[channel]->name,
326 h_simdata->sleeping[channel]->simdata->PID);
327 h_simdata->sleeping[channel] = process; /* I'm waiting. Wake me up when you're ready */
329 __MSG_process_block(max_duration,"");
331 __MSG_process_block(-1,"");
333 if(surf_workstation_resource->extension_public->get_state(h_simdata->host)
335 MSG_RETURN(MSG_HOST_FAILURE);
337 h_simdata->sleeping[channel] = NULL;
340 if (!item || !(t = xbt_fifo_get_item_content(item))) {
344 *PID = MSG_process_get_PID(t->simdata->sender);
351 /** \ingroup msg_gos_functions
353 * \brief Return the number of tasks waiting to be received on a \a
354 channel and sent by \a host.
356 * It takes two parameters.
357 * \param channel the channel on which the agent should be
358 listening. This value has to be >=0 and < than the maximal
359 number of channels fixed with MSG_set_channel_number().
360 * \param host the host that is to be watched.
361 * \return the number of tasks waiting to be received on \a channel
364 int MSG_task_probe_from_host(int channel, m_host_t host)
366 xbt_fifo_item_t item;
371 xbt_assert1((channel>=0) && (channel < msg_global->max_channel),"Invalid channel %d",channel);
375 DEBUG2("Probing on channel %d (%s)", channel,h->name);
377 xbt_fifo_foreach(h->simdata->mbox[channel],item,t,m_task_t) {
378 if(t->simdata->source==host) count++;
384 /** \ingroup msg_gos_functions \brief Put a task on a channel of an
385 * host (with a timeout on the waiting of the destination host) and
386 * waits for the end of the transmission.
388 * This function is used for describing the behavior of an agent. It
389 * takes four parameter.
390 * \param task a #m_task_t to send on another location. This task
391 will not be usable anymore when the function will return. There is
392 no automatic task duplication and you have to save your parameters
393 before calling this function. Tasks are unique and once it has been
394 sent to another location, you should not access it anymore. You do
395 not need to call MSG_task_destroy() but to avoid using, as an
396 effect of inattention, this task anymore, you definitely should
397 renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
398 can be transfered iff it has been correctly created with
400 * \param dest the destination of the message
401 * \param channel the channel on which the agent should put this
402 task. This value has to be >=0 and < than the maximal number of
403 channels fixed with MSG_set_channel_number().
404 * \param max_duration the maximum time to wait for a task before giving
405 up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task
407 * \return #MSG_FATAL if \a task is not properly initialized and
408 #MSG_OK otherwise. Returns #MSG_HOST_FAILURE if the host on which
409 this function was called was shut down. Returns
410 #MSG_TRANSFER_FAILURE if the transfer could not be properly done
411 (network failure, dest failure, timeout...)
413 MSG_error_t MSG_task_put_with_timeout(m_task_t task, m_host_t dest,
414 m_channel_t channel, double max_duration)
416 m_process_t process = MSG_process_self();
417 simdata_task_t task_simdata = NULL;
418 e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM;
419 m_host_t local_host = NULL;
420 m_host_t remote_host = NULL;
425 xbt_assert1((channel>=0) && (channel < msg_global->max_channel),"Invalid channel %d",channel);
427 task_simdata = task->simdata;
428 task_simdata->sender = process;
429 task_simdata->source = MSG_process_get_host(process);
430 xbt_assert0(task_simdata->using==1,
431 "This taks is still being used somewhere else. You cannot send it now. Go fix your code!");
432 task_simdata->comm = NULL;
434 local_host = ((simdata_process_t) process->simdata)->host;
437 DEBUG4("Trying to send a task (%g kB) from %s to %s on channel %d",
438 task->simdata->message_size/1000,local_host->name, remote_host->name, channel);
440 xbt_fifo_push(((simdata_host_t) remote_host->simdata)->
441 mbox[channel], task);
443 PAJE_COMM_START(process,task,channel);
445 if(remote_host->simdata->sleeping[channel]) {
446 DEBUG0("Somebody is listening. Let's wake him up!");
447 __MSG_process_unblock(remote_host->simdata->sleeping[channel]);
450 process->simdata->put_host = dest;
451 process->simdata->put_channel = channel;
452 while(!(task_simdata->comm)) {
455 PAJE_PROCESS_POP_STATE(process);
456 PAJE_COMM_STOP(process,task,channel);
457 MSG_RETURN(MSG_TRANSFER_FAILURE);
460 DEBUG0("Communication not initiated yet. Let's block!");
462 __MSG_process_block(max_duration,task->name);
464 __MSG_process_block(-1,task->name);
468 if(surf_workstation_resource->extension_public->
469 get_state(local_host->simdata->host) == SURF_CPU_OFF) {
470 xbt_fifo_remove(((simdata_host_t) remote_host->simdata)->mbox[channel],
472 PAJE_PROCESS_POP_STATE(process);
473 PAJE_COMM_STOP(process,task,channel);
474 MSG_task_destroy(task);
475 MSG_RETURN(MSG_HOST_FAILURE);
478 DEBUG0("Registering to this communication");
479 surf_workstation_resource->common_public->action_use(task_simdata->comm);
480 process->simdata->put_host = NULL;
481 process->simdata->put_channel = -1;
484 PAJE_PROCESS_PUSH_STATE(process,"C",task);
486 state=surf_workstation_resource->common_public->action_get_state(task_simdata->comm);
487 while (state==SURF_ACTION_RUNNING) {
488 DEBUG0("Waiting for action termination");
489 __MSG_task_wait_event(process, task);
490 state=surf_workstation_resource->common_public->action_get_state(task_simdata->comm);
492 DEBUG0("Action terminated");
493 task->simdata->rate=-1.0; /* Sets the rate back to default */
495 PAJE_PROCESS_POP_STATE(process);
497 if(state == SURF_ACTION_DONE) {
498 if(surf_workstation_resource->common_public->action_free(task_simdata->comm))
499 task_simdata->comm = NULL;
500 MSG_task_destroy(task);
502 } else if(surf_workstation_resource->extension_public->get_state(local_host->simdata->host)
504 if(surf_workstation_resource->common_public->action_free(task_simdata->comm))
505 task_simdata->comm = NULL;
506 MSG_task_destroy(task);
507 MSG_RETURN(MSG_HOST_FAILURE);
509 if(surf_workstation_resource->common_public->action_free(task_simdata->comm))
510 task_simdata->comm = NULL;
511 MSG_task_destroy(task);
512 MSG_RETURN(MSG_TRANSFER_FAILURE);
515 /** \ingroup msg_gos_functions
516 * \brief Put a task on a channel of an host and waits for the end of the
519 * This function is used for describing the behavior of an agent. It
520 * takes three parameter.
521 * \param task a #m_task_t to send on another location. This task
522 will not be usable anymore when the function will return. There is
523 no automatic task duplication and you have to save your parameters
524 before calling this function. Tasks are unique and once it has been
525 sent to another location, you should not access it anymore. You do
526 not need to call MSG_task_destroy() but to avoid using, as an
527 effect of inattention, this task anymore, you definitely should
528 renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
529 can be transfered iff it has been correctly created with
531 * \param dest the destination of the message
532 * \param channel the channel on which the agent should put this
533 task. This value has to be >=0 and < than the maximal number of
534 channels fixed with MSG_set_channel_number().
535 * \return #MSG_FATAL if \a task is not properly initialized and
536 * #MSG_OK otherwise. Returns #MSG_HOST_FAILURE if the host on which
537 * this function was called was shut down. Returns
538 * #MSG_TRANSFER_FAILURE if the transfer could not be properly done
539 * (network failure, dest failure)
541 MSG_error_t MSG_task_put(m_task_t task,
542 m_host_t dest, m_channel_t channel)
544 return MSG_task_put_with_timeout(task, dest, channel, -1.0);
547 /** \ingroup msg_gos_functions
548 * \brief Does exactly the same as MSG_task_put but with a bounded transmition
553 MSG_error_t MSG_task_put_bounded(m_task_t task,
554 m_host_t dest, m_channel_t channel,
557 MSG_error_t res = MSG_OK;
558 task->simdata->rate=max_rate;
559 res = MSG_task_put(task, dest, channel);
563 /** \ingroup msg_gos_functions
564 * \brief Executes a task and waits for its termination.
566 * This function is used for describing the behavior of an agent. It
567 * takes only one parameter.
568 * \param task a #m_task_t to execute on the location on which the
570 * \return #MSG_FATAL if \a task is not properly initialized and
573 MSG_error_t MSG_task_execute(m_task_t task)
575 m_process_t process = MSG_process_self();
578 DEBUG1("Computing on %s", process->simdata->host->name);
580 __MSG_task_execute(process, task);
582 PAJE_PROCESS_PUSH_STATE(process,"E",task);
583 res = __MSG_wait_for_computation(process,task);
584 PAJE_PROCESS_POP_STATE(process);
588 void __MSG_task_execute(m_process_t process, m_task_t task)
590 simdata_task_t simdata = NULL;
594 simdata = task->simdata;
595 xbt_assert0((!simdata->compute)&&(task->simdata->using==1),
596 "This taks is executed somewhere else. Go fix your code!");
598 simdata->compute = surf_workstation_resource->extension_public->
599 execute(MSG_process_get_host(process)->simdata->host,
600 simdata->computation_amount);
601 surf_workstation_resource->common_public->
602 set_priority(simdata->compute, simdata->priority);
604 surf_workstation_resource->common_public->action_set_data(simdata->compute,task);
608 MSG_error_t __MSG_wait_for_computation(m_process_t process, m_task_t task)
610 e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM;
611 simdata_task_t simdata = task->simdata;
613 XBT_IN4("(%p(%s) %p(%s))",process,process->name,task,task->name);
616 __MSG_task_wait_event(process, task);
617 state=surf_workstation_resource->common_public->action_get_state(simdata->compute);
618 } while (state==SURF_ACTION_RUNNING);
622 if(state == SURF_ACTION_DONE) {
623 if(surf_workstation_resource->common_public->action_free(simdata->compute))
624 simdata->compute = NULL;
625 simdata->computation_amount = 0.0;
628 } else if(surf_workstation_resource->extension_public->
629 get_state(MSG_process_get_host(process)->simdata->host)
631 if(surf_workstation_resource->common_public->action_free(simdata->compute))
632 simdata->compute = NULL;
634 MSG_RETURN(MSG_HOST_FAILURE);
636 if(surf_workstation_resource->common_public->action_free(simdata->compute))
637 simdata->compute = NULL;
639 MSG_RETURN(MSG_TASK_CANCELLED);
642 /** \ingroup m_task_management
643 * \brief Creates a new #m_task_t (a parallel one....).
645 * A constructor for #m_task_t taking six arguments and returning the
646 corresponding object.
647 * \param name a name for the object. It is for user-level information
649 * \param host_nb the number of hosts implied in the parallel task.
650 * \param host_list an array of \p host_nb m_host_t.
651 * \param computation_amount an array of \p host_nb
652 doubles. computation_amount[i] is the total number of operations
653 that have to be performed on host_list[i].
654 * \param communication_amount an array of \p host_nb* \p host_nb doubles.
655 * \param data a pointer to any data may want to attach to the new
656 object. It is for user-level information and can be NULL. It can
657 be retrieved with the function \ref MSG_task_get_data.
659 * \return The new corresponding object.
661 m_task_t MSG_parallel_task_create(const char *name,
663 const m_host_t *host_list,
664 double *computation_amount,
665 double *communication_amount,
668 simdata_task_t simdata = xbt_new0(s_simdata_task_t,1);
669 m_task_t task = xbt_new0(s_m_task_t,1);
673 task->name = xbt_strdup(name);
674 task->simdata = simdata;
678 simdata->sleeping = xbt_dynar_new(sizeof(m_process_t),NULL);
679 simdata->rate = -1.0;
681 simdata->sender = NULL;
682 simdata->source = NULL;
683 simdata->host_nb = host_nb;
685 simdata->host_list = xbt_new0(void *, host_nb);
686 simdata->comp_amount = computation_amount;
687 simdata->comm_amount = communication_amount;
689 for(i=0;i<host_nb;i++)
690 simdata->host_list[i] = host_list[i]->simdata->host;
696 static void __MSG_parallel_task_execute(m_process_t process, m_task_t task)
698 simdata_task_t simdata = NULL;
702 simdata = task->simdata;
704 xbt_assert0(simdata->host_nb,"This is not a parallel task. Go to hell.");
706 simdata->compute = surf_workstation_resource->extension_public->
707 execute_parallel_task(task->simdata->host_nb,
708 task->simdata->host_list,
709 task->simdata->comp_amount,
710 task->simdata->comm_amount,
714 surf_workstation_resource->common_public->action_set_data(simdata->compute,task);
717 MSG_error_t MSG_parallel_task_execute(m_task_t task)
719 m_process_t process = MSG_process_self();
722 DEBUG0("Computing on a tons of guys");
724 __MSG_parallel_task_execute(process, task);
726 if(task->simdata->compute)
727 res = __MSG_wait_for_computation(process,task);
735 /** \ingroup msg_gos_functions
736 * \brief Sleep for the specified number of seconds
738 * Makes the current process sleep until \a time seconds have elapsed.
740 * \param nb_sec a number of second
742 MSG_error_t MSG_process_sleep(double nb_sec)
744 e_surf_action_state_t state = SURF_ACTION_NOT_IN_THE_SYSTEM;
745 m_process_t process = MSG_process_self();
746 m_task_t dummy = NULL;
747 simdata_task_t simdata = NULL;
749 xbt_assert1(nb_sec>=0,"Invalid duration %g",nb_sec);
752 dummy = MSG_task_create("MSG_sleep", nb_sec, 0.0, NULL);
753 simdata = dummy->simdata;
755 simdata->compute = surf_workstation_resource->extension_public->
756 sleep(MSG_process_get_host(process)->simdata->host,
757 simdata->computation_amount);
758 surf_workstation_resource->common_public->action_set_data(simdata->compute,dummy);
763 __MSG_task_wait_event(process, dummy);
764 state=surf_workstation_resource->common_public->action_get_state(simdata->compute);
765 } while (state==SURF_ACTION_RUNNING);
768 if(state == SURF_ACTION_DONE) {
769 if(surf_workstation_resource->extension_public->
770 get_state(MSG_process_get_host(process)->simdata->host)
772 if(surf_workstation_resource->common_public->action_free(simdata->compute))
773 simdata->compute = NULL;
774 MSG_RETURN(MSG_HOST_FAILURE);
776 if(__MSG_process_isBlocked(process)) {
777 __MSG_process_unblock(MSG_process_self());
779 if(surf_workstation_resource->extension_public->
780 get_state(MSG_process_get_host(process)->simdata->host)
782 if(surf_workstation_resource->common_public->action_free(simdata->compute))
783 simdata->compute = NULL;
784 MSG_RETURN(MSG_HOST_FAILURE);
786 if(surf_workstation_resource->common_public->action_free(simdata->compute))
787 simdata->compute = NULL;
788 MSG_task_destroy(dummy);
790 } else MSG_RETURN(MSG_HOST_FAILURE);
793 /** \ingroup msg_gos_functions
794 * \brief Return the number of MSG tasks currently running on
795 * the host of the current running process.
797 static int MSG_get_msgload(void)
803 xbt_assert0(0, "This function is still to be specified correctly (what do you mean by 'load', exactly?). In the meantime, please don't use it");
804 process = MSG_process_self();
805 return xbt_fifo_size(process->simdata->host->simdata->process_list);
808 /** \ingroup msg_gos_functions
810 * \brief Return the last value returned by a MSG function (except
813 MSG_error_t MSG_get_errno(void)
815 return PROCESS_GET_ERRNO();