116 static void restore(
void* context);
125 bool tryRequireSignalFrames();
126 void clearSignalFrameRequirement();
127 void setUserReturnSignalParked(
bool parked);
129 enum UserReturnWorkFlag :
size_t {
130 UserReturnExternalWork = 1,
131 UserReturnEventsDeferred = 1 << 1,
132 UserReturnSignalFrames = 1 << 3,
133 UserReturnDeferredException = 1 << 4,
134 UserReturnOriginalSyscall = 1 << 5,
137 bool canSkipUserReturnWork();
138 bool clearUserReturnWorkIfIdle();
139 bool userReturnWorkPending()
const {
140 return __atomic_load_n(&m_UserReturnWorkPending, __ATOMIC_ACQUIRE) != 0 ||
141 isTerminationDeferred();
143 bool requiresSignalFrames()
const {
144 return __atomic_load_n(&m_SignalFramesRequired, __ATOMIC_ACQUIRE);
159 static void discard(
void* context);
189 typedef int (*ThreadStartFunc)(
void*);
209 Thread(
Process* pParent, ThreadStartFunc pStartFunction,
void* pParam,
void* pStack = 0,
210 bool semiUser =
false,
bool bDontPickCore =
false,
bool delayedStart =
false,
220 Thread(
Process* pParent, SyscallState& state,
bool delayedStart =
false,
229 virtual bool interceptSyscall(SyscallState&, uintptr_t&)
const = 0;
232 bool hasSecurityState()
const {
233 return __atomic_load_n(&m_HasSecurityState, __ATOMIC_ACQUIRE);
235 SecurityStateRef securityState();
236 void setSecurityState(
const SecurityStateRef& state);
240 AffinityResult requestAffinity(
const CpuAffinityMask& mask, uint64_t& generation);
242 AffinityResult waitAffinity(uint64_t generation);
248 AffinityResult completeAffinityAtSafePoint(
bool* waited =
nullptr);
249 bool affinityWorkPending()
const {
250 return __atomic_load_n(&m_AffinityReturnPending, __ATOMIC_ACQUIRE) != 0;
252#if PEDIGREE_AFFINITY_TESTS
253 using AffinityCommitHook = void (*)(
Thread*);
254 static void setAffinityCommitHookForTest(
Thread* target, AffinityCommitHook hook);
275 void notifySubsystemExit();
277 void forceToStartupProcessor();
281 SchedulerState& state();
287 SchedulerState* pushState();
293 void popState(
bool clean =
true);
296 void abandonCurrentState(
bool clean =
false);
299 void abandonAllStates();
310 void discardUserStackMetadataForExec();
317 return __atomic_load_n(&m_nStateLevel, __ATOMIC_ACQUIRE);
320 void* getSyscallDispatchContext()
const {
321 return m_SyscallDispatchContext;
323 void setSyscallDispatchContext(
void* context) {
324 m_SyscallDispatchContext = context;
328 void allocateStackAtLevel(
size_t stateLevel);
331 void setKernelStack();
337 void pokeState(
size_t stateLevel, SchedulerState& state);
345 void setClearChildTid(uintptr_t address);
349 return __atomic_exchange_n(&m_ClearChildTid,
static_cast<uintptr_t
>(0), __ATOMIC_ACQ_REL);
352 void setRobustList(uintptr_t address,
size_t ownerId);
354 uintptr_t getRobustList()
const {
355 return __atomic_load_n(&m_RobustList, __ATOMIC_ACQUIRE);
358 uintptr_t takeRobustList(
size_t& ownerId);
361 void recordTime(CpuTimeMode mode);
364 void trackTime(CpuTimeMode mode);
367 void transitionTime(CpuTimeMode from, CpuTimeMode to,
bool interruptsAlreadyDisabled =
false);
374 if constexpr (PEDIGREE_TIME_ACCOUNTING && !PEDIGREE_SAMPLED_TIME_ACCOUNTING) {
379 const auto sample = Time::sampleCpuTime();
380 const Time::Timestamp elapsed =
381 m_TimeAccounting.elapsedAtInterruptDisabled(from, sample.timestamp, sample.processor);
382 m_TimeAccounting.recordAtInterruptDisabled(to, sample.timestamp, sample.processor);
383 __atomic_store_n(&m_CurrentTimeAccountingMode,
static_cast<size_t>(to), __ATOMIC_RELEASE);
385 publishTimeAccounting(from, elapsed);
389 __atomic_store_n(&m_CurrentTimeAccountingMode,
static_cast<size_t>(to), __ATOMIC_RELEASE);
394 CpuTimeMode currentTimeAccountingMode()
const;
397 void accountTimerTick(Time::Timestamp delta,
bool kernelMode);
399#if PEDIGREE_BENCHMARK_SYSCALL_TIMING
400 static constexpr size_t NoSyscallTimingSlot = ~static_cast<size_t>(0);
402 size_t installSyscallTimingSlot(
size_t slot) {
403 return __atomic_exchange_n(&m_ActiveSyscallTimingSlot, slot, __ATOMIC_ACQ_REL);
406 void restoreSyscallTimingSlot(
size_t slot) {
407 __atomic_store_n(&m_ActiveSyscallTimingSlot, slot, __ATOMIC_RELEASE);
413 return __atomic_load_n(&m_UserTime, __ATOMIC_ACQUIRE);
415 Time::Timestamp getKernelTime()
const {
416 return __atomic_load_n(&m_KernelTime, __ATOMIC_ACQUIRE);
419#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
421 void publishTimeAccountingForHostedTest(Time::Timestamp user, Time::Timestamp system);
429 return m_ExecutionPersonality;
451 bool startDetached();
459 void* getKernelStack();
462 void* getKernelStackBase(
size_t* size)
const;
472 size_t getTaskId()
const {
473 return __atomic_load_n(&m_TaskId, __ATOMIC_ACQUIRE);
478 return m_StateLevels[m_nStateLevel].m_Errno;
483 m_StateLevels[m_nStateLevel].m_Errno = err;
486 enum InterruptionReason {
488 InterruptedByTimeout,
494 return getInterruptionReason() != NotInterrupted;
497 void clearInterruption() {
498 m_StateLevels[m_nStateLevel].m_InterruptionReason = NotInterrupted;
501 InterruptionReason getInterruptionReason() {
502 return m_StateLevels[m_nStateLevel].m_InterruptionReason;
505 void setInterruptionReason(InterruptionReason reason) {
506 m_StateLevels[m_nStateLevel].m_InterruptionReason = reason;
510 void markTimeoutInterruptedWait();
513 void markSignalInterruptedWait();
536 return __atomic_load_n(&m_UnwindState, __ATOMIC_ACQUIRE);
539 void setUnwindState(UnwindType ut);
542 void deferProcessExit(
int code);
545 void deferSignalExit(
int signal);
559 bool deferSubsystemException(
size_t type, uintptr_t faultAddress, uintptr_t errorCode);
561 bool hasDeferredSubsystemException()
const {
562 return __atomic_load_n(&m_DeferredSubsystemExceptionState, __ATOMIC_ACQUIRE) != 0;
566 bool takeDeferredSubsystemException(
size_t& type, uintptr_t& faultAddress, uintptr_t& errorCode);
570 return __atomic_load_n(&m_TerminationDeferralDepth, __ATOMIC_ACQUIRE) != 0;
575 for (
size_t attempt = 0; attempt < 2; ++attempt) {
576 const size_t generation = __atomic_load_n(&m_DebugStateGeneration, __ATOMIC_ACQUIRE);
577 if (generation & 1) {
581 const DebugState state = __atomic_load_n(&m_DebugState, __ATOMIC_RELAXED);
582 const uintptr_t observedAddress = __atomic_load_n(&m_DebugStateAddress, __ATOMIC_RELAXED);
583 if (generation == __atomic_load_n(&m_DebugStateGeneration, __ATOMIC_ACQUIRE)) {
584 address = observedAddress;
594 __atomic_add_fetch(&m_DebugStateGeneration,
static_cast<size_t>(1), __ATOMIC_ACQ_REL);
595 __atomic_store_n(&m_DebugStateAddress, address, __ATOMIC_RELAXED);
596 __atomic_store_n(&m_DebugState, state, __ATOMIC_RELAXED);
597 __atomic_add_fetch(&m_DebugStateGeneration,
static_cast<size_t>(1), __ATOMIC_RELEASE);
602 const void* channelOwner;
603 uintptr_t channelValue;
604 WaitQueue::WakeReason reason;
624 bool sendEvent(
Event* pEvent);
627 void waitForEvent(WaitQueue::StackDiscardCleanup onStackDiscard =
nullptr,
628 void* stackDiscardContext =
nullptr);
634 bool waitForEventOrSignalInterruption(WaitQueue::StackDiscardCleanup onStackDiscard =
nullptr,
635 void* stackDiscardContext =
nullptr);
637#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
638 enum StateTransitionWindow {
639 StatePushBeforePublish,
640 StatePushAfterPublish,
641 StatePopAfterPublish,
643 enum ExternalLeaseReleasePhase {
644 ExternalLeaseFinalReleaseUnlocked,
645 ExternalLeaseBeforeWaiterWake,
647 using StateTransitionHook = void (*)(StateTransitionWindow window,
Thread* thread,
648 size_t previousLevel,
size_t nextLevel);
649 using JoinOperationHook = void (*)(
Thread* target,
Process* parent);
650 using ExternalLeaseReleaseHook = void (*)(
Thread* target, ExternalLeaseReleasePhase phase);
651 using DeferredScopeLockHook = void (*)();
652 using SignalWaitPreEnrolmentHook = void (*)(
Thread* target);
655 static void setStateTransitionHook(StateTransitionHook hook);
658 static void setJoinOperationHook(JoinOperationHook hook);
661 static void setExternalLeaseReleaseHookForHostedTest(
Thread* target,
662 ExternalLeaseReleaseHook hook);
665 static void setSignalWaitPreEnrolmentHookForHostedTest(
Thread* target,
666 SignalWaitPreEnrolmentHook hook);
669 bool isReapableForHostedTest();
672 bool wasStartPublishedForHostedTest();
675 bool waitUntilReapableForHostedTest();
681 bool runHostedPrequeuedEventRegression();
684 bool runHostedEventDeliveryLeaseRegression();
687 bool runHostedEventShutdownRegression();
690 bool runHostedStatePublicationRegression();
693 bool runHostedStateCleanupRegression();
696 bool runHostedExecStackOwnershipRegression();
699 void withDeferredScopeLockForTest(DeferredScopeLockHook hook);
705 void inhibitEvent(
size_t eventNumber,
bool bInhibit);
708 uint64_t getSignalMask();
711 void setSignalMask(uint64_t mask);
714 uint64_t getSignalMaskForReturnFrame();
717 void commitSignalHandlerMask(uint64_t mask);
720 void restoreDeferredSignalMask(
size_t stateLevel);
724 return m_OriginalSyscallState;
727 void setOriginalSyscallState(
const SyscallState* state) {
728 m_OriginalSyscallState = state;
730 __atomic_fetch_or(&m_UserReturnWorkPending, UserReturnOriginalSyscall, __ATOMIC_RELEASE);
732 __atomic_fetch_and(&m_UserReturnWorkPending, ~
static_cast<size_t>(UserReturnOriginalSyscall),
738 void setCurrentSignalDelivery(
size_t signalNumber,
size_t continuationEpoch);
741 bool getCurrentSignalDelivery(
size_t& signalNumber,
size_t& continuationEpoch);
744 void prepareSignalStateForExec();
747 bool hasTemporarySignalWaitInterruption();
750 bool hasActiveTemporarySignalMask();
753 bool retainTemporarySignalWaitInterruptionOrClear();
765 return m_AlternateSignalStack;
769 void cullEvent(
Event* pEvent);
773 void cullEvent(
size_t eventNumber);
776 void cullSignalEvent(
size_t signalNumber);
782 bool transferProcessSignalsTo(
Thread& target);
789 bool replaceSignalEvent(
size_t signalNumber,
Event* replacement,
int processDirected = -1,
790 uint64_t rebindGeneration = 0);
793 bool hasSignalEvent(
size_t signalNumber,
int processDirected = -1);
795 bool acceptingEvents();
796 uint64_t pendingSignalMask(
bool processOnly =
false);
797 uint64_t pendingSignalOrder(
size_t signal,
bool processOnly =
false);
798 Event::Delivery reservePendingSignal(uint64_t mask,
bool processOnly =
false,
799 uint64_t expectedSequence = ~uint64_t(0));
801 void cullSignalSource(
const void* source);
802 void setSynchronousSignalMask(uint64_t mask);
803 uint64_t getSynchronousSignalMask();
808 bool hasEvent(
Event* pEvent);
809 bool hasEvent(
size_t eventNumber);
811 void setPriority(
size_t p) {
814 size_t getPriority() {
819 void unexpectedExit();
822 uintptr_t getTlsBase();
831#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
837 using TlsResetHook = void (*)(
Thread* thread, TlsResetPhase phase, uintptr_t base);
840 static void setTlsResetHookForHostedTest(
Thread* target, TlsResetHook hook);
848 void setTlsBase(uintptr_t base);
851 uintptr_t getUserGsBase()
const {
854 void setUserGsBase(uintptr_t base);
855 void saveUserGsBase();
895 bool joinForCompletion();
920 static void threadExited()
NORETURN;
923 bool eventsDeferred() const;
926 ExecutionContext executionContext() const;
930 return __atomic_load_n(&m_pScheduler, __ATOMIC_ACQUIRE);
933 const String& getName()
const {
937 void setName(
const String& name) {
942 void setName(
const char (&name)[N]) {
943 m_Name.assign(name, N);
948 size_t enterHostedSignalHandler();
951 void leaveHostedSignalHandler(
size_t stateLevel);
953 size_t getHostedSignalDepth()
const {
954 const size_t level = __atomic_load_n(&m_nStateLevel, __ATOMIC_ACQUIRE);
955 return __atomic_load_n(&m_StateLevels[level].m_HostedSignalDepth, __ATOMIC_ACQUIRE);
965 void deferTermination();
966 void resumeTermination();
967 void markUserReturnWorkFlag(UserReturnWorkFlag flag) {
968 __atomic_fetch_or(&m_UserReturnWorkPending,
static_cast<size_t>(flag), __ATOMIC_RELEASE);
970 void clearUserReturnWorkFlag(UserReturnWorkFlag flag) {
971 __atomic_fetch_and(&m_UserReturnWorkPending, ~
static_cast<size_t>(flag), __ATOMIC_RELEASE);
973 void markUserReturnWorkPending() {
974 markUserReturnWorkFlag(UserReturnExternalWork);
983 void retireDeferredScopes(
bool allStateLevels,
size_t stateLevel = 0);
984 size_t stateCleanupCheckpoint();
985 void retireDeferredScopesAfter(
size_t checkpoint);
986 void retireDeferredScopesMatching(
bool allStateLevels,
size_t stateLevel,
987 bool newerThanCheckpoint,
size_t checkpoint);
989 AtomicStateCleanupRecord::Cleanup cleanup,
void* context);
994 DeferredScopeRecord::Cleanup cleanup,
void* context);
997 DeferredScopeRecord::Cleanup cleanup =
nullptr,
998 void* context =
nullptr);
1006 void publishTimeAccounting(CpuTimeMode mode, Time::Timestamp elapsed);
1009 void publishReadyNotification();
1012 void cleanStateLevel(
size_t level);
1014 size_t beginTemporarySignalMask(uint64_t signalMask);
1015 bool finishTemporarySignalMask(
size_t stateLevel,
bool deferForUserReturn =
true);
1016 bool waitForEventInternal(
bool stopOnSignalInterruption,
1017 WaitQueue::StackDiscardCleanup onStackDiscard,
1018 void* stackDiscardContext);
1020 enum class EventSelection {
1022 WithoutExactUserReturn,
1024 StoppedProcessKernel,
1028 bool eventNeedsUserReturnFrameUnlocked(
Event* event)
const;
1029 bool eventIsDeliverableUnlocked(
Event* event,
1030 EventSelection selection = EventSelection::AnyDeliverable);
1033 bool hasEventsUnlocked(EventSelection selection = EventSelection::AnyDeliverable);
1034 bool hasDeliverableEventsUnlocked(EventSelection selection = EventSelection::AnyDeliverable);
1037 void markDeferredUserReturnSignalInterruption();
1040 void wakeForDeliverableEvents();
1044 EventSelection selection = EventSelection::AnyDeliverable);
1047 void setStatus(Status s);
1048 void setStatusUnlocked(Status s);
1054 bool markReapable();
1057 bool joinInternal(
bool completion);
1066 static void discardJoin(
void* context);
1069 bool beginExternalLease();
1072 void endExternalLease();
1075 void closeExternalLeaseAdmission();
1078 void closeExternalLeaseAdmissionAndDrain();
1082 bool hasActiveWaitUnlocked()
const;
1083 bool hasActiveWaitAtAnyLevel()
const;
1084 bool activeWaitPendingUnlocked()
const;
1087 void unlinkWaitsForStackDiscard();
1094 void markTerminalWaitCancelledBeforeBlockUnlocked(
size_t level);
1095 bool consumeTerminalWaitCancelledBeforeBlockUnlocked();
1096 void clearTerminalWaitCancelledBeforeBlockUnlocked(
size_t level);
1133 bool m_TemporarySignalMaskActive;
1134 bool m_TemporarySignalWaitInterrupted;
1135 bool m_DeferredSignalMaskRestore;
1139 size_t m_DispatchedSignalContinuationEpoch;
1146 InterruptionReason m_InterruptionReason;
1166 size_t m_HostedSignalDepth;
1177 size_t m_nStateLevel = 0;
1182 uint32_t m_FilesystemUid = 0, m_FilesystemGid = 0;
1183 bool m_FilesystemIdsValid =
false;
1186 bool m_HasSecurityState =
false;
1195 Time::Timestamp m_UserTime = 0;
1196 Time::Timestamp m_KernelTime = 0;
1199 size_t m_CurrentTimeAccountingMode =
static_cast<size_t>(CpuTimeMode::Kernel);
1201#if PEDIGREE_BENCHMARK_SYSCALL_TIMING
1202 size_t m_ActiveSyscallTimingSlot = NoSyscallTimingSlot;
1208 void* m_pAllocatedStack =
nullptr;
1212 size_t m_TaskId = 0;
1216 uintptr_t m_DebugStateAddress = 0;
1219 size_t m_DebugStateGeneration = 0;
1226 uint64_t m_AffinityGeneration = 0;
1227 uint64_t m_AffinityCompleted = 0;
1228 bool m_AffinityPending =
false;
1229 bool m_AffinityGatePending =
false;
1230 bool m_AffinityWorkQueued =
false;
1231 size_t m_AffinityReturnPending = 0;
1232 bool m_SignalFramesRequired =
false;
1233 bool m_UserReturnSignalParked =
false;
1234 size_t m_UserReturnWorkPending = 0;
1235 Thread* m_AffinityNext =
nullptr;
1236 bool m_HasSchedulerContext =
false;
1237 bool m_ReadyPublicationPending =
false;
1240 size_t m_Priority = DEFAULT_PRIORITY;
1244 Thread* m_pReadyNext =
nullptr;
1245 size_t m_ReadyQueuePriority = MAX_PRIORITIES;
1246 bool m_bReadyQueued =
false;
1249 void* m_pTlsBase =
nullptr;
1251 uintptr_t m_UserGsBase = 0;
1274 size_t m_nExternalLeases = 0;
1277 bool m_bExternalLeaseAdmissionClosed =
false;
1285 bool m_bExternalLeaseReleaseInProgress =
false;
1297 size_t m_EventSendersInFlight = 0;
1304 const SyscallState* m_OriginalSyscallState =
nullptr;
1305 void* m_SyscallDispatchContext =
nullptr;
1307 size_t m_ActiveSyscalls[serviceEnd] = {};
1314 bool m_ExitToIdle =
false;
1326 uint64_t m_DeferredProcessExitRequest = 0;
1327 uint64_t m_SynchronousSignalMask = 0;
1330 size_t m_DeferredSubsystemExceptionState = 0;
1331 size_t m_DeferredSubsystemExceptionType = 0;
1332 uintptr_t m_DeferredSubsystemExceptionFaultAddress = 0;
1333 uintptr_t m_DeferredSubsystemExceptionErrorCode = 0;
1336 bool m_bTlsBaseOverride =
false;
1339 bool m_bShutdown =
false;
1342 bool m_bSubsystemExitNotified =
false;
1345 uintptr_t m_ClearChildTid = 0;
1348 uintptr_t m_RobustList = 0;
1349 size_t m_RobustListOwnerId = 0;
1352 bool m_bStartRequested =
false;
1355 bool m_bDetached =
false;
1358 bool m_bJoinClaimed =
false;
1361 bool m_bDetachedRetirementClaimed =
false;
1364 bool m_bThreadExitRequested =
false;
1367 bool m_bExitStarted =
false;
1370 bool m_bReapable =
false;
1373 bool m_bProcessExitOwned =
false;
1376 bool m_bProcessExitParticipant =
false;
1379 size_t m_EventDeferralDepth = 0;
1381#if PEDIGREE_LATENCY_ACCOUNTING
1383 Time::Timestamp m_EventDeferralStarted = 0;
1387 size_t m_TerminationDeferralDepth = 0;
1391 size_t m_NextStateCleanupSequence = 0;
1393#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
1394 Spinlock m_DeferredScopeRegressionLock;