Mercurial > ~astiob > upreckon > hgweb
diff win32.py @ 82:06356af50bf9
Finished testcases reorganization and CPU time limit implementation
We now have:
* Win32-specific code in the win32 module (including bug fixes),
* UNIX-specific and generic code in the unix module,
* a much cleaner testcases module,
* wait4-based resource limits working on Python 3 (this is a bug fix),
* no warning/error reported on non-Win32 when -x is not passed
but standard input does not come from a terminal,
* the maxtime configuration variable replaced with two new variables
named maxcputime and maxwalltime,
* CPU time reported if it can be determined unless an error occurs sooner
than it is determined (e. g. if the wall-clock time limit is exceeded),
* memory limits enforced even if Upreckon's forking already breaks them,
* CPU time limits and private virtual memory limits honoured on Win32,
* CPU time limits honoured on UNIX(-like) platforms supporting wait4
or getrusage,
* address space limits honoured on UNIX(-like) platforms supporting
setrlimit with RLIMIT_AS/RLIMIT_VMEM,
* resident set size limits honoured on UNIX(-like) platforms supporting
wait4.
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Wed, 23 Feb 2011 23:35:27 +0000 |
parents | 24752db487c5 |
children | 741ae3391b61 |
line wrap: on
line diff
--- a/win32.py Wed Feb 16 15:30:57 2011 +0000 +++ b/win32.py Wed Feb 23 23:35:27 2011 +0000 @@ -1,19 +1,20 @@ -# Copyright (c) 2011 Chortos-2 <chortos@inbox.lv> +# Copyright (c) 2010-2011 Chortos-2 <chortos@inbox.lv> from __future__ import division, with_statement +import sys try: from compat import * - from testcases import (TimeLimitExceeded, MemoryLimitExceeded, - CanceledByUser, CannotStartTestee) + import testcases # mutual import except ImportError: import __main__ __main__.import_error(sys.exc_info()[1]) -from __main__ import clock from ctypes import * from ctypes.wintypes import * +from msvcrt import getch as pause from subprocess import Popen +from __main__ import clock # Defaults that may be overwritten by values from _subprocess INFINITE = -1 @@ -42,7 +43,7 @@ else: ProcessTimes = namedtuple('ProcessTimes', 'kernel user') -__all__ = 'call', 'kill', 'terminate' +__all__ = 'call', 'kill', 'terminate', 'pause' # Automatically convert _subprocess handle objects into low-level HANDLEs @@ -315,7 +316,7 @@ ('PeakProcessMemoryUsed', SIZE_T), ('PeakJobMemoryUsed', SIZE_T)) -prototype = WINFUNCTYPE(BOOL, HANDLE, c_int, c_void_p, DWORD) +prototype = WINFUNCTYPE(BOOL, Handle, c_int, c_void_p, DWORD) flags = (1, 'job'), (1, 'infoclass'), (1, 'info'), (1, 'infosize') try: _setjobinfo = prototype(('SetInformationJobObject',windll.kernel32), flags) @@ -327,7 +328,7 @@ if not result: raise WinError() _setjobinfo.errcheck = errcheck def SetInformationJobObject(job, infoclass, info): - return _setjobinfo(job, infoclass, info, sizeof(info)) + return _setjobinfo(job, infoclass, byref(info), sizeof(info)) ( JobObjectBasicAccountingInformation, @@ -417,13 +418,6 @@ console_input = True FlushConsoleInputBuffer(stdin) -def kill(process): - try: - process.terminate() - except AttributeError: - TerminateProcess(process._handle) -terminate = kill - def call(*args, **kwargs): case = kwargs.pop('case') job = CreateJobObject(None) @@ -443,14 +437,14 @@ try: case.process = Popen(*args, **kwargs) except OSError: - raise CannotStartTestee(sys.exc_info()[1]) + raise testcases.CannotStartTestee(sys.exc_info()[1]) case.time_started = clock() AssignProcessToJobObject(job, case.process._handle) if not console_input: if case.maxwalltime: if (WaitForSingleObject(case.process._handle, case.maxwalltime) != WAIT_OBJECT_0): - raise TimeLimitExceeded + raise testcases.WallTimeLimitExceeded else: case.process.wait() else: @@ -467,9 +461,9 @@ ir.EventType == 1 and ir.Event.KeyEvent.bKeyDown and ir.Event.KeyEvent.wVirtualKeyCode == 27): - raise CanceledByUser + raise testcases.CanceledByUser else: - raise TimeLimitExceeded + raise testcases.WallTimeLimitExceeded else: while case.process.poll() is None: if (WaitForMultipleObjects(handles, False, INFINITE) == @@ -479,16 +473,24 @@ ir.EventType == 1 and ir.Event.KeyEvent.bKeyDown and ir.Event.KeyEvent.wVirtualKeyCode == 27): - raise CanceledByUser + raise testcases.CanceledByUser case.time_stopped = clock() - if case.maxcputime and GetProcessTimes: + if GetProcessTimes: try: times = GetProcessTimes(case.process._handle) except WindowsError: pass else: - if times.kernel + times.user > case.maxcputime: - raise TimeLimitExceeded + time = times.kernel + times.user + case.time_stopped = time + case.time_started = 0 + case.time_limit_string = case.cpu_time_limit_string + if case.maxcputime and time > case.maxcputime: + raise testcases.CPUTimeLimitExceeded + if case.maxcputime and case.process.returncode == 1816: + raise testcases.CPUTimeLimitExceeded + if case.maxmemory and case.process.returncode == -0x3ffffffb: + raise testcases.MemoryLimitExceeded if case.maxmemory and GetProcessMemoryInfo: try: counters = GetProcessMemoryInfo(case.process._handle) @@ -496,4 +498,12 @@ pass else: if counters.PeakPagefileUsage > case.maxmemory * 1048576: - raise MemoryLimitExceeded \ No newline at end of file + raise testcases.MemoryLimitExceeded + + +def kill(process): + try: + process.terminate() + except AttributeError: + TerminateProcess(process._handle) +terminate = kill \ No newline at end of file