/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuOSThread.hpp Date: 2021-6-12 Author: Reece ***/ #pragma once #if defined(AURORA_IS_POSIX_DERIVED) #include #endif namespace Aurora::Threading::Threads { struct OSThread : IAuroraThread { OSThread(); OSThread(const ThreadInfo &info); OSThread(AuUInt64); ~OSThread(); bool Run() override; void Exit() override; bool Exiting() override; void SendExitSignal() override; void UnsafeForceTerminateSignal() override; void SetPriority(EThreadPriority prio) override; void SetThrottle(EThreadThrottle prio) override; void SetAffinity(const HWInfo::CpuBitId &mask) override; void SetName(const AuString &name) override; EThreadPriority GetPriority() override; EThreadThrottle GetThrottle() override; HWInfo::CpuBitId GetMask() override; AuString GetName() override; AuSPtr GetTlsView() override; void ExecuteInDeadThread(AuFunction callback) override; AuSPtr AsWaitable() override; void AddLastHopeTlsHook(const AuSPtr &feature) override; void Detach() override; void _ThreadEP(); AuSPtr AsLoopSource() override; AuSPtr GetShutdownSignalWaitable() override; AuSPtr GetShutdownSignalLS() override; bool InternalKillForceNtfy(); bool InternalKill(bool locked); void AffinityPrioThrottleTickAmendECores(); protected: bool Exit(bool willReturnToOS, bool isEOL = false); bool ExecuteNewOSContext(AuFunction task); void UpdatePrio(EThreadThrottle throttle, EThreadPriority prio); void UpdateAffinity(const HWInfo::CpuBitId &mask); void UpdateName(); void OSAttach(); void OSDeatach(); void TeminateOSContext(bool calledFromThis); void FreeOSContext(); void HookReleaseThreadResources(); void HookOnExit(); private: #if defined(AURORA_IS_POSIX_DERIVED) jmp_buf env; #endif Primitives::SpinLock tlsLock_; AuSPtr tls_; OSThread * tlsReferenceThread_ {}; AuString name_; ThreadInfo info_; HWInfo::CpuBitId mask_ = HWInfo::CpuBitId().Not(); HWInfo::CpuBitId throttleMask_ = HWInfo::CpuBitId().Not(); EThreadPriority prio_ = EThreadPriority::ePrioNormal; EThreadThrottle throttle_ = EThreadThrottle::eNormal; bool bNotOwned {}; bool bSupportsAltKill {}; bool userManagingAffinity_ {}; bool exiting_{}; bool contextUsed_{}; // can this thread instance execute code again? Primitives::EventShared_t terminated_; Primitives::EventShared_t terminateSignal_; AuSPtr terminateSignalLs_; AuSPtr terminatedSignalLs_; bool bLongJmpOnce {}; Primitives::CriticalSectionUnique_t exitOnlyOnce_; AuList> threadFeatures_; AuFunction task_; #if defined(AURORA_IS_MODERNNT_DERIVED) HANDLE handle_ = INVALID_HANDLE_VALUE; #elif defined(AURORA_HAS_PTHREADS) pthread_t handle_ {}; #endif AuUInt64 unixThreadId_ = 0; bool detached_ {}; }; void InitThreading(); }