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) *debugger = string; 140 else *debugger = defaultDbg; 141 } 142 PetscFunctionReturn(0); 143 } 144 145 #undef __FUNCT__ 146 #define __FUNCT__ "PetscSetDebuggerFromString" 147 /*@C 148 PetscSetDebuggerFromString - Set the complete path for the 149 debugger for PETSc to use. 150 151 Not collective 152 153 Level: developer 154 155 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 156 @*/ 157 PetscErrorCode PetscSetDebuggerFromString(const char *string) 158 { 159 const char *debugger = PETSC_NULL; 160 PetscBool xterm = PETSC_TRUE; 161 char *f; 162 PetscErrorCode ierr; 163 164 PetscFunctionBegin; 165 ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 166 if (f) xterm = PETSC_FALSE; 167 ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 168 if (f) xterm = PETSC_FALSE; 169 ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 170 ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 171 ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 172 ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 173 ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 174 ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 175 ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 176 ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 177 ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 178 ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 179 ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 180 ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 181 ierr = PetscCheckDebugger_Private("lldb", string, &debugger);CHKERRQ(ierr); 182 183 ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 184 PetscFunctionReturn(0); 185 } 186 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "PetscAttachDebugger" 190 /*@ 191 PetscAttachDebugger - Attaches the debugger to the running process. 192 193 Not Collective 194 195 Level: advanced 196 197 Concepts: debugger^starting from program 198 199 Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 200 201 .seealso: PetscSetDebugger() 202 @*/ 203 PetscErrorCode PetscAttachDebugger(void) 204 { 205 #if !defined(PETSC_CANNOT_START_DEBUGGER) 206 int child =0; 207 PetscReal sleeptime=0; 208 PetscErrorCode ierr; 209 char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 210 #endif 211 212 PetscFunctionBegin; 213 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 214 (*PetscErrorPrintf)("System cannot start debugger\n"); 215 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 216 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 217 MPI_Abort(PETSC_COMM_WORLD,1); 218 #else 219 ierr = PetscGetDisplay(display,128);CHKERRQ(ierr); 220 ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 221 if (ierr) { 222 (*PetscErrorPrintf)("Cannot determine program name\n"); 223 PetscFunctionReturn(1); 224 } 225 if (!program[0]) { 226 (*PetscErrorPrintf)("Cannot determine program name\n"); 227 PetscFunctionReturn(1); 228 } 229 child = (int)fork(); 230 if (child < 0) { 231 (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 232 PetscFunctionReturn(1); 233 } 234 235 /* 236 Swap role the parent and child. This is (I think) so that control c typed 237 in the debugger goes to the correct process. 238 */ 239 if (child) child = 0; 240 else child = (int)getppid(); 241 242 if (child) { /* I am the parent, will run the debugger */ 243 const char *args[10]; 244 char pid[10]; 245 PetscInt j,jj; 246 PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 247 248 ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 249 /* 250 We need to send a continue signal to the "child" process on the 251 alpha, otherwise it just stays off forever 252 */ 253 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 254 kill(child,SIGCONT); 255 #endif 256 sprintf(pid,"%d",child); 257 258 ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 259 ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr); 260 ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr); 261 ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr); 262 ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr); 263 ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr); 264 ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr); 265 ierr = PetscStrcmp(Debugger,"idb",&isidb);CHKERRQ(ierr); 266 ierr = PetscStrcmp(Debugger,"workshop",&isworkshop);CHKERRQ(ierr); 267 ierr = PetscStrcmp(Debugger,"lldb",&islldb);CHKERRQ(ierr); 268 269 if (isxxgdb || isups || isddd) { 270 args[1] = program; args[2] = pid; args[3] = "-display"; 271 args[0] = Debugger; args[4] = display; args[5] = 0; 272 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 273 if (execvp(args[0],(char**)args) < 0) { 274 perror("Unable to start debugger"); 275 exit(0); 276 } 277 } else if (iskdbg) { 278 args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 279 args[0] = Debugger; args[5] = display; args[6] = 0; 280 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 281 if (execvp(args[0],(char**)args) < 0) { 282 perror("Unable to start debugger"); 283 exit(0); 284 } 285 } else if (isxldb) { 286 args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 287 args[0] = Debugger; args[5] = display; args[6] = 0; 288 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 289 if (execvp(args[0],(char**)args) < 0) { 290 perror("Unable to start debugger"); 291 exit(0); 292 } 293 } else if (isworkshop) { 294 args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 295 args[0] = Debugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = 0; 296 (*PetscErrorPrintf)("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 297 if (execvp(args[0],(char**)args) < 0) { 298 perror("Unable to start debugger"); 299 exit(0); 300 } 301 } else { 302 j = 0; 303 if (Xterm) { 304 PetscBool cmp; 305 char *tmp,*tmp1; 306 ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 307 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 308 args[j++] = tmp = DebugTerminal; 309 if (display[0]) { 310 args[j++] = "-display"; args[j++] = display; 311 } 312 while (*tmp) { 313 ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 314 if (!tmp1) break; 315 *tmp1 = 0; 316 tmp = tmp1+1; 317 args[j++] = tmp; 318 } 319 } 320 args[j++] = Debugger; 321 jj = j; 322 args[j++] = program; args[j++] = pid; args[j++] = 0; 323 324 if (isidb) { 325 j = jj; 326 args[j++] = "-pid"; 327 args[j++] = pid; 328 args[j++] = "-gdb"; 329 args[j++] = program; 330 args[j++] = 0; 331 } 332 if (islldb) { 333 j = jj; 334 args[j++] = "-p"; 335 args[j++] = pid; 336 args[j++] = 0; 337 } 338 #if defined(PETSC_USE_P_FOR_DEBUGGER) 339 if (isdbx) { 340 j = jj; 341 args[j++] = "-p"; 342 args[j++] = pid; 343 args[j++] = program; 344 args[j++] = 0; 345 } 346 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 347 if (isxdb) { 348 j = jj; 349 args[j++] = "-l"; 350 args[j++] = "ALL"; 351 args[j++] = "-P"; 352 args[j++] = pid; 353 args[j++] = program; 354 args[j++] = 0; 355 } 356 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 357 if (isdbx) { 358 j = jj; 359 args[j++] = "-a"; 360 args[j++] = pid; 361 args[j++] = 0; 362 } 363 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 364 if (isdbx) { 365 j = jj; 366 args[j++] = "-pid"; 367 args[j++] = pid; 368 args[j++] = program; 369 args[j++] = 0; 370 } 371 #endif 372 if (Xterm) { 373 if (display[0]) (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",Debugger,program,pid,display,hostname); 374 else (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",Debugger,program,pid,hostname); 375 376 if (execvp(args[0],(char**)args) < 0) { 377 perror("Unable to start debugger in xterm"); 378 exit(0); 379 } 380 } else { 381 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",Debugger,program,pid,hostname); 382 if (execvp(args[0],(char**)args) < 0) { 383 perror("Unable to start debugger"); 384 exit(0); 385 } 386 } 387 } 388 } else { /* I am the child, continue with user code */ 389 sleeptime = 10; /* default to sleep waiting for debugger */ 390 ierr = PetscOptionsGetReal(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr); 391 if (sleeptime < 0) sleeptime = -sleeptime; 392 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 393 /* 394 HP cannot attach process to sleeping debugger, hence count instead 395 */ 396 { 397 PetscReal x = 1.0; 398 int i =10000000; 399 while (i--) x++; /* cannot attach to sleeper */ 400 } 401 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 402 /* 403 IBM sleep may return at anytime, hence must see if there is more time to sleep 404 */ 405 { 406 int left = sleeptime; 407 while (left > 0) left = PetscSleep(left) - 1; 408 } 409 #else 410 PetscSleep(sleeptime); 411 #endif 412 } 413 #endif 414 PetscFunctionReturn(0); 415 } 416 417 #undef __FUNCT__ 418 #define __FUNCT__ "PetscAttachDebuggerErrorHandler" 419 /*@C 420 PetscAttachDebuggerErrorHandler - Error handler that attaches 421 a debugger to a running process when an error is detected. 422 This routine is useful for examining variables, etc. 423 424 Not Collective 425 426 Input Parameters: 427 + comm - communicator over which error occurred 428 . line - the line number of the error (indicated by __LINE__) 429 . fun - function where error occured (indicated by __FUNCT__) 430 . file - the file in which the error was detected (indicated by __FILE__) 431 . dir - the directory of the file (indicated by __SDIR__) 432 . message - an error text string, usually just printed to the screen 433 . number - the generic error number 434 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 435 - ctx - error handler context 436 437 Options Database Keys: 438 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 439 debugger attachment 440 441 Level: developer 442 443 Notes: 444 By default the GNU debugger, gdb, is used. Alternatives are dbx and 445 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 446 447 Most users need not directly employ this routine and the other error 448 handlers, but can instead use the simplified interface SETERR, which has 449 the calling sequence 450 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 451 452 Notes for experienced users: 453 Use PetscPushErrorHandler() to set the desired error handler. The 454 currently available PETSc error handlers are 455 $ PetscTraceBackErrorHandler() 456 $ PetscAttachDebuggerErrorHandler() 457 $ PetscAbortErrorHandler() 458 or you may write your own. 459 460 Concepts: debugger^error handler 461 Concepts: error handler^attach debugger 462 463 .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 464 PetscAbortErrorHandler() 465 @*/ 466 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) 467 { 468 PetscErrorCode ierr; 469 470 PetscFunctionBegin; 471 if (!fun) fun = "User provided function"; 472 if (!dir) dir = " "; 473 if (!mess) mess = " "; 474 475 (*PetscErrorPrintf)("%s() line %d in %s%s %s\n",fun,line,dir,file,mess); 476 477 ierr = PetscAttachDebugger(); 478 if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 479 480 PetscFunctionReturn(0); 481 } 482 483 #undef __FUNCT__ 484 #define __FUNCT__ "PetscStopForDebugger" 485 /*@C 486 PetscStopForDebugger - Prints a message to the screen indicating how to 487 attach to the process with the debugger and then waits for the 488 debugger to attach. 489 490 Not Collective 491 492 Level: advanced 493 494 Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 495 496 Concepts: debugger^waiting for attachment 497 498 .seealso: PetscSetDebugger(), PetscAttachDebugger() 499 @*/ 500 PetscErrorCode PetscStopForDebugger(void) 501 { 502 PetscErrorCode ierr; 503 PetscInt sleeptime=0; 504 #if !defined(PETSC_CANNOT_START_DEBUGGER) 505 int ppid; 506 PetscMPIInt rank; 507 char program[PETSC_MAX_PATH_LEN],hostname[256]; 508 PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb; 509 #endif 510 511 PetscFunctionBegin; 512 #if defined(PETSC_CANNOT_START_DEBUGGER) 513 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 514 #else 515 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 516 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 517 ierr = PetscGetHostName(hostname,256); 518 if (ierr) { 519 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 520 PetscFunctionReturn(0); 521 } 522 523 ierr = PetscGetProgramName(program,256); 524 if (ierr) { 525 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 526 PetscFunctionReturn(0); 527 } 528 if (!program[0]) { 529 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 530 PetscFunctionReturn(0); 531 } 532 533 ppid = getpid(); 534 535 ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 536 ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr); 537 ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr); 538 ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr); 539 ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr); 540 ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr); 541 ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr); 542 543 if (isxxgdb || isups || isddd || iskdbg) (*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) (*PetscErrorPrintf)("{%d]%s>>%s -a %d %s\n",rank,hostname,Debugger,ppid,program); 547 #endif 548 #if defined(PETSC_USE_P_FOR_DEBUGGER) 549 else if (isdbx) (*PetscErrorPrintf)("[%d]%s>>%s -p %d %s\n",rank,hostname,Debugger,ppid,program); 550 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 551 else if (isxdb) (*PetscErrorPrintf)("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,Debugger,ppid,program); 552 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 553 else if (isdbx) (*PetscErrorPrintf)("[%d]%s>>%s -a %d\n",rank,hostname,Debugger,ppid); 554 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 555 else if (isdbx) (*PetscErrorPrintf)("[%d]%s>>%s -pid %d %s\n",rank,hostname,Debugger,ppid,program); 556 #else 557 else (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid); 558 #endif 559 #endif /* PETSC_CANNOT_START_DEBUGGER */ 560 561 fflush(stdout); /* ignore error because may already be in error handler */ 562 563 sleeptime = 25; /* default to sleep waiting for debugger */ 564 PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL); /* ignore error because may already be in error handler */ 565 if (sleeptime < 0) sleeptime = -sleeptime; 566 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 567 /* 568 HP cannot attach process to sleeping debugger, hence count instead 569 */ 570 { 571 PetscReal x = 1.0; 572 int i =10000000; 573 while (i--) x++; /* cannot attach to sleeper */ 574 } 575 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 576 /* 577 IBM sleep may return at anytime, hence must see if there is more time to sleep 578 */ 579 { 580 int left = sleeptime; 581 while (left > 0) left = sleep(left) - 1; 582 } 583 #else 584 PetscSleep(sleeptime); 585 #endif 586 PetscFunctionReturn(0); 587 } 588 589 590 591