Description:
reports running time, checks exit status; modified running time test case, memory test case.
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r114:e28e189186ff - - 4 files changed: 86 inserted, 17 deleted
@@ -172,206 +172,257 | |||
|
172 | 172 | si->dwFlags = STARTF_USESTDHANDLES; |
|
173 | 173 | if((inname!=0) && (strcmp(inname,"-")!=0)) { |
|
174 | 174 | si->hStdInput = CreateFile(inname, |
|
175 | 175 | FILE_READ_DATA, |
|
176 | 176 | FILE_SHARE_READ, |
|
177 | 177 | &sa, |
|
178 | 178 | OPEN_EXISTING, |
|
179 | 179 | FILE_ATTRIBUTE_NORMAL, |
|
180 | 180 | NULL); |
|
181 | 181 | } else |
|
182 | 182 | si->hStdInput = NULL; |
|
183 | 183 | |
|
184 | 184 | if((outname!=0) && (strcmp(outname,"-")!=0)) { |
|
185 | 185 | si->hStdOutput = CreateFile(outname, |
|
186 | 186 | FILE_WRITE_DATA, |
|
187 | 187 | FILE_SHARE_READ, |
|
188 | 188 | &sa, |
|
189 | 189 | CREATE_ALWAYS, |
|
190 | 190 | FILE_ATTRIBUTE_NORMAL, |
|
191 | 191 | NULL); |
|
192 | 192 | } else |
|
193 | 193 | si->hStdOutput = NULL; |
|
194 | 194 | |
|
195 | 195 | si->hStdError = NULL; |
|
196 | 196 | } |
|
197 | 197 | |
|
198 | 198 | // taken from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx |
|
199 | 199 | void PrintMemoryInfo(DWORD processID) |
|
200 | 200 | { |
|
201 | 201 | HANDLE hProcess; |
|
202 | 202 | PROCESS_MEMORY_COUNTERS pmc; |
|
203 | 203 | |
|
204 | 204 | // Print the process identifier. |
|
205 | 205 | |
|
206 | 206 | printf("\nProcess ID: %u\n", processID); |
|
207 | 207 | |
|
208 | 208 | // Print information about the memory usage of the process. |
|
209 | 209 | |
|
210 | 210 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | |
|
211 | 211 | PROCESS_VM_READ, |
|
212 | 212 | FALSE,processID); |
|
213 | 213 | if(hProcess == NULL) |
|
214 | 214 | return; |
|
215 | 215 | |
|
216 | 216 | if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { |
|
217 | 217 | printf("\tPageFaultCount: %d\n",pmc.PageFaultCount); |
|
218 | 218 | printf("\tPeakWorkingSetSize: %d\n", |
|
219 | 219 | pmc.PeakWorkingSetSize); |
|
220 | 220 | printf("\tWorkingSetSize: %d\n",pmc.WorkingSetSize); |
|
221 | 221 | printf("\tQuotaPeakPagedPoolUsage: %d\n", |
|
222 | 222 | pmc.QuotaPeakPagedPoolUsage); |
|
223 | 223 | printf("\tQuotaPagedPoolUsage: %d\n", |
|
224 | 224 | pmc.QuotaPagedPoolUsage); |
|
225 | 225 | printf("\tQuotaPeakNonPagedPoolUsage: %d\n", |
|
226 | 226 | pmc.QuotaPeakNonPagedPoolUsage); |
|
227 | 227 | printf("\tQuotaNonPagedPoolUsage: %d\n", |
|
228 | 228 | pmc.QuotaNonPagedPoolUsage); |
|
229 | 229 | printf("\tPagefileUsage: %d\n",pmc.PagefileUsage); |
|
230 | 230 | printf("\tPeakPagefileUsage: %d\n", |
|
231 | 231 | pmc.PeakPagefileUsage); |
|
232 | 232 | } |
|
233 | 233 | CloseHandle( hProcess ); |
|
234 | 234 | } |
|
235 | 235 | |
|
236 | 236 | int check_memory_usage(DWORD pid, int max_mem, int *actual_usage) { |
|
237 | 237 | // modified from http://msdn.microsoft.com/en-us/library/ms682050(VS.85).aspx |
|
238 | 238 | //PrintMemoryInfo(pid); |
|
239 | 239 | HANDLE hProcess; |
|
240 | 240 | PROCESS_MEMORY_COUNTERS pmc; |
|
241 | 241 | |
|
242 | 242 | if((max_mem==0) || (pid==0)) |
|
243 | 243 | return 1; |
|
244 | 244 | |
|
245 | 245 | if(pid == get_ntvdm_pid()) { |
|
246 | 246 | fprintf(stderr,"ntvdm: ignored\n"); |
|
247 | 247 | return 1; |
|
248 | 248 | } |
|
249 | 249 | |
|
250 | 250 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | |
|
251 | 251 | PROCESS_VM_READ, |
|
252 | 252 | FALSE, pid); |
|
253 | 253 | if(hProcess == NULL) |
|
254 | 254 | return 1; |
|
255 | 255 | |
|
256 | 256 | int max_mem_usage = 0; |
|
257 | 257 | if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { |
|
258 | 258 | max_mem_usage = pmc.PeakWorkingSetSize; |
|
259 | 259 | if(pmc.PeakPagefileUsage > max_mem_usage) |
|
260 | 260 | max_mem_usage = pmc.PeakPagefileUsage; |
|
261 | 261 | } |
|
262 | 262 | CloseHandle(hProcess); |
|
263 | 263 | if(actual_usage != NULL) |
|
264 | 264 | (*actual_usage) = max_mem_usage; |
|
265 | 265 | return (max_mem_usage <= max_mem); |
|
266 | 266 | } |
|
267 | 267 | |
|
268 | + void report_stat(double time_used, int memory_used) | |
|
269 | + { | |
|
270 | + fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n", | |
|
271 | + time_used, | |
|
272 | + time_used, (double)0, | |
|
273 | + memory_used); | |
|
274 | + } | |
|
275 | + | |
|
276 | + double get_process_time_usage(HANDLE hProcess) | |
|
277 | + { | |
|
278 | + FILETIME creation_time; | |
|
279 | + FILETIME exit_time; | |
|
280 | + FILETIME kernel_time; | |
|
281 | + FILETIME user_time; | |
|
282 | + GetProcessTimes(hProcess, | |
|
283 | + &creation_time, | |
|
284 | + &exit_time, | |
|
285 | + &kernel_time, | |
|
286 | + &user_time); | |
|
287 | + | |
|
288 | + SYSTEMTIME sys_kernel_time; | |
|
289 | + SYSTEMTIME sys_user_time; | |
|
290 | + FileTimeToSystemTime(&kernel_time, &sys_kernel_time); | |
|
291 | + FileTimeToSystemTime(&user_time, &sys_user_time); | |
|
292 | + | |
|
293 | + double time_used = | |
|
294 | + ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) + | |
|
295 | + (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0)); | |
|
296 | + return time_used; | |
|
297 | + } | |
|
298 | + | |
|
268 | 299 | int execute(char *exname, char *inname, char *outname, double t, int max_mem) |
|
269 | 300 | { |
|
270 | 301 | STARTUPINFO si; |
|
271 | 302 | PROCESS_INFORMATION pi; |
|
272 | 303 | int ifsuccess = EXE_RESULT_OK; |
|
273 | 304 | |
|
274 | 305 | ZeroMemory(&si, sizeof(si)); |
|
275 | 306 | si.cb = sizeof(si); |
|
276 | 307 | ZeroMemory(&pi, sizeof(pi)); |
|
277 | 308 | |
|
278 | 309 | setstartupinfo(&si, inname, outname); |
|
279 | 310 | |
|
280 | 311 | if(!CreateProcess( NULL, // No module name (use command line). |
|
281 | 312 | TEXT(exname), // Command line. |
|
282 | 313 | NULL, // Process handle not inheritable. |
|
283 | 314 | NULL, // Thread handle not inheritable. |
|
284 | 315 | TRUE, // Set handle inheritance to FALSE. |
|
285 | 316 | 0, // No creation flags. |
|
286 | 317 | NULL, // Use parent's environment block. |
|
287 | 318 | NULL, // Use parent's starting directory. |
|
288 | 319 | &si, // Pointer to STARTUPINFO structure. |
|
289 | 320 | &pi)) // Pointer to PROCESS_INFORMATION structure. |
|
290 | 321 | { |
|
291 | 322 | //printf( "CreateProcess failed (%d).\n", GetLastError() ); |
|
323 | + fprintf(stderr, "Process creation error.\n"); | |
|
324 | + report_stat(0,0); | |
|
325 | + return EXE_RESULT_ERROR; | |
|
292 | 326 | } |
|
293 | 327 | //fprintf(stderr,"Process ID: %ld\n",pi.dwProcessId); |
|
294 | 328 | //fprintf(stderr,"time limit = %d\n",t); |
|
295 | 329 | |
|
296 | 330 | // checking memory usage |
|
297 | 331 | // wait 0.1 sec before checking mem usage |
|
298 | 332 | |
|
333 | + SetProcessWorkingSetSize(pi.hProcess, | |
|
334 | + 1, | |
|
335 | + max_mem); | |
|
299 | 336 | int actual_memory_usage = 0; |
|
300 | 337 | |
|
301 | 338 | Sleep(INITIAL_WAIT_FOR_MEM_CHECK); |
|
302 | 339 | if(!check_memory_usage(pi.dwProcessId,max_mem,&actual_memory_usage)) { |
|
303 | 340 | // using too much memory |
|
304 | 341 | fprintf(stderr,"Memory limit exceeded.\n"); |
|
305 | 342 | //PrintMemoryInfo(pi.dwProcessId); |
|
306 | 343 | ifsuccess = EXE_RESULT_MEMORY; |
|
307 | 344 | } |
|
308 | 345 | |
|
309 | 346 | if((ifsuccess == EXE_RESULT_MEMORY) || |
|
310 | 347 | (WaitForSingleObject(pi.hProcess, |
|
311 | 348 | (int)(t*1000) + 1 |
|
312 | 349 | - INITIAL_WAIT_FOR_MEM_CHECK)==WAIT_TIMEOUT)) { |
|
313 | - // need to kill... | |
|
350 | + // Kill process, because (1) it used too much memory, or (2) time limit | |
|
314 | 351 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi.dwProcessId); |
|
315 | 352 | |
|
316 | 353 | if(ifsuccess != EXE_RESULT_MEMORY) |
|
317 | 354 | fprintf(stderr,"Time limit exceeded.\n"); |
|
318 | 355 | if(hProcess != NULL) { |
|
319 | 356 | fprintf(stderr,"killing pid: %ld\n",pi.dwProcessId); |
|
320 | 357 | TerminateProcess(hProcess, 0); |
|
321 | 358 | wait_dialog(); |
|
322 | 359 | } else { |
|
323 | 360 | DWORD dwNtvdmId = get_ntvdm_pid(); |
|
324 | 361 | fprintf(stderr,"killing (ntvdm) pid: %ld\n",dwNtvdmId); |
|
325 | 362 | if(dwNtvdmId!=0) { |
|
326 | 363 | hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwNtvdmId); |
|
327 | 364 | TerminateProcess(hProcess, 0); |
|
328 | 365 | } else { |
|
329 | 366 | fprintf(stderr,"killing process error\n"); |
|
330 | 367 | } |
|
331 | 368 | |
|
332 | 369 | if(get_ntvdm_pid()!=0) { |
|
333 | 370 | fprintf(stderr,"killing error, ntvdm.exe still remains;"); |
|
334 | 371 | fprintf(stderr,"please MANUALLY kill it."); |
|
335 | 372 | fflush(stderr); |
|
336 | 373 | do { |
|
337 | 374 | Sleep(1000); |
|
338 | 375 | } while(get_ntvdm_pid()!=0); |
|
339 | 376 | fprintf(stderr,"... done\n"); |
|
340 | 377 | wait_dialog(); |
|
341 | 378 | } |
|
342 | 379 | } |
|
343 | 380 | if(ifsuccess != EXE_RESULT_MEMORY) |
|
344 | 381 | ifsuccess = EXE_RESULT_TIMEOUT; |
|
345 | 382 | } |
|
383 | + | |
|
384 | + // check memory after terminated | |
|
346 | 385 | if((ifsuccess==EXE_RESULT_OK) && |
|
347 | 386 | (!check_memory_usage(pi.dwProcessId,max_mem, &actual_memory_usage))) { |
|
348 | 387 | // using too much memory |
|
349 | 388 | ifsuccess = EXE_RESULT_MEMORY; |
|
350 | 389 | } |
|
390 | + | |
|
391 | + // check return code | |
|
392 | + if(ifsuccess==EXE_RESULT_OK) { | |
|
393 | + DWORD exitcode; | |
|
394 | + GetExitCodeProcess(pi.hProcess, &exitcode); | |
|
395 | + if(exitcode!=0) { | |
|
396 | + fprintf(stderr,"Exit status %d.\n", (int)exitcode); | |
|
397 | + ifsuccess = EXE_RESULT_ERROR; | |
|
398 | + } | |
|
399 | + } | |
|
400 | + | |
|
351 | 401 | wait_dialog(); |
|
402 | + | |
|
352 | 403 | if(si.hStdInput!=NULL) |
|
353 | 404 | CloseHandle(si.hStdInput); |
|
354 | 405 | if(si.hStdOutput!=NULL) |
|
355 | 406 | CloseHandle(si.hStdOutput); |
|
356 | 407 | |
|
357 | 408 | if(ifsuccess==EXE_RESULT_OK) |
|
358 | 409 | fprintf(stderr,"OK\n"); |
|
359 | 410 | else if(ifsuccess==EXE_RESULT_TIMEOUT) |
|
360 | 411 | fprintf(stderr,"Time limit exceeded.\n"); |
|
361 | - else | |
|
412 | + else if(ifsuccess==EXE_RESULT_MEMORY) | |
|
362 | 413 | fprintf(stderr,"Memory limit exceeded.\n"); |
|
363 | 414 | |
|
364 | - double actual_time_usage; | |
|
415 | + double actual_time_usage = get_process_time_usage(pi.hProcess); | |
|
416 | + /* | |
|
365 | 417 | if(ifsuccess==EXE_RESULT_TIMEOUT) |
|
366 | 418 | actual_time_usage = t+1; |
|
367 | 419 | else |
|
368 | 420 | actual_time_usage = t; |
|
421 | + */ | |
|
369 | 422 | |
|
370 | - fprintf(stderr,"%.4lfr%.4lfu%.4lfs%dm\n", | |
|
371 | - actual_time_usage, | |
|
372 | - actual_time_usage, (double)0, | |
|
423 | + report_stat(actual_time_usage, | |
|
373 | 424 | (actual_memory_usage + 1023)/1024); |
|
374 | 425 | |
|
375 | 426 | return ifsuccess; |
|
376 | 427 | } |
|
377 | 428 |
@@ -1,25 +1,26 | |||
|
1 | 1 | /* |
|
2 | 2 | This sandbox module is from [Fossil |
|
3 | 3 | grader](http://code.google.com/p/fossil-grader/). |
|
4 | 4 | |
|
5 | 5 | The code is a modification from an unknown source on the internet. |
|
6 | 6 | |
|
7 | 7 | */ |
|
8 | 8 | #ifndef EXECUTE_H_INCLUDED |
|
9 | 9 | #define EXECUTE_H_INCLUDED |
|
10 | 10 | |
|
11 | 11 | #define EXE_RESULT_OK 0 |
|
12 | 12 | #define EXE_RESULT_TIMEOUT 1 |
|
13 | 13 | #define EXE_RESULT_MEMORY 2 |
|
14 | + #define EXE_RESULT_ERROR 3 | |
|
14 | 15 | |
|
15 | 16 | #ifdef __cplusplus |
|
16 | 17 | extern "C" { |
|
17 | 18 | #endif |
|
18 | 19 | |
|
19 | 20 | int execute(char *exname, char *inname, char *outname, double t, int max_mem=0); |
|
20 | 21 | |
|
21 | 22 | #ifdef __cplusplus |
|
22 | 23 | } |
|
23 | 24 | #endif |
|
24 | 25 | |
|
25 | 26 | #endif |
@@ -1,20 +1,20 | |||
|
1 | 1 | #include <stdio.h> |
|
2 | 2 | #include <stdlib.h> |
|
3 | 3 | |
|
4 | 4 | int main() |
|
5 | 5 | { |
|
6 | 6 | int a,b; |
|
7 | 7 | int r; |
|
8 | 8 | char *huge_array; |
|
9 | 9 | |
|
10 | 10 | r = scanf("%d %d",&a,&b); |
|
11 | 11 | |
|
12 |
- huge_array = (char *)malloc(5 |
|
|
12 | + huge_array = (char *)malloc(5*1024*1024); | |
|
13 | 13 | if(huge_array==NULL) |
|
14 | 14 | printf("NO!"); |
|
15 | 15 | else |
|
16 | 16 | printf("%d\n",a+b); |
|
17 | 17 | |
|
18 | 18 | return 0; |
|
19 | 19 | } |
|
20 | 20 |
@@ -1,39 +1,56 | |||
|
1 | 1 | #include <stdio.h> |
|
2 | 2 | #include <stdlib.h> |
|
3 | 3 | #include <unistd.h> |
|
4 | - #include <sys/time.h> | |
|
5 | 4 | #include <time.h> |
|
6 |
- #include < |
|
|
5 | + #include <windows.h> | |
|
6 | + | |
|
7 | + // run it for 0.5 s | |
|
7 | 8 | |
|
8 | - // run it for 1.5 s | |
|
9 | + double get_running_time() | |
|
10 | + { | |
|
11 | + FILETIME creation_time; | |
|
12 | + FILETIME exit_time; | |
|
13 | + FILETIME kernel_time; | |
|
14 | + FILETIME user_time; | |
|
15 | + GetProcessTimes(GetCurrentProcess(), | |
|
16 | + &creation_time, | |
|
17 | + &exit_time, | |
|
18 | + &kernel_time, | |
|
19 | + &user_time); | |
|
20 | + | |
|
21 | + SYSTEMTIME sys_kernel_time; | |
|
22 | + SYSTEMTIME sys_user_time; | |
|
23 | + | |
|
24 | + FileTimeToSystemTime(&kernel_time, &sys_kernel_time); | |
|
25 | + FileTimeToSystemTime(&user_time, &sys_user_time); | |
|
26 | + | |
|
27 | + double time_used = | |
|
28 | + ((sys_kernel_time.wSecond + sys_kernel_time.wMilliseconds/1000.0) + | |
|
29 | + (sys_user_time.wSecond + sys_user_time.wMilliseconds/1000.0)); | |
|
30 | + return time_used; | |
|
31 | + } | |
|
9 | 32 | |
|
10 | 33 | int main() |
|
11 | 34 | { |
|
12 | 35 | int a,b; |
|
13 | 36 | |
|
14 | 37 | int c=0; |
|
15 | 38 | int r; |
|
16 | 39 | |
|
17 | 40 | r = scanf("%d %d",&a,&b); |
|
18 | 41 | printf("%d\n",a+b); |
|
19 | 42 | |
|
20 | - struct rusage ru; | |
|
21 | - | |
|
22 | 43 | while(1) { |
|
23 | 44 | c++; |
|
24 | 45 | b+=c; |
|
25 | 46 | while(c<100000) { |
|
26 | 47 | c++; |
|
27 | 48 | b+=c; |
|
28 | 49 | } |
|
29 | - getrusage(RUSAGE_SELF,&ru); | |
|
30 | - double rtime = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec; | |
|
31 | - rtime += (double)ru.ru_utime.tv_usec / 1000000.0; | |
|
32 | - rtime += (double)ru.ru_stime.tv_usec / 1000000.0; | |
|
33 | - if(rtime > 0.5) | |
|
50 | + if(get_running_time() > 0.5) | |
|
34 | 51 | break; |
|
35 | 52 | } |
|
36 | 53 | printf("%d\n",b); |
|
37 | 54 | exit(0); |
|
38 | 55 | } |
|
39 | 56 |
You need to be logged in to leave comments.
Login now