#pragma once #include "ThreadState.hpp" #include "cpuset.hpp" #include "orbis-config.hpp" #include "types.hpp" #include "../KernelAllocator.hpp" #include "../ucontext.hpp" #include "../utils/SharedAtomic.hpp" #include "../utils/SharedCV.hpp" #include "../utils/SharedMutex.hpp" #include namespace orbis { struct Process; static constexpr std::uint32_t kThreadSuspendFlag = 1 << 31; struct Thread { utils::shared_mutex mtx; Process *tproc = nullptr; uint64_t retval[2]{}; void *context{}; kvector altStack; ptr stackStart; ptr stackEnd; uint64_t fsBase{}; uint64_t gsBase{}; char name[32]{}; cpuset affinity{~0u}; SigSet sigMask = {0x7fff'ffff, ~0u, ~0u, ~0u}; rtprio prio{ .type = 2, .prio = 10, }; utils::shared_mutex suspend_mtx; utils::shared_cv suspend_cv; kvector sigReturns; kvector blockedSignals; kvector queuedSignals; shared_atomic32 suspendFlags{0}; std::int64_t hostTid = -1; lwpid_t tid = -1; unsigned unblocked = 0; ThreadState state = ThreadState::INACTIVE; std::thread handle; std::thread::native_handle_type nativeHandle; // Used to wake up thread in sleep queue utils::shared_cv sync_cv; uint64_t evfResultPattern; uint64_t evfIsCancelled; [[nodiscard]] std::thread::native_handle_type getNativeHandle() { if (handle.joinable()) { return handle.native_handle(); } return nativeHandle; } // Print backtrace void where(); void unblock(); void block(); void suspend(); void resume(); void sendSignal(int signo); void notifyUnblockedSignal(int signo); // FIXME: implement thread destruction void incRef() {} void decRef() {} }; extern thread_local Thread *g_currentThread; struct scoped_unblock { scoped_unblock(); ~scoped_unblock(); scoped_unblock(const scoped_unblock &) = delete; }; class scoped_unblock_now { bool unblocked = false; public: scoped_unblock_now() { if (g_currentThread && g_currentThread->context) { g_currentThread->unblock(); unblocked = true; } } ~scoped_unblock_now() { if (unblocked) { g_currentThread->block(); } } scoped_unblock_now(const scoped_unblock_now &) = delete; }; } // namespace orbis