| 440 | } |
| 441 | |
| 442 | void |
| 443 | ThreadList::suspendThreads() |
| 444 | { |
| 445 | int needrescan; |
| 446 | Thread *thread; |
| 447 | Thread *next; |
| 448 | |
| 449 | DmtcpRWLockInit(&threadResumeLock); |
| 450 | JASSERT(DmtcpRWLockWrLock(&threadResumeLock) == 0); |
| 451 | |
| 452 | /* Halt all other threads - force them to call stopthisthread |
| 453 | * If any have blocked checkpointing, wait for them to unblock before |
| 454 | * signalling |
| 455 | */ |
| 456 | lock_threads(); |
| 457 | do { |
| 458 | needrescan = 0; |
| 459 | numUserThreads = 0; |
| 460 | for (thread = activeThreads; thread != NULL; thread = next) { |
| 461 | next = thread->next; |
| 462 | |
| 463 | if (thread == curThread) { |
| 464 | continue; |
| 465 | } |
| 466 | |
| 467 | if (thread->exiting == 1) { |
| 468 | continue; |
| 469 | } |
| 470 | |
| 471 | /* Do various things based on thread's state */ |
| 472 | switch (thread->state) { |
| 473 | case ST_RUNNING: |
| 474 | |
| 475 | /* Thread is running. Send it a signal so it will call stopthisthread. |
| 476 | * We will need to rescan (hopefully it will be suspended by then) |
| 477 | */ |
| 478 | if (Thread_UpdateState(thread, ST_SIGNALED, ST_RUNNING)) { |
| 479 | if (THREAD_TGKILL(motherpid, thread->tid, |
| 480 | SigInfo::ckptSignal()) < 0) { |
| 481 | JASSERT(errno == ESRCH) (JASSERT_ERRNO) (thread->tid) |
| 482 | .Text("error signalling thread"); |
| 483 | ThreadList::threadIsDead(thread); |
| 484 | } else { |
| 485 | needrescan = 1; |
| 486 | } |
| 487 | } |
| 488 | break; |
| 489 | |
| 490 | case ST_SIGNALED: |
| 491 | if (THREAD_TGKILL(motherpid, thread->tid, 0) == -1 && errno == ESRCH) { |
| 492 | ThreadList::threadIsDead(thread); |
| 493 | } else { |
| 494 | needrescan = 1; |
| 495 | } |
| 496 | break; |
| 497 | |
| 498 | case ST_SUSPINPROG: |
| 499 | numUserThreads++; |
nothing calls this directly
no test coverage detected