Description:
box uses user time
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r130:db5312fad511 - - 1 file changed: 26 inserted, 4 deleted

@@ -154,275 +154,297
154 fprintf(stderr,"Some dialog opens; please MANUALLY kill it.");
154 fprintf(stderr,"Some dialog opens; please MANUALLY kill it.");
155 fflush(stderr);
155 fflush(stderr);
156 do {
156 do {
157 Sleep(1000);
157 Sleep(1000);
158 } while(check_ntvdm_dialog());
158 } while(check_ntvdm_dialog());
159 fprintf(stderr,"... done\n");
159 fprintf(stderr,"... done\n");
160 }
160 }
161 }
161 }
162
162
163 void setstartupinfo(STARTUPINFO *si, char *inname, char *outname)
163 void setstartupinfo(STARTUPINFO *si, char *inname, char *outname)
164 {
164 {
165 SECURITY_ATTRIBUTES sa;
165 SECURITY_ATTRIBUTES sa;
166
166
167 ZeroMemory(&sa, sizeof(sa));
167 ZeroMemory(&sa, sizeof(sa));
168 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
168 sa.nLength = sizeof(SECURITY_ATTRIBUTES);
169 sa.lpSecurityDescriptor = NULL;
169 sa.lpSecurityDescriptor = NULL;
170 sa.bInheritHandle = TRUE;
170 sa.bInheritHandle = TRUE;
171
171
172 si->dwFlags = STARTF_USESTDHANDLES;
172 si->dwFlags = STARTF_USESTDHANDLES;
173 if((inname!=0) && (strcmp(inname,"-")!=0)) {
173 if((inname!=0) && (strcmp(inname,"-")!=0)) {
174 si->hStdInput = CreateFile(inname,
174 si->hStdInput = CreateFile(inname,
175 FILE_READ_DATA,
175 FILE_READ_DATA,
176 FILE_SHARE_READ,
176 FILE_SHARE_READ,
177 &sa,
177 &sa,
178 OPEN_EXISTING,
178 OPEN_EXISTING,
179 FILE_ATTRIBUTE_NORMAL,
179 FILE_ATTRIBUTE_NORMAL,
180 NULL);
180 NULL);
181 } else
181 } else
182 si->hStdInput = NULL;
182 si->hStdInput = NULL;
183
183
184 if((outname!=0) && (strcmp(outname,"-")!=0)) {
184 if((outname!=0) && (strcmp(outname,"-")!=0)) {
185 si->hStdOutput = CreateFile(outname,
185 si->hStdOutput = CreateFile(outname,
186 FILE_WRITE_DATA,
186 FILE_WRITE_DATA,
187 FILE_SHARE_READ,
187 FILE_SHARE_READ,
188 &sa,
188 &sa,
189 CREATE_ALWAYS,
189 CREATE_ALWAYS,
190 FILE_ATTRIBUTE_NORMAL,
190 FILE_ATTRIBUTE_NORMAL,
191 NULL);
191 NULL);
192 } else
192 } else
193 si->hStdOutput = NULL;
193 si->hStdOutput = NULL;
194
194
195 si->hStdError = NULL;
195 si->hStdError = NULL;
196 }
196 }
197
197
198 // taken from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx
198 // taken from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx
199 void PrintMemoryInfo(DWORD processID)
199 void PrintMemoryInfo(DWORD processID)
200 {
200 {
201 HANDLE hProcess;
201 HANDLE hProcess;
202 PROCESS_MEMORY_COUNTERS pmc;
202 PROCESS_MEMORY_COUNTERS pmc;
203
203
204 // Print the process identifier.
204 // Print the process identifier.
205
205
206 printf("\nProcess ID: %u\n", processID);
206 printf("\nProcess ID: %u\n", processID);
207
207
208 // Print information about the memory usage of the process.
208 // Print information about the memory usage of the process.
209
209
210 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
210 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
211 PROCESS_VM_READ,
211 PROCESS_VM_READ,
212 FALSE,processID);
212 FALSE,processID);
213 if(hProcess == NULL)
213 if(hProcess == NULL)
214 return;
214 return;
215
215
216 if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
216 if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
217 printf("\tPageFaultCount: %d\n",pmc.PageFaultCount);
217 printf("\tPageFaultCount: %d\n",pmc.PageFaultCount);
218 printf("\tPeakWorkingSetSize: %d\n",
218 printf("\tPeakWorkingSetSize: %d\n",
219 pmc.PeakWorkingSetSize);
219 pmc.PeakWorkingSetSize);
220 printf("\tWorkingSetSize: %d\n",pmc.WorkingSetSize);
220 printf("\tWorkingSetSize: %d\n",pmc.WorkingSetSize);
221 printf("\tQuotaPeakPagedPoolUsage: %d\n",
221 printf("\tQuotaPeakPagedPoolUsage: %d\n",
222 pmc.QuotaPeakPagedPoolUsage);
222 pmc.QuotaPeakPagedPoolUsage);
223 printf("\tQuotaPagedPoolUsage: %d\n",
223 printf("\tQuotaPagedPoolUsage: %d\n",
224 pmc.QuotaPagedPoolUsage);
224 pmc.QuotaPagedPoolUsage);
225 printf("\tQuotaPeakNonPagedPoolUsage: %d\n",
225 printf("\tQuotaPeakNonPagedPoolUsage: %d\n",
226 pmc.QuotaPeakNonPagedPoolUsage);
226 pmc.QuotaPeakNonPagedPoolUsage);
227 printf("\tQuotaNonPagedPoolUsage: %d\n",
227 printf("\tQuotaNonPagedPoolUsage: %d\n",
228 pmc.QuotaNonPagedPoolUsage);
228 pmc.QuotaNonPagedPoolUsage);
229 printf("\tPagefileUsage: %d\n",pmc.PagefileUsage);
229 printf("\tPagefileUsage: %d\n",pmc.PagefileUsage);
230 printf("\tPeakPagefileUsage: %d\n",
230 printf("\tPeakPagefileUsage: %d\n",
231 pmc.PeakPagefileUsage);
231 pmc.PeakPagefileUsage);
232 }
232 }
233 CloseHandle( hProcess );
233 CloseHandle( hProcess );
234 }
234 }
235
235
236 int check_memory_usage(DWORD pid, int max_mem, int *actual_usage) {
236 int check_memory_usage(DWORD pid, int max_mem, int *actual_usage) {
237 // modified from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx
237 // modified from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx
238 //PrintMemoryInfo(pid);
238 //PrintMemoryInfo(pid);
239 HANDLE hProcess;
239 HANDLE hProcess;
240 PROCESS_MEMORY_COUNTERS pmc;
240 PROCESS_MEMORY_COUNTERS pmc;
241
241
242 if((max_mem==0) || (pid==0))
242 if((max_mem==0) || (pid==0))
243 return 1;
243 return 1;
244
244
245 if(pid == get_ntvdm_pid()) {
245 if(pid == get_ntvdm_pid()) {
246 fprintf(stderr,"ntvdm: ignored\n");
246 fprintf(stderr,"ntvdm: ignored\n");
247 return 1;
247 return 1;
248 }
248 }
249
249
250 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
250 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
251 PROCESS_VM_READ,
251 PROCESS_VM_READ,
252 FALSE, pid);
252 FALSE, pid);
253 if(hProcess == NULL)
253 if(hProcess == NULL)
254 return 1;
254 return 1;
255
255
256 int max_mem_usage = 0;
256 int max_mem_usage = 0;
257 if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
257 if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) {
258 max_mem_usage = pmc.PeakWorkingSetSize;
258 max_mem_usage = pmc.PeakWorkingSetSize;
259 if(pmc.PeakPagefileUsage > max_mem_usage)
259 if(pmc.PeakPagefileUsage > max_mem_usage)
260 max_mem_usage = pmc.PeakPagefileUsage;
260 max_mem_usage = pmc.PeakPagefileUsage;
261 }
261 }
262 CloseHandle(hProcess);
262 CloseHandle(hProcess);
263 if(actual_usage != NULL)
263 if(actual_usage != NULL)
264 (*actual_usage) = max_mem_usage;
264 (*actual_usage) = max_mem_usage;
265 return (max_mem_usage <= max_mem);
265 return (max_mem_usage <= max_mem);
266 }
266 }
267
267
268 void report_stat(double time_used, int memory_used)
268 void report_stat(double time_used, int memory_used)
269 {
269 {
270 fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n",
270 fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n",
271 time_used,
271 time_used,
272 time_used, (double)0,
272 time_used, (double)0,
273 memory_used);
273 memory_used);
274 }
274 }
275
275
276 double get_process_time_usage(HANDLE hProcess)
276 double get_process_time_usage(HANDLE hProcess)
277 {
277 {
278 FILETIME creation_time;
278 FILETIME creation_time;
279 FILETIME exit_time;
279 FILETIME exit_time;
280 FILETIME kernel_time;
280 FILETIME kernel_time;
281 FILETIME user_time;
281 FILETIME user_time;
282 GetProcessTimes(hProcess,
282 GetProcessTimes(hProcess,
283 &creation_time,
283 &creation_time,
284 &exit_time,
284 &exit_time,
285 &kernel_time,
285 &kernel_time,
286 &user_time);
286 &user_time);
287
287
288 SYSTEMTIME sys_kernel_time;
288 SYSTEMTIME sys_kernel_time;
289 SYSTEMTIME sys_user_time;
289 SYSTEMTIME sys_user_time;
290 FileTimeToSystemTime(&kernel_time, &sys_kernel_time);
290 FileTimeToSystemTime(&kernel_time, &sys_kernel_time);
291 FileTimeToSystemTime(&user_time, &sys_user_time);
291 FileTimeToSystemTime(&user_time, &sys_user_time);
292
292
293 double time_used =
293 double time_used =
294 ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) +
294 ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) +
295 (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0));
295 (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0));
296 return time_used;
296 return time_used;
297 }
297 }
298
298
299 int execute(char *exname, char *inname, char *outname, double t, int max_mem)
299 int execute(char *exname, char *inname, char *outname, double t, int max_mem)
300 {
300 {
301 STARTUPINFO si;
301 STARTUPINFO si;
302 PROCESS_INFORMATION pi;
302 PROCESS_INFORMATION pi;
303 int ifsuccess = EXE_RESULT_OK;
303 int ifsuccess = EXE_RESULT_OK;
304
304
305 ZeroMemory(&si, sizeof(si));
305 ZeroMemory(&si, sizeof(si));
306 si.cb = sizeof(si);
306 si.cb = sizeof(si);
307 ZeroMemory(&pi, sizeof(pi));
307 ZeroMemory(&pi, sizeof(pi));
308
308
309 setstartupinfo(&si, inname, outname);
309 setstartupinfo(&si, inname, outname);
310
310
311 if(!CreateProcess( NULL, // No module name (use command line).
311 if(!CreateProcess( NULL, // No module name (use command line).
312 TEXT(exname), // Command line.
312 TEXT(exname), // Command line.
313 NULL, // Process handle not inheritable.
313 NULL, // Process handle not inheritable.
314 NULL, // Thread handle not inheritable.
314 NULL, // Thread handle not inheritable.
315 TRUE, // Set handle inheritance to FALSE.
315 TRUE, // Set handle inheritance to FALSE.
316 0, // No creation flags.
316 0, // No creation flags.
317 NULL, // Use parent's environment block.
317 NULL, // Use parent's environment block.
318 NULL, // Use parent's starting directory.
318 NULL, // Use parent's starting directory.
319 &si, // Pointer to STARTUPINFO structure.
319 &si, // Pointer to STARTUPINFO structure.
320 &pi)) // Pointer to PROCESS_INFORMATION structure.
320 &pi)) // Pointer to PROCESS_INFORMATION structure.
321 {
321 {
322 //printf( "CreateProcess failed (%d).\n", GetLastError() );
322 //printf( "CreateProcess failed (%d).\n", GetLastError() );
323 fprintf(stderr, "Process creation error.\n");
323 fprintf(stderr, "Process creation error.\n");
324 report_stat(0,0);
324 report_stat(0,0);
325 return EXE_RESULT_ERROR;
325 return EXE_RESULT_ERROR;
326 }
326 }
327 //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId);
327 //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId);
328 //fprintf(stderr,"time limit = %d\n",t);
328 //fprintf(stderr,"time limit = %d\n",t);
329
329
330 // checking memory usage
330 // checking memory usage
331 // wait 0.1 sec before checking mem usage
331 // wait 0.1 sec before checking mem usage
332
332
333 SetProcessWorkingSetSize(pi.hProcess,
333 SetProcessWorkingSetSize(pi.hProcess,
334 1,
334 1,
335 max_mem);
335 max_mem);
336 int actual_memory_usage = 0;
336 int actual_memory_usage = 0;
337
337
338 Sleep(INITIAL_WAIT_FOR_MEM_CHECK);
338 Sleep(INITIAL_WAIT_FOR_MEM_CHECK);
339 if(!check_memory_usage(pi.dwProcessId,max_mem,&actual_memory_usage)) {
339 if(!check_memory_usage(pi.dwProcessId,max_mem,&actual_memory_usage)) {
340 // using too much memory
340 // using too much memory
341 fprintf(stderr,"Memory limit exceeded.\n");
341 fprintf(stderr,"Memory limit exceeded.\n");
342 //PrintMemoryInfo(pi.dwProcessId);
342 //PrintMemoryInfo(pi.dwProcessId);
343 ifsuccess = EXE_RESULT_MEMORY;
343 ifsuccess = EXE_RESULT_MEMORY;
344 }
344 }
345
345
346 - if((ifsuccess == EXE_RESULT_MEMORY) ||
346 + //printf("PID: %d\n", pi.dwProcessId);
347 - (WaitForSingleObject(pi.hProcess,
347 +
348 - (int)(t*1000) + 1
348 + if(ifsuccess != EXE_RESULT_MEMORY) {
349 - - INITIAL_WAIT_FOR_MEM_CHECK)==WAIT_TIMEOUT)) {
349 + int based_time = (int)(t*1000) + 1 - INITIAL_WAIT_FOR_MEM_CHECK;
350 + bool major_timed_out = (WaitForSingleObject(pi.hProcess,
351 + based_time)==WAIT_TIMEOUT);
352 + if(major_timed_out) {
353 + // wait some more for user time.
354 + double time_used = get_process_time_usage(pi.hProcess);
355 + while(time_used <= t) {
356 + int iter_time = 100;
357 + if(t - time_used < 200)
358 + iter_time = 20;
359 + bool iter_timed_out = (WaitForSingleObject(pi.hProcess,
360 + iter_time)==WAIT_TIMEOUT);
361 + if(!iter_timed_out)
362 + break;
363 +
364 + time_used = get_process_time_usage(pi.hProcess);
365 + //printf("%lf\n",time_used);
366 + }
367 + ifsuccess = EXE_RESULT_TIMEOUT;
368 + }
369 + }
370 +
371 + if((ifsuccess == EXE_RESULT_MEMORY) || (ifsuccess == EXE_RESULT_TIMEOUT)) {
350 // Kill process, because (1) it used too much memory, or (2) time limit
372 // Kill process, because (1) it used too much memory, or (2) time limit
351 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
373 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId);
352
374
353 if(ifsuccess != EXE_RESULT_MEMORY)
375 if(ifsuccess != EXE_RESULT_MEMORY)
354 fprintf(stderr,"Time limit exceeded.\n");
376 fprintf(stderr,"Time limit exceeded.\n");
355 if(hProcess != NULL) {
377 if(hProcess != NULL) {
356 fprintf(stderr,"killing pid: %ld\n",pi.dwProcessId);
378 fprintf(stderr,"killing pid: %ld\n",pi.dwProcessId);
357 TerminateProcess(hProcess, 0);
379 TerminateProcess(hProcess, 0);
358 wait_dialog();
380 wait_dialog();
359 } else {
381 } else {
360 DWORD dwNtvdmId = get_ntvdm_pid();
382 DWORD dwNtvdmId = get_ntvdm_pid();
361 fprintf(stderr,"killing (ntvdm) pid: %ld\n",dwNtvdmId);
383 fprintf(stderr,"killing (ntvdm) pid: %ld\n",dwNtvdmId);
362 if(dwNtvdmId!=0) {
384 if(dwNtvdmId!=0) {
363 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwNtvdmId);
385 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwNtvdmId);
364 TerminateProcess(hProcess, 0);
386 TerminateProcess(hProcess, 0);
365 } else {
387 } else {
366 fprintf(stderr,"killing process error\n");
388 fprintf(stderr,"killing process error\n");
367 }
389 }
368
390
369 if(get_ntvdm_pid()!=0) {
391 if(get_ntvdm_pid()!=0) {
370 fprintf(stderr,"killing error, ntvdm.exe still remains;");
392 fprintf(stderr,"killing error, ntvdm.exe still remains;");
371 fprintf(stderr,"please MANUALLY kill it.");
393 fprintf(stderr,"please MANUALLY kill it.");
372 fflush(stderr);
394 fflush(stderr);
373 do {
395 do {
374 Sleep(1000);
396 Sleep(1000);
375 } while(get_ntvdm_pid()!=0);
397 } while(get_ntvdm_pid()!=0);
376 fprintf(stderr,"... done\n");
398 fprintf(stderr,"... done\n");
377 wait_dialog();
399 wait_dialog();
378 }
400 }
379 }
401 }
380 if(ifsuccess != EXE_RESULT_MEMORY)
402 if(ifsuccess != EXE_RESULT_MEMORY)
381 ifsuccess = EXE_RESULT_TIMEOUT;
403 ifsuccess = EXE_RESULT_TIMEOUT;
382 }
404 }
383
405
384 // check memory after terminated
406 // check memory after terminated
385 if((ifsuccess==EXE_RESULT_OK) &&
407 if((ifsuccess==EXE_RESULT_OK) &&
386 (!check_memory_usage(pi.dwProcessId,max_mem, &actual_memory_usage))) {
408 (!check_memory_usage(pi.dwProcessId,max_mem, &actual_memory_usage))) {
387 // using too much memory
409 // using too much memory
388 ifsuccess = EXE_RESULT_MEMORY;
410 ifsuccess = EXE_RESULT_MEMORY;
389 }
411 }
390
412
391 // check return code
413 // check return code
392 if(ifsuccess==EXE_RESULT_OK) {
414 if(ifsuccess==EXE_RESULT_OK) {
393 DWORD exitcode;
415 DWORD exitcode;
394 GetExitCodeProcess(pi.hProcess, &exitcode);
416 GetExitCodeProcess(pi.hProcess, &exitcode);
395 if(exitcode!=0) {
417 if(exitcode!=0) {
396 fprintf(stderr,"Exit status %d.\n", (int)exitcode);
418 fprintf(stderr,"Exit status %d.\n", (int)exitcode);
397 ifsuccess = EXE_RESULT_ERROR;
419 ifsuccess = EXE_RESULT_ERROR;
398 }
420 }
399 }
421 }
400
422
401 wait_dialog();
423 wait_dialog();
402
424
403 if(si.hStdInput!=NULL)
425 if(si.hStdInput!=NULL)
404 CloseHandle(si.hStdInput);
426 CloseHandle(si.hStdInput);
405 if(si.hStdOutput!=NULL)
427 if(si.hStdOutput!=NULL)
406 CloseHandle(si.hStdOutput);
428 CloseHandle(si.hStdOutput);
407
429
408 if(ifsuccess==EXE_RESULT_OK)
430 if(ifsuccess==EXE_RESULT_OK)
409 fprintf(stderr,"OK\n");
431 fprintf(stderr,"OK\n");
410 else if(ifsuccess==EXE_RESULT_TIMEOUT)
432 else if(ifsuccess==EXE_RESULT_TIMEOUT)
411 fprintf(stderr,"Time limit exceeded.\n");
433 fprintf(stderr,"Time limit exceeded.\n");
412 else if(ifsuccess==EXE_RESULT_MEMORY)
434 else if(ifsuccess==EXE_RESULT_MEMORY)
413 fprintf(stderr,"Memory limit exceeded.\n");
435 fprintf(stderr,"Memory limit exceeded.\n");
414
436
415 double actual_time_usage = get_process_time_usage(pi.hProcess);
437 double actual_time_usage = get_process_time_usage(pi.hProcess);
416 /*
438 /*
417 if(ifsuccess==EXE_RESULT_TIMEOUT)
439 if(ifsuccess==EXE_RESULT_TIMEOUT)
418 actual_time_usage = t+1;
440 actual_time_usage = t+1;
419 else
441 else
420 actual_time_usage = t;
442 actual_time_usage = t;
421 */
443 */
422
444
423 report_stat(actual_time_usage,
445 report_stat(actual_time_usage,
424 (actual_memory_usage + 1023)/1024);
446 (actual_memory_usage + 1023)/1024);
425
447
426 return ifsuccess;
448 return ifsuccess;
427 }
449 }
428
450
You need to be logged in to leave comments. Login now