6export module zxfoundation.dgp.domain.types;
7import zxfoundation.base.types;
8import zxfoundation.base.typestate;
9import zxfoundation.scoms.kobject.base;
10import zxfoundation.memory.vm.types;
11import zxfoundation.sync.qspinlock.core;
12import zxfoundation.dgp.isolation.types;
13import zxfoundation.dgp.signal.types;
14import zxfoundation.dgp.sync_contract;
15import zxfoundation.sched.policy;
16import zxfoundation.sched.entity;
17import zxfoundation.sched.sd.types;
18import zxfoundation.sched.rt.bandwidth;
19import zxfoundation.sched.nohz.core;
20import zxfoundation.sched.cbs.core;
21import arch.s390x.cpu.aste.consts;
22import arch.s390x.mmu.types;
23import arch.s390x.sched.types;
31namespace zxfoundation::dgp::domain {
34 using strand_id = u32;
37 constexpr strand_id STRAND_ID_INVALID = 0xFFFF'FFFFU;
40 constexpr u32 MAX_STRANDS_PER_DOMAIN = 64U;
43 using strand_entry_fn =
auto (*)(
void*)
noexcept ->
void;
46 struct strand_create_request {
47 u32 owner_domain{0xFFFF'FFFFU};
48 strand_entry_fn entry{
nullptr};
52 arch::s390x::sched::user_regs* uregs{
nullptr};
63 enum class strand_flags : u8 {
68 [[nodiscard]]
constexpr auto operator|(strand_flags a, strand_flags b)
noexcept -> strand_flags {
69 return static_cast<strand_flags>(
static_cast<u8>(a) |
static_cast<u8>(b));
71 [[nodiscard]]
constexpr auto operator&(strand_flags a, strand_flags b)
noexcept -> strand_flags {
72 return static_cast<strand_flags>(
static_cast<u8>(a) &
static_cast<u8>(b));
74 constexpr auto operator|=(strand_flags& a, strand_flags b)
noexcept -> strand_flags& {
78 constexpr auto operator&=(strand_flags& a, strand_flags b)
noexcept -> strand_flags& {
87 scoms::kobject::bobject ko{};
91 sched::sched_substate substate{sched::sched_substate::idle};
95 strand_flags flags{strand_flags::none};
97 zxfoundation::sched::sched_entity se{};
99 strand_body* body{
nullptr};
103 lib::list_node sched_link{};
105 zxfoundation::sched::sched_policy sched_policy{};
106 zxfoundation::sched::sched_admission_result sched_admission{};
108 strand()
noexcept =
default;
109 strand(
const strand&) =
delete;
110 auto operator=(
const strand&) =
delete;
111 strand(strand&&) =
delete;
112 auto operator=(strand&&) =
delete;
116 static_assert(
__builtin_offsetof(strand, ko) == 0,
117 "strand::ko must be at offset 0");
119 static_assert(
__builtin_offsetof(strand, se) == 40,
120 "strand::se must be at offset 40");
122 static_assert(
__builtin_offsetof(strand, kstack_top) == 112,
123 "strand::kstack_top must be at offset 112");
125 static_assert(
__builtin_offsetof(strand, ksp) == 120,
126 "strand::ksp must be at offset 120 — __switch_to_asm depends on this");
132 lib::list_node strand_list{};
134 u64 rt_runtime_used_ns{0};
135 u64 rt_period_start_ns{0};
136 u64 deadline_runtime_used_ns{0};
137 u64 absolute_deadline_ns{0};
140 sched::sched_avg pelt_avg{};
143 sched::cbs::cbs_replen cbs{};
145 void* blocked_on{
nullptr};
146 lib::list_node pi_waiters{};
148 sched::sched_class_id saved_class{zxfoundation::sched::sched_class_id::fair};
152 arch::s390x::sched::user_regs uregs{};
154 strand_body()
noexcept =
default;
155 strand_body(
const strand_body&) =
delete;
156 auto operator=(
const strand_body&) =
delete;
157 strand_body(strand_body&&) =
delete;
158 auto operator=(strand_body&&) =
delete;
162 [[nodiscard]]
inline auto is_idle_strand(
const strand& s)
noexcept ->
bool {
163 return (s.flags & strand_flags::idle) != strand_flags::none;
167 using domain_id = u32;
170 constexpr domain_id DOMAIN_ID_INVALID = 0xFFFF'FFFFU;
173 constexpr domain_id DOMAIN_ID_NUCLEUS = 0U;
176 constexpr u32 MAX_DOMAINS = 256U;
179 constexpr u8 SKEY_NUCLEUS = 0U;
182 constexpr u8 SKEY_USER_BASE = 8U;
185 constexpr u8 SKEY_USER_MAX = 15U;
188 enum class domain_flags : u32 {
191 need_resched = 1U << 2,
196 static_assert(
static_cast<u32>(domain_flags::need_resched) == 4U,
197 "domain_flags::need_resched must match TIF_NEED_RESCHED in entry.S");
199 [[nodiscard]]
constexpr auto operator|(domain_flags a, domain_flags b)
noexcept -> domain_flags {
200 return static_cast<domain_flags>(
static_cast<u32>(a) |
static_cast<u32>(b));
202 [[nodiscard]]
constexpr auto operator&(domain_flags a, domain_flags b)
noexcept -> domain_flags {
203 return static_cast<domain_flags>(
static_cast<u32>(a) &
static_cast<u32>(b));
205 [[nodiscard]]
constexpr auto operator~(domain_flags f)
noexcept -> domain_flags {
206 return static_cast<domain_flags>(~
static_cast<u32>(f));
208 [[nodiscard]]
constexpr auto operator!(domain_flags f)
noexcept ->
bool {
209 return static_cast<u32>(f) == 0;
211 constexpr auto operator|=(domain_flags& a, domain_flags b)
noexcept -> domain_flags& {
215 constexpr auto operator&=(domain_flags& a, domain_flags b)
noexcept -> domain_flags& {
222 scoms::kobject::bobject ko{};
224 const char* name{
nullptr};
226 domain_flags flags{domain_flags::none};
231 strand primary_strand{};
233 char name_storage[64]{};
235 arch::s390x::mmu::typed_asce<arch::s390x::mmu::dat_level::region_1> asce{};
236 arch::s390x::cpu::aste::art_context art{};
237 u16 portal_ar_mask{0};
243 zxfoundation::dgp::isolation::isolation_rights granted_rights{zxfoundation::dgp::isolation::isolation_rights::none};
245 std::atomic<u16> revocation_epoch{0};
246 u32 storage_key_generation{0};
247 zxfoundation::dgp::isolation::skey_revocation_state storage_key_state{zxfoundation::dgp::isolation::skey_revocation_state::none};
248 zxfoundation::dgp::sync_contract::teardown_phase teardown_phase{zxfoundation::dgp::sync_contract::teardown_phase::none};
250 u32 pending_rights_revoke_raw{0};
252 lib::list_node domain_list{};
253 lib::list_head strands{};
254 memory::vm::vm_space vm_space{};
255 signal::signal_queue signal_queue{};
258 u64 rt_capability_token{0};
259 u64 rt_period_ns{100'000'000ULL};
260 u64 rt_budget_ns{20'000'000ULL};
261 u64 rt_reserved_ns{0};
262 u64 deadline_period_ns{100'000'000ULL};
263 u64 deadline_budget_ns{10'000'000ULL};
264 u64 deadline_reserved_ns{0};
265 zxfoundation::sched::sched_mask allowed_cpus{};
266 zxfoundation::sched::sched_mask allowed_numa_nodes{};
268 domain()
noexcept =
default;
269 domain(
const domain&) =
delete;
270 auto operator=(
const domain&) =
delete;
271 domain(domain&&) =
delete;
272 auto operator=(domain&&) =
delete;
275 static_assert(
__builtin_offsetof(domain, ko) == 0,
276 "domain::ko must be at offset 0 — kobject layout constraint");
278 static_assert(
__builtin_offsetof(domain, primary_strand) == 48,
279 "domain::primary_strand must be at offset 48");
281 [[nodiscard]]
auto is_idle_domain(
const domain& d)
noexcept ->
bool {
282 return (d.flags & domain_flags::idle) != domain_flags::none;
285 [[nodiscard]]
auto is_active_domain(
const domain& d)
noexcept ->
bool {
286 return d.ko.state == zxfoundation::base::lifecycle_state::active;