Description:
[grader] added fractional timelimit git-svn-id: http://theory.cpe.ku.ac.th/grader/judge/trunk/scripts@191 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r51:3618759afb50 - - 6 files changed: 66 inserted, 57 deleted

@@ -0,0 +1,38
1 + #include <stdio.h>
2 + #include <stdlib.h>
3 + #include <unistd.h>
4 + #include <sys/time.h>
5 + #include <time.h>
6 + #include <sys/resource.h>
7 +
8 + // run it for 1.5 s
9 +
10 + int main()
11 + {
12 + int a,b;
13 +
14 + int c=0;
15 +
16 + scanf("%d %d",&a,&b);
17 + printf("%d\n",a+b);
18 +
19 + struct rusage ru;
20 +
21 + while(1) {
22 + c++;
23 + b+=c;
24 + while(c<100000) {
25 + c++;
26 + b+=c;
27 + }
28 + getrusage(RUSAGE_SELF,&ru);
29 + double rtime = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec;
30 + rtime += (double)ru.ru_utime.tv_usec / 1000000.0;
31 + rtime += (double)ru.ru_stime.tv_usec / 1000000.0;
32 + if(rtime > 0.5)
33 + break;
34 + }
35 + printf("%d\n",b);
36 + exit(0);
37 + }
38 +
@@ -158,27 +158,32
158 end
158 end
159 if task==nil
159 if task==nil
160 sleep(1)
160 sleep(1)
161 end
161 end
162 end
162 end
163
163
164 when "prob"
164 when "prob"
165 engine = Grader::Engine.new
165 engine = Grader::Engine.new
166 runner = Grader::Runner.new(engine, grader_proc)
166 runner = Grader::Runner.new(engine, grader_proc)
167
167
168 grader_proc.report_active if grader_proc!=nil
168 grader_proc.report_active if grader_proc!=nil
169
169
170 - prob = Problem.find_by_name(ARGV[2])
170 + ARGV.shift
171 - if prob==nil
171 + ARGV.shift
172 - puts "cannot find problem: #{ARGV[2]}"
172 +
173 - else
173 + ARGV.each do |prob_name|
174 - runner.grade_problem(prob)
174 + prob = Problem.find_by_name(prob_name)
175 + if prob==nil
176 + puts "cannot find problem: #{prob_name}"
177 + else
178 + runner.grade_problem(prob)
179 + end
175 end
180 end
176
181
177 else
182 else
178 display_manual
183 display_manual
179 exit(0)
184 exit(0)
180 end
185 end
181
186
182 # report inactive
187 # report inactive
183 grader_proc.report_inactive if grader_proc!=nil
188 grader_proc.report_inactive if grader_proc!=nil
184
189
@@ -20,25 +20,25
20 #include <sys/user.h>
20 #include <sys/user.h>
21 #include <sys/time.h>
21 #include <sys/time.h>
22 #include <sys/ptrace.h>
22 #include <sys/ptrace.h>
23 #include <sys/signal.h>
23 #include <sys/signal.h>
24 #include <sys/sysinfo.h>
24 #include <sys/sysinfo.h>
25 #include <sys/syscall.h>
25 #include <sys/syscall.h>
26 #include <sys/resource.h>
26 #include <sys/resource.h>
27
27
28 #define NONRET __attribute__((noreturn))
28 #define NONRET __attribute__((noreturn))
29 #define UNUSED __attribute__((unused))
29 #define UNUSED __attribute__((unused))
30
30
31 static int filter_syscalls; /* 0=off, 1=liberal, 2=totalitarian */
31 static int filter_syscalls; /* 0=off, 1=liberal, 2=totalitarian */
32 - static int timeout;
32 + static double timeout;
33 static int pass_environ;
33 static int pass_environ;
34 static int use_wall_clock;
34 static int use_wall_clock;
35 static int file_access;
35 static int file_access;
36 static int verbose;
36 static int verbose;
37 static int memory_limit;
37 static int memory_limit;
38 static int allow_times;
38 static int allow_times;
39 static char *redir_stdin, *redir_stdout;
39 static char *redir_stdin, *redir_stdout;
40 static char *set_cwd;
40 static char *set_cwd;
41
41
42 static pid_t box_pid;
42 static pid_t box_pid;
43 static int is_ptraced;
43 static int is_ptraced;
44 static volatile int timer_tick;
44 static volatile int timer_tick;
@@ -318,28 +318,28
318 }
318 }
319
319
320 static void
320 static void
321 signal_int(int unused UNUSED)
321 signal_int(int unused UNUSED)
322 {
322 {
323 /* Interrupts are fatal, so no synchronization requirements. */
323 /* Interrupts are fatal, so no synchronization requirements. */
324 die("Interrupted.");
324 die("Interrupted.");
325 }
325 }
326
326
327 static void
327 static void
328 check_timeout(void)
328 check_timeout(void)
329 {
329 {
330 - int sec;
330 + double sec;
331
331
332 if (use_wall_clock)
332 if (use_wall_clock)
333 - sec = time(NULL) - start_time;
333 + sec = (double)(time(NULL) - start_time);
334 else
334 else
335 {
335 {
336 char buf[4096], *x;
336 char buf[4096], *x;
337 int c, utime, stime;
337 int c, utime, stime;
338 static int proc_status_fd;
338 static int proc_status_fd;
339 if (!proc_status_fd)
339 if (!proc_status_fd)
340 {
340 {
341 sprintf(buf, "/proc/%d/stat", (int) box_pid);
341 sprintf(buf, "/proc/%d/stat", (int) box_pid);
342 proc_status_fd = open(buf, O_RDONLY);
342 proc_status_fd = open(buf, O_RDONLY);
343 if (proc_status_fd < 0)
343 if (proc_status_fd < 0)
344 die("open(%s): %m", buf);
344 die("open(%s): %m", buf);
345 }
345 }
@@ -354,30 +354,30
354 x++;
354 x++;
355 while (*x == ' ')
355 while (*x == ' ')
356 x++;
356 x++;
357 if (*x++ != '(')
357 if (*x++ != '(')
358 die("proc syntax error 1");
358 die("proc syntax error 1");
359 while (*x && (*x != ')' || x[1] != ' '))
359 while (*x && (*x != ')' || x[1] != ' '))
360 x++;
360 x++;
361 while (*x == ')' || *x == ' ')
361 while (*x == ')' || *x == ' ')
362 x++;
362 x++;
363 if (sscanf(x, "%*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d", &utime, &stime) != 2)
363 if (sscanf(x, "%*c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %d %d", &utime, &stime) != 2)
364 die("proc syntax error 2");
364 die("proc syntax error 2");
365 //printf("%s - %d\n",x,ticks_per_sec);
365 //printf("%s - %d\n",x,ticks_per_sec);
366 - sec = (utime + stime + ticks_per_sec-1)/ticks_per_sec;
366 + sec = ((double)(utime + stime))/(double)ticks_per_sec;
367 }
367 }
368 if (verbose > 1)
368 if (verbose > 1)
369 fprintf(stderr, "[timecheck: %d seconds]\n", sec);
369 fprintf(stderr, "[timecheck: %d seconds]\n", sec);
370 if (sec > timeout) {
370 if (sec > timeout) {
371 - die("Time limit exceeded.");
371 + die("Time limit exceeded.",sec,timeout);
372 }
372 }
373 }
373 }
374
374
375 static void
375 static void
376 check_memory_usage()
376 check_memory_usage()
377 {
377 {
378 char proc_fname[100];
378 char proc_fname[100];
379 sprintf(proc_fname,"/proc/%d/statm",box_pid);
379 sprintf(proc_fname,"/proc/%d/statm",box_pid);
380 //printf("proc fname: %s\n",proc_fname);
380 //printf("proc fname: %s\n",proc_fname);
381 FILE *fp = fopen(proc_fname,"r");
381 FILE *fp = fopen(proc_fname,"r");
382 if(fp!=NULL) {
382 if(fp!=NULL) {
383 char line[1000];
383 char line[1000];
@@ -457,25 +457,28
457 if (p != box_pid)
457 if (p != box_pid)
458 die("wait4: unknown pid %d exited!", p);
458 die("wait4: unknown pid %d exited!", p);
459 if (WIFEXITED(stat))
459 if (WIFEXITED(stat))
460 {
460 {
461 struct timeval total;
461 struct timeval total;
462 int wall;
462 int wall;
463 wall = time(NULL) - start_time;
463 wall = time(NULL) - start_time;
464 timeradd(&rus.ru_utime, &rus.ru_stime, &total);
464 timeradd(&rus.ru_utime, &rus.ru_stime, &total);
465
465
466 box_pid = 0;
466 box_pid = 0;
467 if (WEXITSTATUS(stat))
467 if (WEXITSTATUS(stat))
468 fprintf(stderr,"Exited with error status %d.\n", WEXITSTATUS(stat));
468 fprintf(stderr,"Exited with error status %d.\n", WEXITSTATUS(stat));
469 - else if ((use_wall_clock ? wall : total.tv_sec) > timeout)
469 + else if ((use_wall_clock ?
470 + wall :
471 + (double) total.tv_sec +
472 + ((double) total.tv_usec/1000000.0)) > timeout)
470 fprintf(stderr,"Time limit exceeded.\n");
473 fprintf(stderr,"Time limit exceeded.\n");
471 else
474 else
472 // report OK and statistics
475 // report OK and statistics
473 fprintf(stderr,"OK\n");
476 fprintf(stderr,"OK\n");
474
477
475 print_running_stat((double) wall,
478 print_running_stat((double) wall,
476 (double) rus.ru_utime.tv_sec +
479 (double) rus.ru_utime.tv_sec +
477 ((double) rus.ru_utime.tv_usec/1000000.0),
480 ((double) rus.ru_utime.tv_usec/1000000.0),
478 (double) rus.ru_stime.tv_sec +
481 (double) rus.ru_stime.tv_sec +
479 ((double) rus.ru_stime.tv_usec/1000000.0),
482 ((double) rus.ru_stime.tv_usec/1000000.0),
480 max_mem_used);
483 max_mem_used);
481 /*
484 /*
@@ -637,25 +640,25
637 filter_syscalls++;
640 filter_syscalls++;
638 break;
641 break;
639 case 'i':
642 case 'i':
640 redir_stdin = optarg;
643 redir_stdin = optarg;
641 break;
644 break;
642 case 'm':
645 case 'm':
643 memory_limit = atol(optarg);
646 memory_limit = atol(optarg);
644 break;
647 break;
645 case 'o':
648 case 'o':
646 redir_stdout = optarg;
649 redir_stdout = optarg;
647 break;
650 break;
648 case 't':
651 case 't':
649 - timeout = atol(optarg);
652 + timeout = atof(optarg);
650 break;
653 break;
651 case 'T':
654 case 'T':
652 allow_times++;
655 allow_times++;
653 break;
656 break;
654 case 'v':
657 case 'v':
655 verbose++;
658 verbose++;
656 break;
659 break;
657 case 'w':
660 case 'w':
658 use_wall_clock = 1;
661 use_wall_clock = 1;
659 break;
662 break;
660 default:
663 default:
661 usage();
664 usage();
@@ -1,20 +1,24
1 problem do
1 problem do
2 num_tests 2
2 num_tests 2
3 full_score 20
3 full_score 20
4 time_limit_each 1
4 time_limit_each 1
5 mem_limit_each 16
5 mem_limit_each 16
6 score_each 10
6 score_each 10
7
7
8 + test 1 do
9 + time_limit 0.5
10 + end
11 +
8 run 1 do
12 run 1 do
9 tests 1
13 tests 1
10 end
14 end
11
15
12 test 2 do
16 test 2 do
13 - time_limit 2
17 + time_limit 0.6
14 end
18 end
15
19
16 run 2 do
20 run 2 do
17 tests 2
21 tests 2
18 end
22 end
19
23
20 end
24 end
@@ -39,29 +39,29
39
39
40 it "should produce timeout error when submission runs forever" do
40 it "should produce timeout error when submission runs forever" do
41 @problem_test_timeout = stub(Problem,
41 @problem_test_timeout = stub(Problem,
42 :id => 1, :name => 'test_timeout',
42 :id => 1, :name => 'test_timeout',
43 :full_score => 10)
43 :full_score => 10)
44 grader_should(:grade => "test2_timeout.c",
44 grader_should(:grade => "test2_timeout.c",
45 :on => @problem_test_timeout,
45 :on => @problem_test_timeout,
46 :and_report => {
46 :and_report => {
47 :score => 0,
47 :score => 0,
48 :comment => 'FAILED: TT'})
48 :comment => 'FAILED: TT'})
49 end
49 end
50
50
51 - it "should produce timeout error correctly when submission runs slower than expected in less than a second" do
51 + it "should produce timeout error correctly with fractional running time and fractional time limits" do
52 - @problem_test_timeout = stub(Problem,
52 + @problem_test_timeout = stub(Problem,
53 :id => 1, :name => 'test_timeout',
53 :id => 1, :name => 'test_timeout',
54 :full_score => 20)
54 :full_score => 20)
55 - grader_should(:grade => "test2_1-5sec.c",
55 + grader_should(:grade => "test2_05sec.c",
56 :on => @problem_test_timeout,
56 :on => @problem_test_timeout,
57 :and_report => {
57 :and_report => {
58 :score => 10,
58 :score => 10,
59 :comment => 'FAILED: TP'})
59 :comment => 'FAILED: TP'})
60 end
60 end
61
61
62 it "should produce runtime error when submission uses too much static memory" do
62 it "should produce runtime error when submission uses too much static memory" do
63 @problem_test_memory = stub(Problem,
63 @problem_test_memory = stub(Problem,
64 :id => 1, :name => 'test_memory',
64 :id => 1, :name => 'test_memory',
65 :full_score => 20)
65 :full_score => 20)
66 grader_should(:grade => "add_too_much_memory_static.c",
66 grader_should(:grade => "add_too_much_memory_static.c",
67 :on => @problem_test_memory,
67 :on => @problem_test_memory,
deleted file
You need to be logged in to leave comments. Login now