Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix test lua-msg-masterslave-console (was broken since r9407)
[simgrid.git] / src / gras / Virtu / sg_process.c
1 /* process_sg - GRAS process handling on simulator                          */
2
3 /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7  * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include "xbt/ex.h"
10 #include "xbt/dict.h"
11 #include "gras_modinter.h"      /* module initialization interface */
12 #include "gras/Virtu/virtu_sg.h"
13 #include "gras/Msg/msg_interface.h"     /* For some checks at simulation end */
14 #include "gras/Transport/transport_interface.h" /* For some checks at simulation end */
15 #if HAVE_LUA
16 #include <lua.h>
17 #include <lauxlib.h>
18 #include <lualib.h>
19 #endif
20 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(gras_virtu_process);
21
22 static long int PID = 1;
23
24
25 void gras_agent_spawn(const char *name,
26                       xbt_main_func_t code, int argc, char *argv[],
27                       xbt_dict_t properties)
28 {
29
30   SIMIX_req_process_create(name, code, NULL,
31                            gras_os_myname(), argc, argv, properties);
32 }
33
34 /* **************************************************************************
35  * Process constructor/destructor (semi-public interface)
36  * **************************************************************************/
37
38 void gras_process_init()
39 {
40   gras_hostdata_t *hd =
41       (gras_hostdata_t *) SIMIX_host_self_get_data();
42   gras_procdata_t *pd = xbt_new0(gras_procdata_t, 1);
43   gras_trp_procdata_t trp_pd;
44   long int pid = PID++; /* make sure the first process gets the first id */
45
46   if (!hd) {
47     /* First process on this host (FIXME: does not work if the SIMIX user contexts are truly parallel) */
48     hd = xbt_new(gras_hostdata_t, 1);
49     hd->refcount = 1;
50     hd->ports = xbt_dynar_new(sizeof(gras_sg_portrec_t), NULL);
51     SIMIX_host_self_set_data((void *) hd);
52   } else {
53     hd->refcount++;
54   }
55
56   SIMIX_process_self_set_data((void *) pd);
57   gras_procdata_init();
58
59   trp_pd = (gras_trp_procdata_t) gras_libdata_by_name("gras_trp");
60   pd->pid = pid;
61
62   if (SIMIX_process_self() != NULL) {
63     pd->ppid = gras_os_getpid();
64   } else
65     pd->ppid = -1;
66
67   trp_pd->msg_selectable_sockets = xbt_queue_new(0, sizeof(gras_socket_t));
68
69   trp_pd->meas_selectable_sockets =
70       xbt_queue_new(0, sizeof(gras_socket_t));
71
72   VERB2("Creating process '%s' (%d)", SIMIX_process_self_get_name(),
73       gras_os_getpid());
74 }
75
76 void gras_process_exit()
77 {
78   xbt_dynar_t sockets =
79       ((gras_trp_procdata_t) gras_libdata_by_name("gras_trp"))->sockets;
80   gras_socket_t sock_iter;
81   unsigned int cursor;
82   gras_hostdata_t *hd =
83       (gras_hostdata_t *) SIMIX_host_self_get_data();
84   gras_procdata_t *pd =
85       (gras_procdata_t *) SIMIX_req_process_get_data(SIMIX_process_self());
86
87   gras_msg_procdata_t msg_pd =
88       (gras_msg_procdata_t) gras_libdata_by_name("gras_msg");
89   gras_trp_procdata_t trp_pd =
90       (gras_trp_procdata_t) gras_libdata_by_name("gras_trp");
91
92   xbt_queue_free(&trp_pd->msg_selectable_sockets);
93
94   xbt_queue_free(&trp_pd->meas_selectable_sockets);
95
96
97   xbt_assert0(hd, "Run gras_process_init (ie, gras_init)!!");
98
99   VERB2("GRAS: Finalizing process '%s' (%d)",
100         SIMIX_req_process_get_name(SIMIX_process_self()), gras_os_getpid());
101
102   if (xbt_dynar_length(msg_pd->msg_queue)) {
103     unsigned int cpt;
104     s_gras_msg_t msg;
105     WARN2
106         ("process %d terminated, but %ld messages are still queued. Message list:",
107          gras_os_getpid(), xbt_dynar_length(msg_pd->msg_queue));
108     xbt_dynar_foreach(msg_pd->msg_queue, cpt, msg) {
109       WARN5("   Message %s (%s) from %s@%s:%d", msg.type->name,
110             e_gras_msg_kind_names[msg.kind],
111             gras_socket_peer_proc(msg.expe),
112             gras_socket_peer_name(msg.expe),
113             gras_socket_peer_port(msg.expe));
114     }
115   }
116
117   /* if each process has its sockets list, we need to close them when the
118      process finish */
119   xbt_dynar_foreach(sockets, cursor, sock_iter) {
120     VERB1("Closing the socket %p left open on exit. Maybe a socket leak?",
121           sock_iter);
122     gras_socket_close(sock_iter);
123   }
124   if (!--(hd->refcount)) {
125     xbt_dynar_free(&hd->ports);
126     free(hd);
127   }
128   gras_procdata_exit();
129   free(pd);
130 }
131
132 /* **************************************************************************
133  * Process data (public interface)
134  * **************************************************************************/
135
136 gras_procdata_t *gras_procdata_get(void)
137 {
138   gras_procdata_t *pd =
139       (gras_procdata_t *) SIMIX_req_process_get_data(SIMIX_process_self());
140
141   xbt_assert0(pd, "Run gras_process_init! (ie, gras_init)");
142
143   return pd;
144 }
145
146 void *gras_libdata_by_name_from_remote(const char *name, smx_process_t p)
147 {
148   gras_procdata_t *pd = (gras_procdata_t *) SIMIX_req_process_get_data(p);
149
150   xbt_assert2(pd,
151               "process '%s' on '%s' didn't run gras_process_init! (ie, gras_init)",
152               SIMIX_req_process_get_name(p),
153               SIMIX_req_host_get_name(SIMIX_req_process_get_host(p)));
154
155   return gras_libdata_by_name_from_procdata(name, pd);
156 }
157
158 /** @brief retrieve the value of a given process property (or NULL if not defined) */
159 const char *gras_process_property_value(const char *name)
160 {
161   return xbt_dict_get_or_null(SIMIX_req_process_get_properties
162                              (SIMIX_process_self()), name);
163 }
164
165 /** @brief retrieve the process properties dictionnary
166  *  @warning it's the original one, not a copy. Don't mess with it
167  */
168 xbt_dict_t gras_process_properties(void)
169 {
170   return SIMIX_req_process_get_properties(SIMIX_process_self());
171 }
172
173 /* **************************************************************************
174  * OS virtualization function
175  * **************************************************************************/
176
177
178 int gras_os_getpid(void)
179 {
180   gras_procdata_t *data;
181   data = (gras_procdata_t *) SIMIX_process_self_get_data();
182   if (data != NULL)
183     return data->pid;
184
185   return 0;
186 }
187
188 /** @brief retrieve the value of a given host property (or NULL if not defined) */
189 const char *gras_os_host_property_value(const char *name)
190 {
191   return
192       xbt_dict_get_or_null(SIMIX_req_host_get_properties
193                            (SIMIX_req_process_get_host(SIMIX_process_self())),
194                            name);
195 }
196
197 /** @brief retrieve the host properties dictionnary
198  *  @warning it's the original one, not a copy. Don't mess with it
199  */
200 xbt_dict_t gras_os_host_properties(void)
201 {
202   return
203       SIMIX_req_host_get_properties(SIMIX_req_process_get_host
204                                 (SIMIX_process_self()));
205 }
206
207 /* **************************************************************************
208  * Interface with SIMIX
209  * (these functions are called by the stuff generated by gras_stub_generator)
210  * **************************************************************************/
211
212 XBT_LOG_EXTERNAL_CATEGORY(gras_trp);
213 XBT_LOG_EXTERNAL_CATEGORY(gras_trp_sg);
214
215 void gras_global_init(int *argc, char **argv)
216 {
217   XBT_LOG_CONNECT(gras_trp_sg, gras_trp);
218   SIMIX_global_init(argc, argv);
219 }
220
221 void gras_create_environment(const char *file)
222 {
223   SIMIX_create_environment(file);
224 }
225
226 void gras_function_register(const char *name, xbt_main_func_t code)
227 {
228   SIMIX_function_register(name, code);
229 }
230
231 void gras_function_register_default(xbt_main_func_t code)
232 {
233   SIMIX_function_register_default(code);
234 }
235
236 void gras_main()
237 {
238   /* Clean IO before the run */
239   fflush(stdout);
240   fflush(stderr);
241   SIMIX_run();
242
243   return;
244 }
245
246 void gras_launch_application(const char *file)
247 {
248   SIMIX_launch_application(file);
249 }
250
251 void gras_load_environment_script(const char *script_file)
252 {
253 #ifdef HAVE_LUA
254   lua_State *L = lua_open();
255   luaL_openlibs(L);
256
257   if (luaL_loadfile(L, script_file) || lua_pcall(L, 0, 0, 0)) {
258     printf("error: %s\n", lua_tostring(L, -1));
259     return;
260   }
261 #else
262   xbt_die
263       ("Lua is not available!! to call gras_load_environment_script, lua should be available...");
264 #endif
265   return;
266 }
267
268 void gras_clean()
269 {
270   SIMIX_clean();
271 }