Changed uname to "wrapped" getHostName
[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 // $Id: main.C,v 1.49 1998/04/06 04:22:37 wylie Exp $
43
44 /*
45  * main.C - main routine for paradyn.  
46  *   This routine creates DM, UIM, VM, and PC threads.
47  */
48
49 #include "tcl.h"
50 #include "tk.h"
51
52 #include "../TCthread/tunableConst.h"
53 #include "util/h/headers.h"
54 #include "paradyn.h"
55 #include "thread/h/thread.h"
56 #include "dataManager.thread.SRVR.h"
57 #include "VM.thread.SRVR.h"
58 #include "../UIthread/tkTools.h" // tclpanic
59 #include "util/h/makenan.h"
60 #include "paradyn/src/DMthread/BufferPool.h"
61 #include "paradyn/src/DMthread/DVbufferpool.h"
62
63 // trace data streams
64 BufferPool<traceDataValueType>  tracedatavalues_bufferpool;
65
66 // maybe this should be a thread, but for now it's a global var.
67 BufferPool<dataValueType>  datavalues_bufferpool;
68
69
70 extern void *UImain(void *);
71 extern void *DMmain(void *);
72 extern void *PCmain(void *);
73 extern void *VMmain (void *);
74
75 #define MBUFSIZE 256
76 #define DEBUGBUFSIZE    4096
77
78 thread_t UIMtid;
79 thread_t MAINtid;
80 thread_t PCtid;
81 thread_t DMtid;
82 thread_t VMtid;
83 //thread_t TCtid; // tunable constants
84
85 // expanded stack by a factor of 10 to support AIX - jkh 8/14/95
86 // wrapped it in an ifdef so others don't pay the price --ari 10/95
87 #if defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1)
88 char UIStack[327680];
89 #else
90 char UIStack[32768];
91 #endif
92
93 // applicationContext *context;
94 dataManagerUser *dataMgr;
95 performanceConsultantUser *perfConsult;
96 UIMUser *uiMgr;
97 VMUser  *vmMgr;
98 int paradyn_debug=0;
99 char debug_buf[DEBUGBUFSIZE];
100
101 // default_host defines the host where programs run when no host is
102 // specified in a PCL process definition, or in the process definition window.
103 string default_host;
104
105
106 #define PRINT_DEBUG_MACRO                               \
107 do {                                                    \
108         va_list args;                                   \
109         va_start(args,format);                          \
110         (void) fflush(stdout);                          \
111         (void) vsprintf(debug_buf, format, args);       \
112         (void) fprintf(stdout,"THREAD %d: %s\n",        \
113                thr_self(), debug_buf);                  \
114         (void) fflush(stdout);                          \
115         va_end(args);                                   \
116 } while (0)
117
118 void print_debug_macro(const char* format, ...){
119   if(paradyn_debug > 0)
120      PRINT_DEBUG_MACRO;
121   return;
122 }
123
124 void eFunction(int errno, char *message)
125 {
126     printf("error #%d: %s\b", errno, message);
127     abort();
128 }
129
130 //extern bool metMain(string&);
131 extern bool metDoTunable();
132 extern bool metDoProcess();
133 extern bool metDoDaemon();
134
135 Tcl_Interp *interp;
136 int         tty;
137
138 bool inDeveloperMode = false; // global variable used elsewhere
139 void develModeCallback(bool newValue) {
140    inDeveloperMode = newValue;
141
142    // plus any other necessary action...
143    // The shg wants to hear of such changes, so it can resize its
144    // status line (w/in the shg window) appropriately
145    extern void shgDevelModeChange(Tcl_Interp *, bool);
146    shgDevelModeChange(interp, inDeveloperMode);
147 }
148
149 int
150 main (int argc, char **argv)
151 {
152   char mbuf[MBUFSIZE];
153   unsigned int msgsize;
154   tag_t mtag;
155   char *temp=NULL;
156
157   // Initialize tcl/tk
158   interp = Tcl_CreateInterp();
159   assert(interp);
160
161   tty = isatty(0);
162   Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
163
164   if (Tcl_Init(interp) == TCL_ERROR)
165      tclpanic(interp, "tcl_init() failed (perhaps TCL_LIBRARY not set?)");
166   if (Tk_Init(interp) == TCL_ERROR)
167      tclpanic(interp, "tk_init() failed (perhaps TK_LIBRARY not set?)");
168 //  if (Tix_Init(interp) == TCL_ERROR)
169 //     tclpanic(interp, "tix_init() failed (perhaps TIX_LIBRARY not set?");
170
171   // copy command-line arguments into tcl vrbles argc / argv
172   char *args = Tcl_Merge(argc - 1, (const char **) (argv + 1));
173   Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
174   ckfree(args);
175
176   string argcStr = string(argc - 1);
177   Tcl_SetVar(interp, "argc", argcStr.string_of(), TCL_GLOBAL_ONLY);
178   Tcl_SetVar(interp, "argv0", argv[0], TCL_GLOBAL_ONLY);
179
180   // Here is one tunable constant that is definitely intended to be hard-coded in:
181    tunableBooleanConstantDeclarator tcInDeveloperMode("developerMode",
182          "Allow access to all tunable constants, including those limited to developer mode.  (Use with caution)",
183          false, // initial value
184          develModeCallback,
185          userConstant);
186
187     tunableConstantRegistry::createFloatTunableConstant
188     ("EnableRequestPacketSize",
189      "Enable request packet size",
190      NULL,
191      developerConstant,
192      10.0, // initial value
193      1.0,  // min
194      100.0); // max
195
196   //
197   // We check our own read/write events.
198   //
199   P_signal(SIGPIPE, (P_sig_handler) SIG_IGN);
200
201   // get paradyn_debug environment var PARADYNDEBUG, if its value
202   // is > 1, then PARADYN_DEBUG msgs will be printed to stdout
203   temp = (char *) getenv("PARADYNDEBUG");
204   if (temp != NULL) {
205     paradyn_debug = atoi(temp);
206   }
207   else {
208     paradyn_debug = 0;
209   }
210
211 // parse the command line arguments
212   int a_ct=1;
213   char *fname=0, *sname=0, *xname=0;
214   while (argv[a_ct]) {
215     if (fname == 0 && !strcmp(argv[a_ct], "-f") && argv[a_ct+1]) {
216       fname = argv[++a_ct];
217     } else if (sname == 0 && !strcmp(argv[a_ct], "-s") && argv[a_ct+1]) {
218       sname = argv[++a_ct];
219     } else if (xname == 0 && !strcmp(argv[a_ct], "-x") && argv[a_ct+1]) {
220       xname = argv[++a_ct];
221     } else if (!default_host.length() && (!strcmp(argv[a_ct], "-default_host") || !strcmp(argv[a_ct], "-d")) && argv[a_ct+1]) {
222       default_host = argv[++a_ct];
223     } else {
224       printf("usage: %s [-f <pcl_filename>] [-s <tcl_scriptname>]"
225                       " [-x <connect_filename>] [-default_host <hostname>]\n",
226                  argv[0]);
227       exit(-1);
228     }
229     a_ct++;
230   }
231
232   // initialize default host here, if it was not defined in a command line argument
233   if (!default_host.length()) {
234     default_host = getHostName();
235   }
236
237 // get tid of parent
238   MAINtid = thr_self();
239
240 // Structure used to pass initial arguments to data manager
241 //  init_struct init; init.tid = MAINtid; init.met_file = fname;
242
243 // call sequential initialization routines
244   if(!dataManager::DM_sequential_init(fname)) {
245     printf("Error found in Paradyn Configuration File, exiting\n");
246     exit(-1);
247   }
248   VM::VM_sequential_init(); 
249
250
251      /* initialize the 4 main threads of paradyn: data manager, visi manager,
252         user interface manager, performance consultant */
253   
254 // initialize DM
255
256   if (thr_create(0, 0, DMmain, (void *) &MAINtid, 0, 
257                  (unsigned int *) &DMtid) == THR_ERR)
258     exit(1);
259   PARADYN_DEBUG (("DM thread created\n"));
260
261   msgsize = MBUFSIZE;
262   mtag = MSG_TAG_DM_READY;
263   msg_recv(&mtag, mbuf, &msgsize);
264   msg_send (DMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
265   dataMgr = new dataManagerUser (DMtid);
266   // context = dataMgr->createApplicationContext(eFunction);
267
268 // initialize UIM 
269  
270   if (thr_create (UIStack, sizeof(UIStack), &UImain, NULL,
271                   0, &UIMtid) == THR_ERR) 
272     exit(1);
273   PARADYN_DEBUG (("UI thread created\n"));
274
275   msgsize = MBUFSIZE;
276   mtag = MSG_TAG_UIM_READY;
277   msg_recv(&mtag, mbuf, &msgsize);
278   msg_send (UIMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
279   uiMgr = new UIMUser (UIMtid);
280
281 // initialize PC
282
283   if (thr_create(0, 0, PCmain, (void*) &MAINtid, 0, 
284                  (unsigned int *) &PCtid) == THR_ERR)
285     exit(1);
286   PARADYN_DEBUG (("PC thread created\n"));
287
288   msgsize = MBUFSIZE;
289   mtag = MSG_TAG_PC_READY;
290   msg_recv(&mtag, mbuf, &msgsize);
291   msg_send (PCtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
292   perfConsult = new performanceConsultantUser (PCtid);
293
294 // initialize VM
295   if (thr_create(0, 0, VMmain, (void *) &MAINtid, 0, 
296                  (unsigned int *) &VMtid) == THR_ERR)
297     exit(1);
298
299   PARADYN_DEBUG (("VM thread created\n"));
300   msgsize = MBUFSIZE;
301   mtag = MSG_TAG_VM_READY;
302   msg_recv(&mtag, mbuf, &msgsize);
303   msg_send (VMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0);
304   vmMgr = new VMUser (VMtid);
305
306   // execute the commands in the configuration files
307   metDoTunable();
308   metDoDaemon();
309   metDoProcess();
310
311   // keep this here to prevent UI from starting up till everything's 
312   // been initialized properly!!
313   //  -OR-
314   // move this elsewhere to create a race condition
315   if (sname)
316     uiMgr->readStartupFile (sname);
317  
318   if (xname)
319     dataMgr->printDaemonStartInfo (xname);
320
321 // wait for UIM thread to exit 
322
323   thr_join (UIMtid, NULL, NULL);
324
325   Tcl_DeleteInterp(interp);
326 }