8#include "pedigree/kernel/Atomic.h"
9#include "pedigree/kernel/Log.h"
10#include "pedigree/kernel/processor/InterruptHandler.h"
11#include "pedigree/kernel/processor/InterruptManager.h"
12#include "pedigree/kernel/processor/Processor.h"
16#include "system/kernel/core/processor/hosted/InterruptManager.h"
19constexpr size_t TestSignal = SIGWINCH;
21bool check(
bool condition,
const char* detail) {
26 ERROR(
"HOSTED-WAIT-TEST: FAIL interrupt-manager-lock-independent: " << detail);
32 explicit CountingHandler(
size_t identity)
37 observedContext(static_cast<size_t>(ExecutionContext::AtomicThread)) {}
39 void interrupt(
size_t interruptNumber, InterruptState&)
override {
40 observedIdentity = m_Identity;
41 observedSignal = interruptNumber;
46 const size_t m_Identity;
56void dispatchWhileMutationLocked() {
57 g_MutationHookCalls += 1;
58 if (::raise(TestSignal) == 0) {
61 g_RaiseSucceeded += 1;
66bool runHostedInterruptManagerRegressions() {
68 CountingHandler first(1);
69 CountingHandler second(2);
71 g_MutationHookCalls = 0;
77 HostedInterruptManager::withMutationLockForTest(dispatchWhileMutationLocked);
81 const bool emptyRemovalRejected =
83 const bool secondInstalled =
85 if (secondInstalled) {
86 HostedInterruptManager::withMutationLockForTest(dispatchWhileMutationLocked);
88 const bool secondRemoved =
93 passed &= check(firstInstalled && duplicateRejected && firstRemoved && emptyRemovalRejected &&
94 secondInstalled && secondRemoved,
95 "install/remove exclusivity changed");
96 passed &= check(g_MutationHookCalls == 2 && g_RaiseSucceeded == 2,
97 "production dispatch did not return while the mutation lock was held");
98 passed &= check(first.calls == 1 && first.observedIdentity == 1 &&
99 first.observedSignal == TestSignal && second.calls == 1 &&
100 second.observedIdentity == 2 && second.observedSignal == TestSignal,
101 "dispatch observed a stale or invalid handler publication");
103 first.observedContext ==
static_cast<size_t>(ExecutionContext::HostedSyntheticIrq) &&
104 second.observedContext ==
static_cast<size_t>(ExecutionContext::HostedSyntheticIrq) &&
106 "hosted signal context leaked or was not classified");
109 NOTICE(
"HOSTED-WAIT-TEST: PASS interrupt-manager-lock-independent");
Abstract base class for interrupt-handlers.
Handles interrupts and interrupt registrations from kernel components.
static EXPORTED_PUBLIC InterruptManager & instance()
virtual bool registerInterruptHandler(size_t nInterruptNumber, InterruptHandler *pHandler)=0
static ExecutionContext executionContext()