-
Notifications
You must be signed in to change notification settings - Fork 9
/
test-app.c
173 lines (149 loc) · 4.81 KB
/
test-app.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
* test-trans.c - Checks the correctness and performance of all of the
* student's transpose functions and records the results for their
* official submitted version as well.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <getopt.h>
#include <sys/types.h>
#include "cachelab.h"
#include <sys/wait.h> // fir WEXITSTATUS
#include <limits.h> // for INT_MAX
/*
* eval_perf - Evaluate the performance of the registered transpose functions
*/
void eval_perf(unsigned int s, unsigned int E, unsigned int b, char *app_cmd)
{
int flag;
unsigned int len;
unsigned long long int marker_start, marker_end, addr;
char buf[1000], cmd[255];
char filename[128];
/* Open the complete trace file */
FILE* full_trace_fp;
FILE* part_trace_fp;
/* Evaluate the performance of bfs function */
printf("\nStep 1: Validating and generating memory traces\n");
/* Use valgrind to generate the trace */
sprintf(cmd, "valgrind --tool=lackey --trace-mem=yes --log-fd=1 -v %s > trace.tmp", app_cmd);
flag=WEXITSTATUS(system(cmd));
if (0!=flag) {
printf("Validation error.\nSkipping performance evaluation for this function.\n");
exit(1);
}
/* Get the start and end marker addresses */
FILE* marker_fp = fopen(".marker", "r");
assert(marker_fp);
fscanf(marker_fp, "%llx %llx", &marker_start, &marker_end);
fclose(marker_fp);
full_trace_fp = fopen("trace.tmp", "r");
assert(full_trace_fp);
/* Filtered trace for each app goes in a separate file */
sprintf(filename, "%s.trace", app_cmd);
part_trace_fp = fopen(filename, "w");
assert(part_trace_fp);
/* Locate trace corresponding to the trans function */
flag = 0;
while (fgets(buf, 1000, full_trace_fp) != NULL) {
/* We are only interested in memory access instructions */
if (buf[0]==' ' && buf[2]==' ' &&
(buf[1]=='S' || buf[1]=='M' || buf[1]=='L' )) {
sscanf(buf+3, "%llx,%u", &addr, &len);
/* If start marker found, set flag */
if (addr == marker_start)
flag = 1;
/* Valgrind creates many spurious accesses to the
stack that have nothing to do with the students
code. At the moment, we are ignoring all stack
accesses by using the simple filter of recording
accesses to only the low 32-bit portion of the
address space. At some point it would be nice to
try to do more informed filtering so that would
eliminate the valgrind stack references while
include the student stack references. */
if (flag && addr < 0xffffffff) {
fputs(buf, part_trace_fp);
}
/* if end marker found, close trace file */
if (addr == marker_end) {
flag = 0;
fclose(part_trace_fp);
break;
}
}
}
fclose(full_trace_fp);
/* Run the reference simulator */
printf("Step 2: Evaluating performance (s=%d, E=%d, b=%d)\n", s, E, b);
sprintf(cmd, "./csim-ref -s %u -E %u -b %u -t %s.trace",
s, E, b, app_cmd);
system(cmd);
}
/*
* usage - Print usage info
*/
void usage(char *argv[]){
printf("Usage: %s [-h] -i <CSR file name>\n", argv[0]);
printf("Options:\n");
printf(" -h Print this help message.\n");
printf(" -i <app> app cmd\n");
printf("Example: %s -i %s\n", argv[0], "./bfs");
}
/*
* sigsegv_handler - SIGSEGV handler
*/
void sigsegv_handler(int signum){
printf("Error: Segmentation Fault.\n");
printf("TEST_TRANS_RESULTS=0:0\n");
fflush(stdout);
exit(1);
}
/*
* sigalrm_handler - SIGALRM handler
*/
void sigalrm_handler(int signum){
printf("Error: Program timed out.\n");
printf("TEST_TRANS_RESULTS=0:0\n");
fflush(stdout);
exit(1);
}
/*
* main - Main routine
*/
int main(int argc, char* argv[])
{
char c;
char *app_cmd;
while ((c = getopt(argc,argv,"i:h")) != -1) {
switch(c) {
case 'i':
app_cmd = optarg;
break;
case 'h':
usage(argv);
exit(0);
default:
usage(argv);
exit(1);
}
}
/* Install SIGSEGV and SIGALRM handlers */
if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
fprintf(stderr, "Unable to install SIGALRM handler\n");
exit(1);
}
if (signal(SIGALRM, sigalrm_handler) == SIG_ERR) {
fprintf(stderr, "Unable to install SIGALRM handler\n");
exit(1);
}
/* Time out and give up after a while */
alarm(600);
/* Check the performance of the student's transpose function */
eval_perf(5, 1, 5, app_cmd);
return 0;
}