removed matherr.h
[dyninst.git] / paradyn / src / pdMain / main.C
1 /* $Log: main.C,v $
2 /* Revision 1.36  1995/12/20 20:18:35  newhall
3 /* removed matherr.h
4 /*
5  * Revision 1.35  1995/12/03  21:33:11  newhall
6  * changes to support new sampleDataCallbackFunc
7  *
8  * Revision 1.34  1995/11/21  15:24:39  naim
9  * Exiting if there is an unrecoverable parse error - naim
10  *
11  * Revision 1.33  1995/11/13  19:59:02  naim
12  * Adding error flag that is turned on when there is an error reading the
13  * paradyn configuration file. The called to showError had to be moved some-
14  * where else because uiMgr has not been initialized yet at this point - naim
15  *
16  * Revision 1.32  1995/11/13  14:54:49  naim
17  * Adding error message #85 - naim
18  *
19  * Revision 1.31  1995/11/08  21:17:31  naim
20  * Adding matherr exception handler function to avoid error message when
21  * computing the "not a number" (NaN) value - naim
22  *
23  * Revision 1.30  1995/11/06  02:48:59  tamches
24  * used tkTools.h
25  * removed code to pass args to UIthread (no longer used)
26  * changed hysteresisRange to a developer mode TC
27  *
28  * Revision 1.29  1995/10/30 23:08:03  naim
29  * Taking the comment out of Tcl_DeleteInterp call - naim
30  *
31  * Revision 1.28  1995/10/19  22:43:04  mjrg
32  * Read both -s and -f files.
33  *
34  * Revision 1.27  1995/08/24  15:02:55  hollings
35  * AIX/SP-2 port (including option for split instruction/data heaps)
36  * Tracing of rexec (correctly spawns a paradynd if needed)
37  * Added rtinst function to read getrusage stats (can now be used in metrics)
38  * Critical Path
39  * Improved Error reporting in MDL sematic checks
40  * Fixed MDL Function call statement
41  * Fixed bugs in TK usage (strings passed where UID expected)
42  *
43  * Revision 1.26  1995/08/23  21:03:21  mjrg
44  * moved call to readStartUpFile() to after commands in configuration
45  * file are executed.
46  *
47  * Revision 1.25  1995/08/20  03:42:02  newhall
48  * changed arguments to DM_sequential_init
49  *
50  * Revision 1.24  1995/08/18  22:00:16  mjrg
51  * Added calls to metDoProcess, metDoDaemon, metDoTunable.
52  *
53  * Revision 1.23  1995/08/16  15:17:40  krisna
54  * double-bug fix.
55  *   * do not pass addresses of stack variables into thread functions
56  *   * do not use the first item of a struct as a scalar
57  *
58  * Revision 1.22  1995/08/14 22:49:49  tamches
59  * Removed the TC thread.
60  * The main tunable constant dictionaries are global variables
61  * (in TCthread/TCmain.C); their constructors automatically
62  * initialize the TC registry before main() even starts.  Hence,
63  * no problems declaring any tunable constants after main starts.
64  * But, don't declare any tunable constants as global variables.
65  *
66  * Revision 1.21  1995/08/13  23:22:26  tamches
67  * Moved tcl/tk initialization code here from UImain.
68  * tcl/tk initialization is now the very first thing done
69  * in main()
70  *
71  * Revision 1.20  1995/08/12  22:27:51  newhall
72  * added calls to DM and VM sequential initialization routines
73  *
74  * Revision 1.19  1995/08/11  21:51:16  newhall
75  * Parsing of PDL files is done before thread creation
76  * Removed call to dataManager kludge method function
77  *
78  * Revision 1.18  1995/06/02  20:55:58  newhall
79  * made code compatable with new DM interface
80  *
81  * Revision 1.17  1995/05/18  11:00:31  markc
82  * added mdl hooks
83  *
84  * Revision 1.16  1995/02/27  19:13:49  tamches
85  * Many changes to reflect changes in tunable constants.
86  * First change: TCthread is launched
87  * other changes: Many tunable constants are declared here (within
88  * main()) since they may no longer be declared globally in any
89  * module.
90  *
91  * Revision 1.15  1995/02/16  08:25:09  markc
92  * Removed system includes
93  * Added includes of posix interfaces
94  *
95  * Revision 1.14  1994/11/02  04:39:01  karavan
96  * added -s commandline option for a tcl script
97  *
98  * Revision 1.13  1994/11/01  22:27:22  karavan
99  * Changed debugging printfs to PARADYN_DEBUG calls.
100  *
101  * Revision 1.12  1994/09/22  01:22:48  markc
102  * Gave correct signature for signal
103  *
104  * Revision 1.11  1994/08/22  15:54:49  markc
105  * Added command line argument to specify application config file.
106  *
107  * Revision 1.10  1994/07/28  22:31:42  krisna
108  * proper prototypes and starting code for thread main functions
109  *
110  * Revision 1.9  1994/07/19  23:52:58  markc
111  * Moved "include "metricExt.h"" to main.C from paradyn.h to remove false
112  * dependencies.
113  *
114  * Revision 1.8  1994/07/07  03:26:24  markc
115  * Added calls to parser routines.
116  *
117  * Revision 1.7  1994/05/18  00:51:03  hollings
118  * We don't want SIGPIPEs to kill us.
119  *
120  * Revision 1.6  1994/05/10  03:57:54  hollings
121  * Changed data upcall to return array of buckets.
122  *
123  * Revision 1.5  1994/04/28  22:07:39  newhall
124  * added PARADYN_DEBUG macro: prints debug message if PARADYNDEBUG
125  * environment variable has value >= 1
126  *
127  * Revision 1.4  1994/04/21  23:25:19  hollings
128  * changed to no initial paradynd being defined.
129  *
130  * Revision 1.3  1994/04/10  19:08:48  newhall
131  * added visualization manager thread create
132  *
133  * Revision 1.2  1994/04/05  04:36:48  karavan
134  * Changed order of thread initialization to avoid deadlock.  Added global
135  * user variables for data manager, uim, and performance consultant.
136  *
137  * Revision 1.1  1994/03/29  20:20:54  karavan
138  * initial version for testing
139  * */
140
141 /*
142  * main.C - main routine for paradyn.  
143  *   This routine creates DM, UIM, VM, and PC threads.
144  */
145
146 #include "tclclean.h"
147 #include "tkclean.h"
148
149 #include "../TCthread/tunableConst.h"
150 #include "util/h/headers.h"
151 #include "paradyn.h"
152 #include "thread/h/thread.h"
153 #include "dataManager.thread.SRVR.h"
154 #include "VM.thread.SRVR.h"
155 #include "../UIthread/tkTools.h" // tclpanic
156 #include "util/h/makenan.h"
157 #include "paradyn/src/DMthread/BufferPool.h"
158 #include "paradyn/src/DMthread/DVbufferpool.h"
159
160 // maybe this should be a thread, but for now it's a global var.
161 BufferPool<dataValueType>  datavalues_bufferpool;
162
163
164 extern void *UImain(void *);
165 extern void *DMmain(void *);
166 extern void *PCmain(void *);
167 extern void *VMmain (void *);
168 //extern void *TCmain (void *); // tunable consts
169
170 #define MBUFSIZE 256
171 #define DEBUGBUFSIZE    4096
172
173 thread_t UIMtid;
174 thread_t MAINtid;
175 thread_t PCtid;
176 thread_t DMtid;
177 thread_t VMtid;
178 //thread_t TCtid; // tunable constants
179
180 // expanded stack by a factor of 10 to support AIX - jkh 8/14/95
181 // wrapped it in an ifdef so others don't pay the price --ari 10/95
182 #ifdef rs6000_ibm_aix3_2
183 char UIStack[327680];
184 #else
185 char UIStack[32768];
186 #endif
187
188
189
190 // applicationContext *context;
191 dataManagerUser *dataMgr;
192 performanceConsultantUser *perfConsult;
193 UIMUser *uiMgr;
194 VMUser  *vmMgr;
195 int paradyn_debug;
196 char debug_buf[DEBUGBUFSIZE];
197
198
199 #define PRINT_DEBUG_MACRO                               \
200 do {                                                    \
201         va_list args;                                   \
202         va_start(args,format);                          \
203         (void) fflush(stdout);                          \
204         (void) vsprintf(debug_buf, format, args);       \
205         (void) fprintf(stdout,"THREAD %d: %s\n",        \
206                thr_self(), debug_buf);                  \
207         (void) fflush(stdout);                          \
208         va_end(args);                                   \
209 } while (0)
210
211 void print_debug_macro(const char* format, ...){
212   if(paradyn_debug > 0)
213      PRINT_DEBUG_MACRO;
214   return;
215 }
216
217 void eFunction(int errno, char *message)
218 {
219     printf("error #%d: %s\b", errno, message);
220     abort();
221 }
222
223 extern bool metDoTunable();
224 extern bool metDoProcess();
225 extern bool metMain(string&);
226 extern bool metDoProcess();
227 extern bool metDoDaemon();
228
229
230 //extern void tclpanic(Tcl_Interp *, const char *msg);
231 Tcl_Interp *interp;
232 Tk_Window   mainWindow;
233 int         tty;
234
235 int
236 main (int argc, char **argv)
237 {
238
239 //  CLargStruct* clargs;
240   char mbuf[MBUFSIZE];
241   unsigned int msgsize;
242   tag_t mtag;
243   char *temp;
244
245   // Initialize tcl/tk
246   interp = Tcl_CreateInterp();
247   assert(interp);
248
249   mainWindow = Tk_CreateMainWindow(interp, NULL, "paradyn", "Paradyn");
250   if (mainWindow == NULL)
251      tclpanic(interp, "Could not Tk_CreateMainWindow");
252   Tk_GeometryRequest(mainWindow, 725, 475);
253
254   if (false)
255      // This is cool for X debugging...but we don't want it normally.
256      // It forces a flush after every X event -- no buffering.
257      XSynchronize(Tk_Display(mainWindow), True);
258
259   tty = isatty(0);
260   Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
261
262   if (Tcl_Init(interp) == TCL_ERROR)
263      tclpanic(interp, "tcl_init() failed (perhaps TCL_LIBRARY not set?)");
264   if (Tk_Init(interp) == TCL_ERROR)
265      tclpanic(interp, "tk_init() failed (perhaps TK_LIBRARY not set?");
266 //  if (Tix_Init(interp) == TCL_ERROR)
267 //     tclpanic(interp, "tix_init() failed (perhaps TIX_LIBRARY not set?");
268
269   // copy command-line arguments into tcl vrbles argc / argv
270   char *args = Tcl_Merge(argc - 1, (const char **) (argv + 1));
271   Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
272   ckfree(args);
273
274   string argcStr = string(argc - 1);
275   Tcl_SetVar(interp, "argc", argcStr.string_of(), TCL_GLOBAL_ONLY);
276   Tcl_SetVar(interp, "argv0", argv[0], TCL_GLOBAL_ONLY);
277
278   // Here is one tunable constant that is definitely intended to be hard-coded in:
279    tunableBooleanConstantDeclarator tcInDeveloperMode("developerMode",
280          "Allow access to all tunable constants, including those limited to developer mode.  (Use with caution)",
281          false, // initial value
282          NULL, // no callback routine (yet)
283          userConstant);
284
285   //
286   // We check our own read/write events.
287   //
288   P_signal(SIGPIPE, (P_sig_handler) SIG_IGN);
289
290   if ((argc != 1 && argc != 3 && argc != 5) ||
291       ((argc == 3) && strcmp(argv[1],"-f") && strcmp(argv[1],"-s")) ||
292       ((argc == 5) && strcmp(argv[3],"-f") && strcmp(argv[3],"-s"))) {
293     printf("usage: %s [-f <pcl_filename>] [-s <tcl_scriptname>]\n", argv[0]);
294     exit(-1);
295   }
296
297   // get paradyn_debug environment var PARADYNDEBUG, if its value
298   // is > 1, then PARADYN_DEBUG msgs will be printed to stdout
299   if((temp = (char *) getenv("PARADYNDEBUG"))){
300      paradyn_debug = atoi(temp);
301   }
302   else {
303     paradyn_debug = 0;
304   }
305
306 // parse the command line arguments
307   int a_ct=0;
308   char *fname=0, *sname=0;
309   while (argv[a_ct + 1]) {
310     if (!strcmp(argv[a_ct], "-f")) {
311       fname = argv[a_ct+1];
312     } else if (!strcmp(argv[a_ct], "-s")) {
313         sname = argv[a_ct+1];
314       }
315     a_ct++;
316   }
317
318 // get tid of parent
319   MAINtid = thr_self();
320
321 // Structure used to pass initial arguments to data manager
322 //  init_struct init; init.tid = MAINtid; init.met_file = fname;
323
324 // call sequential initialization routines
325   if(!dataManager::DM_sequential_init(fname)) {
326     printf("Error found in Paradyn Configuration File, exiting\n");
327     exit(-1);
328   }
329   VM::VM_sequential_init(); 
330
331
332      /* initialize the 4 main threads of paradyn: data manager, visi manager,
333         user interface manager, performance consultant */
334   
335 // initialize Tunable Constants thread
336 //  if (THR_ERR == thr_create(NULL, // stack
337 //                          0, // stack size
338 //                          TCmain, // entry-point function
339 //                          NULL, // args
340 //                          0, // flags
341 //                          &TCtid))
342 //     exit(1);
343 //  PARADYN_DEBUG (("TC thread created\n"));
344 //  // wait until TC has properly initialized (it'll send us a blank msg)
345 //  mtag = MSG_TAG_TC_READY;
346 //  msgsize = MBUFSIZE;
347 //  (void)msg_recv(&mtag, mbuf, &msgsize);
348 ////  cout << "pdMain: TC thread has given us the okay to continue creating threads!" << endl;
349   
350 // Declare some tunable constants (declaring them here makes them last as long
351 // as this routine does, which is "forever")
352   extern bool predictedCostLimitValidChecker(float); // in PCauto.C
353   tunableFloatConstantDeclarator pcl ("predictedCostLimit",
354                                  "Max. allowable perturbation of the application.",
355                                  100.0, // initial value
356                                  predictedCostLimitValidChecker, // validation function (in PCauto.C)
357                                  NULL, // callback routine
358                                  userConstant);
359
360   tunableFloatConstantDeclarator mnh ("maxEval",
361                                  "Max. number of hypotheses to consider at once.",
362                                  25.0, // initial
363                                  0.0,  // min
364                                  250.0, // max
365                                  NULL, // callback
366                                  userConstant);
367   tunableFloatConstantDeclarator hysRange("hysteresisRange",
368                                           "Fraction above and below threshold that a test should use.",
369                                           0.15, // initial
370                                           0.0, // min
371                                           1.0, // max
372                                           NULL, // callback
373                                           developerConstant);
374
375   //
376   // Fix this soon... This should be based on some real information.
377   //
378   tunableFloatConstantDeclarator minObsTime("minObservationTime",
379                                             "min. time (in seconds) to wait after changing inst to start try hypotheses.",
380                                             1.0, // initial
381                                             0.0, // min
382                                             60.0, // max
383                                             NULL, // callback
384                                             userConstant);
385
386   tunableFloatConstantDeclarator sufficientTime("sufficientTime",
387                                                 "How long to wait (in seconds) before we can conclude a hypothesis is false.",
388                                                 6.0, // initial
389                                                 0.0, // min
390                                                 1000.0, // max
391                                                 NULL,
392                                                 userConstant);
393   tunableBooleanConstantDeclarator printNodes("printNodes",
394                                               "Print out changes to the state of SHG nodes",
395                                               false, // initial value
396                                               NULL, // callback
397                                               developerConstant);
398
399   tunableBooleanConstantDeclarator printTestResults("printTestResults",
400                                                     "Print out the result of each test as it is computed",
401                                                     false,
402                                                     NULL,
403                                                     developerConstant);
404
405   tunableBooleanConstantDeclarator pcEvalPrint("pcEvalPrint",
406                                                "Print out the values of tests each time they are evaluated",
407                                                false,
408                                                NULL,
409                                                developerConstant);
410                                                
411   tunableBooleanConstantDeclarator suppressSHG("suppressSHG",
412                                                "Don't print the SHG",
413                                                false,
414                                                NULL,
415                                                userConstant);
416
417 // initialize DM
418
419   if (thr_create(0, 0, DMmain, (void *) &MAINtid, 0, 
420                  (unsigned int *) &DMtid) == THR_ERR)
421     exit(1);
422   PARADYN_DEBUG (("DM thread created\n"));
423
424   msgsize = MBUFSIZE;
425   mtag = MSG_TAG_DM_READY;
426   msg_recv(&mtag, mbuf, &msgsize);
427   msg_send (DMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
428   dataMgr = new dataManagerUser (DMtid);
429   // context = dataMgr->createApplicationContext(eFunction);
430
431 // initialize UIM 
432  
433   if (thr_create (UIStack, sizeof(UIStack), &UImain, NULL,
434                   0, &UIMtid) == THR_ERR) 
435     exit(1);
436   PARADYN_DEBUG (("UI thread created\n"));
437
438   msgsize = MBUFSIZE;
439   mtag = MSG_TAG_UIM_READY;
440   msg_recv(&mtag, mbuf, &msgsize);
441   msg_send (UIMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
442   uiMgr = new UIMUser (UIMtid);
443
444 // initialize PC
445
446   if (thr_create(0, 0, PCmain, (void*) &MAINtid, 0, 
447                  (unsigned int *) &PCtid) == THR_ERR)
448     exit(1);
449   PARADYN_DEBUG (("PC thread created\n"));
450
451   msgsize = MBUFSIZE;
452   mtag = MSG_TAG_PC_READY;
453   msg_recv(&mtag, mbuf, &msgsize);
454   msg_send (PCtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
455   perfConsult = new performanceConsultantUser (PCtid);
456
457 // initialize VM
458   if (thr_create(0, 0, VMmain, (void *) &MAINtid, 0, 
459                  (unsigned int *) &VMtid) == THR_ERR)
460     exit(1);
461
462   PARADYN_DEBUG (("VM thread created\n"));
463   msgsize = MBUFSIZE;
464   mtag = MSG_TAG_VM_READY;
465   msg_recv(&mtag, mbuf, &msgsize);
466   msg_send (VMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
467   vmMgr = new VMUser (VMtid);
468
469   // execute the commands in the configuration files
470   metDoTunable();
471   metDoDaemon();
472   metDoProcess();
473
474   // keep this here to prevent UI from starting up till everything's 
475   // been initialized properly!!
476   //  -OR-
477   // move this elsewhere to create a race condition
478   if (sname)
479     uiMgr->readStartupFile (sname);
480  
481 // wait for UIM thread to exit 
482
483   thr_join (UIMtid, NULL, NULL);
484
485   Tcl_DeleteInterp(interp);
486 }