1 /* 2 Code to handle PETSc starting up in debuggers,etc. 3 */ 4 5 #include <petscsys.h> /*I "petscsys.h" I*/ 6 #include <signal.h> 7 #if defined(PETSC_HAVE_UNISTD_H) 8 #include <unistd.h> 9 #endif 10 #if defined(PETSC_HAVE_STDLIB_H) 11 #include <stdlib.h> 12 #endif 13 14 /* 15 These are the debugger and display used if the debugger is started up 16 */ 17 static char Debugger[PETSC_MAX_PATH_LEN]; 18 static char DebugTerminal[PETSC_MAX_PATH_LEN]; 19 static PetscBool Xterm = PETSC_TRUE; 20 21 #undef __FUNCT__ 22 #define __FUNCT__ "PetscSetDebugTerminal" 23 /*@C 24 PetscSetDebugTerminal - Sets the terminal to use (instead of xterm) for debugging. 25 26 Not Collective 27 28 Input Parameters: 29 + terminal - name of terminal and any flags required to execute a program. 30 For example "xterm -e", "urxvt -e". 31 32 Options Database Keys: 33 -debug_terminal terminal - use this terminal instead of xterm 34 35 Level: developer 36 37 Notes: 38 You can start the debugger for all processes in the same GNU screen session. 39 40 mpirun -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 41 42 will open 4 windows in the session named "debug". 43 44 Fortran Note: 45 This routine is not supported in Fortran. 46 47 Concepts: debugger^setting 48 49 .seealso: PetscSetDebugger() 50 @*/ 51 PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 52 { 53 PetscErrorCode ierr; 54 55 PetscFunctionBegin; 56 ierr = PetscStrcpy(DebugTerminal,terminal);CHKERRQ(ierr); 57 PetscFunctionReturn(0); 58 } 59 60 #undef __FUNCT__ 61 #define __FUNCT__ "PetscSetDebugger" 62 /*@C 63 PetscSetDebugger - Sets options associated with the debugger. 64 65 Not Collective 66 67 Input Parameters: 68 + debugger - name of debugger, which should be in your path, 69 usually "dbx", "gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 70 supports "xdb", and IBM rs6000 supports "xldb". 71 72 - xterm - flag to indicate debugger window, set to either 1 (to indicate 73 debugger should be started in a new xterm) or 0 (to start debugger 74 in initial window (the option 0 makes no sense when using more 75 than one processor.) 76 77 Level: developer 78 79 Fortran Note: 80 This routine is not supported in Fortran. 81 82 Concepts: debugger^setting 83 84 .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler() 85 @*/ 86 PetscErrorCode PetscSetDebugger(const char debugger[],PetscBool xterm) 87 { 88 PetscErrorCode ierr; 89 90 PetscFunctionBegin; 91 if (debugger) { 92 ierr = PetscStrcpy(Debugger,debugger);CHKERRQ(ierr); 93 } 94 Xterm = xterm; 95 PetscFunctionReturn(0); 96 } 97 98 #undef __FUNCT__ 99 #define __FUNCT__ "PetscSetDefaultDebugger" 100 /*@ 101 PetscSetDefaultDebugger - Causes PETSc to use its default debugger. 102 103 Not collective 104 105 Level: advanced 106 107 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 108 @*/ 109 PetscErrorCode PetscSetDefaultDebugger(void) 110 { 111 PetscErrorCode ierr; 112 113 PetscFunctionBegin; 114 #if defined(PETSC_USE_DBX_DEBUGGER) 115 ierr = PetscSetDebugger("dbx",PETSC_TRUE);CHKERRQ(ierr); 116 #elif defined(PETSC_USE_XDB_DEBUGGER) 117 ierr = PetscSetDebugger("xdb",PETSC_TRUE);CHKERRQ(ierr); 118 #elif defined(PETSC_USE_IDB_DEBUGGER) 119 ierr = PetscSetDebugger("idb",PETSC_TRUE);CHKERRQ(ierr); 120 #else /* Default is gdb */ 121 ierr = PetscSetDebugger("gdb",PETSC_TRUE);CHKERRQ(ierr); 122 #endif 123 ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr); 124 PetscFunctionReturn(0); 125 } 126 127 #undef __FUNCT__ 128 #define __FUNCT__ "PetscCheckDebugger_Private" 129 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 130 { 131 PetscBool exists; 132 char *f; 133 PetscErrorCode ierr; 134 135 PetscFunctionBegin; 136 ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 137 if (f) { 138 ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 139 if (exists) { 140 *debugger = string; 141 } else { 142 *debugger = defaultDbg; 143 } 144 } 145 PetscFunctionReturn(0); 146 } 147 148 #undef __FUNCT__ 149 #define __FUNCT__ "PetscSetDebuggerFromString" 150 /*@C 151 PetscSetDebuggerFromString - Set the complete path for the 152 debugger for PETSc to use. 153 154 Not collective 155 156 Level: advanced 157 158 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 159 @*/ 160 PetscErrorCode PetscSetDebuggerFromString(char *string) 161 { 162 const char *debugger = PETSC_NULL; 163 PetscBool xterm = PETSC_TRUE; 164 char *f; 165 PetscErrorCode ierr; 166 167 PetscFunctionBegin; 168 ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 169 if (f) xterm = PETSC_FALSE; 170 ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 171 if (f) xterm = PETSC_FALSE; 172 ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 173 ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 174 ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 175 ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 176 ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 177 ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 178 ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 179 ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 180 ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 181 ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 182 ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 183 ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 184 185 ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 186 PetscFunctionReturn(0); 187 } 188 189 190 #undef __FUNCT__ 191 #define __FUNCT__ "PetscAttachDebugger" 192 /*@ 193 PetscAttachDebugger - Attaches the debugger to the running process. 194 195 Not Collective 196 197 Level: advanced 198 199 Concepts: debugger^starting from program 200 201 Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 202 203 .seealso: PetscSetDebugger() 204 @*/ 205 PetscErrorCode PetscAttachDebugger(void) 206 { 207 #if !defined(PETSC_CANNOT_START_DEBUGGER) 208 int child=0; 209 PetscReal sleeptime=0; 210 PetscErrorCode ierr; 211 char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 212 #endif 213 214 PetscFunctionBegin; 215 216 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 217 (*PetscErrorPrintf)("System cannot start debugger\n"); 218 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 219 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 220 MPI_Abort(PETSC_COMM_WORLD,1); 221 #else 222 ierr = PetscGetDisplay(display,128);CHKERRQ(ierr); 223 ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 224 if (ierr) { 225 (*PetscErrorPrintf)("Cannot determine program name\n"); 226 PetscFunctionReturn(1); 227 } 228 if (!program[0]) { 229 (*PetscErrorPrintf)("Cannot determine program name\n"); 230 PetscFunctionReturn(1); 231 } 232 child = (int)fork(); 233 if (child < 0) { 234 (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 235 PetscFunctionReturn(1); 236 } 237 238 /* 239 Swap role the parent and child. This is (I think) so that control c typed 240 in the debugger goes to the correct process. 241 */ 242 if (child) { child = 0; } 243 else { child = (int)getppid(); } 244 245 if (child) { /* I am the parent, will run the debugger */ 246 const char *args[10]; 247 char pid[10]; 248 PetscInt j,jj; 249 PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg; 250 251 ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 252 /* 253 We need to send a continue signal to the "child" process on the 254 alpha, otherwise it just stays off forever 255 */ 256 #if defined (PETSC_NEED_KILL_FOR_DEBUGGER) 257 kill(child,SIGCONT); 258 #endif 259 sprintf(pid,"%d",child); 260 261 ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 262 ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr); 263 ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr); 264 ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr); 265 ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr); 266 ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr); 267 ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr); 268 ierr = PetscStrcmp(Debugger,"idb",&isidb);CHKERRQ(ierr); 269 ierr = PetscStrcmp(Debugger,"workshop",&isworkshop);CHKERRQ(ierr); 270 271 if (isxxgdb || isups || isddd ) { 272 args[1] = program; args[2] = pid; args[3] = "-display"; 273 args[0] = Debugger; args[4] = display; args[5] = 0; 274 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 275 if (execvp(args[0],(char**)args) < 0) { 276 perror("Unable to start debugger"); 277 exit(0); 278 } 279 } else if (iskdbg) { 280 args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 281 args[0] = Debugger; args[5] = display; args[6] = 0; 282 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 283 if (execvp(args[0],(char**)args) < 0) { 284 perror("Unable to start debugger"); 285 exit(0); 286 } 287 } else if (isxldb) { 288 args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 289 args[0] = Debugger; args[5] = display; args[6] = 0; 290 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 291 if (execvp(args[0],(char**)args) < 0) { 292 perror("Unable to start debugger"); 293 exit(0); 294 } 295 } else if (isworkshop) { 296 args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 297 args[0] = Debugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = 0; 298 (*PetscErrorPrintf)("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 299 if (execvp(args[0],(char**)args) < 0) { 300 perror("Unable to start debugger"); 301 exit(0); 302 } 303 } else { 304 j = 0; 305 if (Xterm) { 306 PetscBool cmp; 307 char *tmp,*tmp1; 308 ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 309 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 310 args[j++] = tmp = DebugTerminal; 311 if (display[0]) { 312 args[j++] = "-display"; args[j++] = display; 313 } 314 while (*tmp) { 315 ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 316 if (!tmp1) break; 317 *tmp1 = 0; 318 tmp = tmp1+1; 319 args[j++] = tmp; 320 } 321 } 322 args[j++] = Debugger; 323 jj = j; 324 args[j++] = program; args[j++] = pid; args[j++] = 0; 325 326 if (isidb) { 327 j = jj; 328 args[j++] = "-pid"; 329 args[j++] = pid; 330 args[j++] = "-gdb"; 331 args[j++] = program; 332 args[j++] = 0; 333 } 334 #if defined(PETSC_USE_P_FOR_DEBUGGER) 335 if (isdbx) { 336 j = jj; 337 args[j++] = "-p"; 338 args[j++] = pid; 339 args[j++] = program; 340 args[j++] = 0; 341 } 342 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 343 if (isxdb) { 344 j = jj; 345 args[j++] = "-l"; 346 args[j++] = "ALL"; 347 args[j++] = "-P"; 348 args[j++] = pid; 349 args[j++] = program; 350 args[j++] = 0; 351 } 352 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 353 if (isdbx) { 354 j = jj; 355 args[j++] = "-a"; 356 args[j++] = pid; 357 args[j++] = 0; 358 } 359 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 360 if (isdbx) { 361 j = jj; 362 args[j++] = "-pid"; 363 args[j++] = pid; 364 args[j++] = program; 365 args[j++] = 0; 366 } 367 #endif 368 if (Xterm) { 369 if (display[0]) { 370 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",Debugger,program,pid,display,hostname); 371 } else { 372 (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",Debugger,program,pid,hostname); 373 } 374 if (execvp(args[0],(char**)args) < 0) { 375 perror("Unable to start debugger in xterm"); 376 exit(0); 377 } 378 } else { 379 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",Debugger,program,pid,hostname); 380 if (execvp(args[0],(char**)args) < 0) { 381 perror("Unable to start debugger"); 382 exit(0); 383 } 384 } 385 } 386 } else { /* I am the child, continue with user code */ 387 sleeptime = 10; /* default to sleep waiting for debugger */ 388 ierr = PetscOptionsGetReal(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr); 389 if (sleeptime < 0) sleeptime = -sleeptime; 390 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 391 /* 392 HP cannot attach process to sleeping debugger, hence count instead 393 */ 394 { 395 PetscReal x = 1.0; 396 int i=10000000; 397 while (i--) x++ ; /* cannot attach to sleeper */ 398 } 399 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 400 /* 401 IBM sleep may return at anytime, hence must see if there is more time to sleep 402 */ 403 { 404 int left = sleeptime; 405 while (left > 0) {left = PetscSleep(left) - 1;} 406 } 407 #else 408 PetscSleep(sleeptime); 409 #endif 410 } 411 #endif 412 PetscFunctionReturn(0); 413 } 414 415 #undef __FUNCT__ 416 #define __FUNCT__ "PetscAttachDebuggerErrorHandler" 417 /*@C 418 PetscAttachDebuggerErrorHandler - Error handler that attaches 419 a debugger to a running process when an error is detected. 420 This routine is useful for examining variables, etc. 421 422 Not Collective 423 424 Input Parameters: 425 + comm - communicator over which error occurred 426 . line - the line number of the error (indicated by __LINE__) 427 . fun - function where error occured (indicated by __FUNCT__) 428 . file - the file in which the error was detected (indicated by __FILE__) 429 . dir - the directory of the file (indicated by __SDIR__) 430 . message - an error text string, usually just printed to the screen 431 . number - the generic error number 432 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 433 - ctx - error handler context 434 435 Options Database Keys: 436 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 437 debugger attachment 438 439 Level: developer 440 441 Notes: 442 By default the GNU debugger, gdb, is used. Alternatives are dbx and 443 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 444 445 Most users need not directly employ this routine and the other error 446 handlers, but can instead use the simplified interface SETERR, which has 447 the calling sequence 448 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 449 450 Notes for experienced users: 451 Use PetscPushErrorHandler() to set the desired error handler. The 452 currently available PETSc error handlers are 453 $ PetscTraceBackErrorHandler() 454 $ PetscAttachDebuggerErrorHandler() 455 $ PetscAbortErrorHandler() 456 or you may write your own. 457 458 Concepts: debugger^error handler 459 Concepts: error handler^attach debugger 460 461 .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 462 PetscAbortErrorHandler() 463 @*/ 464 PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char* fun,const char *file,const char* dir,PetscErrorCode num,PetscErrorType p,const char* mess,void *ctx) 465 { 466 PetscErrorCode ierr; 467 468 PetscFunctionBegin; 469 if (!fun) fun = "User provided function"; 470 if (!dir) dir = " "; 471 if (!mess) mess = " "; 472 473 (*PetscErrorPrintf)("%s() line %d in %s%s %s\n",fun,line,dir,file,mess); 474 475 ierr = PetscAttachDebugger(); 476 if (ierr) { /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 477 abort(); 478 } 479 PetscFunctionReturn(0); 480 } 481 482 #undef __FUNCT__ 483 #define __FUNCT__ "PetscStopForDebugger" 484 /*@C 485 PetscStopForDebugger - Prints a message to the screen indicating how to 486 attach to the process with the debugger and then waits for the 487 debugger to attach. 488 489 Not Collective 490 491 Level: advanced 492 493 Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 494 495 Concepts: debugger^waiting for attachment 496 497 .seealso: PetscSetDebugger(), PetscAttachDebugger() 498 @*/ 499 PetscErrorCode PetscStopForDebugger(void) 500 { 501 PetscErrorCode ierr; 502 PetscInt sleeptime=0; 503 #if !defined(PETSC_CANNOT_START_DEBUGGER) 504 int ppid; 505 PetscMPIInt rank; 506 char program[PETSC_MAX_PATH_LEN],hostname[256]; 507 PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb; 508 #endif 509 510 PetscFunctionBegin; 511 #if defined(PETSC_CANNOT_START_DEBUGGER) 512 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 513 #else 514 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 515 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 516 ierr = PetscGetHostName(hostname,256); 517 if (ierr) { 518 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 519 PetscFunctionReturn(0); 520 } 521 522 ierr = PetscGetProgramName(program,256); 523 if (ierr) { 524 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 525 PetscFunctionReturn(0); 526 } 527 if (!program[0]) { 528 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 529 PetscFunctionReturn(0); 530 } 531 532 ppid = getpid(); 533 534 ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 535 ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr); 536 ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr); 537 ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr); 538 ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr); 539 ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr); 540 ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr); 541 542 if (isxxgdb || isups || isddd || iskdbg ) { 543 (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid); 544 } 545 #if defined(PETSC_USE_A_FOR_DEBUGGER) 546 else if (isxldb) { 547 (*PetscErrorPrintf)("{%d]%s>>%s -a %d %s\n",rank,hostname,Debugger,ppid,program); 548 } 549 #endif 550 #if defined(PETSC_USE_P_FOR_DEBUGGER) 551 else if (isdbx) { 552 (*PetscErrorPrintf)("[%d]%s>>%s -p %d %s\n",rank,hostname,Debugger,ppid,program); 553 } 554 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 555 else if (isxdb) { 556 (*PetscErrorPrintf)("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,Debugger,ppid,program); 557 } 558 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 559 else if (isdbx) { 560 (*PetscErrorPrintf)("[%d]%s>>%s -a %d\n",rank,hostname,Debugger,ppid); 561 } 562 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 563 else if (isdbx) { 564 (*PetscErrorPrintf)("[%d]%s>>%s -pid %d %s\n",rank,hostname,Debugger,ppid,program); 565 } 566 #else 567 else { 568 (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid); 569 } 570 #endif 571 #endif /* PETSC_CANNOT_START_DEBUGGER */ 572 573 fflush(stdout); /* ignore error because may already be in error handler */ 574 575 sleeptime = 25; /* default to sleep waiting for debugger */ 576 PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL); /* ignore error because may already be in error handler */ 577 if (sleeptime < 0) sleeptime = -sleeptime; 578 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 579 /* 580 HP cannot attach process to sleeping debugger, hence count instead 581 */ 582 { 583 PetscReal x = 1.0; 584 int i=10000000; 585 while (i--) x++ ; /* cannot attach to sleeper */ 586 } 587 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 588 /* 589 IBM sleep may return at anytime, hence must see if there is more time to sleep 590 */ 591 { 592 int left = sleeptime; 593 while (left > 0) {left = sleep(left) - 1;} 594 } 595 #else 596 PetscSleep(sleeptime); 597 #endif 598 PetscFunctionReturn(0); 599 } 600 601 602 603