public IEnumerator<TestData> GetDataEnumerator(Problem Problem)
 {
     var problem_path = _profile.TestDataSavePath + Problem.Id;
     var files = Directory.GetFiles(problem_path + "\\input\\");
     return new SDNUDataEnumerator((int index) => {
         if (index >= files.Length)
             return null;
         var res = new TestData();
         res.Name = Path.GetFileNameWithoutExtension(files[index]);
         try { res.Input = File.ReadAllText(string.Format("{0}\\input\\{1}.in", problem_path, res.Name)); } catch { }
         try { res.Output = File.ReadAllText(string.Format("{0}\\output\\{1}.out", problem_path, res.Name)); } catch { }
         if (res.Input == null && res.Output == null)
             return null;
         return res;
     });
 }
Exemple #2
0
        private bool Run(Task task, TestData data, Result res, string JudgeTempPath, char[] Buffer)
        {
            Process run = new Process();
            run.StartInfo.FileName = wrap_judge_path(_profile.RunnerFileName, JudgeTempPath);
            run.StartInfo.Arguments = wrap_judge_path(_profile.RunnerParameters, JudgeTempPath);
            run.StartInfo.WorkingDirectory = wrap_judge_path(_profile.RunnerWorkingDirectory, JudgeTempPath);
            run.StartInfo.UseShellExecute = false;
            run.StartInfo.RedirectStandardInput = true;
            run.StartInfo.RedirectStandardOutput = true;
            run.StartInfo.RedirectStandardError = true;
            run.StartInfo.CreateNoWindow = true;

            //Monitor to measure memory and time usage and kill when memory or time limit exceed.
            int MemoryCost = 0, TimeCost = 0;
            var monitor = new System.Timers.Timer(MonitorInterval);
            monitor.Elapsed += (object sender, System.Timers.ElapsedEventArgs args) =>
            {
                if (run.HasExited)
                {
                    monitor.Stop();
                    monitor.Dispose();
                }
                else
                {
                    try
                    {
                        var c_memory = (int)(run.PeakPagedMemorySize64 / 1024);
                        if (c_memory > MemoryCost)
                        {
                            MemoryCost = c_memory;
                            if (MemoryCost > task.MemoryLimit)
                            {
                                res.ResultCode = ResultCode.MemoryLimitExceeded;
                                res.MemoryCost = MemoryCost;
                                try
                                {
                                    run.Kill();
                                }
                                catch { }
                            }
                        }
                        TimeCost = (int)((DateTime.Now - run.StartTime).TotalMilliseconds / _profile.TimeLimitScale);
                        //TimeCost = (int)(run.TotalProcessorTime.TotalMilliseconds / _profile.TimeLimitScale);
                        if (TimeCost > task.TimeLimit)
                        {
                            res.ResultCode = ResultCode.TimeLimitExceeded;
                            res.TimeCost = task.TimeLimit;
                            try
                            {
                                run.Kill();
                            }
                            catch { }
                        }
                    }
                    catch { }
                }
            };
            monitor.Start();

            string error_output = null;
            bool error_output_readed = false;
            string standard_output = null;
            bool standard_output_readed = false;
            //int error_pro_time = 0;
            //int output_pro_time = 0;

            ThreadPool.QueueUserWorkItem((object context) =>
            {
                while (true)
                {
                    try
                    {
                        //var start_time = run.TotalProcessorTime.TotalMilliseconds;
                        //Stopwatch sw = Stopwatch.StartNew();
                        error_output = EncodingUtils.DetectAndReadToEndAndDispose(run.StandardError.BaseStream);
                        //sw.Stop();
                        //error_pro_time = (int)(sw.ElapsedMilliseconds - run.TotalProcessorTime.TotalMilliseconds + start_time);
                        error_output_readed = true;
                        break;
                    }
                    catch
                    {
                        Thread.Sleep(100);
                    }
                }
            });

            ThreadPool.QueueUserWorkItem((object context) =>
            {
                while (true)
                {
                    try
                    {
                        //var start_time = run.TotalProcessorTime.TotalMilliseconds;
                        //Stopwatch sw = Stopwatch.StartNew();
                        standard_output = EncodingUtils.DetectAndReadToEndAndDispose(run.StandardOutput.BaseStream);
                        //sw.Stop();
                        //output_pro_time = (int)(sw.ElapsedMilliseconds - run.TotalProcessorTime.TotalMilliseconds + start_time);
                        standard_output_readed = true;
                        break;
                    }
                    catch
                    {
                        Thread.Sleep(100);
                    }
                }
            });

            run.Start();
            using (var usage = AffinityManager.GetUsage(run.ProcessorAffinity))
            {
                try
                {
                    try
                    {
                        run.ProcessorAffinity = usage.Affinity;
                        run.PriorityClass = ProcessPriorityClass.RealTime;
                        MemoryCost = (int)(run.PeakPagedMemorySize64 / 1024);
                    }
                    catch { }
                    run.StandardInput.WriteLine(data.Input);
                    run.StandardInput.Close();
                    /*run.StandardInput.AutoFlush = true;
                    int part_len = BufferSize, start_index, end_index;
                    for (start_index = 0, end_index = part_len; end_index < data.Input.Length; start_index += part_len, end_index += part_len)
                        run.StandardInput.Write(data.Input.Substring(start_index, part_len));
                    run.StandardInput.WriteLine(data.Input.Substring(start_index, data.Input.Length - start_index));*/
                }
                catch (Exception ex)
                {
                    if (res.ResultCode != ResultCode.MemoryLimitExceeded && res.ResultCode != ResultCode.TimeLimitExceeded)
                        throw ex;
                }

                if (!run.WaitForExit((int)(task.TimeLimit * _profile.TimeLimitScale)))
                {
                    if (res.ResultCode == ResultCode.MemoryLimitExceeded || res.ResultCode == ResultCode.TimeLimitExceeded)
                        return false;
                    try
                    {
                        if (run.ExitCode != 0)
                        {
                            res.ResultCode = ResultCode.RuntimeError;
                            res.Detail = grep_directory(
                                EncodingUtils.DetectAndReadToEndAndDispose(run.StandardError.BaseStream),
                                JudgeTempPath
                            );
                            return false;
                        }
                    }
                    catch { }
                    try
                    {
                        run.Kill();
                    }
                    catch { }
                    res.ResultCode = ResultCode.TimeLimitExceeded;
                    res.TimeCost = task.TimeLimit;
                    return false;
                }

                if (res.ResultCode == ResultCode.MemoryLimitExceeded || res.ResultCode == ResultCode.TimeLimitExceeded)
                    return false;

                try
                {
                    MemoryCost = (int)(run.PeakPagedMemorySize64 / 1024);
                }
                catch { }
                res.MemoryCost = MemoryCost;
                if (res.MemoryCost > task.MemoryLimit)
                {
                    res.ResultCode = ResultCode.MemoryLimitExceeded;
                    return false;
                }

                try
                {
                    TimeCost = (int)((run.ExitTime - run.StartTime).TotalMilliseconds / _profile.TimeLimitScale);
                    //TimeCost = (int)(run.TotalProcessorTime.TotalMilliseconds / _profile.TimeLimitScale);
                }
                catch { }
                if (TimeCost > res.TimeCost)
                {
                    res.TimeCost = TimeCost;
                    if (TimeCost > task.TimeLimit)
                    {
                        res.ResultCode = ResultCode.TimeLimitExceeded;
                        res.TimeCost = task.TimeLimit;
                        return false;
                    }
                }

                while (!error_output_readed || !standard_output_readed)
                    Thread.Sleep(100);

                if (run.ExitCode != 0)
                {
                    res.ResultCode = ResultCode.RuntimeError;
                    res.Detail = grep_directory(error_output, JudgeTempPath);
                    return false;
                }

                if (standard_output.Length > _profile.OutputLimit)
                {
                    res.ResultCode = ResultCode.OutputLimitExcceeded;
                    return false;
                }
                var output = standard_output.Replace("\r\n", "\n").Replace("\r", "\n").TrimEnd('\n');
                var e_output = data.Output.Replace("\r\n", "\n").Replace("\r", "\n").TrimEnd('\n');
                if (output == e_output)
                    return true;
                else
                {
                    var output_l = output.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    var e_output_l = e_output.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    if (output_l.Length == e_output_l.Length)
                    {
                        int i;
                        for (i = 0; i < output_l.Length; ++i)
                            if (output_l[i].TrimEnd() != e_output_l[i].TrimEnd())
                                break;
                        if (i == output_l.Length)
                            res.ResultCode = ResultCode.PresentationError;
                        else
                            res.ResultCode = ResultCode.WrongAnswer;
                    }
                    else
                        res.ResultCode = ResultCode.WrongAnswer;
                    return false;
                }
            }
        }