kernel+tests: M4 shared-fate — nine group-death test cases, per-space arena cursors
Eight new QEMU cases (thread-fault-group, kill-threaded-group, kill-via-worker-tid, racing-triggers, exit-group, leader-thread-exit, thread-exit-solo, shm-mapping-ref) driving seven new thread-test modes; a shared checkGroupDead asserts the contract everywhere: one notification, badged with the leader, reason on the leader's record, no member listed, claims released first. The shm-mapping-ref case flushed out the per-task DMA/shared-memory arena cursor bug directly (a sibling's regions mapped over the worker's), so both cursors moved to the AddressSpaceRef like the mmap/MMIO cursors before them (threading M7 pattern). Runtime gains Thread.tryExitCurrent for the leader -EPERM refusal path. Docs updated: threading.md's shared-fate gap is closed, process-management.md and process-lifecycle.md describe the leader re-key, plan status = implemented. Full suite: 100/100.
This commit is contained in:
@@ -121,8 +121,10 @@ pub const Task = struct {
|
||||
ipc_reply_ptr: u64 = 0, // client: reply buffer (virtual_address)
|
||||
ipc_reply_cap: u64 = 0,
|
||||
ipc_status: i64 = 0, // client: reply length / -errno, written by the replier
|
||||
dma_map_next: u64 = 0, // bump pointer into this task's DMA arena (0 = unseeded)
|
||||
shared_memory_map_next: u64 = 0, // bump pointer into this task's shared-memory arena (0 = unseeded)
|
||||
// The DMA and shared-memory arena cursors moved to the per-address-space object
|
||||
// (`AddressSpaceRef`) like the mmap/MMIO cursors before them — per-TASK cursors made
|
||||
// sibling threads hand out overlapping windows of the one shared arena
|
||||
// (docs/shared-fate-plan.md M4 tripped exactly that).
|
||||
ipc_send_cap: u64 = ~@as(u64, 0), // handle to transfer with this message (abi.no_cap = none)
|
||||
ipc_received_cap: u64 = ~@as(u64, 0), // client: handle the reply's transferred cap landed at (abi.no_cap = none)
|
||||
next: ?*Task = null, // ready-queue link (also the endpoint sender-FIFO link)
|
||||
@@ -173,6 +175,8 @@ const AddressSpaceRef = struct {
|
||||
count: u32 = 0,
|
||||
mmap_next: u64 = 0,
|
||||
device_map_next: u64 = 0,
|
||||
dma_next: u64 = 0, // bump pointer into this space's DMA arena (0 = unseeded)
|
||||
shared_memory_next: u64 = 0, // bump pointer into this space's shared-memory arena (0 = unseeded)
|
||||
// Group-death state (docs/shared-fate-plan.md), set once by the first kill
|
||||
// trigger and never cleared while the entry lives. `dying` gates
|
||||
// retainAddressSpace — no new member may join a dying group (closing the
|
||||
@@ -395,6 +399,24 @@ pub fn addressSpaceDeviceMapNextPtr(root: u64) ?*u64 {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Pointer to the DMA arena cursor for address space `root` (see
|
||||
/// `addressSpaceMmapNextPtr`). Caller holds the kernel lock.
|
||||
pub fn addressSpaceDmaNextPtr(root: u64) ?*u64 {
|
||||
for (&address_space_refs) |*entry| {
|
||||
if (entry.count != 0 and entry.root == root) return &entry.dma_next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Pointer to the shared-memory arena cursor for address space `root` (see
|
||||
/// `addressSpaceMmapNextPtr`). Caller holds the kernel lock.
|
||||
pub fn addressSpaceSharedMemoryNextPtr(root: u64) ?*u64 {
|
||||
for (&address_space_refs) |*entry| {
|
||||
if (entry.count != 0 and entry.root == root) return &entry.shared_memory_next;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
var next_id: u32 = 1;
|
||||
|
||||
/// Per-CPU scheduler state: the task each core is running, its own idle task, and a
|
||||
|
||||
Reference in New Issue
Block a user