MCPcopy Create free account
hub / github.com/clementgallet/libTAS / stopThisThread

Method stopThisThread

src/library/checkpoint/SaveStateManager.cpp:747–844  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

745}
746
747void SaveStateManager::stopThisThread(int signum)
748{
749 GlobalNative gn;
750
751 ThreadInfo *current_thread = ThreadManager::getCurrentThread();
752
753 if (current_thread->state == ThreadInfo::ST_TERMINATED) {
754 pthread_exit(nullptr);
755 }
756
757 if (current_thread->state == ThreadInfo::ST_CKPNTHREAD) {
758 return;
759 }
760
761 /* Make sure we don't get called twice for same thread */
762 if (ThreadManager::updateState(current_thread, ThreadInfo::ST_SUSPINPROG, ThreadInfo::ST_SIGNALED)) {
763
764 /* Set up our restart point, ie, we get jumped to here after a restore */
765
766 ThreadLocalStorage::saveTLSState(&current_thread->tlsInfo); // save thread local storage
767 MYASSERT(getcontext(&current_thread->savctx) == 0)
768
769 /* We save the current stack pointer, so that we can use the remaining
770 * space in the stack as a stack segment for the clone() call if the current
771 * thread has to be created */
772 save_sp(&current_thread->saved_sp);
773
774 if (!restoreInProgress) {
775
776 /* Both state saving and state loading operations go here first, to
777 * suspend the thread. */
778
779 /* Tell the checkpoint thread that we're all saved away */
780 MYASSERT(ThreadManager::updateState(current_thread, ThreadInfo::ST_SUSPENDED, ThreadInfo::ST_SUSPINPROG))
781 sem_post(&semNotifyCkptThread);
782
783 /* Then wait for the ckpt thread to write the ckpt file then wake us up */
784 LOG(LL_DEBUG, LCF_CHECKPOINT, "Thread suspended");
785
786 /* Before suspending, we must position the stack pointer so that it
787 * always takes the same value. Because the stack pointer may not be
788 * the same between saving and loading the thread, and so returning
789 * after the `pthread_mutex_lock()` will cause a crash.
790 * To do that, we allocate on the stack a big array so that we reach
791 * near the end of the stack. */
792 ptrdiff_t free_space = reinterpret_cast<ptrdiff_t>(current_thread->saved_sp)
793 - reinterpret_cast<ptrdiff_t>(current_thread->stack_addr);
794 free_space -= 4096*4; // Arbitrary size left to run the remaining code
795
796 LOG(LL_DEBUG, LCF_CHECKPOINT, "Current stack pointer %p and base stack %p size %zu, allocate %td bytes", current_thread->saved_sp, current_thread->stack_addr, current_thread->stack_size, free_space);
797 if (free_space < 0) {
798 LOG(LL_WARN, LCF_CHECKPOINT, "We don't have enough space left in the stack to pad");
799 }
800 else {
801 uintptr_t *pad = static_cast<uintptr_t*>(alloca(free_space));
802 pad[0] = reinterpret_cast<uintptr_t>(pad); // to hopefully prevent optimization
803 }
804

Callers

nothing calls this directly

Calls 3

pthread_exitFunction · 0.85
save_spFunction · 0.85
sem_postFunction · 0.85

Tested by

no test coverage detected