The Pedigree Project 0.1
module-admission-regressions.cc
1/* Copyright (c) 2026, Pedigree Developers. */
2#include "pedigree/kernel/Log.h"
3#include "pedigree/kernel/linker/KernelElf.h"
4
5#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
6namespace {
7Module::UnloadAdmission decision = Module::UnloadAdmission::Busy;
8size_t admissions = 0;
9size_t exits = 0;
10bool sawTerminal = false;
11Module::UnloadAdmission admit(bool terminal) {
12 ++admissions;
13 sawTerminal = terminal;
14 return decision;
15}
16void exitModule() {
17 ++exits;
18}
19bool attempt(Module& module, bool terminal) {
20 if (KernelElf::claimModuleUnloadForTest(&module) != KernelElf::TestUnloadClaimed)
21 return false;
22 return KernelElf::completeGuardedModuleUnloadForTest(&module, terminal);
23}
24} // namespace
25bool runHostedModuleAdmissionRegressions() {
26 Module module;
27 module.name.assign("unload-admission-fixture");
28 module.status = Module::Active;
29 module.unloadAdmission = admit;
30 module.exit = exitModule;
31 decision = Module::UnloadAdmission::Busy;
32 admissions = exits = 0;
33 bool passed = !attempt(module, false) && module.isActive() && !module.unloadComplete &&
34 module.unloadable && admissions == 1 && exits == 0 && !sawTerminal;
35 decision = Module::UnloadAdmission::KeepMapped;
36 passed &= !attempt(module, false) && module.isActive() && module.unloadable && exits == 0;
37 decision = Module::UnloadAdmission::Ready;
38 passed &= attempt(module, false) && module.isUnloaded() && exits == 1 && admissions == 3;
39
40 Module provider;
41 provider.name.assign("retained-storage-provider");
42 provider.status = Module::Active;
43 Module consumer;
44 consumer.name.assign("retained-storage-consumer");
45 consumer.status = Module::Active;
46 consumer.unloadAdmission = admit;
47 consumer.exit = exitModule;
48 const char* dependencies[] = {"retained-storage-provider", nullptr};
49 consumer.depends = dependencies;
50 decision = Module::UnloadAdmission::KeepMapped;
51 passed &= !attempt(consumer, true) && consumer.isActive() && !consumer.unloadable &&
52 !consumer.unloadComplete && sawTerminal && exits == 1;
53 Module* modules[] = {&provider, &consumer};
54 Module* order[2]{};
55 passed &= KernelElf::planModuleUnloadOrderForTest(modules, 2, order, 2) == 0 &&
56 provider.isActive() && consumer.isActive();
57 if (passed)
58 NOTICE("HOSTED-STORAGE-PAGING: PASS module-admission-retention");
59 else
60 ERROR("HOSTED-STORAGE-PAGING: FAIL module-admission-retention");
61 return passed;
62}
63#endif