aboutsummaryrefslogtreecommitdiffstats
path: root/toj/center/src/jmod_test_line.cpp
diff options
context:
space:
mode:
authorpzread <netfirewall@gmail.com>2013-03-01 22:30:00 +0800
committerpzread <netfirewall@gmail.com>2013-03-01 22:30:00 +0800
commit56688ed6d0b18f68ac8ddd82c4944c5d2777d20a (patch)
treebb943e164f82b4a826f1d9ce253bfabf912c0004 /toj/center/src/jmod_test_line.cpp
parent69d7b55a1c9d3100d42b9c91ab995de44b13d73b (diff)
downloadtaiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.tar
taiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.tar.gz
taiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.tar.bz2
taiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.tar.lz
taiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.tar.xz
taiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.tar.zst
taiwan-online-judge-56688ed6d0b18f68ac8ddd82c4944c5d2777d20a.zip
Taiwan Online Judge Alpha 1
Diffstat (limited to 'toj/center/src/jmod_test_line.cpp')
-rw-r--r--toj/center/src/jmod_test_line.cpp189
1 files changed, 189 insertions, 0 deletions
diff --git a/toj/center/src/jmod_test_line.cpp b/toj/center/src/jmod_test_line.cpp
new file mode 100644
index 0000000..85340ad
--- /dev/null
+++ b/toj/center/src/jmod_test_line.cpp
@@ -0,0 +1,189 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<limits.h>
+#include<dlfcn.h>
+#include<pthread.h>
+#include<json/json.h>
+
+#include"judge_def.h"
+#include"judgm_lib.h"
+#include"judgm_line.h"
+#include"jmod_test.h"
+#include"jmod_test_line.h"
+
+static int line_load_setfile(FILE *set_file,int test_id,int &timelimit,int &memlimit,double &score){
+ int ret;
+
+ json_object *jso;
+ char buf[JUDGE_SET_FILEMAX];
+
+ fread(buf,1,sizeof(buf),set_file);
+ jso = json_tokener_parse(buf);
+
+ timelimit = json_object_get_int(json_object_object_get(jso,"timelimit"));
+ memlimit = json_object_get_int(json_object_object_get(jso,"memlimit"));
+ score = json_object_get_double(json_object_array_get_idx(json_object_object_get(jso,"score"),test_id - 1));
+
+ json_object_put(jso);
+ return 0;
+}
+static void line_sigaction(int sig_num,siginfo_t *sig_info,void *context){
+ if(sig_info->si_pid == line_proc->pid && line_proc->status == JUDGE_RUN){
+ if(!line_proc->proc_wait(false)){
+ line_chk_stop_fn();
+ }
+ }
+}
+static int line_sig_set(){
+ struct sigaction sig;
+
+ sig.sa_sigaction = line_sigaction;
+ sigemptyset(&sig.sa_mask);
+ sig.sa_flags = SA_SIGINFO | SA_RESTART;
+ if(sigaction(SIGCHLD,&sig,NULL)){
+ return -1;
+ }
+
+ return 0;
+}
+static int line_sig_restore(){
+ struct sigaction sig;
+
+ sig.sa_handler = SIG_DFL;
+ sigemptyset(&sig.sa_mask);
+ sig.sa_flags = 0;
+ if(sigaction(SIGCHLD,&sig,NULL)){
+ return -1;
+ }
+
+ return 0;
+}
+static int line_sig_block(){
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask,SIGCHLD);
+ if(pthread_sigmask(SIG_BLOCK,&mask,NULL)){
+ return -1;
+ }
+
+ return 0;
+}
+static int line_sig_unblock(){
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask,SIGCHLD);
+ if(pthread_sigmask(SIG_UNBLOCK,&mask,NULL)){
+ return -1;
+ }
+
+ return 0;
+}
+static int line_sig_wait(){
+ sigset_t mask;
+ int num;
+
+ sigfillset(&mask);
+ sigdelset(&mask,SIGKILL);
+ sigdelset(&mask,SIGTERM);
+ sigdelset(&mask,SIGINT);
+ sigdelset(&mask,SIGCHLD);
+ sigsuspend(&mask);
+
+ return 0;
+}
+DLL_PUBLIC int run(judgm_line_info *info){
+ int i;
+
+ line_result_data *res_data;
+
+ int set_timelimit;
+ int set_memlimit;
+ double set_score;
+ line_set_data *set_data;
+
+ char main_path[PATH_MAX + 1];
+ char exe_path[PATH_MAX + 1];
+
+ check_init_fn chk_init_fn;
+ check_run_fn chk_run_fn;
+ judgm_proc_check_fn chk_proc_fn;
+
+ char data_path[PATH_MAX + 1];
+ int chk_status;
+
+ set_data = (line_set_data*)info->set_data;
+
+ res_data = (line_result_data*)info->res_data;
+ info->res_len = sizeof(line_result_data);
+
+ res_data->test_id = set_data->test_id;
+ res_data->status = JUDGE_ERR;
+ res_data->score = 0;
+ res_data->runtime = 0;
+ res_data->memory = 0;
+
+ if(line_load_setfile(info->set_file,set_data->test_id,set_timelimit,set_memlimit,set_score)){
+ return -1;
+ }
+
+ snprintf(main_path,sizeof(main_path),"%s/main.cpp",info->code_path);
+ snprintf(exe_path,sizeof(exe_path),"%s/test",info->run_path);
+ if(judgm_compile(info->subid,main_path,exe_path,info->lang,false,res_data->errmsg,sizeof(res_data->errmsg))){
+ res_data->status = JUDGE_CE;
+ return -1;
+ }
+
+ chk_init_fn = (check_init_fn)dlsym(info->check_dll,"init");
+ chk_run_fn = (check_run_fn)dlsym(info->check_dll,"run");
+ chk_proc_fn = (judgm_proc_check_fn)dlsym(info->check_dll,"proc");
+ line_chk_stop_fn = (check_stop_fn)dlsym(info->check_dll,"stop");
+ line_proc = new judgm_proc(info->judgk_modfd,info->run_path,exe_path,set_timelimit,(set_timelimit * 10 + 5000),set_memlimit,chk_proc_fn);
+
+ snprintf(data_path,sizeof(data_path),"%s/private/%d",info->pro_path,set_data->test_id);
+ if(chk_init_fn(info->judgk_modfd,data_path,info->run_path)){
+ delete line_proc;
+ return -1;
+ }
+ if(line_sig_set()){
+ delete line_proc;
+ return -1;
+ }
+
+ if(line_proc->proc_run()){
+ delete line_proc;
+ return -1;
+ }
+ chk_run_fn(chk_status);
+
+ line_sig_block();
+ if(line_proc->status == JUDGE_RUN){
+ line_proc->proc_kill();
+ line_sig_wait();
+ }
+ line_sig_unblock();
+
+ printf("check status %d proc status %d\n",chk_status,line_proc->status);
+
+ if(line_sig_restore()){
+ delete line_proc;
+ return -1;
+ }
+
+ if(line_proc->status != JUDGE_AC){
+ res_data->status = line_proc->status;
+ }else{
+ res_data->status = chk_status;
+ }
+ if(res_data->status == JUDGE_AC){
+ res_data->score = set_score;
+ }else{
+ res_data->score = 0;
+ }
+ res_data->runtime = line_proc->runtime;
+ res_data->memory = line_proc->memory;
+
+ delete line_proc;
+ return 0;
+}