Skip to content

Commit c4ff349

Browse files
committed
feat(sandbox): return extra informations
1 parent 9fe33e4 commit c4ff349

1 file changed

Lines changed: 22 additions & 6 deletions

File tree

src/sandbox/mod.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::{
99
time::{Duration, Instant},
1010
};
1111

12+
use byte_unit::Byte;
1213
use cgroups_rs::{CgroupPid, fs::Cgroup};
1314
use nix::{libc::getpid, sys::signal::Signal};
1415
pub 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

Comments
 (0)