61 void initialise(
Thread* pThread);
66 void checkEventState(uintptr_t userStack);
70 void eventHandlerReturned()
NORETURN;
78 void addThread(
Thread* pThread,
Thread::ThreadStartFunc pStartFunction,
void* pParam,
79 bool bUsermode,
void* pStack);
84 void addThread(
Thread* pThread, SyscallState& state);
100 void abandonCurrentThreadStack(StackDiscardReason reason,
Spinlock* pLock = 0)
NORETURN;
103 static
size_t stackDiscardCount();
106 static
size_t stackDiscardCount(StackDiscardReason reason);
109 void requestCurrentThreadExitToIdle();
112 void timer(uint64_t delta, InterruptState& state);
115 void setClockDeadline(uint64_t deadline);
117 void removeThread(
Thread* pThread);
119 void threadStatusChanged(
Thread* pThread);
121 size_t logicalCpu()
const {
124 bool isIdleThread(
const Thread* thread)
const {
125 return thread == __atomic_load_n(&m_pIdleThread, __ATOMIC_ACQUIRE);
127 uint64_t nominalQuantumNs()
const {
128 return m_NominalQuantumNs;
132 void ringIrqWorkDoorbell();
147 void publishDeferredTimeAccounting();
150 void serviceIrqWorkDoorbell();
153 void servicePendingScheduling();
155 enum class ProcessStopGateMode {
157 DirectUserTransition,
167 ProcessStopGateMode mode = ProcessStopGateMode::StopOnly);
174 InterruptState& state, UserReturnFrame::Origin origin = UserReturnFrame::Origin::Interrupt,
175 bool diagnosticSample =
false);
179 SyscallState& state, UserReturnFrame::Origin origin = UserReturnFrame::Origin::Syscall,
180 bool diagnosticSample =
false);
184#if PEDIGREE_ACTIVITY_DIAGNOSTICS
185 return (++m_UserReturnDiagnosticSequence % ActivityDiagnostics::UserReturnSamplePeriod) == 0;
192 void commitUserReturnTerminalState();
195 void requestIdleThreadWakeup();
197 void setIdle(
Thread* pThread);
200 void idleUntilInterrupt();
202#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
204 bool runHostedNewThreadWorkerRegressions();
206 static bool currentIrqWorkDoorbellPendingForTest();
207 static void serviceCurrentIrqWorkDoorbellForTest();
220 void schedule(
Thread::Status nextStatus =
Thread::Ready,
bool dispatchEvents = true);
221 void scheduleWithInterruptState(
Thread::Status nextStatus,
bool dispatchEvents,
222 bool previousInterruptState);
228 void publishReadyFromWait(
Thread* pThread);
230 void finishCurrentThreadExit(
Spinlock* pLock,
bool transferToIdle)
NORETURN;
233 void serviceDeferredSubsystemException(InterruptState& state,
bool diagnosticSample = false);
236 void checkEventState(uintptr_t userStack,
Thread::EventSelection selection);
239 void checkEventState(uintptr_t userStack,
Thread::EventSelection selection,
240 InterruptState* interruptState, SyscallState* syscallState);
253 static
void deleteThreadThenRestoreState(
Thread* pThread, SchedulerState& newState,
254 volatile uintptr_t* pLock = 0)
NORETURN;
256 static
void deleteThread(
Thread* pThread);
258 void startNewThreadWorker(
Process* pParent);
259 void stopNewThreadWorker();
261 void startTimeAccountingWorker(
Process* pParent);
262 void stopTimeAccountingWorker();
263 static
int timeAccountingWorkerEntry(
void* instance);
264 int runTimeAccountingWorker();
265 void publishDeferredThreadReap(
Thread* thread);
266 bool drainDeferredThreadReaps();
267 bool enqueueAffinity(
Thread* thread,
bool accepted = false);
268 void drainAffinityRequests();
269 void prompt(
bool readyPublication = false);
270 void armLocalQuantumIfNeeded();
271 void updateOneShotTimer();
272 void programOneShotTimer();
274 void serviceWorkerWakeups();
279 Mutex m_NewThreadDataLock;
282 List<
void*> m_NewThreadData;
283 List<
void*> m_DelayedNewThreadData;
284 bool m_NewThreadAdmissionOpen;
285 bool m_StopNewThreadWorker;
290 Atomic<
size_t> m_nDeferredThreadReaps;
291 Atomic<
size_t> m_DeferredThreadReapPublicationState;
292 Atomic<
size_t> m_StopTimeAccountingWorker;
296 Atomic<
size_t> m_IrqWorkDoorbell;
297 Atomic<
size_t> m_ReschedulePending;
298 Atomic<
size_t> m_RemotePromptPending;
299 Atomic<uint64_t> m_ClockDeadline;
303 Thread* m_AffinityHead =
nullptr;
304 Thread* m_AffinityTail =
nullptr;
305 Atomic<
size_t> m_AffinityRequests;
306 bool m_AffinityAdmissionOpen = false;
307 size_t m_LogicalCpu = ~
size_t(0);
308 size_t m_PhysicalCpu = 0;
309 uint64_t m_NominalQuantumNs = 0;
310 uint64_t m_QuantumDeadline = 0;
311 uint64_t m_NextLoadSampleDeadline = 0;
312 bool m_OneShotTimer = false;
314#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
318 static constexpr size_t DeferredReapPublicationClosed =
static_cast<size_t>(1)
319 << ((
sizeof(
size_t) * 8) - 1);
320 static constexpr size_t DeferredReapPublicationCountMask = ~DeferredReapPublicationClosed;
322 static int processorAddThread(
void* instance);
325 bool m_IdleWakeRequested =
false;
326 size_t m_SchedulerTickCounter = 0;
327 size_t m_UserReturnDiagnosticSequence = 0;