This commit is contained in:
MeiK 2020-09-03 10:55:03 +08:00
parent d4a454683d
commit e56903de1c
4 changed files with 39 additions and 43 deletions

View File

@ -14,7 +14,7 @@ futures-util = { version = "0.3", default-features = false }
async-stream = "0.2" async-stream = "0.2"
tower = "0.3" tower = "0.3"
tempfile = "3" tempfile = "3"
libc = "0.2" libc = "0.2.76"
[build-dependencies] [build-dependencies]
tonic-build ={ version = "0.3" } tonic-build ={ version = "0.3" }

View File

@ -33,8 +33,8 @@ message JudgeRequest {
} }
message JudgeResponse { message JudgeResponse {
int32 time_used = 1; int64 time_used = 1;
int32 memory_used = 2; int64 memory_used = 2;
enum JudgeResult { enum JudgeResult {
Accepted = 0; Accepted = 0;
WrongAnswer = 1; WrongAnswer = 1;

View File

@ -1,5 +1,5 @@
use super::error::{Error, Result}; use super::error::{Error, Result};
use super::process::Process; use super::process::{Process, ProcessStatus};
use crate::river::judge_request::Language; use crate::river::judge_request::Language;
use crate::river::judge_response::{JudgeResult, JudgeStatus}; use crate::river::judge_response::{JudgeResult, JudgeStatus};
use crate::river::{JudgeRequest, JudgeResponse}; use crate::river::{JudgeRequest, JudgeResponse};
@ -20,11 +20,21 @@ impl JudgeResponse {
status: JudgeStatus::Running as i32, 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<JudgeResponse> { pub async fn judger(request: &JudgeRequest) -> Result<JudgeResponse> {
// TODO
let mut resp = JudgeResponse::new(); let mut resp = JudgeResponse::new();
resp.time_used = request.time_limit; resp.time_used = request.time_limit.into();
resp.status = JudgeStatus::Ended as i32; resp.status = JudgeStatus::Ended as i32;
return Ok(resp); return Ok(resp);
} }
@ -68,9 +78,7 @@ pub async fn compile(request: &JudgeRequest, path: &Path) -> Result<JudgeRespons
let status = process.await?; let status = process.await?;
if status.exit_code != 0 { if status.exit_code != 0 {
resp.exit_code = status.exit_code; resp.set_process_status(&status);
resp.stdout = status.stdout;
resp.stderr = status.stderr;
resp.result = JudgeResult::CompileError as i32; resp.result = JudgeResult::CompileError as i32;
resp.status = JudgeStatus::Ended as i32; resp.status = JudgeStatus::Ended as i32;
} }
@ -78,43 +86,18 @@ pub async fn compile(request: &JudgeRequest, path: &Path) -> Result<JudgeRespons
} }
pub fn pending() -> JudgeResponse { pub fn pending() -> JudgeResponse {
JudgeResponse { let mut resp = JudgeResponse::new();
time_used: 0, resp.status = JudgeStatus::Pending as i32;
memory_used: 0, resp
result: JudgeResult::Accepted as i32,
errno: 0,
exit_code: 0,
stdout: "".into(),
stderr: "".into(),
errmsg: "".into(),
status: JudgeStatus::Pending as i32,
}
} }
pub fn running() -> JudgeResponse { pub fn running() -> JudgeResponse {
JudgeResponse { let resp = JudgeResponse::new();
time_used: 0, resp
memory_used: 0,
result: JudgeResult::Accepted as i32,
errno: 0,
exit_code: 0,
stdout: "".into(),
stderr: "".into(),
errmsg: "".into(),
status: JudgeStatus::Running as i32,
}
} }
pub fn compiling() -> JudgeResponse { pub fn compiling() -> JudgeResponse {
JudgeResponse { let mut resp = JudgeResponse::new();
time_used: 0, resp.status = JudgeStatus::Compiling as i32;
memory_used: 0, resp
result: JudgeResult::Accepted as i32,
errno: 0,
exit_code: 0,
stdout: "".into(),
stderr: "".into(),
errmsg: "".into(),
status: JudgeStatus::Compiling as i32,
}
} }

View File

@ -252,8 +252,11 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus {
ru_nivcsw: 0 as libc::c_long, ru_nivcsw: 0 as libc::c_long,
}; };
unsafe { unsafe {
libc::waitpid(pid, &mut status, 0); let val = libc::wait4(pid, &mut status, 0, &mut rusage);
libc::getrusage(pid, &mut rusage); if val < 0 {
eprintln!("{:?}", io::Error::last_os_error().raw_os_error());
panic!("How dare you!");
}
} }
let mut exit_code = 0; let mut exit_code = 0;
@ -270,6 +273,12 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus {
0 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() { let real_time_used = match start.elapsed() {
Ok(elapsed) => elapsed.as_millis(), Ok(elapsed) => elapsed.as_millis(),
// 这种地方如果出错了,确实没有办法解决 // 这种地方如果出错了,确实没有办法解决
@ -290,6 +299,8 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus {
exit_code: exit_code, exit_code: exit_code,
status: status, status: status,
signal: signal, signal: signal,
time_used: time_used,
memory_used: memory_used,
real_time_used: real_time_used, real_time_used: real_time_used,
stdout: stdout, stdout: stdout,
stderr: stderr, stderr: stderr,
@ -302,6 +313,8 @@ pub struct ProcessStatus {
pub exit_code: i32, pub exit_code: i32,
pub status: i32, pub status: i32,
pub signal: i32, pub signal: i32,
pub time_used: i64,
pub memory_used: i64,
pub real_time_used: u128, pub real_time_used: u128,
pub stdout: String, pub stdout: String,
pub stderr: String, pub stderr: String,