Windows Kernel evaluation of hustoj (1)

Source: Internet
Author: User
Windows Kernel evaluation of hustoj (1)

Author: You lanhai

Home: http://blog.csdn.net/you_lan_hai

 

2013.4.9 Note: The latest project address is https://github.com/nslib/freejudger. The new freejudger version is completely different from the one I wrote earlier. Although we are busy, we will continue to develop freejudger until the function is complete. For details, see:Hustoj's Windows Kernel evaluation (2)

 


The online judge system (OJ) is used to determine online whether the Code submitted by a user can solve the problem, it is often used as a platform for Training Students' Programming Practice Ability in colleges and universities, as well as ACM/ICPC and other programming competition platforms. At present, 985 and 211 of colleges and universities have their own OJ, but it is quite difficult to develop an OJ for colleges and universities with weak strength. Although the OJ system can be shared, it is not convenient to rely on others' OJ for internal exercises and training. Today, there are already a lot of OJ systems, but there are not many open-source systems, and there are fewer open-source evaluation kernels. If there is a problem with the Judgment program, you have to wait for others to update it. This may be because of the hard development process.

Hustoj is an outstanding Open Source System, which follows GPL, not only fully functional, but also maintained by the development team, eliminating the need for repeated labor in Colleges and Universities (see: http://code.google.com/p/hustoj ). Although the Web can be built on any operating system, the hustoj kernel is determined by the Linux version. I believe there will be more cainiao teams using Windows, at least we were like this in the past, how difficult is it to build a Linux environment.

When I was in school, I was one of the heads of the ACM team. We didn't have our own OJ. during training, I would go to another school's OJ to do the exercises. In most schools, the questions library of OJ is difficult, and countless new users are defeated. I witnessed several hundred teams and then lost more than 30 people, I have witnessed many computer science students who want to become programming masters playing games. As a team leader, I feel that I am not doing anything. Although some schools may have easier questions about OJ, we often encounter such embarrassment that websites cannot be logged on at important times!

As the worst professional of a hard-pressed unattended school, you want to build your own OJ for your development team. Join us: group 117975329, verification information csdn.

Okay, not much nonsense, no code no truth, Windows version of hustoj kernel Evaluation Project: http://code.google.com/p/online-judger/, has completed most of the functions, basic available, it is recommended to use SVN tool (recommended tortoisesvn) download the latest source code.

Principles
1. the database management module (dbmanager) queries the submitted information from the database that the current result is to be determined and awaiting re-determination, and assembles the information into internal identifiable task data (tasks ), the task is then transferred to the judgment unit (judgecell) for judgment.
2. The judgecell manages a set of judgecore, and each judgecore runs in an independent thread. The evaluation kernel constantly obtains tasks from the evaluation unit. If a task is found, the evaluation is performed once. Then, the evaluation result is fed back to the upper layer through the callback interface. Finally, the evaluation result is fed back to dbmanager.
3. After receiving the result, dbmanager writes the result back to the database.
4. A judgecore consists of three execution components (excuter): The Compiler (compiler), the executor (runner), and The matcher (matcher, execute the user program and generate output data to match the output data of the user program with the test data. Judgecore currently only supports C and C ++ languages.


Development Tools

Visual Studio 2008

Solution composition
The solution has three projects: lzdata, ACM, and judger.
1. lzdata is a tool for reading/writing configuration files in other projects. Currently, lzd and XML are supported. The XML format is not well supported. Currently, only the value assignment syntax is supported, and the syntax of annotations, help, and other formats is not supported.
2. ACM, which encapsulates some common Windows APIs, such as threads, processes, network communication, file processing, and MySQL.
3. judger is the judge Kernel Program of hustoj. Judger/bin is the output directory of the kernel program.

Todo
1. the kernel sandbox operating mode can be judged.
2. Added support for Java code evaluation.
3. Added support for Sim.
4. multi-process evaluation unit.
5. Support for the hustoj ide test function.


Simple test environment setup

1. Install the Wamp (Windows + Apache + MySQL + PHP) integrated environment.

2. Download hustoj and place its web directory under the Wamp/WWW directory. For database configuration, see hustoj/install/readme.

3. Download the judge program for Windows. After compilation, judger.exe is generated under the judger/bindirectory. Judger.exe can be placed in any directory, but the configuration file (config. in XML), the <testdatapath> item path must be consistent with the configuration item 'oss _ data' of the hustoj test data. It is best to use an absolute path for this path.

The program is not very well written. Welcome to the Windows Programming brick house and the OJ kernel brick house to leave your valuable bricks. The Windows sandbox (job) feature encountered several difficult issues:

1. If the job time has reached and the program has not been terminated, it usually takes 2-5 s to wait.

2. when the code containing a large array containing static declarations (the Array Memory exceeds the limit of the job) is judged, the subprocess will pop up an error dialog box when the resumethread is called after the process is added to the job. For example:

# Include... Char buffer [100*1024*1024]; // exceeds the memory limit of the job. Int main ().....

Therefore, the program execution program does not use the sandbox function, but simply starts the monitoring thread to monitor the execution of sub-processes. If the sub-process exceeds the limit, it is forcibly terminated.

Attach a piece of sandbox (job) implementation code to look at your fingers:

Bool zprocessjob: Create (const tstring & cmd, bool start _/* = true */) {If (null! = M_hprocess) {outputmsg (_ T ("process has been created! "); Return false;} int64 limittime = m_limittime * 10000; // 100ns (1 S = 10 ^ 9ns) int limitmemory = m_limitmemory * 1024; // bytes if (limitmemory <0) // exceeds the int range {limitmemory = 128*1024*1024; // default 128 m }////////////////////////////////// //////////////////////////////////////// // create a job sandbox (job) //////////////////////////////////////// /// // tstring jobname; generateguid (jobn AME); If (! M_job.create (jobname) {outputmsg (_ T ("create job faild! "); Return false ;} //////////////////////////////////////// /// // sets the job information/ //////////////////////////////////////// /// // sets the basic restriction information jobobject_extended_limit_information subprocesslimitres; zeromemory (& subprocesslimitres, sizeof (subprocesslimitres); jobobject_basic_limit_information & basicinfo = subprocesslimitres. basiclimitinformation; B Asicinfo. limitflags = job_object_limit_process_time | \ job_object_limit_priority_class | \ job_object_limit_process_memory | \ job_object_limit_die_on_unhandled_exception; basicinfo. priorityclass = normal_priority_class; // The default priority is basicinfo. perprocessusertimelimit. quadpart = limittime; // subprocess execution time NS (1 S = 10 ^ 9ns) subprocesslimitres. processmemorylimit = limitmemory; // memory limit m_job.setinformation (jobobjectex Tendedlimitinformation, & subprocesslimitres, sizeof (subprocesslimitres); // enable timereport for messages that have completed the port's time limit; zeromemory (& timereport, sizeof (timereport); timereport. endofjobtimeaction = job_object_post_at_end_of_job; m_job.setinformation (jobobjectendofjobtimeinformation, & timereport, sizeof (attributes); // UI limits jobobject_basic_ui_restrict Ions subprocesslimitui; zeromemory (& subprocesslimitui, sizeof (subprocesslimitui); subprocesslimitui. uirestrictionsclass = job_object_uilimit_none | \ job_object_uilimit_desktop | \ activities | \ job_object_uilimit_displaysettings | \ activities; m_job.setin Formation (jobobjectbasicuirestrictions, & subprocesslimitui, sizeof (subprocesslimitui); // associate a job with the completion port to determine its running status and the reason for exiting int id = generateid (); m_iocphandle = createiocompletionport (invalid_handle_value, null, ID, 0); jobobject_associate_completion_port jobcp; zeromemory (& jobcp, sizeof (jobcp); jobcp. completionkey = (pvoid) ID; jobcp. completionport = m_iocphandle; m_job.setinformation (jobobjectassoci Atecompletionportinformation, & jobcp, sizeof (jobcp )); //////////////////////////////////////// /// // create a sub-process/ //////////////////////////////////////// /// // tchar cmd _ [bufsize]; lstrcpy (CMD _, cmd. c_str (); m_hinput = createinputfile (); m_houtput = createoutputfile (); /* The first parameter of CreateProcess directs the standard output and error output to the m_houtput we created to direct the standard input to the m_hinput we created to set the subprocess to accept Stdin and stdout redirection */startupinfo; zeromemory (& startupinfo, sizeof (startupinfo); startupinfo. CB = sizeof (startupinfo); startupinfo. hstdoutput = m_houtput; startupinfo. hstderror = m_houtput; startupinfo. hstdinput = m_hinput; startupinfo. dwflags = startf_usestdhandles; process_information processinfo; zeromemory (& processinfo, sizeof (processinfo); If (! CreateProcess (CMD _, true, create_suincluded | create_breakaway_from_job, startupinfo, processinfo) {return false;} m_hprocess = processinfo. hprocess; m_hthread = processinfo. hthread; //////////////////////////////////////// /// // job Association ////////////////////////////////////// /// // If (start _) {start ();} return true;} bool zprocessjo B: Start () {outputmsga ("start run."); If (! M_job.assinprocess (m_hprocess) {outputmsg (_ T ("failed to apply process to job! % D "), getlasterror (); Return false;} // resumethread (m_hthread) of the promoter process; // close the safe_close_handle (m_hinput) handle of the standard input file and the zero-time output file ); safe_close_handle (m_houtput); // closes the main thread handle of the main process safe_close_handle (m_hthread); // waits until the sub-process finishes processing or consumes resources to exit DWORD executeresult =-1; lpoverlapped processinfo; bool done = false; while (! Done) {getqueuedcompletionstatus (m_iocphandle, & executeresult, & completekey, & processinfo, infinite); Switch (executeresult) {Case job_object_msg_new_process: {outputmsg (text ("New Process (ID = % d) in job"), processinfo);} break; Case job_object_msg_end_of_job_time: {outputmsg (text ("job time limit reached"); m_exitcode = 1; done = true;} break; Case job_object_msg_end_of_process_time: {outpu Tmsg (text ("job process (ID = % d) Time limit reached"), processinfo); m_exitcode = 1; done = true;} break; Case job_object_msg_process_memory_limit: {outputmsg (text ("process (ID = % d) exceeded memory limit"), processinfo); m_exitcode = 2; done = true;} break; Case job_object_msg_job_memory_limit: {outputmsg (text ("process (ID = % d) exceeded job memory limit"), processinfo); m_exitcode = 2; done = true ;} Break; Case job_object_msg_active_process_limit: {outputmsg (text ("too ready active processes in job");} break; Case job_object_msg_active_process_zero: {outputmsg (text ("job contains no active processes"); done = true;} break; Case job_object_msg_exit_process: {outputmsg (text ("process (ID = % d) terminated "), processinfo); done = true;} break; Case job_object_msg_abnormal_exit_process: {ou Tputmsg (text ("process (ID = % d) terminated abnormally"), processinfo); m_exitcode = 3; done = true;} break; default: outputmsg (text ("unknown notification: % d"), executeresult); m_exitcode = 99; break ;}}%jobai; zeromemory (& jobai, sizeof (jobai )); queryinformationjobobject (m_job.handle (), jobobjectbasicandioaccountinginformation, & jobai, sizeof (jobai), n Ull); required Joeli; zeromemory (& Joeli, sizeof (Joeli); queryinformationjobobject (m_job.handle (), role, & Joeli, sizeof (Joeli), null); m_runtime = jobai. basicinfo. totalusertime. lowpart/10000; m_runmemory = Joeli. peakprocessmemoryused/1024; // closes the Process Handle safe_close_handle (m_hprocess); // closes the completion port safe_close_handle (m_iocphandle); // to ensure security, kill all processes in the job whil E (! M_job.terminate (0) {outputmsg (_ T ("An error occurred while stopping the job! % D "), getlasterror (); sleep (1000) ;}// close the job handle m_job.close (); outputmsga (" end run. "); Return true ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.