Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Adding Killall function
[simgrid.git] / src / msg / global.c
1 /*      $Id$     */
2
3 /* Copyright (c) 2002,2003,2004 Arnaud Legrand. All rights reserved.        */
4
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. */
7
8 #include"private.h"
9 #include"xbt/sysdep.h"
10 #include "xbt/error.h"
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(global, msg,
12                                 "Logging specific to MSG (global)");
13
14 MSG_Global_t msg_global = NULL;
15
16 /* static void MarkAsFailed(m_task_t t, TBX_HashTable_t failedProcessList); */
17 /* static xbt_fifo_t MSG_buildFailedHostList(long double a, long double b); */
18
19 /********************************* MSG **************************************/
20
21 /** \ingroup msg_simulation
22  * \brief Initialize some MSG internal data.
23  */
24 void MSG_global_init(void)
25 {
26   int argc=0;
27   char **argv=NULL;
28
29   CRITICAL0("Please stop using this function. Use MSG_global_init_args instead.");
30   DIE_IMPOSSIBLE;
31   MSG_global_init_args(&argc,argv);
32 }
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   if (!msg_global) {
40     msg_global = xbt_new0(s_MSG_Global_t,1);
41
42     surf_init(argc, argv);      /* Initialize some common structures */
43     xbt_context_init();
44     msg_global->host = xbt_fifo_new();
45     msg_global->process_to_run = xbt_fifo_new();
46     msg_global->process_list = xbt_fifo_new();
47     msg_global->max_channel = 0;
48     msg_global->current_process = NULL;
49     msg_global->registered_functions = xbt_dict_new();
50     msg_global->PID = 1;
51   }
52 }
53
54 /** \ingroup msg_easier_life
55  * \brief Traces MSG events in the Paje format.
56  */
57 void MSG_paje_output(const char *filename)
58 {
59   int i;
60   const char *paje_preembule="%EventDef SetLimits       0\n"
61     "%  StartTime       date\n"
62     "%  EndTime date\n"
63     "%EndEventDef\n"
64     "%EventDef  PajeDefineContainerType 1\n"
65     "%  NewType string\n"
66     "%  ContainerType   string\n"
67     "%  NewName string\n"
68     "%EndEventDef\n"
69     "%EventDef  PajeDefineEventType     2\n"
70     "%  NewType string\n"
71     "%  ContainerType   string\n"
72     "%  NewName string\n"
73     "%EndEventDef\n"
74     "%EventDef  PajeDefineStateType     3\n"
75     "%  NewType string\n"
76     "%  ContainerType   string\n"
77     "%  NewName string\n"
78     "%EndEventDef\n"
79     "%EventDef  PajeDefineVariableType  4\n"
80     "%  NewType string\n"
81     "%  ContainerType   string\n"
82     "%  NewName string\n"
83     "%EndEventDef\n"
84     "%EventDef  PajeDefineLinkType      5\n"
85     "%  NewType string\n"
86     "%  ContainerType   string\n"
87     "%  SourceContainerType     string\n"
88     "%  DestContainerType       string\n"
89     "%  NewName string\n"
90     "%EndEventDef\n"
91     "%EventDef  PajeDefineEntityValue   6\n"
92     "%  NewValue        string\n"
93     "%  EntityType      string\n"
94     "%  NewName string\n"
95     "%EndEventDef\n"
96     "%EventDef  PajeCreateContainer     7\n"
97     "%  Time    date\n"
98     "%  NewContainer    string\n"
99     "%  NewContainerType        string\n"
100     "%  Container       string\n"
101     "%  NewName string\n"
102     "%EndEventDef\n"
103     "%EventDef  PajeDestroyContainer    8\n"
104     "%  Time    date\n"
105     "%  Name    string\n"
106     "%  Type    string\n"
107     "%EndEventDef\n"
108     "%EventDef  PajeNewEvent    9\n"
109     "%  Time    date\n"
110     "%  EntityType      string\n"
111     "%  Container       string\n"
112     "%  Value   string\n"
113     "%EndEventDef\n"
114     "%EventDef  PajeSetState    10\n"
115     "%  Time    date\n"
116     "%  EntityType      string\n"
117     "%  Container       string\n"
118     "%  Value   string\n"
119     "%EndEventDef\n"
120     "%EventDef  PajeSetState    101\n"
121     "%  Time    date\n"
122     "%  EntityType      string\n"
123     "%  Container       string\n"
124     "%  Value   string\n"
125     "%  FileName        string\n"
126     "%  LineNumber      int\n"
127     "%EndEventDef\n"
128     "%EventDef  PajePushState   111\n"
129     "%  Time    date\n"
130     "%  EntityType      string\n"
131     "%  Container       string\n"
132     "%  Value   string\n"
133     "%  FileName        string\n"
134     "%  LineNumber      int\n"
135     "%EndEventDef\n"
136     "%EventDef  PajePushState   11\n"
137     "%  Time    date\n"
138     "%  EntityType      string\n"
139     "%  Container       string\n"
140     "%  Value   string\n"
141     "%EndEventDef\n"
142     "%EventDef  PajePopState    12\n"
143     "%  Time    date\n"
144     "%  EntityType      string\n"
145     "%  Container       string\n"
146     "%EndEventDef\n"
147     "%EventDef  PajeSetVariable 13\n"
148     "%  Time    date\n"
149     "%  EntityType      string\n"
150     "%  Container       string\n"
151     "%  Value   double\n"
152     "%EndEventDef\n"
153     "%EventDef  PajeAddVariable 14\n"
154     "%  Time    date\n"
155     "%  EntityType      string\n"
156     "%  Container       string\n"
157     "%  Value   double\n"
158     "%EndEventDef\n"
159     "%EventDef  PajeSubVariable 15\n"
160     "%  Time    date\n"
161     "%  EntityType      string\n"
162     "%  Container       string\n"
163     "%  Value   double\n"
164     "%EndEventDef\n"
165     "%EventDef  PajeStartLink   16\n"
166     "%  Time    date\n"
167     "%  EntityType      string\n"
168     "%  Container       string\n"
169     "%  Value   string\n"
170     "%  SourceContainer string\n"
171     "%  Key     string\n"
172     "%EndEventDef\n"
173     "%EventDef  PajeEndLink     17\n"
174     "%  Time    date\n"
175     "%  EntityType      string\n"
176     "%  Container       string\n"
177     "%  Value   string\n"
178     "%  DestContainer   string\n"
179     "%  Key     string\n"
180     "%EndEventDef\n";
181
182   const char *type_definitions = "1     Sim_t   0       Simulation_t\n"
183     "1  H_t     Sim_t   m_host_t\n"
184     "1  P_t     H_t     m_process_t\n"
185     "3  S_t     P_t     \"Process State\"\n"
186     "6  E       S_t     Executing\n"
187     "6  B       S_t     Blocked\n"
188     "6  C       S_t     Communicating\n"
189     "5  Comm    Sim_t   P_t     P_t     Communication_t\n";
190
191   const char *ext = ".trace";
192   int ext_len = strlen(ext);
193   int len;
194
195   xbt_assert0(msg_global, "Initialize MSG first\n");
196   xbt_assert0(!msg_global->paje_output, "Paje output allready defined\n");
197   xbt_assert0(filename, "Need a real file name\n");
198
199   len = strlen(filename);
200   if((len<ext_len) || (strncmp(filename+len-ext_len,ext,ext_len))) {
201     CRITICAL2("%s does not end by \"%s\". It may cause troubles when using Paje\n",
202               filename,ext);
203   }
204
205   xbt_assert0(filename, "Need a real file name\n");
206
207   msg_global->paje_output=fopen(filename,"w");
208   xbt_assert1(msg_global->paje_output, "Failed to open %s \n",filename);
209
210   fprintf(msg_global->paje_output,"%s",paje_preembule);
211   fprintf(msg_global->paje_output,"%s",type_definitions);
212   for(i=0; i<msg_global->max_channel; i++) {
213     fprintf(msg_global->paje_output, "6 COMM_%d Comm    \"Channel %d\"\n" ,i,i);
214   }
215   fprintf(msg_global->paje_output,
216           "7    0.0     CUR     Sim_t   0       \"MSG simulation\"\n");
217
218 }
219
220 /** \ingroup msg_simulation
221  * \brief Defines the verbosity of the simulation.
222  */
223 void MSG_set_verbosity(MSG_outputmode_t mode)
224 {
225   CRITICAL0("MSG_set_verbosity : Not implemented yet.");
226 }
227
228 /** \ingroup m_channel_management
229  * \brief Set the number of channel in the simulation.
230  *
231  * This function has to be called to fix the number of channel in the
232    simulation before creating any host. Indeed, each channel is
233    represented by a different mailbox on each #m_host_t. This
234    function can then be called only once. This function takes only one
235    parameter.
236  * \param number the number of channel in the simulation. It has to be >0
237  */
238 MSG_error_t MSG_set_channel_number(int number)
239 {
240   xbt_assert0((msg_global) && (msg_global->max_channel == 0), "Channel number already set!");
241
242   msg_global->max_channel = number;
243
244   return MSG_OK;
245 }
246
247 /** \ingroup m_simulation
248  * \brief Set the sharing policy used for the links
249  *
250  * This function can be called to change the sharing policy used for the links 
251    (see \ref paper_tcp). By default the store and forward mechanism is used
252    with a parameter equal to 0.1. This function has to be called before creating 
253    any link. 
254  * \param mode the sharing policy used for the links: can be either 
255    MSG_STORE_AND_FORWARD or MSG_TCP.
256  * \param param a parameter for the sharing policy. It has to be >0. It is 
257    currently used only for the MSG_STORE_AND_FORWARD flavor and represents the
258    granularity of the communications (i.e. the packet size).
259  */
260 MSG_error_t MSG_set_sharing_policy(MSG_sharing_t mode, long double param)
261 {
262   CRITICAL0("MSG_set_sharing_policy: this function is now deprecated and useless. Store and forward does not exist anymore. Please stop using it.");
263   
264   return MSG_OK;
265 }
266
267 /** \ingroup m_channel_management
268  * \brief Return the number of channel in the simulation.
269  *
270  * This function has to be called once the number of channel is fixed. I can't 
271    figure out a reason why anyone would like to call this function but nevermind.
272  * \return the number of channel in the simulation.
273  */
274 int MSG_get_channel_number(void)
275 {
276   xbt_assert0((msg_global)&&(msg_global->max_channel != 0), "Channel number not set yet!");
277
278   return msg_global->max_channel;
279 }
280
281 /** \ingroup msg_simulation
282  * \brief Launch the MSG simulation
283  */
284 MSG_error_t MSG_main(void)
285 {
286   m_process_t process = NULL;
287   int nbprocess,i;
288   double elapsed_time = 0.0;
289
290   /* Clean IO before the run */
291   fflush(stdout);
292   fflush(stderr);
293
294   surf_solve(); /* Takes traces into account. Returns 0.0 */
295 /* xbt_fifo_size(msg_global->process_to_run) */
296   while (1) {
297     xbt_context_empty_trash();
298     while ((process = xbt_fifo_pop(msg_global->process_to_run))) {
299 /*       fprintf(stderr,"-> %s (%d)\n",process->name, process->simdata->PID); */
300       DEBUG3("Scheduling  %s(%d) on %s",             
301              process->name,process->simdata->PID,
302              process->simdata->host->name);
303       msg_global->current_process = process;
304       xbt_context_schedule(process->simdata->context);
305       msg_global->current_process = NULL;
306     }
307     DEBUG1("%Lg : Calling surf_solve",MSG_getClock());
308     elapsed_time = surf_solve();
309     DEBUG1("Elapsed_time %lg",elapsed_time);
310
311 /*     fprintf(stderr, "====== %Lg =====\n",Now); */
312 /*     if (elapsed_time==0.0) { */
313 /*       fprintf(stderr, "No change in time\n"); */
314 /*     } */
315     if (elapsed_time<0.0) {
316 /*       fprintf(stderr, "We're done %lg\n",elapsed_time); */
317       break;
318     }
319
320     {
321       surf_action_t action = NULL;
322       surf_resource_t resource = NULL;
323       m_task_t task = NULL;
324       
325       xbt_dynar_foreach(resource_list, i, resource) {
326         while ((action =
327                xbt_swag_extract(resource->common_public->states.
328                                 failed_action_set))) {
329           task = action->data;
330           if(task) {
331             int _cursor;
332             DEBUG1("** %s failed **",task->name);
333 /*          fprintf(stderr,"** %s **\n",task->name); */
334             xbt_dynar_foreach(task->simdata->sleeping,_cursor,process) {
335               DEBUG3("\t preparing to wake up %s(%d) on %s",         
336                      process->name,process->simdata->PID,
337                      process->simdata->host->name);
338               xbt_fifo_unshift(msg_global->process_to_run, process);
339             }
340             process=NULL;
341           }
342         }
343         while ((action =
344                xbt_swag_extract(resource->common_public->states.
345                                 done_action_set))) {
346           task = action->data;
347           if(task) {
348             int _cursor;
349             DEBUG1("** %s done **",task->name);
350 /*          fprintf(stderr,"** %s **\n",task->name); */
351             xbt_dynar_foreach(task->simdata->sleeping,_cursor,process) {
352               DEBUG3("\t preparing to wake up %s(%d) on %s",         
353                      process->name,process->simdata->PID,
354                      process->simdata->host->name);
355               xbt_fifo_unshift(msg_global->process_to_run, process);
356             }
357             process=NULL;
358           }
359         }
360       }
361     }
362   }
363
364   if ((nbprocess=xbt_fifo_size(msg_global->process_list)) == 0) {
365     fprintf(stderr,
366             "MSG: Congratulations ! Simulation terminated : all process are over\n");
367     return MSG_OK;
368   } else {
369     xbt_fifo_item_t item = NULL;
370     fprintf(stderr,"MSG: Oops ! Deadlock or code not perfectly clean.\n");
371     fprintf(stderr,"MSG: %d processes are still running, waiting for something.\n",
372             nbprocess);
373     /*  List the process and their state */
374     fprintf(stderr,"MSG: <process>(<pid>) on <host>: <status>.\n");
375     xbt_fifo_foreach(msg_global->process_list,item,process,m_process_t) {
376       simdata_process_t p_simdata = (simdata_process_t) process->simdata;
377       simdata_host_t h_simdata=(simdata_host_t)p_simdata->host->simdata;
378       
379
380       fprintf(stderr,"MSG:  %s(%d) on %s: ",
381              process->name,p_simdata->PID,
382              p_simdata->host->name);
383
384       if (process->simdata->blocked)      
385         fprintf(stderr,"[blocked] ");
386       if (process->simdata->suspended)    
387         fprintf(stderr,"[suspended] ");
388
389       for (i=0; i<msg_global->max_channel; i++) {
390         if (h_simdata->sleeping[i] == process) {
391           fprintf(stderr,"Listening on channel %d.\n",i);
392           break;
393         }
394       }
395       if (i==msg_global->max_channel) {
396         if(p_simdata->waiting_task) {
397           if(p_simdata->waiting_task->simdata->compute) {
398             if(p_simdata->put_host) 
399               fprintf(stderr,"Trying to send a task on Host %s, channel %d.\n",
400                       p_simdata->put_host->name, p_simdata->put_channel);
401             else 
402               fprintf(stderr,"Waiting for %s to finish.\n",p_simdata->waiting_task->name);
403           } else if (p_simdata->waiting_task->simdata->comm)
404             fprintf(stderr,"Waiting for %s to be finished transfered.\n",
405                     p_simdata->waiting_task->name);
406           else
407             fprintf(stderr,"UNKNOWN STATUS. Please report this bug.\n");
408         }
409         else { /* Must be trying to put a task somewhere */
410           fprintf(stderr,"UNKNOWN STATUS. Please report this bug.\n");
411         }
412       } 
413     }
414     if(XBT_LOG_ISENABLED(msg, xbt_log_priority_debug) ||
415        XBT_LOG_ISENABLED(global, xbt_log_priority_debug)) {
416       DEBUG0("Aborting!");
417       xbt_abort();
418     }
419
420     return MSG_WARNING;
421   }
422 }
423
424 /* static void MarkAsFailed(m_task_t t, TBX_HashTable_t failedProcessList)  */
425 /* { */
426 /*   simdata_task_t simdata = NULL; */
427 /*   xbt_fifo_item_t i = NULL; */
428 /*   m_process_t p = NULL; */
429   
430 /*   xbt_assert0((t!=NULL),"Invalid task"); */
431 /*   simdata = t->simdata; */
432
433 /* #define KILL(task) if(task) SG_failTask(task) */
434 /*   KILL(simdata->compute); */
435 /*   KILL(simdata->TCP_comm); */
436 /*   KILL(simdata->s[0]); */
437 /*   KILL(simdata->s[1]); */
438 /*   KILL(simdata->s[2]); */
439 /*   KILL(simdata->s[3]); */
440 /*   KILL(simdata->sleep); */
441 /* #undef KILL   */
442 /* /\*   if(simdata->comm) SG_failEndToEndTransfer(simdata->comm); *\/ */
443   
444 /*   xbt_fifo_foreach(simdata->sleeping,i,p,m_process_t) { */
445 /*     if(!TBX_HashTable_isInList(failedProcessList,p,TBX_basicHash))  */
446 /*       TBX_HashTable_insert(failedProcessList,p,TBX_basicHash); */
447 /*   } */
448   
449 /* } */
450
451 /* static xbt_fifo_t MSG_buildFailedHostList(long double begin, long double end) */
452 /* { */
453 /*   xbt_fifo_t failedHostList = xbt_fifo_new(); */
454 /*   m_host_t host = NULL; */
455 /*   xbt_fifo_item_t i; */
456
457 /*   xbt_fifo_foreach(msg_global->host,i,host,m_host_t) { */
458 /*     SG_Resource r= ((simdata_host_t) (host->simdata))->host; */
459
460 /*     if(SG_evaluateFailureTrace(r->failure_trace,begin,end)!=-1.0) */
461 /*       xbt_fifo_insert(failedHostList,host); */
462 /*   } */
463
464 /*   return failedHostList; */
465 /* } */
466
467 /** \ingroup msg_simulation
468  * \brief Kill all running process
469
470  * \param reset_PIDs should we reset the PID numbers. A negative
471  *   number means no reset and a positive number will be used to set the PID
472  *   of the next newly created process.
473  */
474 int MSG_process_killall(int reset_PIDs)
475 {
476   xbt_fifo_item_t i = NULL;
477   m_process_t p = NULL;
478
479   while((p=xbt_fifo_shift(msg_global->process_list))) {
480     MSG_process_kill(p);
481   }
482   xbt_context_empty_trash();
483   if(reset_PIDs>0) {
484     msg_global->PID = reset_PIDs; 
485     msg_global->session++;
486  }
487
488   return msg_global->PID;
489 }
490
491 /** \ingroup msg_simulation
492  * \brief Clean the MSG simulation
493  */
494 MSG_error_t MSG_clean(void)
495 {
496   xbt_fifo_item_t i = NULL;
497   m_host_t h = NULL;
498   m_process_t p = NULL;
499
500
501   while((p=xbt_fifo_shift(msg_global->process_list))) {
502     MSG_process_kill(p);
503   }
504   xbt_context_exit();
505
506   xbt_fifo_foreach(msg_global->host,i,h,m_host_t) {
507     __MSG_host_destroy(h);
508   }
509   xbt_fifo_free(msg_global->host);
510   xbt_fifo_free(msg_global->process_to_run);
511   xbt_fifo_free(msg_global->process_list);
512   xbt_dict_free(&(msg_global->registered_functions));
513
514   if(msg_global->paje_output) {
515     fclose(msg_global->paje_output);
516     msg_global->paje_output = NULL;
517   }
518   xbt_free(msg_global);
519   surf_finalize();
520
521   return MSG_OK;
522 }
523
524
525 /** \ingroup msg_easier_life
526  * \brief A clock (in second).
527  */
528 long double MSG_getClock(void) {
529   return surf_get_clock();
530 }
531