Skip to content

Commit

Permalink
feat: add memory_check_only
Browse files Browse the repository at this point in the history
close: add config memory_limit_check_only #8
  • Loading branch information
bytemain committed Feb 28, 2021
1 parent 1702b47 commit cd13ec3
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 20 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ testc: c judge
NODE_BASE=./tests/node

testnode: judge
./judge -l node.log -t 1000 -i $(NODE_BASE)/1.in -o $(NODE_BASE)/1.out -u node.tmp.out -- node $(NODE_BASE)/main.js
./judge -l node.log -t 1000 -m 2048 --mco -i $(NODE_BASE)/1.in -o $(NODE_BASE)/1.out -u node.tmp.out -- node $(NODE_BASE)/main.js


cleantest:
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,26 @@ make libjudge

下面简单介绍一个例子:

![example](https://user-images.githubusercontent.com/13938334/109389825-1b264b00-7949-11eb-9b07-11778ba3c77b.png)
![image](https://user-images.githubusercontent.com/13938334/109407241-1baafa00-79ba-11eb-8f14-51fa0ee23d27.png)

判本仓库根目录下 `tests/node/` 的题。

只需要执行 `./judge [选项...] <命令> [参数...]` 即可,比如:

```sh
./judge -l node.log -t 1000 -i ./tests/node/1.in -o ./tests/node/1.out -u node.tmp.out node ./tests/node/main.js
./judge -l node.log -t 1000 -m 2048 --mco -i ./tests/node/1.in -o ./tests/node/1.out -u node.tmp.out -- node ./tests/node/main.js
```

各参数意义:

- `-l, --log_file` Log 日志路径
- `-t, --cpu_time_limit` 限制 CPU 时间,单位是 ms
- `-t, --cpu_time_limit` CPU 时间限制 ,单位是 ms,用于判断是否超过 CPU 时间限制。
- `-m, --memory_limit` 内存限制,单位是 kb,用于判断是否超过内存限制。
- `--memory_check_only, --mco` 只进行内存限制的检查(要确认判题结果),而不进行真正的内存限制,因为在执行 Node.js 时,限制内存会导致 `node` 程序无法正常执行,会报段错误。
- `-i, --system_input` 从该文件读入数据当成待判程序的标准输入,如果不设置,也可以直接向程序使用 pipe 的方式输入数据。
- `-o, --system_output` 判题数据的输出,用于比对程序是否运行正确。
- `-u, --user_output` 将待判程序的标准输出写入该文件。

这里没有用到 `-m` 限制 Memory 的使用,因为在执行 Node.js 时,限制内存会导致 `node` 程序无法正常执行。

更多选项可以输入 `./judge -?` 查看帮助。

如果执行待判程序的命令的参数中需要使用到 `-`(如想用判题程序执行: `python --version`),那你需要将这个参数放在 `--` 后,如:
Expand Down
10 changes: 6 additions & 4 deletions src/judge.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void log_config(struct Config *config)
log_debug("config: cpu_time_limit %d ms", config->cpu_time_limit);
log_debug("config: real_time_limit %d ms", config->real_time_limit);
log_debug("config: memory_limit %d kb", config->memory_limit);
log_debug("config: memory_check_only %d kb", config->memory_check_only);
log_debug("config: memory_check_only %d", config->memory_check_only);
log_debug("config: in_file %s", config->in_file);
log_debug("config: out_file %s", config->out_file);
log_debug("config: user_out_file %s", config->user_out_file);
Expand Down Expand Up @@ -113,10 +113,12 @@ int main(int argc, char *argv[])
CLOSE_LOGGER_FILE();
exit(EXIT_FAILURE);
}

if (config.judge_mode == 1)
if (result.status == PENDING || result.status == ACCEPTED)
{
diff(&config, &result.status);
if (config.judge_mode == 1)
{
diff(&config, &result.status);
}
}
print_result(&result);
}
Expand Down
27 changes: 17 additions & 10 deletions src/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,18 @@ void child_process(struct Config *_config)
// 注意,设置 memory_limit 会导致有些程序 crash,比如 python, node
if (_config->memory_limit != RESOURCE_UNLIMITED)
{
// The maximum size of the process's virtual memory (address space) in bytes.
log_debug("set memory_limit");

struct rlimit max_memory_rl;
// 为了避免代码是正确的,但是因为超过内存 oom 而被判定为 re。
// 如果程序占用低于两倍,最后再重新检查内存占用和配置的关系,就可以判定为超内存而不是 re,如果超过两倍,那就真的 re 了(可能会被 kill)。
max_memory_rl.rlim_max = max_memory_rl.rlim_cur = _config->memory_limit * 1024 * 2;
if (setrlimit(RLIMIT_AS, &max_memory_rl))
CHILD_ERROR_EXIT("set RLIMIT_AS failure");
if (_config->memory_check_only == 0)
{
// The maximum size of the process's virtual memory (address space) in bytes.
log_debug("set memory_limit");

struct rlimit max_memory_rl;
// 为了避免代码是正确的,但是因为超过内存 oom 而被判定为 re。
// 如果程序占用低于两倍,最后再重新检查内存占用和配置的关系,就可以判定为超内存而不是 re,如果超过两倍,那就真的 re 了(可能会被 kill)。
max_memory_rl.rlim_max = max_memory_rl.rlim_cur = _config->memory_limit * 1024 * 2;
if (setrlimit(RLIMIT_AS, &max_memory_rl))
CHILD_ERROR_EXIT("set RLIMIT_AS failure");
}
}

log_debug("set max_output_size");
Expand Down Expand Up @@ -184,9 +187,9 @@ void monitor(pid_t child_pid, struct Config *_config, struct Result *_result, st
}
else
{
log_debug("child process exit normal");
// 程序正常结束,此时可通过WEXITSTATUS(status)获取进程退出状态(exit时参数)
_result->exit_code = WEXITSTATUS(status);
log_debug("child process exit_code %d", _result->exit_code);

if (_result->exit_code != 0)
{
Expand All @@ -195,9 +198,13 @@ void monitor(pid_t child_pid, struct Config *_config, struct Result *_result, st
else
{
if (_result->cpu_time_used > _config->cpu_time_limit)
{
_result->status = TIME_LIMIT_EXCEEDED;
}
else if (_result->memory_used > _config->memory_limit)
{
_result->status = MEMORY_LIMIT_EXCEEDED;
}
}
}
}
Expand Down

0 comments on commit cd13ec3

Please sign in to comment.