XFontStruct --> Tk_Font
[dyninst.git] / paradyn / src / pdMain / main.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 /* $Log: main.C,v $
43 /* Revision 1.47  1997/04/21 16:55:52  hseom
44 /* added support for trace data
45 /*
46  * Revision 1.46  1996/11/26 16:07:20  naim
47  * Fixing asserts - naim
48  *
49  * Revision 1.45  1996/08/16 21:13:02  tamches
50  * updated copyright for release 1.1
51  *
52  * Revision 1.44  1996/08/05 07:33:03  tamches
53  * update for tcl 7.5
54  *
55  * Revision 1.43  1996/05/30 21:56:50  tamches
56  * made UIStack bigger for aix 4.1 too (had been just 3.2)
57  *
58  * Revision 1.42  1996/05/06 17:13:39  newhall
59  * changed initial value of EnableRequestPacketSize tunable constant from 2 to 10
60  *
61  * Revision 1.41  1996/04/05  21:02:39  naim
62  * Chaging default value for packet size tunable constant - naim
63  *
64  * Revision 1.40  1996/03/14  14:22:42  naim
65  * Batching enable data requests for better performance - naim
66  *
67  * Revision 1.39  1996/02/02  02:08:20  karavan
68  * moved performance consultant related tunable constant definitions to the
69  * PC thread.
70  *
71  * Revision 1.38  1996/01/29 22:12:59  mjrg
72  * Added metric propagation when new processes start
73  * Adjust time to account for clock differences between machines
74  * Daemons don't enable internal metrics when they are not running any processes
75  * Changed CM5 start (paradynd doesn't stop application at first breakpoint;
76  * the application stops only after it starts the CM5 daemon)
77  * Added -default_host option to paradyn
78  *
79  */
80
81 /*
82  * main.C - main routine for paradyn.  
83  *   This routine creates DM, UIM, VM, and PC threads.
84  */
85
86 #include "tcl.h"
87 #include "tk.h"
88
89 #include "../TCthread/tunableConst.h"
90 #include "util/h/headers.h"
91 #include "paradyn.h"
92 #include "thread/h/thread.h"
93 #include "dataManager.thread.SRVR.h"
94 #include "VM.thread.SRVR.h"
95 #include "../UIthread/tkTools.h" // tclpanic
96 #include "util/h/makenan.h"
97 #include "paradyn/src/DMthread/BufferPool.h"
98 #include "paradyn/src/DMthread/DVbufferpool.h"
99
100 // trace data streams
101 BufferPool<traceDataValueType>  tracedatavalues_bufferpool;
102
103 // maybe this should be a thread, but for now it's a global var.
104 BufferPool<dataValueType>  datavalues_bufferpool;
105
106
107 extern void *UImain(void *);
108 extern void *DMmain(void *);
109 extern void *PCmain(void *);
110 extern void *VMmain (void *);
111
112 #define MBUFSIZE 256
113 #define DEBUGBUFSIZE    4096
114
115 thread_t UIMtid;
116 thread_t MAINtid;
117 thread_t PCtid;
118 thread_t DMtid;
119 thread_t VMtid;
120 //thread_t TCtid; // tunable constants
121
122 // expanded stack by a factor of 10 to support AIX - jkh 8/14/95
123 // wrapped it in an ifdef so others don't pay the price --ari 10/95
124 #if defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1)
125 char UIStack[327680];
126 #else
127 char UIStack[32768];
128 #endif
129
130 // applicationContext *context;
131 dataManagerUser *dataMgr;
132 performanceConsultantUser *perfConsult;
133 UIMUser *uiMgr;
134 VMUser  *vmMgr;
135 int paradyn_debug=0;
136 char debug_buf[DEBUGBUFSIZE];
137
138 // default_host defines the host where programs run when no host is
139 // specified in a PCL process definition, or in the process definition window.
140 string default_host;
141
142
143 #define PRINT_DEBUG_MACRO                               \
144 do {                                                    \
145         va_list args;                                   \
146         va_start(args,format);                          \
147         (void) fflush(stdout);                          \
148         (void) vsprintf(debug_buf, format, args);       \
149         (void) fprintf(stdout,"THREAD %d: %s\n",        \
150                thr_self(), debug_buf);                  \
151         (void) fflush(stdout);                          \
152         va_end(args);                                   \
153 } while (0)
154
155 void print_debug_macro(const char* format, ...){
156   if(paradyn_debug > 0)
157      PRINT_DEBUG_MACRO;
158   return;
159 }
160
161 void eFunction(int errno, char *message)
162 {
163     printf("error #%d: %s\b", errno, message);
164     abort();
165 }
166
167 extern bool metDoTunable();
168 extern bool metDoProcess();
169 extern bool metMain(string&);
170 extern bool metDoProcess();
171 extern bool metDoDaemon();
172
173 Tcl_Interp *interp;
174 int         tty;
175
176 bool inDeveloperMode = false; // global variable used elsewhere
177 void develModeCallback(bool newValue) {
178    inDeveloperMode = newValue;
179
180    // plus any other necessary action...
181    // The shg wants to hear of such changes, so it can resize its
182    // status line (w/in the shg window) appropriately
183    extern void shgDevelModeChange(Tcl_Interp *, bool);
184    shgDevelModeChange(interp, inDeveloperMode);
185 }
186
187 int
188 main (int argc, char **argv)
189 {
190   char mbuf[MBUFSIZE];
191   unsigned int msgsize;
192   tag_t mtag;
193   char *temp=NULL;
194
195   // Initialize tcl/tk
196   interp = Tcl_CreateInterp();
197   assert(interp);
198
199   tty = isatty(0);
200   Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
201
202   if (Tcl_Init(interp) == TCL_ERROR)
203      tclpanic(interp, "tcl_init() failed (perhaps TCL_LIBRARY not set?)");
204   if (Tk_Init(interp) == TCL_ERROR)
205      tclpanic(interp, "tk_init() failed (perhaps TK_LIBRARY not set?)");
206 //  if (Tix_Init(interp) == TCL_ERROR)
207 //     tclpanic(interp, "tix_init() failed (perhaps TIX_LIBRARY not set?");
208
209   // copy command-line arguments into tcl vrbles argc / argv
210   char *args = Tcl_Merge(argc - 1, (const char **) (argv + 1));
211   Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
212   ckfree(args);
213
214   string argcStr = string(argc - 1);
215   Tcl_SetVar(interp, "argc", argcStr.string_of(), TCL_GLOBAL_ONLY);
216   Tcl_SetVar(interp, "argv0", argv[0], TCL_GLOBAL_ONLY);
217
218   // Here is one tunable constant that is definitely intended to be hard-coded in:
219    tunableBooleanConstantDeclarator tcInDeveloperMode("developerMode",
220          "Allow access to all tunable constants, including those limited to developer mode.  (Use with caution)",
221          false, // initial value
222          develModeCallback,
223          userConstant);
224
225     tunableConstantRegistry::createFloatTunableConstant
226     ("EnableRequestPacketSize",
227      "Enable request packet size",
228      NULL,
229      developerConstant,
230      10.0, // initial value
231      1.0,  // min
232      100.0); // max
233
234   //
235   // We check our own read/write events.
236   //
237   P_signal(SIGPIPE, (P_sig_handler) SIG_IGN);
238
239   // get paradyn_debug environment var PARADYNDEBUG, if its value
240   // is > 1, then PARADYN_DEBUG msgs will be printed to stdout
241   temp = (char *) getenv("PARADYNDEBUG");
242   if (temp != NULL) {
243     paradyn_debug = atoi(temp);
244   }
245   else {
246     paradyn_debug = 0;
247   }
248
249 // parse the command line arguments
250   int a_ct=1;
251   char *fname=0, *sname=0;
252   while (argv[a_ct]) {
253     if (fname == 0 && !strcmp(argv[a_ct], "-f") && argv[a_ct+1]) {
254       fname = argv[++a_ct];
255     } else if (sname == 0 && !strcmp(argv[a_ct], "-s") && argv[a_ct+1]) {
256       sname = argv[++a_ct];
257     } else if (!default_host.length() && (!strcmp(argv[a_ct], "-default_host") || !strcmp(argv[a_ct], "-d")) && argv[a_ct+1]) {
258       default_host = argv[++a_ct];
259     } else {
260       printf("usage: %s [-f <pcl_filename>] [-s <tcl_scriptname>] [-default_host <hostname>]\n", argv[0]);
261       exit(-1);
262     }
263     a_ct++;
264   }
265
266   // initialize default host here, if it was not defined in a command line argument
267   if (!default_host.length()) {
268     struct utsname un;
269     P_uname(&un);
270     default_host = un.nodename;
271   }
272
273 // get tid of parent
274   MAINtid = thr_self();
275
276 // Structure used to pass initial arguments to data manager
277 //  init_struct init; init.tid = MAINtid; init.met_file = fname;
278
279 // call sequential initialization routines
280   if(!dataManager::DM_sequential_init(fname)) {
281     printf("Error found in Paradyn Configuration File, exiting\n");
282     exit(-1);
283   }
284   VM::VM_sequential_init(); 
285
286
287      /* initialize the 4 main threads of paradyn: data manager, visi manager,
288         user interface manager, performance consultant */
289   
290 // initialize DM
291
292   if (thr_create(0, 0, DMmain, (void *) &MAINtid, 0, 
293                  (unsigned int *) &DMtid) == THR_ERR)
294     exit(1);
295   PARADYN_DEBUG (("DM thread created\n"));
296
297   msgsize = MBUFSIZE;
298   mtag = MSG_TAG_DM_READY;
299   msg_recv(&mtag, mbuf, &msgsize);
300   msg_send (DMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
301   dataMgr = new dataManagerUser (DMtid);
302   // context = dataMgr->createApplicationContext(eFunction);
303
304 // initialize UIM 
305  
306   if (thr_create (UIStack, sizeof(UIStack), &UImain, NULL,
307                   0, &UIMtid) == THR_ERR) 
308     exit(1);
309   PARADYN_DEBUG (("UI thread created\n"));
310
311   msgsize = MBUFSIZE;
312   mtag = MSG_TAG_UIM_READY;
313   msg_recv(&mtag, mbuf, &msgsize);
314   msg_send (UIMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
315   uiMgr = new UIMUser (UIMtid);
316
317 // initialize PC
318
319   if (thr_create(0, 0, PCmain, (void*) &MAINtid, 0, 
320                  (unsigned int *) &PCtid) == THR_ERR)
321     exit(1);
322   PARADYN_DEBUG (("PC thread created\n"));
323
324   msgsize = MBUFSIZE;
325   mtag = MSG_TAG_PC_READY;
326   msg_recv(&mtag, mbuf, &msgsize);
327   msg_send (PCtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
328   perfConsult = new performanceConsultantUser (PCtid);
329
330 // initialize VM
331   if (thr_create(0, 0, VMmain, (void *) &MAINtid, 0, 
332                  (unsigned int *) &VMtid) == THR_ERR)
333     exit(1);
334
335   PARADYN_DEBUG (("VM thread created\n"));
336   msgsize = MBUFSIZE;
337   mtag = MSG_TAG_VM_READY;
338   msg_recv(&mtag, mbuf, &msgsize);
339   msg_send (VMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
340   vmMgr = new VMUser (VMtid);
341
342   // execute the commands in the configuration files
343   metDoTunable();
344   metDoDaemon();
345   metDoProcess();
346
347   // keep this here to prevent UI from starting up till everything's 
348   // been initialized properly!!
349   //  -OR-
350   // move this elsewhere to create a race condition
351   if (sname)
352     uiMgr->readStartupFile (sname);
353  
354 // wait for UIM thread to exit 
355
356   thr_join (UIMtid, NULL, NULL);
357
358   Tcl_DeleteInterp(interp);
359 }