/* * Copyright (c) 1996 Barton P. Miller * * We provide the Paradyn Parallel Performance Tools (below * described as Paradyn") on an AS IS basis, and do not warrant its * validity or performance. We reserve the right to update, modify, * or discontinue this software at any time. We shall have no * obligation to supply such updates or modifications or any other * form of support to you. * * This license is for research uses. For such uses, there is no * charge. We define "research use" to mean you may freely use it * inside your organization for whatever purposes you see fit. But you * may not re-distribute Paradyn or parts of Paradyn, in any form * source or binary (including derivatives), electronic or otherwise, * to any other organization or entity without our permission. * * (for other uses, please contact us at paradyn@cs.wisc.edu) * * All warranties, including without limitation, any warranty of * merchantability or fitness for a particular purpose, are hereby * excluded. * * By your use of Paradyn, you understand and agree that we (or any * other person or entity with proprietary rights in Paradyn) are * under no obligation to provide either maintenance services, * update services, notices of latent defects, or correction of * defects for Paradyn. * * Even if advised of the possibility of such damages, under no * circumstances shall we (or any other person or entity with * proprietary rights in the software licensed hereunder) be liable * to you or any third party for direct, indirect, or consequential * damages of any character regardless of type of action, including, * without limitation, loss of profits, loss of use, loss of good * will, or computer failure or malfunction. You agree to indemnify * us (and any other person or entity with proprietary rights in the * software licensed hereunder) for any and all liability it may * incur to third parties resulting from your use of Paradyn. */ /* $Log: main.C,v $ /* Revision 1.47 1997/04/21 16:55:52 hseom /* added support for trace data /* * Revision 1.46 1996/11/26 16:07:20 naim * Fixing asserts - naim * * Revision 1.45 1996/08/16 21:13:02 tamches * updated copyright for release 1.1 * * Revision 1.44 1996/08/05 07:33:03 tamches * update for tcl 7.5 * * Revision 1.43 1996/05/30 21:56:50 tamches * made UIStack bigger for aix 4.1 too (had been just 3.2) * * Revision 1.42 1996/05/06 17:13:39 newhall * changed initial value of EnableRequestPacketSize tunable constant from 2 to 10 * * Revision 1.41 1996/04/05 21:02:39 naim * Chaging default value for packet size tunable constant - naim * * Revision 1.40 1996/03/14 14:22:42 naim * Batching enable data requests for better performance - naim * * Revision 1.39 1996/02/02 02:08:20 karavan * moved performance consultant related tunable constant definitions to the * PC thread. * * Revision 1.38 1996/01/29 22:12:59 mjrg * Added metric propagation when new processes start * Adjust time to account for clock differences between machines * Daemons don't enable internal metrics when they are not running any processes * Changed CM5 start (paradynd doesn't stop application at first breakpoint; * the application stops only after it starts the CM5 daemon) * Added -default_host option to paradyn * */ /* * main.C - main routine for paradyn. * This routine creates DM, UIM, VM, and PC threads. */ #include "tcl.h" #include "tk.h" #include "../TCthread/tunableConst.h" #include "util/h/headers.h" #include "paradyn.h" #include "thread/h/thread.h" #include "dataManager.thread.SRVR.h" #include "VM.thread.SRVR.h" #include "../UIthread/tkTools.h" // tclpanic #include "util/h/makenan.h" #include "paradyn/src/DMthread/BufferPool.h" #include "paradyn/src/DMthread/DVbufferpool.h" // trace data streams BufferPool tracedatavalues_bufferpool; // maybe this should be a thread, but for now it's a global var. BufferPool datavalues_bufferpool; extern void *UImain(void *); extern void *DMmain(void *); extern void *PCmain(void *); extern void *VMmain (void *); #define MBUFSIZE 256 #define DEBUGBUFSIZE 4096 thread_t UIMtid; thread_t MAINtid; thread_t PCtid; thread_t DMtid; thread_t VMtid; //thread_t TCtid; // tunable constants // expanded stack by a factor of 10 to support AIX - jkh 8/14/95 // wrapped it in an ifdef so others don't pay the price --ari 10/95 #if defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1) char UIStack[327680]; #else char UIStack[32768]; #endif // applicationContext *context; dataManagerUser *dataMgr; performanceConsultantUser *perfConsult; UIMUser *uiMgr; VMUser *vmMgr; int paradyn_debug=0; char debug_buf[DEBUGBUFSIZE]; // default_host defines the host where programs run when no host is // specified in a PCL process definition, or in the process definition window. string default_host; #define PRINT_DEBUG_MACRO \ do { \ va_list args; \ va_start(args,format); \ (void) fflush(stdout); \ (void) vsprintf(debug_buf, format, args); \ (void) fprintf(stdout,"THREAD %d: %s\n", \ thr_self(), debug_buf); \ (void) fflush(stdout); \ va_end(args); \ } while (0) void print_debug_macro(const char* format, ...){ if(paradyn_debug > 0) PRINT_DEBUG_MACRO; return; } void eFunction(int errno, char *message) { printf("error #%d: %s\b", errno, message); abort(); } extern bool metDoTunable(); extern bool metDoProcess(); extern bool metMain(string&); extern bool metDoProcess(); extern bool metDoDaemon(); Tcl_Interp *interp; int tty; bool inDeveloperMode = false; // global variable used elsewhere void develModeCallback(bool newValue) { inDeveloperMode = newValue; // plus any other necessary action... // The shg wants to hear of such changes, so it can resize its // status line (w/in the shg window) appropriately extern void shgDevelModeChange(Tcl_Interp *, bool); shgDevelModeChange(interp, inDeveloperMode); } int main (int argc, char **argv) { char mbuf[MBUFSIZE]; unsigned int msgsize; tag_t mtag; char *temp=NULL; // Initialize tcl/tk interp = Tcl_CreateInterp(); assert(interp); tty = isatty(0); Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); if (Tcl_Init(interp) == TCL_ERROR) tclpanic(interp, "tcl_init() failed (perhaps TCL_LIBRARY not set?)"); if (Tk_Init(interp) == TCL_ERROR) tclpanic(interp, "tk_init() failed (perhaps TK_LIBRARY not set?)"); // if (Tix_Init(interp) == TCL_ERROR) // tclpanic(interp, "tix_init() failed (perhaps TIX_LIBRARY not set?"); // copy command-line arguments into tcl vrbles argc / argv char *args = Tcl_Merge(argc - 1, (const char **) (argv + 1)); Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY); ckfree(args); string argcStr = string(argc - 1); Tcl_SetVar(interp, "argc", argcStr.string_of(), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "argv0", argv[0], TCL_GLOBAL_ONLY); // Here is one tunable constant that is definitely intended to be hard-coded in: tunableBooleanConstantDeclarator tcInDeveloperMode("developerMode", "Allow access to all tunable constants, including those limited to developer mode. (Use with caution)", false, // initial value develModeCallback, userConstant); tunableConstantRegistry::createFloatTunableConstant ("EnableRequestPacketSize", "Enable request packet size", NULL, developerConstant, 10.0, // initial value 1.0, // min 100.0); // max // // We check our own read/write events. // P_signal(SIGPIPE, (P_sig_handler) SIG_IGN); // get paradyn_debug environment var PARADYNDEBUG, if its value // is > 1, then PARADYN_DEBUG msgs will be printed to stdout temp = (char *) getenv("PARADYNDEBUG"); if (temp != NULL) { paradyn_debug = atoi(temp); } else { paradyn_debug = 0; } // parse the command line arguments int a_ct=1; char *fname=0, *sname=0; while (argv[a_ct]) { if (fname == 0 && !strcmp(argv[a_ct], "-f") && argv[a_ct+1]) { fname = argv[++a_ct]; } else if (sname == 0 && !strcmp(argv[a_ct], "-s") && argv[a_ct+1]) { sname = argv[++a_ct]; } else if (!default_host.length() && (!strcmp(argv[a_ct], "-default_host") || !strcmp(argv[a_ct], "-d")) && argv[a_ct+1]) { default_host = argv[++a_ct]; } else { printf("usage: %s [-f ] [-s ] [-default_host ]\n", argv[0]); exit(-1); } a_ct++; } // initialize default host here, if it was not defined in a command line argument if (!default_host.length()) { struct utsname un; P_uname(&un); default_host = un.nodename; } // get tid of parent MAINtid = thr_self(); // Structure used to pass initial arguments to data manager // init_struct init; init.tid = MAINtid; init.met_file = fname; // call sequential initialization routines if(!dataManager::DM_sequential_init(fname)) { printf("Error found in Paradyn Configuration File, exiting\n"); exit(-1); } VM::VM_sequential_init(); /* initialize the 4 main threads of paradyn: data manager, visi manager, user interface manager, performance consultant */ // initialize DM if (thr_create(0, 0, DMmain, (void *) &MAINtid, 0, (unsigned int *) &DMtid) == THR_ERR) exit(1); PARADYN_DEBUG (("DM thread created\n")); msgsize = MBUFSIZE; mtag = MSG_TAG_DM_READY; msg_recv(&mtag, mbuf, &msgsize); msg_send (DMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0); dataMgr = new dataManagerUser (DMtid); // context = dataMgr->createApplicationContext(eFunction); // initialize UIM if (thr_create (UIStack, sizeof(UIStack), &UImain, NULL, 0, &UIMtid) == THR_ERR) exit(1); PARADYN_DEBUG (("UI thread created\n")); msgsize = MBUFSIZE; mtag = MSG_TAG_UIM_READY; msg_recv(&mtag, mbuf, &msgsize); msg_send (UIMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0); uiMgr = new UIMUser (UIMtid); // initialize PC if (thr_create(0, 0, PCmain, (void*) &MAINtid, 0, (unsigned int *) &PCtid) == THR_ERR) exit(1); PARADYN_DEBUG (("PC thread created\n")); msgsize = MBUFSIZE; mtag = MSG_TAG_PC_READY; msg_recv(&mtag, mbuf, &msgsize); msg_send (PCtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0); perfConsult = new performanceConsultantUser (PCtid); // initialize VM if (thr_create(0, 0, VMmain, (void *) &MAINtid, 0, (unsigned int *) &VMtid) == THR_ERR) exit(1); PARADYN_DEBUG (("VM thread created\n")); msgsize = MBUFSIZE; mtag = MSG_TAG_VM_READY; msg_recv(&mtag, mbuf, &msgsize); msg_send (VMtid, MSG_TAG_ALL_CHILDREN_READY, (char *) NULL, 0); vmMgr = new VMUser (VMtid); // execute the commands in the configuration files metDoTunable(); metDoDaemon(); metDoProcess(); // keep this here to prevent UI from starting up till everything's // been initialized properly!! // -OR- // move this elsewhere to create a race condition if (sname) uiMgr->readStartupFile (sname); // wait for UIM thread to exit thr_join (UIMtid, NULL, NULL); Tcl_DeleteInterp(interp); }