diff --git a/Cargo.toml b/Cargo.toml index c962ef6..d95e9f5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ futures-util = { version = "0.3", default-features = false } async-stream = "0.2" tower = "0.3" tempfile = "3" -libc = "0.2" +libc = "0.2.76" [build-dependencies] tonic-build ={ version = "0.3" } diff --git a/proto/river.proto b/proto/river.proto index e7c77eb..6313882 100644 --- a/proto/river.proto +++ b/proto/river.proto @@ -33,8 +33,8 @@ message JudgeRequest { } message JudgeResponse { - int32 time_used = 1; - int32 memory_used = 2; + int64 time_used = 1; + int64 memory_used = 2; enum JudgeResult { Accepted = 0; WrongAnswer = 1; diff --git a/src/judger.rs b/src/judger.rs index 0937d9c..16e1d87 100644 --- a/src/judger.rs +++ b/src/judger.rs @@ -1,5 +1,5 @@ use super::error::{Error, Result}; -use super::process::Process; +use super::process::{Process, ProcessStatus}; use crate::river::judge_request::Language; use crate::river::judge_response::{JudgeResult, JudgeStatus}; use crate::river::{JudgeRequest, JudgeResponse}; @@ -20,11 +20,21 @@ impl JudgeResponse { status: JudgeStatus::Running as i32, } } + + fn set_process_status(self: &mut Self, status: &ProcessStatus) { + self.time_used = status.time_used; + self.memory_used = status.memory_used; + self.exit_code = status.exit_code; + self.errno = status.signal; + self.stdout = status.stdout.clone(); + self.stderr = status.stderr.clone(); + } } pub async fn judger(request: &JudgeRequest) -> Result { + // TODO let mut resp = JudgeResponse::new(); - resp.time_used = request.time_limit; + resp.time_used = request.time_limit.into(); resp.status = JudgeStatus::Ended as i32; return Ok(resp); } @@ -68,9 +78,7 @@ pub async fn compile(request: &JudgeRequest, path: &Path) -> Result Result JudgeResponse { - JudgeResponse { - time_used: 0, - memory_used: 0, - result: JudgeResult::Accepted as i32, - errno: 0, - exit_code: 0, - stdout: "".into(), - stderr: "".into(), - errmsg: "".into(), - status: JudgeStatus::Pending as i32, - } + let mut resp = JudgeResponse::new(); + resp.status = JudgeStatus::Pending as i32; + resp } pub fn running() -> JudgeResponse { - JudgeResponse { - time_used: 0, - memory_used: 0, - result: JudgeResult::Accepted as i32, - errno: 0, - exit_code: 0, - stdout: "".into(), - stderr: "".into(), - errmsg: "".into(), - status: JudgeStatus::Running as i32, - } + let resp = JudgeResponse::new(); + resp } pub fn compiling() -> JudgeResponse { - JudgeResponse { - time_used: 0, - memory_used: 0, - result: JudgeResult::Accepted as i32, - errno: 0, - exit_code: 0, - stdout: "".into(), - stderr: "".into(), - errmsg: "".into(), - status: JudgeStatus::Compiling as i32, - } + let mut resp = JudgeResponse::new(); + resp.status = JudgeStatus::Compiling as i32; + resp } diff --git a/src/process.rs b/src/process.rs index b219ac4..43f9366 100644 --- a/src/process.rs +++ b/src/process.rs @@ -252,8 +252,11 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus { ru_nivcsw: 0 as libc::c_long, }; unsafe { - libc::waitpid(pid, &mut status, 0); - libc::getrusage(pid, &mut rusage); + let val = libc::wait4(pid, &mut status, 0, &mut rusage); + if val < 0 { + eprintln!("{:?}", io::Error::last_os_error().raw_os_error()); + panic!("How dare you!"); + } } let mut exit_code = 0; @@ -270,6 +273,12 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus { 0 } }; + // TODO: 添加 CGroup 的量度 + let time_used = rusage.ru_utime.tv_sec * 1000 + + i64::from(rusage.ru_utime.tv_usec) / 1000 + + rusage.ru_stime.tv_sec * 1000 + + i64::from(rusage.ru_stime.tv_usec) / 1000; + let memory_used = rusage.ru_maxrss; let real_time_used = match start.elapsed() { Ok(elapsed) => elapsed.as_millis(), // 这种地方如果出错了,确实没有办法解决 @@ -290,6 +299,8 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus { exit_code: exit_code, status: status, signal: signal, + time_used: time_used, + memory_used: memory_used, real_time_used: real_time_used, stdout: stdout, stderr: stderr, @@ -302,6 +313,8 @@ pub struct ProcessStatus { pub exit_code: i32, pub status: i32, pub signal: i32, + pub time_used: i64, + pub memory_used: i64, pub real_time_used: u128, pub stdout: String, pub stderr: String,