@@ -9,6 +9,7 @@ use std::{
99 time:: { Duration , Instant } ,
1010} ;
1111
12+ use byte_unit:: Byte ;
1213use cgroups_rs:: { CgroupPid , fs:: Cgroup } ;
1314use nix:: { libc:: getpid, sys:: signal:: Signal } ;
1415pub use resource:: Resource ;
@@ -51,22 +52,29 @@ impl Sandbox {
5152 }
5253 }
5354
54- pub fn monitor ( self , mut child : Child ) -> io:: Result < Option < Verdict > > {
55+ pub fn monitor ( & self , mut child : Child ) -> io:: Result < ( Option < Verdict > , Duration , Byte ) > {
5556 self . cgroup
5657 . add_task_by_tgid ( CgroupPid :: from ( child. id ( ) as u64 ) )
5758 . map_err ( io:: Error :: other) ?;
5859
5960 let start = Instant :: now ( ) ;
61+ let mut memory_usage = Byte :: default ( ) ;
6062 let mut prev_cpu_time = self . cgroup . get_cpu_time ( ) ;
6163 let mut idle_start: Option < Instant > = None ;
64+
6265 while child. try_wait ( ) ?. is_none ( ) {
6366 let cpu_time = self . cgroup . get_cpu_time ( ) ;
67+ memory_usage = memory_usage. max ( self . cgroup . get_memory_usage ( ) ) ;
6468
6569 if cpu_time. abs_diff ( prev_cpu_time) <= MIN_CPU_TIME_PER_POLL {
6670 match idle_start {
6771 Some ( idle_start) => {
6872 if idle_start. elapsed ( ) >= IDLE_TIME_LIMIT {
69- return Ok ( Some ( Verdict :: IdleTimeLimitExceeded ) ) ;
73+ return Ok ( (
74+ Some ( Verdict :: IdleTimeLimitExceeded ) ,
75+ cpu_time,
76+ memory_usage,
77+ ) ) ;
7078 }
7179 }
7280 None => idle_start = Some ( Instant :: now ( ) ) ,
@@ -76,7 +84,11 @@ impl Sandbox {
7684 }
7785
7886 if cpu_time >= self . cpu_time_limit || start. elapsed ( ) >= self . wall_time_limit {
79- return Ok ( Some ( Verdict :: TimeLimitExceeded ) ) ;
87+ return Ok ( (
88+ Some ( Verdict :: TimeLimitExceeded ) ,
89+ self . cpu_time_limit ,
90+ memory_usage,
91+ ) ) ;
8092 }
8193
8294 prev_cpu_time = cpu_time;
@@ -87,11 +99,15 @@ impl Sandbox {
8799 // SAFETY: child must be finished at this point to exit the previous loop
88100 let status = child. try_wait ( ) ?. unwrap ( ) ;
89101 if status. success ( ) {
90- return Ok ( None ) ;
102+ return Ok ( ( None , prev_cpu_time , memory_usage ) ) ;
91103 }
92104 match status. signal ( ) . and_then ( |x| Signal :: try_from ( x) . ok ( ) ) {
93- Some ( Signal :: SIGKILL ) => Ok ( Some ( Verdict :: MemoryLimitExceeded ) ) ,
94- _ => Ok ( Some ( Verdict :: RuntimeError ) ) ,
105+ Some ( Signal :: SIGKILL ) => Ok ( (
106+ Some ( Verdict :: MemoryLimitExceeded ) ,
107+ prev_cpu_time,
108+ self . cgroup . get_memory_limit ( ) ,
109+ ) ) ,
110+ _ => Ok ( ( Some ( Verdict :: RuntimeError ) , prev_cpu_time, memory_usage) ) ,
95111 }
96112 }
97113}
0 commit comments