2 * Copyright 1993 Jeff Hollingsworth. All rights reserved.
7 static char Copyright[] = "@(#) Copyright (c) 1993 Jeff Hollingsowrth\
10 static char rcsid[] = "@(#) $Header: /home/jaw/CVSROOT_20081103/CVSROOT/core/paradynd/src/context.C,v 1.6 1994/04/11 23:25:21 hollings Exp $";
14 * context.c - manage a performance context.
17 * Revision 1.6 1994/04/11 23:25:21 hollings
18 * Added pause_time metric.
20 * Revision 1.5 1994/04/09 18:34:51 hollings
21 * Changed {pause,continue}Application to {pause,continue}AllProceses, and
22 * made the RPC interfaces use these. This makes the computation of pause
25 * Revision 1.4 1994/03/31 01:47:54 markc
26 * Extended parameters for addProcess, which default to NULL and 0.
28 * Revision 1.3 1994/03/22 21:03:12 hollings
29 * Made it possible to add new processes (& paradynd's) via addExecutable.
31 * Revision 1.2 1994/03/20 01:53:03 markc
32 * Added a buffer to each process structure to allow for multiple writers on the
33 * traceStream. Replaced old inst-pvm.C. Changed addProcess to return type
36 * Revision 1.1 1994/01/27 20:31:15 hollings
37 * Iinital version of paradynd speaking dynRPC igend protocol.
39 * Revision 1.11 1993/12/13 19:52:40 hollings
40 * added applicationDefined
42 * Revision 1.10 1993/10/19 15:27:54 hollings
43 * AST based mini-tramp code generator.
45 * Revision 1.9 1993/10/01 21:29:41 hollings
46 * Added resource discovery and filters.
48 * Revision 1.8 1993/08/16 16:24:08 hollings
49 * added prototype for ptrace.
51 * Revision 1.7 1993/08/11 01:45:37 hollings
52 * added support for UNIX fork.
54 * Revision 1.6 1993/07/13 18:26:13 hollings
55 * new include file syntax.
57 * Revision 1.5 1993/06/28 23:13:18 hollings
58 * fixed process stopping.
60 * Revision 1.4 1993/06/24 16:18:06 hollings
63 * Revision 1.3 1993/06/22 19:00:01 hollings
66 * Revision 1.2 1993/06/08 20:14:34 hollings
67 * state prior to bc net ptrace replacement.
69 * Revision 1.1 1993/03/19 22:45:18 hollings
79 #include <sys/ptrace.h>
80 #include <sys/signal.h>
84 #include "rtinst/h/rtinst.h"
85 #include "rtinst/h/trace.h"
93 #define MILLION 1000000
95 // <sts/ptrace.h> should really define this.
98 int ptrace(enum ptracereq request,
106 * find out if we have an application defined.
108 Boolean applicationDefined()
110 if (processList.count()) {
117 static AstNode tagArg(Param, (void *) 2);
119 instMaping initialRequests[] = {
120 { "cmmd_debug", "DYNINSTnodeCreate", FUNC_ENTRY },
121 { "cmmd_debug", "DYNINSTparallelInit", FUNC_EXIT },
122 { "cmmd_debug", "DYNINSTbreakPoint", FUNC_EXIT },
123 { "main", "DYNINSTsampleValues", FUNC_EXIT },
125 { "fork", "DYNINSTfork", FUNC_EXIT|FUNC_FULL_ARGS },
127 { "exit", "DYNINSTsampleValues", FUNC_ENTRY },
128 { "exit", "DYNINSTbreakPoint", FUNC_ENTRY },
129 { "main", "DYNINSTinit", FUNC_ENTRY },
130 { "DYNINSTsampleValues", "DYNINSTreportNewTags", FUNC_ENTRY },
131 { "CMMD_send", "DYNINSTrecordTag", FUNC_ENTRY|FUNC_ARG, &tagArg },
132 { "CMMD_receive", "DYNINSTrecordTag", FUNC_ENTRY|FUNC_ARG, &tagArg },
133 { "CMMP_receive_block", "DYNINSTrecordTag", FUNC_ENTRY|FUNC_ARG, &tagArg },
134 { "CMMP_send_block", "DYNINSTrecordTag", FUNC_ENTRY|FUNC_ARG, &tagArg },
135 { "CMMP_send_async", "DYNINSTrecordTag", FUNC_ENTRY|FUNC_ARG, &tagArg },
136 { "CMMP_receive_async", "DYNINSTrecordTag", FUNC_ENTRY|FUNC_ARG, &tagArg },
137 { NULL, NULL, 0, NULL },
140 void forkProcess(traceHeader *hr, traceFork *fr)
146 struct executableRec *newExec;
148 parent = findProcess(fr->ppid);
151 /* attach to the process */
152 val = ptrace(PTRACE_ATTACH, fr->pid, 0, 0, 0);
158 sprintf(name, "%s[%d]", parent->symbols->name, fr->pid);
159 ret = allocateProcess(fr->pid, name);
160 ret->symbols = parseImage(parent->symbols->file, 0);
161 ret->traceLink = parent->traceLink;
162 ret->parent = parent;
164 copyInferriorHeap(parent, ret);
165 // installDefaultInst(ret, initialRequests);
167 newExec = (struct executableRec *) calloc(sizeof(struct executableRec), 1);
169 newExec->name = name;
170 newExec->type = selfTermination;
171 newExec->state = neonatal;
175 int addProcess(int argc, char *argv[], int nenv, char *envp[])
178 struct executableRec *newExec;
180 newExec = (struct executableRec *) calloc(sizeof(struct executableRec), 1);
182 newExec->argc = argc;
183 newExec->argv = (char **) calloc(sizeof(char *), argc+1);
184 for (i=0; i < argc; i++) {
185 newExec->argv[i] = strdup(argv[i]);
188 newExec->name = strdup(argv[0]);
189 newExec->type = selfTermination;
190 newExec->state = neonatal;
192 newExec->proc = createProcess(newExec->argv[0], newExec->argv, nenv, envp);
194 installDefaultInst(newExec->proc, initialRequests);
195 return(newExec->proc->pid);
202 Boolean detachProcess(int pid, Boolean paused)
204 struct List<process *> curr;
206 for (curr = processList; *curr; curr++) {
207 if ((*curr)->pid == pid) {
208 PCptrace(PTRACE_DETACH, *curr, (int*) 1, SIGCONT, NULL);
210 (void) kill((*curr)->pid, SIGSTOP);
211 fprintf(stderr, "deatching process %d leaving it paused\n",
219 Boolean addDataSource(char *name, char *machine,
220 char *login, char *command, int argc, char *argv[])
226 Boolean startApplication()
228 continueAllProcesses();
233 timeStamp startPause;
234 Boolean applicationPaused;
235 extern Boolean firstSampleReceived;
237 // total processor time the application has been paused.
238 // so for a multi-processor system this should be processor * time.
239 timeStamp elapsedPauseTime;
241 Boolean markApplicationPaused()
245 if (applicationPaused) return(False);
246 applicationPaused = True;
248 // get the time when we paused it.
250 gettimeofday(&tv, NULL);
251 startPause = tv.tv_sec;
252 startPause *= MILLION;
253 startPause += tv.tv_usec;
254 printf("paused at %f\n", startPause / 1000000.0);
259 Boolean isApplicationPaused()
261 return(applicationPaused);
264 Boolean continueAllProcesses()
268 struct List<process *> curr;
269 extern void computePauseTimeMetric(time64, time64, sampleValue);
271 for (curr = processList; *curr; curr++) {
272 continueProcess(*curr);
275 if (!applicationPaused) return(False);
276 applicationPaused = False;
278 gettimeofday(&tv, NULL);
279 endPause = tv.tv_sec;
281 endPause += tv.tv_usec;
283 if (!firstSampleReceived) {
287 elapsedPauseTime += (endPause - startPause);
288 printf("continued at %f\n", endPause / 1000000.0);
293 Boolean pauseAllProcesses()
296 struct List<process *> curr;
298 changed = markApplicationPaused();
299 for (curr = processList; *curr; curr++) {