Logo AND Algorithmique Numérique Distribuée

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