diff --git a/std-script/box-win/execute.cpp b/std-script/box-win/execute.cpp --- a/std-script/box-win/execute.cpp +++ b/std-script/box-win/execute.cpp @@ -265,6 +265,37 @@ return (max_mem_usage <= max_mem); } +void report_stat(double time_used, int memory_used) +{ + fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n", + time_used, + time_used, (double)0, + memory_used); +} + +double get_process_time_usage(HANDLE hProcess) +{ + FILETIME creation_time; + FILETIME exit_time; + FILETIME kernel_time; + FILETIME user_time; + GetProcessTimes(hProcess, + &creation_time, + &exit_time, + &kernel_time, + &user_time); + + SYSTEMTIME sys_kernel_time; + SYSTEMTIME sys_user_time; + FileTimeToSystemTime(&kernel_time, &sys_kernel_time); + FileTimeToSystemTime(&user_time, &sys_user_time); + + double time_used = + ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) + + (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0)); + return time_used; +} + int execute(char *exname, char *inname, char *outname, double t, int max_mem) { STARTUPINFO si; @@ -289,13 +320,19 @@ &pi)) // Pointer to PROCESS_INFORMATION structure. { //printf( "CreateProcess failed (%d).\n", GetLastError() ); + fprintf(stderr, "Process creation error.\n"); + report_stat(0,0); + return EXE_RESULT_ERROR; } //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId); //fprintf(stderr,"time limit = %d\n",t); // checking memory usage // wait 0.1 sec before checking mem usage - + + SetProcessWorkingSetSize(pi.hProcess, + 1, + max_mem); int actual_memory_usage = 0; Sleep(INITIAL_WAIT_FOR_MEM_CHECK); @@ -310,7 +347,7 @@ (WaitForSingleObject(pi.hProcess, (int)(t*1000) + 1 - INITIAL_WAIT_FOR_MEM_CHECK)==WAIT_TIMEOUT)) { - // need to kill... + // Kill process, because (1) it used too much memory, or (2) time limit HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); if(ifsuccess != EXE_RESULT_MEMORY) @@ -343,12 +380,26 @@ if(ifsuccess != EXE_RESULT_MEMORY) ifsuccess = EXE_RESULT_TIMEOUT; } + + // check memory after terminated if((ifsuccess==EXE_RESULT_OK) && (!check_memory_usage(pi.dwProcessId,max_mem, &actual_memory_usage))) { // using too much memory ifsuccess = EXE_RESULT_MEMORY; } + + // check return code + if(ifsuccess==EXE_RESULT_OK) { + DWORD exitcode; + GetExitCodeProcess(pi.hProcess, &exitcode); + if(exitcode!=0) { + fprintf(stderr,"Exit status %d.\n", (int)exitcode); + ifsuccess = EXE_RESULT_ERROR; + } + } + wait_dialog(); + if(si.hStdInput!=NULL) CloseHandle(si.hStdInput); if(si.hStdOutput!=NULL) @@ -358,19 +409,19 @@ fprintf(stderr,"OK\n"); else if(ifsuccess==EXE_RESULT_TIMEOUT) fprintf(stderr,"Time limit exceeded.\n"); - else + else if(ifsuccess==EXE_RESULT_MEMORY) fprintf(stderr,"Memory limit exceeded.\n"); - double actual_time_usage; + double actual_time_usage = get_process_time_usage(pi.hProcess); + /* if(ifsuccess==EXE_RESULT_TIMEOUT) actual_time_usage = t+1; else actual_time_usage = t; + */ - fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n", - actual_time_usage, - actual_time_usage, (double)0, - (actual_memory_usage + 1023)/1024); + report_stat(actual_time_usage, + (actual_memory_usage + 1023)/1024); return ifsuccess; } diff --git a/std-script/box-win/execute.h b/std-script/box-win/execute.h --- a/std-script/box-win/execute.h +++ b/std-script/box-win/execute.h @@ -11,6 +11,7 @@ #define EXE_RESULT_OK 0 #define EXE_RESULT_TIMEOUT 1 #define EXE_RESULT_MEMORY 2 +#define EXE_RESULT_ERROR 3 #ifdef __cplusplus extern "C" { diff --git a/test/data/add_too_much_memory_dynamic.c b/test/data/add_too_much_memory_dynamic.c --- a/test/data/add_too_much_memory_dynamic.c +++ b/test/data/add_too_much_memory_dynamic.c @@ -9,7 +9,7 @@ r = scanf("%d %d",&a,&b); - huge_array = (char *)malloc(5000000); + huge_array = (char *)malloc(5*1024*1024); if(huge_array==NULL) printf("NO!"); else diff --git a/test/data/test2_05sec.c b/test/data/test2_05sec.c --- a/test/data/test2_05sec.c +++ b/test/data/test2_05sec.c @@ -1,11 +1,34 @@ #include #include #include -#include #include -#include +#include + +// run it for 0.5 s -// run it for 1.5 s +double get_running_time() +{ + FILETIME creation_time; + FILETIME exit_time; + FILETIME kernel_time; + FILETIME user_time; + GetProcessTimes(GetCurrentProcess(), + &creation_time, + &exit_time, + &kernel_time, + &user_time); + + SYSTEMTIME sys_kernel_time; + SYSTEMTIME sys_user_time; + + FileTimeToSystemTime(&kernel_time, &sys_kernel_time); + FileTimeToSystemTime(&user_time, &sys_user_time); + + double time_used = + ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) + + (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0)); + return time_used; +} int main() { @@ -17,8 +40,6 @@ r = scanf("%d %d",&a,&b); printf("%d\n",a+b); - struct rusage ru; - while(1) { c++; b+=c; @@ -26,11 +47,7 @@ c++; b+=c; } - getrusage(RUSAGE_SELF,&ru); - double rtime = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec; - rtime += (double)ru.ru_utime.tv_usec / 1000000.0; - rtime += (double)ru.ru_stime.tv_usec / 1000000.0; - if(rtime > 0.5) + if(get_running_time() > 0.5) break; } printf("%d\n",b);