Commit | Line | Data |
---|---|---|
e0f018be KM |
1 | /* Copyright (c) 1979 Regents of the University of California */ |
2 | ||
8fe8ed0d | 3 | static char sccsid[] = "@(#)utilities.c 1.5 %G%"; |
e0f018be | 4 | |
8fe8ed0d | 5 | #include <signal.h> |
9a92014d | 6 | #include "whoami.h" |
e0f018be | 7 | #include "vars.h" |
e0f018be KM |
8 | #include "h02opcs.h" |
9 | ||
10 | stats() | |
11 | { | |
12 | struct { | |
13 | long usr_time; | |
14 | long sys_time; | |
15 | long child_usr_time; | |
16 | long child_sys_time; | |
15834a19 | 17 | } tbuf; |
e0f018be KM |
18 | register double l; |
19 | register long count; | |
15834a19 KM |
20 | # ifdef PROFILE |
21 | # define proffile "/vb/grad/mckusick/px/profile/pcnt.out" | |
22 | struct cntrec { | |
23 | double counts[NUMOPS]; /* instruction counts */ | |
24 | long runs; /* number of interpreter runs */ | |
25 | long startdate; /* date profile started */ | |
26 | long usrtime; /* total user time consumed */ | |
27 | long systime; /* total system time consumed */ | |
28 | double stmts; /* number of pascal stmts executed */ | |
29 | } profdata; | |
30 | FILE *datafile; | |
31 | # endif PROFILE | |
e0f018be KM |
32 | |
33 | if (_nodump) | |
34 | return(0); | |
35 | times(&tbuf); | |
15834a19 | 36 | # ifdef PROFILE |
e0f018be | 37 | datafile = fopen(proffile,"r"); |
15834a19 KM |
38 | if (datafile == NULL) |
39 | goto skipprof; | |
40 | count = fread(&profdata,1,sizeof(profdata),datafile); | |
41 | if (count != sizeof(profdata)) | |
42 | goto skipprof; | |
43 | for (count = 0; count < NUMOPS; count++) | |
44 | profdata.counts[count] += _profcnts[count]; | |
45 | profdata.runs += 1; | |
46 | profdata.stmts += _stcnt; | |
47 | profdata.usrtime += tbuf.usr_time; | |
48 | profdata.systime += tbuf.sys_time; | |
49 | datafile = freopen(proffile,"w",datafile); | |
50 | if (datafile == NULL) | |
51 | goto skipprof; | |
52 | count = fwrite(&profdata,1,sizeof(profdata),datafile); | |
53 | if (count != sizeof(profdata)) | |
54 | goto skipprof; | |
55 | fclose(datafile); | |
56 | skipprof: | |
57 | # endif PROFILE | |
e0f018be KM |
58 | l = tbuf.usr_time; |
59 | l = l / HZ; | |
60 | fprintf(stderr, | |
61 | "\n%1ld statements executed in %04.2f seconds cpu time.\n", | |
62 | _stcnt,l); | |
63 | } | |
64 | \f | |
8fe8ed0d KM |
65 | backtrace(type) |
66 | char *type; | |
e0f018be KM |
67 | { |
68 | register struct disp *mydp; | |
69 | register struct stack *ap; | |
70 | register char *cp; | |
71 | register long i, linum; | |
15834a19 | 72 | struct disply disp; |
e0f018be KM |
73 | |
74 | if (_lino <= 0) { | |
75 | fputs("Program was not executed.\n",stderr); | |
76 | return; | |
77 | } | |
15834a19 | 78 | disp = _display; |
8fe8ed0d | 79 | fprintf(stderr, "\n\t%s in \"", type); |
e0f018be KM |
80 | mydp = _dp; |
81 | linum = _lino; | |
82 | for (;;) { | |
83 | ap = mydp->stp; | |
84 | i = linum - (((ap)->entry)->offset & 0177777); | |
85 | fprintf(stderr,"%s\"",(ap->entry)->name); | |
d1c0bd16 | 86 | if (_nodump == FALSE) |
9a92014d | 87 | fprintf(stderr,"+%D near line %D.",i,linum); |
e0f018be KM |
88 | fputc('\n',stderr); |
89 | *mydp = (ap)->odisp; | |
15834a19 KM |
90 | if (mydp <= &_display.frame[1]){ |
91 | _display = disp; | |
8fe8ed0d | 92 | return; |
e0f018be KM |
93 | } |
94 | mydp = (ap)->dp; | |
95 | linum = (ap)->lino; | |
96 | fputs("\tCalled by \"",stderr); | |
97 | } | |
98 | } | |
99 | \f | |
100 | psexit(code) | |
101 | ||
9a92014d | 102 | int code; |
e0f018be KM |
103 | { |
104 | if (_pcpcount != 0) | |
105 | PMFLUSH(_cntrs, _rtns, _pcpcount); | |
106 | if (_mode == PIX) { | |
107 | fputs("Execution terminated",stderr); | |
108 | if (code) | |
109 | fputs(" abnormally",stderr); | |
110 | fputc('.',stderr); | |
111 | fputc('\n',stderr); | |
112 | } | |
113 | stats(); | |
114 | exit(code); | |
115 | } | |
8fe8ed0d KM |
116 | |
117 | /* | |
118 | * Routines to field various types of signals | |
119 | * | |
120 | * catch a library error and generate a backtrace | |
121 | */ | |
122 | liberr() | |
123 | { | |
124 | backtrace("Error"); | |
125 | psexit(2); | |
126 | } | |
127 | ||
128 | /* | |
129 | * catch an interrupt and generate a backtrace | |
130 | */ | |
131 | intr() | |
132 | { | |
133 | signal(SIGINT, intr); | |
134 | backtrace("Interrupted"); | |
135 | psexit(1); | |
136 | } | |
137 | ||
138 | /* | |
139 | * catch memory faults | |
140 | */ | |
141 | memsize() | |
142 | { | |
143 | signal(SIGSEGV, memsize); | |
144 | ERROR("Run time stack overflow\n"); | |
145 | } | |
146 | ||
147 | /* | |
148 | * catch random system faults | |
149 | */ | |
150 | syserr(signum) | |
151 | int signum; | |
152 | { | |
153 | signal(signum, syserr); | |
154 | ERROR("Panic: Computational error in interpreter\n"); | |
155 | } |