summaryrefslogtreecommitdiffstats
path: root/files
diff options
context:
space:
mode:
Diffstat (limited to 'files')
-rw-r--r--files/memtestbin0 -> 13628 bytes
-rw-r--r--files/process.c58
-rwxr-xr-xfiles/stat_log.py394
-rw-r--r--files/testlab2.c195
-rwxr-xr-xfiles/testlab2.sh49
5 files changed, 696 insertions, 0 deletions
diff --git a/files/memtest b/files/memtest
new file mode 100644
index 0000000..8c56b25
--- /dev/null
+++ b/files/memtest
Binary files differ
diff --git a/files/process.c b/files/process.c
new file mode 100644
index 0000000..46eb0b0
--- /dev/null
+++ b/files/process.c
@@ -0,0 +1,58 @@
1#include <stdio.h>
2#include <unistd.h>
3#include <time.h>
4#include <sys/times.h>
5
6#define HZ 100
7
8void cpuio_bound(int last, int cpu_time, int io_time);
9
10int main(int argc, char * argv[])
11{
12 return 0;
13}
14
15/*
16 * 此函数按照参数占用CPU和I/O时间
17 * last: 函数实际占用CPU和I/O的总时间,不含在就绪队列中的时间,>=0是必须的
18 * cpu_time: 一次连续占用CPU的时间,>=0是必须的
19 * io_time: 一次I/O消耗的时间,>=0是必须的
20 * 如果last > cpu_time + io_time,则往复多次占用CPU和I/O
21 * 所有时间的单位为秒
22 */
23void cpuio_bound(int last, int cpu_time, int io_time)
24{
25 struct tms start_time, current_time;
26 clock_t utime, stime;
27 int sleep_time;
28
29 while (last > 0)
30 {
31 /* CPU Burst */
32 times(&start_time);
33 /* 其实只有t.tms_utime才是真正的CPU时间。但我们是在模拟一个
34 * 只在用户状态运行的CPU大户,就像“for(;;);”。所以把t.tms_stime
35 * 加上很合理。*/
36 do
37 {
38 times(&current_time);
39 utime = current_time.tms_utime - start_time.tms_utime;
40 stime = current_time.tms_stime - start_time.tms_stime;
41 } while ( ( (utime + stime) / HZ ) < cpu_time );
42 last -= cpu_time;
43
44 if (last <= 0 )
45 break;
46
47 /* IO Burst */
48 /* 用sleep(1)模拟1秒钟的I/O操作 */
49 sleep_time=0;
50 while (sleep_time < io_time)
51 {
52 sleep(1);
53 sleep_time++;
54 }
55 last -= sleep_time;
56 }
57}
58
diff --git a/files/stat_log.py b/files/stat_log.py
new file mode 100755
index 0000000..2dbe3ee
--- /dev/null
+++ b/files/stat_log.py
@@ -0,0 +1,394 @@
1#!/usr/bin/python
2import sys
3import copy
4
5P_NULL = 0
6P_NEW = 1
7P_READY = 2
8P_RUNNING = 4
9P_WAITING = 8
10P_EXIT = 16
11
12S_STATE = 0
13S_TIME = 1
14
15HZ = 100
16
17graph_title = r"""
18-----===< COOL GRAPHIC OF SCHEDULER >===-----
19
20 [Symbol] [Meaning]
21 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 number PID or tick
23 "-" New or Exit
24 "#" Running
25 "|" Ready
26 ":" Waiting
27 / Running with
28 "+" -| Ready
29 \and/or Waiting
30
31-----===< !!!!!!!!!!!!!!!!!!!!!!!!! >===-----
32"""
33
34usage = """
35Usage:
36%s /path/to/process.log [PID1] [PID2] ... [-x PID1 [PID2] ... ] [-m] [-g]
37
38Example:
39# Include process 6, 7, 8 and 9 in statistics only. (Unit: tick)
40%s /path/to/process.log 6 7 8 9
41
42# Exclude process 0 and 1 from statistics. (Unit: tick)
43%s /path/to/process.log -x 0 1
44
45# Include process 6 and 7 only and print a COOL "graphic"! (Unit: millisecond)
46%s /path/to/process.log 6 7 -m -g
47
48# Include all processes and print a COOL "graphic"! (Unit: tick)
49%s /path/to/process.log -g
50"""
51
52class MyError(Exception):
53 pass
54
55class DuplicateNew(MyError):
56 def __init__(self, pid):
57 args = "More than one 'N' for process %d." % pid
58 MyError.__init__(self, args)
59
60class UnknownState(MyError):
61 def __init__(self, state):
62 args = "Unknown state '%s' found." % state
63 MyError.__init__(self, args)
64
65class BadTime(MyError):
66 def __init__(self, time):
67 args = "The time '%d' is bad. It should >= previous line's time." % time
68 MyError.__init__(self, args)
69
70class TaskHasExited(MyError):
71 def __init__(self, state):
72 args = "The process has exited. Why it enter '%s' state again?" % state
73 MyError.__init__(self, args)
74
75class BadFormat(MyError):
76 def __init__(self):
77 args = "Bad log format"
78 MyError.__init__(self, args)
79
80class RepeatState(MyError):
81 def __init__(self, pid):
82 args = "Previous state of process %d is identical with this line." % (pid)
83 MyError.__init__(self, args)
84
85class SameLine(MyError):
86 def __init__(self):
87 args = "It is a clone of previous line."
88 MyError.__init__(self, args)
89
90class NoNew(MyError):
91 def __init__(self, pid, state):
92 args = "The first state of process %d is '%s'. Why not 'N'?" % (pid, state)
93 MyError.__init__(self, args)
94
95class statistics:
96 def __init__(self, pool, include, exclude):
97 if include:
98 self.pool = process_pool()
99 for process in pool:
100 if process.getpid() in include:
101 self.pool.add(process)
102 else:
103 self.pool = copy.copy(pool)
104
105 if exclude:
106 for pid in exclude:
107 if self.pool.get_process(pid):
108 self.pool.remove(pid)
109
110 def list_pid(self):
111 l = []
112 for process in self.pool:
113 l.append(process.getpid())
114 return l
115
116 def average_turnaround(self):
117 if len(self.pool) == 0:
118 return 0
119 sum = 0
120 for process in self.pool:
121 sum += process.turnaround_time()
122 return float(sum) / len(self.pool)
123
124 def average_waiting(self):
125 if len(self.pool) == 0:
126 return 0
127 sum = 0
128 for process in self.pool:
129 sum += process.waiting_time()
130 return float(sum) / len(self.pool)
131
132 def begin_time(self):
133 begin = 0xEFFFFF
134 for p in self.pool:
135 if p.begin_time() < begin:
136 begin = p.begin_time()
137 return begin
138
139 def end_time(self):
140 end = 0
141 for p in self.pool:
142 if p.end_time() > end:
143 end = p.end_time()
144 return end
145
146 def throughput(self):
147 return len(self.pool) * HZ / float(self.end_time() - self.begin_time())
148
149 def print_graphic(self):
150 begin = self.begin_time()
151 end = self.end_time()
152
153 print graph_title
154
155 for i in range(begin, end+1):
156 line = "%5d " % i
157 for p in self.pool:
158 state = p.get_state(i)
159 if state & P_NEW:
160 line += "-"
161 elif state == P_READY or state == P_READY | P_WAITING:
162 line += "|"
163 elif state == P_RUNNING:
164 line += "#"
165 elif state == P_WAITING:
166 line += ":"
167 elif state & P_EXIT:
168 line += "-"
169 elif state == P_NULL:
170 line += " "
171 elif state & P_RUNNING:
172 line += "+"
173 else:
174 assert False
175 if p.get_state(i-1) != state and state != P_NULL:
176 line += "%-3d" % p.getpid()
177 else:
178 line += " "
179 print line
180
181class process_pool:
182 def __init__(self):
183 self.list = []
184
185 def get_process(self, pid):
186 for process in self.list:
187 if process.getpid() == pid:
188 return process
189 return None
190
191 def remove(self, pid):
192 for process in self.list:
193 if process.getpid() == pid:
194 self.list.remove(process)
195
196 def new(self, pid, time):
197 p = self.get_process(pid)
198 if p:
199 if pid != 0:
200 raise DuplicateNew(pid)
201 else:
202 p.states=[(P_NEW, time)]
203 else:
204 p = process(pid, time)
205 self.list.append(p)
206 return p
207
208 def add(self, p):
209 self.list.append(p)
210
211 def __len__(self):
212 return len(self.list)
213
214 def __iter__(self):
215 return iter(self.list)
216
217class process:
218 def __init__(self, pid, time):
219 self.pid = pid
220 self.states = [(P_NEW, time)]
221
222 def getpid(self):
223 return self.pid
224
225 def change_state(self, state, time):
226 last_state, last_time = self.states[-1]
227 if state == P_NEW:
228 raise DuplicateNew(pid)
229 if time < last_time:
230 raise BadTime(time)
231 if last_state == P_EXIT:
232 raise TaskHasExited(state)
233 if last_state == state and self.pid != 0: # task 0 can have duplicate state
234 raise RepeatState(self.pid)
235
236 self.states.append((state, time))
237
238 def get_state(self, time):
239 rval = P_NULL
240 combo = P_NULL
241 if self.begin_time() <= time <= self.end_time():
242 for state, s_time in self.states:
243 if s_time < time:
244 rval = state
245 elif s_time == time:
246 combo |= state
247 else:
248 break
249 if combo:
250 rval = combo
251 return rval
252
253 def turnaround_time(self):
254 return self.states[-1][S_TIME] - self.states[0][S_TIME]
255
256 def waiting_time(self):
257 return self.state_last_time(P_READY)
258
259 def cpu_time(self):
260 return self.state_last_time(P_RUNNING)
261
262 def io_time(self):
263 return self.state_last_time(P_WAITING)
264
265 def state_last_time(self, state):
266 time = 0
267 state_begin = 0
268 for s,t in self.states:
269 if s == state:
270 state_begin = t
271 elif state_begin != 0:
272 assert state_begin <= t
273 time += t - state_begin
274 state_begin = 0
275 return time
276
277
278 def begin_time(self):
279 return self.states[0][S_TIME]
280
281 def end_time(self):
282 return self.states[-1][S_TIME]
283
284# Enter point
285if len(sys.argv) < 2:
286 print usage.replace("%s", sys.argv[0])
287 sys.exit(0)
288
289# parse arguments
290include = []
291exclude = []
292unit_ms = False
293graphic = False
294ex_mark = False
295
296try:
297 for arg in sys.argv[2:]:
298 if arg == '-m':
299 unit_ms = True
300 continue
301 if arg == '-g':
302 graphic = True
303 continue
304 if not ex_mark:
305 if arg == '-x':
306 ex_mark = True
307 else:
308 include.append(int(arg))
309 else:
310 exclude.append(int(arg))
311except ValueError:
312 print "Bad argument '%s'" % arg
313 sys.exit(-1)
314
315# parse log file and construct processes
316processes = process_pool()
317
318f = open(sys.argv[1], "r")
319
320# Patch process 0's New & Run state
321processes.new(0, 40).change_state(P_RUNNING, 40)
322
323try:
324 prev_time = 0
325 prev_line = ""
326 for lineno, line in enumerate(f):
327
328 if line == prev_line:
329 raise SameLine
330 prev_line = line
331
332 fields = line.split("\t")
333 if len(fields) != 3:
334 raise BadFormat
335
336 pid = int(fields[0])
337 s = fields[1].upper()
338
339 time = int(fields[2])
340 if time < prev_time:
341 raise BadTime(time)
342 prev_time = time
343
344 p = processes.get_process(pid)
345
346 state = P_NULL
347 if s == 'N':
348 processes.new(pid, time)
349 elif s == 'J':
350 state = P_READY
351 elif s == 'R':
352 state = P_RUNNING
353 elif s == 'W':
354 state = P_WAITING
355 elif s == 'E':
356 state = P_EXIT
357 else:
358 raise UnknownState(s)
359 if state != P_NULL:
360 if not p:
361 raise NoNew(pid, s)
362 p.change_state(state, time)
363except MyError, err:
364 print "Error at line %d: %s" % (lineno+1, err)
365 sys.exit(0)
366
367# Stats
368stats = statistics(processes, include, exclude)
369att = stats.average_turnaround()
370awt = stats.average_waiting()
371if unit_ms:
372 unit = "ms"
373 att *= 1000/HZ
374 awt *= 1000/HZ
375else:
376 unit = "tick"
377print "(Unit: %s)" % unit
378print "Process Turnaround Waiting CPU Burst I/O Burst"
379for pid in stats.list_pid():
380 p = processes.get_process(pid)
381 tt = p.turnaround_time()
382 wt = p.waiting_time()
383 cpu = p.cpu_time()
384 io = p.io_time()
385
386 if unit_ms:
387 print "%7d %10d %7d %9d %9d" % (pid, tt*1000/HZ, wt*1000/HZ, cpu*1000/HZ, io*1000/HZ)
388 else:
389 print "%7d %10d %7d %9d %9d" % (pid, tt, wt, cpu, io)
390print "Average: %10.2f %7.2f" % (att, awt)
391print "Throughout: %.2f/s" % (stats.throughput())
392
393if graphic:
394 stats.print_graphic()
diff --git a/files/testlab2.c b/files/testlab2.c
new file mode 100644
index 0000000..bd97b76
--- /dev/null
+++ b/files/testlab2.c
@@ -0,0 +1,195 @@
1/*
2 * Compile: "gcc testlab2.c"
3 * Run: "./a.out"
4 */
5
6#include <string.h>
7#include <assert.h>
8#include <stdio.h>
9#include <errno.h>
10#include <stdlib.h>
11#define __LIBRARY__
12#include <unistd.h>
13
14_syscall2(int, whoami,char*,name,unsigned int,size);
15_syscall1(int, iam, const char*, name);
16
17#define MAX_NAME_LEN 23
18#define NAMEBUF_SIZE (MAX_NAME_LEN + 1)
19/* truncate a long name to SHORT_NAME_LEN for display */
20#define SHORT_NAME_LEN (MAX_NAME_LEN + 2)
21
22/* name score */
23#define TEST_CASE { \
24 {"x", 10, 1, NAMEBUF_SIZE, 1},\
25 {"sunner", 10, 6, NAMEBUF_SIZE, 6},\
26 {"Twenty-three characters", 5, 23, NAMEBUF_SIZE, 23},\
27 {"123456789009876543211234", 5, -1, 0, -1},\
28 {"abcdefghijklmnopqrstuvwxyz", 5, -1, 0, -1},\
29 {"Linus Torvalds", 5, 14, NAMEBUF_SIZE, 14},\
30 {"", 5, 0, NAMEBUF_SIZE, 0},\
31 {"whoami(0xbalabala, 10)", 5, 22, 10, -1},\
32 {NULL, 0, 0, 0, 0} /* End of cases */ \
33}
34/*改动一:增加size,和rval2*/
35
36int test(const char* name, int max_score, int expected_rval1, int size, int expected_rval2);
37void print_message(const char* msgfmt, const char* name);
38
39struct test_case
40{
41 char *name;
42 int score;
43 int rval1; /* return value of iam() */
44 /*改动2:增加size,和rval2定义*/
45 int size; /*Patch for whoami,2009.11.2*/
46 int rval2; /* return value of whoami() */
47};
48
49int main(void)
50{
51 struct test_case cases[] = TEST_CASE;
52
53 int total_score=0, i=0;
54
55 while (cases[i].score != 0)
56 {
57 int score;
58
59 printf("Test case %d:", i+1);
60
61 /*改动3:增加size,和rval2的参数阿*/
62 score = test( cases[i].name,
63 cases[i].score,
64 cases[i].rval1,
65 cases[i].size,
66 cases[i].rval2 );
67
68 total_score += score;
69 i++;
70 }
71
72 printf("Final result: %d%%\n", total_score);
73 return 0;
74
75}
76 /*改动4:增加size,和rval2的声明*/
77int test(const char* name, int max_score, int expected_rval1, int size, int expected_rval2)
78{
79 int rval;
80 int len;
81 char * gotname;
82 int score=-1;
83
84 assert(name != NULL);
85
86 print_message("name = \"%s\", length = %d...", name);
87
88 /*Test iam()*/
89 len = strlen(name);
90 rval = iam(name);
91 /* printf("Return value = %d\n", rval);*/
92
93/*改动5:增加的expected_rval1*/
94 if (rval == expected_rval1)
95 {
96 if (rval == -1 && errno == EINVAL) /*The system call can detect bad name*/
97 {
98 /* print_message("Long name, %s(%d), detected.\n", name);*/
99 printf("PASS\n");
100 score = max_score;
101 }
102 else if (rval == -1 && errno != EINVAL)
103 {
104 printf("\nERROR iam(): Bad errno %d. It should be %d(EINVAL).\n", errno, EINVAL);
105 score = 0;
106 }
107 /* iam() is good. Test whoami() next. */
108 }
109 else
110 {
111 printf("\nERROR iam(): Return value is %d. It should be %d.\n", rval, expected_rval1);
112 score = 0;
113 }
114
115 if (score != -1)
116 return score;
117
118 /*Test whoami()*/
119 gotname = (char*)malloc(len+1);
120 if (gotname == NULL)
121 exit(-1);
122
123 memset(gotname, 0, len+1);
124
125 /* printf("Get: buffer length = %d.\n", len+1); */
126
127 rval = whoami(gotname, size);
128 /* printf("Return value = %d\n", rval); */
129
130/*改动6:增加的expected_rval2*/
131/*改动++:比较多 ,但还是顺序的改改*/
132
133 if(rval == expected_rval2)
134 {
135 if(rval == -1)
136 {
137 printf("PASS\n");
138 score = max_score;
139 }
140 else
141 {
142 if (strcmp(gotname, name) == 0)
143 {
144 /* print_message("Great! We got %s(%d) finally!\n", gotname); */
145 printf("PASS\n");
146 score = max_score;
147 }
148 else
149 {
150 print_message("\nERROR whoami(): we got %s(%d). ", gotname);
151 print_message("It should be %s(%d).\n", name);
152 score = 0;
153 }
154 }
155 }
156 else if (rval == -1)
157 {
158 printf("\nERROR whoami(): Return value is -1 and errno is %d. Why?\n", errno);
159 score = 0;
160 }
161 else
162 {
163 printf("\nERROR whoami(): Return value should be %d, not %d.\n", expected_rval2, rval);
164 score = 0;
165 }
166
167 free(gotname);
168 assert(score != -1);
169
170 return score;
171}
172
173void print_message(const char* msgfmt, const char* name)
174{
175 char short_name[SHORT_NAME_LEN + 4] = {0};
176 int len;
177
178 len = strlen(name);
179
180 if (len == 0)
181 {
182 strcpy(short_name, "NULL");
183 }
184 else if (len <= SHORT_NAME_LEN)
185 {
186 strcpy(short_name, name);
187 }
188 else
189 {
190 memset(short_name, '.', SHORT_NAME_LEN+3);
191 memcpy(short_name, name, SHORT_NAME_LEN);
192 }
193
194 printf(msgfmt, short_name, len);
195}
diff --git a/files/testlab2.sh b/files/testlab2.sh
new file mode 100755
index 0000000..7f79876
--- /dev/null
+++ b/files/testlab2.sh
@@ -0,0 +1,49 @@
1#/bin/sh
2
3string1="Sunner"
4string2="Richard Stallman"
5string3="This is a very very long string!"
6
7score1=10
8score2=10
9score3=10
10
11expected1="Sunner"
12expected2="Richard Stallman"
13expected3="Richard Stallman"
14
15echo Testing string:$string1
16./iam "$string1"
17result=`./whoami`
18if [ "$result" = "$expected1" ]; then
19 echo PASS.
20else
21 score1=0
22 echo FAILED.
23fi
24score=$score1
25
26echo Testing string:$string2
27./iam "$string2"
28result=`./whoami`
29if [ "$result" = "$expected2" ]; then
30 echo PASS.
31else
32 score2=0
33 echo FAILED.
34fi
35score=$score+$score2
36
37echo Testing string:$string3
38./iam "$string3"
39result=`./whoami`
40if [ "$result" = "$expected3" ]; then
41 echo PASS.
42else
43 score3=0
44 echo FAILED.
45fi
46score=$score+$score3
47
48let "totalscore=$score"
49echo Score: $score = $totalscore%