Example #1
0
        private async Task Judge(CompileResult res1, CompileResult res2, Encoding languageEncoding)
        {
            int   peakRunTimeMs = 0;
            float peakMemoryMb  = 0;

            var info = new Process2JudgeInfo
            {
                MemoryLimitMb = _fullM.MemoryLimitMb,
                TimeLimitMs   = _fullM.TimeLimitMs,
                Path1         = res1.PathToAssembly,
                Path2         = res2.PathToAssembly
            };

            for (short times = 0; times < _fullM.RunTimes; ++times)
            {
                _log.DebugExt($"NativeDll Juding {times + 1} of {_fullM.RunTimes}...");
                Process2JudgeResult result = Sandbox.Process2Judge(info, languageEncoding);
                _log.DebugExt("NativeDll Judged.");

                peakRunTimeMs = Math.Max(peakRunTimeMs, result.TimeMs);
                peakMemoryMb  = Math.Max(peakMemoryMb, result.MemoryMb);

                if (!result.Process1Ok)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.RuntimeError, peakRunTimeMs, peakMemoryMb));

                    return;
                }
                if (!result.Process2Ok)
                {
                    await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.RuntimeError, peakRunTimeMs, peakMemoryMb));

                    return;
                }

                if (!result.Accepted)
                {
                    await _client.Update(ClientJudgeModel.CreateProcess2WrongAnswer(_spush.Id, peakRunTimeMs, peakMemoryMb, result.P1Result.Output, result.P2Result.Output));

                    return;
                }
            }

            await _client.Update(ClientJudgeModel.Create(_spush.Id, SolutionState.Accepted, peakRunTimeMs, peakMemoryMb));
        }
Example #2
0
File: Sandbox.cs Project: sdcb/sdoj
        public static Process2JudgeResult Process2Judge(Process2JudgeInfo p2info, Encoding languageEncoding)
        {
            // 步骤:
            // 1、启动评测
            // 2、将进程输入、输出重定向
            // 3、等待程序运行完成
            // 4、处理并返回程序运行结果。

            // 1、启动评测
            var info1 = new SandboxRunInfo
            {
                LimitProcessCount = 1,
                MemoryLimitMb     = 512.0f,
                TimeLimitMs       = 10000,
                Path = p2info.Path1
            };
            SandboxIoResult io1 = BeginRun(info1);

            if (!io1.Succeed)
            {
                EndRun(io1.InstanceHandle);
                return(new Process2JudgeResult
                {
                    P1Result = (JudgeResult)io1
                });
            }

            var info2 = new SandboxRunInfo
            {
                LimitProcessCount = 1,
                MemoryLimitMb     = p2info.MemoryLimitMb,
                TimeLimitMs       = p2info.TimeLimitMs,
                Path = p2info.Path2
            };
            SandboxIoResult io2 = BeginRun(info2);

            if (!io2.Succeed)
            {
                EndRun(io2.InstanceHandle);
                return(new Process2JudgeResult
                {
                    P2Result = (JudgeResult)io2
                });
            }

            // 2、将两个进程的输入输出重定向。
            Func <FileStream, FileStream, CancellationToken, Task> transformFunc = async(toRead, toWrite, cancel) =>
            {
                var buffer = new char[4096];
                using (var reader = new StreamReader(toRead, Encoding.Default))
                    using (var writer = new StreamWriter(toWrite))
                    {
                        while (!cancel.IsCancellationRequested)
                        {
                            var c = await reader.ReadAsync(buffer, 0, buffer.Length);

                            if (c != 0)
                            {
                                await writer.WriteAsync(buffer, 0, c);

                                Debug.WriteLine($"{Task.CurrentId}: {new string(buffer, 0, c)}");
                                await writer.FlushAsync();
                            }
                            else
                            {
                                await Task.Delay(10);
                            }
                        }
                    }
            };

            var cancelToken  = new CancellationTokenSource();
            var transform12  = transformFunc(io1.OutputReadStream, io2.InputWriteStream, cancelToken.Token);
            var transform21  = transformFunc(io2.OutputReadStream, io1.InputWriteStream, cancelToken.Token);
            var stdErrorTask = ReadToEndFrom(io1.ErrorReadStream, languageEncoding);

            io2.ErrorReadStream.Dispose();

            // 3、等待程序运行完成
            var run1 = EndRun(io1.InstanceHandle);
            var run2 = EndRun(io2.InstanceHandle);

            cancelToken.Cancel(throwOnFirstException: false);
            transform21.Wait();
            transform12.Wait();
            stdErrorTask.Wait();

            // 4、返回运行结果。
            var toReturn = new Process2JudgeResult
            {
                P1Result = (JudgeResult)run1,
                P2Result = (JudgeResult)run2
            };

            toReturn.P1Result.Output = stdErrorTask.Result;
            return(toReturn);
        }