Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
3ab2ecab75b098cd6fceae580899e9f1940606fe
[simgrid.git] / src / msg / global.c
1 /*     $Id$      */
2
3 /* Copyright (c) 2002-2007 Arnaud Legrand.                                  */
4 /* Copyright (c) 2007 Bruno Donassolo.                                      */
5 /* All rights reserved.                                                     */
6
7 /* This program is free software; you can redistribute it and/or modify it
8  * under the terms of the license (GNU LGPL) which comes with this package. */
9
10 #include "msg/private.h"
11 #include "xbt/sysdep.h"
12 #include "xbt/log.h"
13 #include "xbt/virtu.h"
14 #include "xbt/ex.h"             /* ex_backtrace_display */
15 #include "mailbox.h"
16
17 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_kernel, msg,
18                                 "Logging specific to MSG (kernel)");
19
20 MSG_Global_t msg_global = NULL;
21
22
23 /** \defgroup msg_simulation   MSG simulation Functions
24  *  \brief This section describes the functions you need to know to
25  *  set up a simulation. You should have a look at \ref MSG_examples 
26  *  to have an overview of their usage.
27  */
28 /** @addtogroup msg_simulation
29  *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Simulation functions" --> \endhtmlonly
30  */
31
32 /********************************* MSG **************************************/
33
34 /** \ingroup msg_simulation
35  * \brief Initialize some MSG internal data.
36  */
37 void MSG_global_init_args(int *argc, char **argv)
38 {
39   MSG_global_init(argc, argv);
40 }
41
42 /** \ingroup msg_simulation
43  * \brief Initialize some MSG internal data.
44  */
45 void MSG_global_init(int *argc, char **argv)
46 {
47   xbt_getpid = MSG_process_self_PID;
48   if (!msg_global) {
49     SIMIX_global_init(argc, argv);
50
51     msg_global = xbt_new0(s_MSG_Global_t, 1);
52
53     msg_global->host = xbt_fifo_new();
54     msg_global->process_list = xbt_fifo_new();
55     msg_global->max_channel = 0;
56     msg_global->PID = 1;
57
58         /* initialization of the mailbox module */
59         MSG_mailbox_mod_init();
60
61     SIMIX_function_register_process_create(_MSG_process_create_from_SIMIX);
62     SIMIX_function_register_process_cleanup(__MSG_process_cleanup);
63     SIMIX_function_register_process_kill(_MSG_process_kill_from_SIMIX);
64   }
65   return;
66 }
67
68 /** \ingroup msg_easier_life
69  * \brief Traces MSG events in the Paje format.
70  */
71
72 void MSG_paje_output(const char *filename)
73 {
74 }
75
76 /** \defgroup m_channel_management    Understanding channels
77  *  \brief This section briefly describes the channel notion of MSG
78  *  (#m_channel_t).
79  */
80 /** @addtogroup m_channel_management
81  *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Channels" --> \endhtmlonly
82  * 
83  *
84  *  For convenience, the simulator provides the notion of channel
85  *  that is close to the tag notion in MPI. A channel is not a
86  *  socket. It doesn't need to be opened neither closed. It rather
87  *  corresponds to the ports opened on the different machines.
88  */
89
90
91 /** \ingroup m_channel_management
92  * \brief Set the number of channel in the simulation.
93  *
94  * This function has to be called to fix the number of channel in the
95    simulation before creating any host. Indeed, each channel is
96    represented by a different mailbox on each #m_host_t. This
97    function can then be called only once. This function takes only one
98    parameter.
99  * \param number the number of channel in the simulation. It has to be >0
100  */
101 MSG_error_t MSG_set_channel_number(int number)
102 {
103   xbt_assert0((msg_global)
104               && (msg_global->max_channel == 0),
105               "Channel number already set!");
106
107   msg_global->max_channel = number;
108
109   return MSG_OK;
110 }
111
112 /** \ingroup m_channel_management
113  * \brief Return the number of channel in the simulation.
114  *
115  * This function has to be called once the number of channel is fixed. I can't 
116    figure out a reason why anyone would like to call this function but nevermind.
117  * \return the number of channel in the simulation.
118  */
119 int MSG_get_channel_number(void)
120 {
121   xbt_assert0((msg_global)
122               && (msg_global->max_channel != 0),
123               "Channel number not set yet!");
124
125   return msg_global->max_channel;
126 }
127
128 void __MSG_display_process_status(void)
129 {
130 }
131
132
133 /* FIXME: Yeah, I'll do it in a portable maner one day [Mt] */
134 #include <signal.h>
135
136 static void _XBT_CALL inthandler(int ignored)
137 {
138   INFO0("CTRL-C pressed. Displaying status and bailing out");
139   __MSG_display_process_status();
140   exit(1);
141 }
142
143 /** \ingroup msg_simulation
144  * \brief Launch the MSG simulation
145  */
146 MSG_error_t MSG_main(void)
147 {
148   smx_cond_t cond = NULL;
149   smx_action_t smx_action;
150   xbt_fifo_t actions_done = xbt_fifo_new();
151   xbt_fifo_t actions_failed = xbt_fifo_new();
152
153   /* Prepare to display some more info when dying on Ctrl-C pressing */
154   signal(SIGINT, inthandler);
155
156   /* Clean IO before the run */
157   fflush(stdout);
158   fflush(stderr);
159
160   //surf_solve(); /* Takes traces into account. Returns 0.0 */
161   /* xbt_fifo_size(msg_global->process_to_run) */
162
163   while (SIMIX_solve(actions_done, actions_failed) != -1.0) {
164
165     while ((smx_action = xbt_fifo_pop(actions_failed))) {
166
167
168       DEBUG1("** %s failed **", smx_action->name);
169       while ((cond = xbt_fifo_pop(smx_action->cond_list))) {
170         SIMIX_cond_broadcast(cond);
171       }
172       /* action finished, destroy it */
173       //      SIMIX_action_destroy(smx_action);
174     }
175
176     while ((smx_action = xbt_fifo_pop(actions_done))) {
177
178       DEBUG1("** %s done **", smx_action->name);
179       while ((cond = xbt_fifo_pop(smx_action->cond_list))) {
180         SIMIX_cond_broadcast(cond);
181       }
182       /* action finished, destroy it */
183       //SIMIX_action_destroy(smx_action);
184     }
185   }
186   xbt_fifo_free(actions_failed);
187   xbt_fifo_free(actions_done);
188   return MSG_OK;
189 }
190
191 /** \ingroup msg_simulation
192  * \brief Kill all running process
193
194  * \param reset_PIDs should we reset the PID numbers. A negative
195  *   number means no reset and a positive number will be used to set the PID
196  *   of the next newly created process.
197  */
198 int MSG_process_killall(int reset_PIDs)
199 {
200   m_process_t p = NULL;
201   m_process_t self = MSG_process_self();
202
203   while ((p = xbt_fifo_pop(msg_global->process_list))) {
204     if (p != self)
205       MSG_process_kill(p);
206   }
207
208   if (reset_PIDs > 0) {
209     msg_global->PID = reset_PIDs;
210     msg_global->session++;
211   }
212
213   return msg_global->PID;
214
215 }
216
217 /** \ingroup msg_simulation
218  * \brief Clean the MSG simulation
219  */
220 MSG_error_t MSG_clean(void)
221 {
222   xbt_fifo_item_t i = NULL;
223   m_host_t h = NULL;
224   m_process_t p = NULL;
225
226
227   while ((p = xbt_fifo_pop(msg_global->process_list))) {
228     MSG_process_kill(p);
229   }
230
231   xbt_fifo_foreach(msg_global->host, i, h, m_host_t) {
232     __MSG_host_destroy(h);
233   }
234   xbt_fifo_free(msg_global->host);
235   xbt_fifo_free(msg_global->process_list);
236
237   free(msg_global);
238   msg_global = NULL;
239
240   /* cleanup all resources in the mailbox module */
241   MSG_mailbox_mod_exit();
242
243   SIMIX_clean();
244
245   
246
247   return MSG_OK;
248 }
249
250
251 /** \ingroup msg_easier_life
252  * \brief A clock (in second).
253  */
254 double MSG_get_clock(void)
255 {
256   return SIMIX_get_clock();
257 }