Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Functions implemented, task_execute tested with a small example.
[simgrid.git] / src / msg_simix / msg_simix_gos.c
1 #include "msg_simix_private.h"
2 #include "xbt/sysdep.h"
3 #include "xbt/log.h"
4
5 /** \defgroup msg_gos_functions MSG Operating System Functions
6  *  \brief This section describes the functions that can be used
7  *  by an agent for handling some task.
8  */
9
10 static MSG_error_t __MSG_task_get_with_time_out_from_host(m_task_t * task,
11                                                         m_channel_t channel,
12                                                         double max_duration,
13                                                         m_host_t host)
14 {
15
16         xbt_die("not implemented yet");
17         MSG_RETURN(MSG_OK);
18 }
19
20 /** \ingroup msg_gos_functions
21  * \brief Listen on a channel and wait for receiving a task.
22  *
23  * It takes two parameters.
24  * \param task a memory location for storing a #m_task_t. It will
25    hold a task when this function will return. Thus \a task should not
26    be equal to \c NULL and \a *task should be equal to \c NULL. If one of
27    those two condition does not hold, there will be a warning message.
28  * \param channel the channel on which the agent should be
29    listening. This value has to be >=0 and < than the maximal
30    number of channels fixed with MSG_set_channel_number().
31  * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
32  * if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
33  */
34 MSG_error_t MSG_task_get(m_task_t * task,
35                          m_channel_t channel)
36 {
37   return MSG_task_get_with_time_out(task, channel, -1);
38 }
39
40 /** \ingroup msg_gos_functions
41  * \brief Listen on a channel and wait for receiving a task with a timeout.
42  *
43  * It takes three parameters.
44  * \param task a memory location for storing a #m_task_t. It will
45    hold a task when this function will return. Thus \a task should not
46    be equal to \c NULL and \a *task should be equal to \c NULL. If one of
47    those two condition does not hold, there will be a warning message.
48  * \param channel the channel on which the agent should be
49    listening. This value has to be >=0 and < than the maximal
50    number of channels fixed with MSG_set_channel_number().
51  * \param max_duration the maximum time to wait for a task before giving
52     up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task 
53     will not be modified and will still be
54     equal to \c NULL when returning. 
55  * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
56    if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
57  */
58 MSG_error_t MSG_task_get_with_time_out(m_task_t * task,
59                                        m_channel_t channel,
60                                        double max_duration)
61 {
62   return __MSG_task_get_with_time_out_from_host(task, channel, max_duration, NULL);
63 }
64
65 /** \ingroup msg_gos_functions
66  * \brief Listen on \a channel and waits for receiving a task from \a host.
67  *
68  * It takes three parameters.
69  * \param task a memory location for storing a #m_task_t. It will
70    hold a task when this function will return. Thus \a task should not
71    be equal to \c NULL and \a *task should be equal to \c NULL. If one of
72    those two condition does not hold, there will be a warning message.
73  * \param channel the channel on which the agent should be
74    listening. This value has to be >=0 and < than the maximal
75    number of channels fixed with MSG_set_channel_number().
76  * \param host the host that is to be watched.
77  * \return #MSG_FATAL if \a task is equal to \c NULL, #MSG_WARNING
78    if \a *task is not equal to \c NULL, and #MSG_OK otherwise.
79  */
80 MSG_error_t MSG_task_get_from_host(m_task_t * task, int channel, 
81                                    m_host_t host)
82 {
83   return __MSG_task_get_with_time_out_from_host(task, channel, -1, host);
84 }
85
86 /** \ingroup msg_gos_functions
87  * \brief Test whether there is a pending communication on a channel.
88  *
89  * It takes one parameter.
90  * \param channel the channel on which the agent should be
91    listening. This value has to be >=0 and < than the maximal
92    number of channels fixed with MSG_set_channel_number().
93  * \return 1 if there is a pending communication and 0 otherwise
94  */
95 int MSG_task_Iprobe(m_channel_t channel)
96 {
97         xbt_die("not implemented yet");
98         return 0;
99 }
100
101 /** \ingroup msg_gos_functions
102  * \brief Test whether there is a pending communication on a channel, and who sent it.
103  *
104  * It takes one parameter.
105  * \param channel the channel on which the agent should be
106    listening. This value has to be >=0 and < than the maximal
107    number of channels fixed with MSG_set_channel_number().
108  * \return -1 if there is no pending communication and the PID of the process who sent it otherwise
109  */
110 int MSG_task_probe_from(m_channel_t channel)
111 {
112         xbt_die("not implemented yet");
113         return 0;
114 }
115
116 /** \ingroup msg_gos_functions
117  * \brief Wait for at most \a max_duration second for a task reception
118    on \a channel. *\a PID is updated with the PID of the first process
119    that triggered this event if any.
120  *
121  * It takes three parameters:
122  * \param channel the channel on which the agent should be
123    listening. This value has to be >=0 and < than the maximal.
124    number of channels fixed with MSG_set_channel_number().
125  * \param PID a memory location for storing an int.
126  * \param max_duration the maximum time to wait for a task before
127     giving up. In the case of a reception, *\a PID will be updated
128     with the PID of the first process to send a task.
129  * \return #MSG_HOST_FAILURE if the host is shut down in the meantime
130    and #MSG_OK otherwise.
131  */
132 MSG_error_t MSG_channel_select_from(m_channel_t channel, double max_duration,
133                                     int *PID)
134 {
135         xbt_die("not implemented yet");
136         MSG_RETURN(MSG_OK);
137 }
138
139
140 /** \ingroup msg_gos_functions
141
142  * \brief Return the number of tasks waiting to be received on a \a
143    channel and sent by \a host.
144  *
145  * It takes two parameters.
146  * \param channel the channel on which the agent should be
147    listening. This value has to be >=0 and < than the maximal
148    number of channels fixed with MSG_set_channel_number().
149  * \param host the host that is to be watched.
150  * \return the number of tasks waiting to be received on \a channel
151    and sent by \a host.
152  */
153 int MSG_task_probe_from_host(int channel, m_host_t host)
154 {
155         xbt_die("not implemented yet");
156         return 0;
157 }
158
159 /** \ingroup msg_gos_functions \brief Put a task on a channel of an
160  * host (with a timeout on the waiting of the destination host) and
161  * waits for the end of the transmission.
162  *
163  * This function is used for describing the behavior of an agent. It
164  * takes four parameter.
165  * \param task a #m_task_t to send on another location. This task
166    will not be usable anymore when the function will return. There is
167    no automatic task duplication and you have to save your parameters
168    before calling this function. Tasks are unique and once it has been
169    sent to another location, you should not access it anymore. You do
170    not need to call MSG_task_destroy() but to avoid using, as an
171    effect of inattention, this task anymore, you definitely should
172    renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
173    can be transfered iff it has been correctly created with
174    MSG_task_create().
175  * \param dest the destination of the message
176  * \param channel the channel on which the agent should put this
177    task. This value has to be >=0 and < than the maximal number of
178    channels fixed with MSG_set_channel_number().
179  * \param max_duration the maximum time to wait for a task before giving
180     up. In such a case, #MSG_TRANSFER_FAILURE will be returned, \a task 
181     will not be modified 
182  * \return #MSG_FATAL if \a task is not properly initialized and
183    #MSG_OK otherwise. Returns #MSG_HOST_FAILURE if the host on which
184    this function was called was shut down. Returns
185    #MSG_TRANSFER_FAILURE if the transfer could not be properly done
186    (network failure, dest failure, timeout...)
187  */
188 MSG_error_t MSG_task_put_with_timeout(m_task_t task, m_host_t dest, 
189                                       m_channel_t channel, double max_duration)
190 {
191         xbt_die("not implemented yet");
192         MSG_RETURN(MSG_OK);
193 }
194 /** \ingroup msg_gos_functions
195  * \brief Put a task on a channel of an host and waits for the end of the
196  * transmission.
197  *
198  * This function is used for describing the behavior of an agent. It
199  * takes three parameter.
200  * \param task a #m_task_t to send on another location. This task
201    will not be usable anymore when the function will return. There is
202    no automatic task duplication and you have to save your parameters
203    before calling this function. Tasks are unique and once it has been
204    sent to another location, you should not access it anymore. You do
205    not need to call MSG_task_destroy() but to avoid using, as an
206    effect of inattention, this task anymore, you definitely should
207    renitialize it with #MSG_TASK_UNINITIALIZED. Note that this task
208    can be transfered iff it has been correctly created with
209    MSG_task_create().
210  * \param dest the destination of the message
211  * \param channel the channel on which the agent should put this
212    task. This value has to be >=0 and < than the maximal number of
213    channels fixed with MSG_set_channel_number().
214  * \return #MSG_FATAL if \a task is not properly initialized and
215  * #MSG_OK otherwise. Returns #MSG_HOST_FAILURE if the host on which
216  * this function was called was shut down. Returns
217  * #MSG_TRANSFER_FAILURE if the transfer could not be properly done
218  * (network failure, dest failure)
219  */
220 MSG_error_t MSG_task_put(m_task_t task,
221                          m_host_t dest, m_channel_t channel)
222 {
223   return MSG_task_put_with_timeout(task, dest, channel, -1.0);
224 }
225
226 /** \ingroup msg_gos_functions
227  * \brief Does exactly the same as MSG_task_put but with a bounded transmition 
228  * rate.
229  *
230  * \sa MSG_task_put
231  */
232 MSG_error_t MSG_task_put_bounded(m_task_t task,
233                                  m_host_t dest, m_channel_t channel,
234                                  double max_rate)
235 {
236   MSG_error_t res = MSG_OK;
237   task->simdata->rate=max_rate;
238   res = MSG_task_put(task, dest, channel);
239   return(res);
240 }
241
242 /** \ingroup msg_gos_functions
243  * \brief Executes a task and waits for its termination.
244  *
245  * This function is used for describing the behavior of an agent. It
246  * takes only one parameter.
247  * \param task a #m_task_t to execute on the location on which the
248    agent is running.
249  * \return #MSG_FATAL if \a task is not properly initialized and
250  * #MSG_OK otherwise.
251  */
252 MSG_error_t MSG_task_execute(m_task_t task)
253 {
254         simdata_task_t simdata = NULL;
255
256   CHECK_HOST();
257
258   simdata = task->simdata;
259   xbt_assert0((!simdata->compute)&&(task->simdata->using==1),
260               "This taks is executed somewhere else. Go fix your code!");
261   simdata->using++;
262         SIMIX_mutex_lock(simdata->mutex);
263   simdata->compute = SIMIX_action_execute(SIMIX_host_self(), task->name, simdata->computation_amount);
264         SIMIX_action_set_priority(simdata->compute, simdata->priority);
265
266         SIMIX_register_action_to_condition(simdata->compute, simdata->cond);
267         SIMIX_register_condition_to_action(simdata->compute, simdata->cond);
268         
269         SIMIX_cond_wait(simdata->cond, simdata->mutex);
270
271         SIMIX_mutex_unlock(simdata->mutex);
272   simdata->using--;
273
274 //      MSG_RETURN(MSG_OK);
275         return MSG_OK;
276 }
277
278 void __MSG_task_execute(m_process_t process, m_task_t task)
279 {
280
281 }
282
283 MSG_error_t __MSG_wait_for_computation(m_process_t process, m_task_t task)
284 {
285         MSG_RETURN(MSG_OK);
286 }
287 /** \ingroup m_task_management
288  * \brief Creates a new #m_task_t (a parallel one....).
289  *
290  * A constructor for #m_task_t taking six arguments and returning the 
291    corresponding object.
292  * \param name a name for the object. It is for user-level information
293    and can be NULL.
294  * \param host_nb the number of hosts implied in the parallel task.
295  * \param host_list an array of \p host_nb m_host_t.
296  * \param computation_amount an array of \p host_nb
297    doubles. computation_amount[i] is the total number of operations
298    that have to be performed on host_list[i].
299  * \param communication_amount an array of \p host_nb* \p host_nb doubles.
300  * \param data a pointer to any data may want to attach to the new
301    object.  It is for user-level information and can be NULL. It can
302    be retrieved with the function \ref MSG_task_get_data.
303  * \see m_task_t
304  * \return The new corresponding object.
305  */
306 m_task_t MSG_parallel_task_create(const char *name, 
307                                   int host_nb,
308                                   const m_host_t *host_list,
309                                   double *computation_amount,
310                                   double *communication_amount,
311                                   void *data)
312 {
313   m_task_t task = xbt_new0(s_m_task_t,1);
314         xbt_die("not implemented yet");
315   return task;
316 }
317
318
319 static void __MSG_parallel_task_execute(m_process_t process, m_task_t task)
320 {
321         return;
322 }
323
324 MSG_error_t MSG_parallel_task_execute(m_task_t task)
325 {
326
327         xbt_die("not implemented yet");
328   return MSG_OK;  
329 }
330
331
332 /** \ingroup msg_gos_functions
333  * \brief Sleep for the specified number of seconds
334  *
335  * Makes the current process sleep until \a time seconds have elapsed.
336  *
337  * \param nb_sec a number of second
338  */
339 MSG_error_t MSG_process_sleep(double nb_sec)
340 {
341         smx_action_t act_sleep;
342         m_process_t proc = MSG_process_self();
343         smx_mutex_t mutex;
344         smx_cond_t cond;
345         /* create action to sleep */
346         act_sleep = SIMIX_action_sleep(SIMIX_process_get_host(proc->simdata->smx_process),nb_sec);
347         
348         mutex = SIMIX_mutex_init();
349         SIMIX_mutex_lock(mutex);
350         /* create conditional and register action to it */
351         cond = SIMIX_cond_init();
352
353         SIMIX_register_condition_to_action(act_sleep, cond);
354         SIMIX_register_action_to_condition(act_sleep, cond);
355         SIMIX_cond_wait(cond,mutex);
356         SIMIX_mutex_unlock(mutex);
357
358         /* remove variables */
359         SIMIX_action_destroy(act_sleep);
360         SIMIX_cond_destroy(cond);
361         SIMIX_mutex_destroy(mutex);
362
363         MSG_RETURN(MSG_OK);
364 }
365
366 /** \ingroup msg_gos_functions
367  * \brief Return the number of MSG tasks currently running on
368  * the host of the current running process.
369  */
370 static int MSG_get_msgload(void) 
371 {
372         xbt_die("not implemented yet");
373         return 0;
374 }
375
376 /** \ingroup msg_gos_functions
377  *
378  * \brief Return the last value returned by a MSG function (except
379  * MSG_get_errno...).
380  */
381 MSG_error_t MSG_get_errno(void)
382 {
383   return PROCESS_GET_ERRNO();
384 }