diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index fe97f131cd..1787e4ea66 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1678,8 +1678,6 @@ static void prepare_throw_access_violation(x64_context* context, const char* cau RIP(context) = (u64)std::addressof(throw_access_violation); } -static void _handle_interrupt(x64_context* ctx); - #ifdef _WIN32 static LONG exception_handler(PEXCEPTION_POINTERS pExp) @@ -1819,11 +1817,6 @@ static void signal_handler(int sig, siginfo_t* info, void* uct) { x64_context* context = (ucontext_t*)uct; - if (sig == SIGUSR1) - { - return _handle_interrupt(context); - } - #ifdef __APPLE__ const bool is_writing = context->uc_mcontext->__es.__err & 0x2; #else @@ -1865,14 +1858,6 @@ const bool s_exception_handler_set = []() -> bool std::abort(); } - sa.sa_sigaction = signal_handler; - - if (::sigaction(SIGUSR1, &sa, NULL) == -1) - { - std::printf("sigaction(SIGUSR1) failed (0x%x).", errno); - std::abort(); - } - return true; }(); @@ -1987,10 +1972,6 @@ void thread_ctrl::initialize() void thread_ctrl::finalize(std::exception_ptr eptr) noexcept { - // Disable and discard possible interrupts - interrupt_disable(); - test_interrupt(); - // TODO vm::reservation_free(); @@ -2187,149 +2168,6 @@ void thread_ctrl::notify() } } -static thread_local x64_context s_tls_context{}; - -static void _handle_interrupt(x64_context* ctx) -{ - // Copy context for further use (TODO: is it safe on all platforms?) - s_tls_context = *ctx; - thread_ctrl::handle_interrupt(); -} - -static thread_local void(*s_tls_handler)() = nullptr; - -[[noreturn]] static void execute_interrupt_handler() -{ - // Fix stack for throwing - if (s_tls_ret_pos) s_tls_ret_addr = std::exchange(*(u64*)s_tls_ret_pos, s_tls_ret_addr); - - // Run either throwing or returning interrupt handler - s_tls_handler(); - - // Restore context in the case of return - const auto ctx = &s_tls_context; - - if (s_tls_ret_pos) - { - RIP(ctx) = std::exchange(*(u64*)s_tls_ret_pos, s_tls_ret_addr); - RSP(ctx) += sizeof(u64); - } - else - { - RIP(ctx) = s_tls_ret_addr; - } - -#ifdef _WIN32 - RtlRestoreContext(ctx, nullptr); -#else - ::setcontext(ctx); -#endif -} - -void thread_ctrl::handle_interrupt() -{ - const auto _this = g_tls_this_thread; - const auto ctx = &s_tls_context; - - if (_this->m_guard & 0x80000000) - { - // Discard interrupt if interrupts are disabled - if (_this->m_iptr.exchange(nullptr)) - { - _this->_notify(&thread_ctrl::m_icv); - } - } - else if (_this->m_guard == 0) - { - // Set interrupt immediately if no guard set - if (const auto handler = _this->m_iptr.exchange(nullptr)) - { - _this->_notify(&thread_ctrl::m_icv); - -#ifdef _WIN32 - // Install function call - s_tls_ret_addr = RIP(ctx); - s_tls_ret_pos = is_leaf_function(s_tls_ret_addr) ? 0 : RSP(ctx) -= sizeof(u64); - s_tls_handler = handler; - RIP(ctx) = (u64)execute_interrupt_handler; -#else - // Call handler directly (TODO: install function call preserving red zone) - return handler(); -#endif - } - } - else - { - // Set delayed interrupt otherwise - _this->m_guard |= 0x40000000; - } - -#ifdef _WIN32 - RtlRestoreContext(ctx, nullptr); -#endif -} - -void thread_ctrl::interrupt(void(*handler)()) -{ - semaphore_lock lock(m_mutex); - - verify(HERE), this != g_tls_this_thread; // TODO: self-interrupt - verify(HERE), m_iptr.compare_and_swap_test(nullptr, handler); // TODO: multiple interrupts - -#ifdef _WIN32 - const auto ctx = &s_tls_context; - - const HANDLE nt = (HANDLE)m_thread.load();//OpenThread(THREAD_ALL_ACCESS, FALSE, m_data->thread_id); - verify(HERE), nt; - verify(HERE), SuspendThread(nt) != -1; - - ctx->ContextFlags = CONTEXT_FULL; - verify(HERE), GetThreadContext(nt, ctx); - - ctx->ContextFlags = CONTEXT_FULL; - const u64 _rip = RIP(ctx); - RIP(ctx) = (u64)std::addressof(thread_ctrl::handle_interrupt); - verify(HERE), SetThreadContext(nt, ctx); - - RIP(ctx) = _rip; - verify(HERE), ResumeThread(nt) != -1; - //CloseHandle(nt); -#else - pthread_kill(m_thread.load(), SIGUSR1); -#endif - - while (m_iptr) - { - m_icv.wait(lock); - } -} - -void thread_ctrl::test_interrupt() -{ - if (m_guard & 0x80000000) - { - if (m_iptr.exchange(nullptr)) - { - _notify(&thread_ctrl::m_icv); - } - - return; - } - - if (m_guard == 0x40000000 && !std::uncaught_exception()) - { - m_guard = 0; - - // Execute delayed interrupt handler - if (const auto handler = m_iptr.exchange(nullptr)) - { - _notify(&thread_ctrl::m_icv); - - return handler(); - } - } -} - void thread_ctrl::test() { const auto _this = g_tls_this_thread; diff --git a/Utilities/Thread.h b/Utilities/Thread.h index f265b49773..ab29162f36 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -112,15 +112,6 @@ class thread_ctrl final // Thread initial task or atexit task task_stack m_task; - // Thread interrupt guard counter - volatile u32 m_guard = 0x80000000; - - // Thread interrupt condition variable - cond_variable m_icv; - - // Interrupt function - atomic_t m_iptr{nullptr}; - // Fixed name std::string m_name; @@ -170,42 +161,6 @@ public: // Notify the thread void notify(); - // Internal - static void handle_interrupt(); - - // Interrupt thread with specified handler call - void interrupt(void(*handler)()); - - // Interrupt guard recursive enter - void guard_enter() - { - m_guard++; - } - - // Interrupt guard recursive leave - void guard_leave() - { - if (UNLIKELY(--m_guard & 0x40000000)) - { - test_interrupt(); - } - } - - // Allow interrupts - void interrupt_enable() - { - m_guard &= ~0x80000000; - } - - // Disable and discard any interrupt - void interrupt_disable() - { - m_guard |= 0x80000000; - } - - // Check interrupt if delayed by guard scope - void test_interrupt(); - // Wait once with timeout. Abortable, may throw. May spuriously return false. static inline bool wait_for(u64 usec) { @@ -333,36 +288,6 @@ public: } }; -// Interrupt guard scope -class thread_guard final -{ - thread_ctrl* m_thread; - -public: - thread_guard(const thread_guard&) = delete; - - thread_guard(thread_ctrl* thread) - //: m_thread(thread) - { - //m_thread->guard_enter(); - } - - thread_guard(named_thread& thread) - //: thread_guard(thread.get()) - { - } - - thread_guard() - //: thread_guard(thread_ctrl::get_current()) - { - } - - ~thread_guard() noexcept(false) - { - //m_thread->guard_leave(); - } -}; - // Wrapper for named thread, joins automatically in the destructor, can only be used in function scope class scope_thread final {