nx_lysosome.nx source
↩ module page · 99 lines · 3055 B
1// nx_lysosome.nx -- cleanup / recycling queue for terminated cells.
2//
3// Biology: lysosomes are organelles that digest cellular waste --
4// when a cell dies (apoptosis) or organelle wears out, lysosomes
5// recycle the components. Nishi lysosome is the cleanup queue:
6// terminated cells get enqueued; lysosome drains the queue at
7// caller's cadence, freeing memory + capability tokens + provenance
8// branches back to the pool.
9//
10// Composes:
11// nx_cell -- terminated cells enqueue here
12// nx_brane -- on drain, brane.revoke_all is called
13// nx_chromatin -- germline preserved; chromatin survives lysosome
14// nx_evict_journal -- each lysis logged
15
16import "nx_syscalls.nx"
17import "nx_tier.nx"
18
19const NX_LYSO_OK: nx_int = 0
20const NX_LYSO_ERR_FULL: nx_int = 1
21const NX_LYSO_ERR_EMPTY: nx_int = 2
22
23struct NxLysosomeEntry {
24 cell_id: nx_int,
25 enqueued_us: nx_size,
26 reason: nx_int,
27}
28
29struct NxLysosome {
30 queue: *NxLysosomeEntry,
31 capacity: nx_size,
32 head: nx_size, // next slot to enqueue
33 tail: nx_size, // next slot to drain
34 count: nx_size,
35 total_drained: nx_int,
36}
37
38const NX_LYSO_ENTRY_BYTES: nx_size = 24
39
40func nx_lysosome_new(capacity: nx_size) -> *NxLysosome {
41 let l: *NxLysosome = (sys_mmap(40)) as *NxLysosome
42 let bytes: nx_size = capacity * NX_LYSO_ENTRY_BYTES
43 l.queue = (sys_mmap(bytes)) as *NxLysosomeEntry
44 l.capacity = capacity
45 l.head = 0
46 l.tail = 0
47 l.count = 0
48 l.total_drained = 0
49 return l
50}
51
52func _lyso_at(l: *NxLysosome, idx: nx_size) -> *NxLysosomeEntry {
53 return (l.queue as i64 + (idx as i64) * NX_LYSO_ENTRY_BYTES) as *NxLysosomeEntry
54}
55
56func nx_lysosome_enqueue(l: *NxLysosome,
57 cell_id: nx_int,
58 reason: nx_int,
59 now_us: nx_size) -> nx_int {
60 if l.count >= l.capacity { return NX_LYSO_ERR_FULL }
61 let e: *NxLysosomeEntry = _lyso_at(l, l.head)
62 e.cell_id = cell_id
63 e.enqueued_us = now_us
64 e.reason = reason
65 l.head = l.head + 1
66 if l.head >= l.capacity { l.head = 0 }
67 l.count = l.count + 1
68 return NX_LYSO_OK
69}
70
71// ===== nx_lysosome_drain_one ======================================
72//
73// Pop the oldest queued cell_id. Caller receives the cell_id and
74// is responsible for the actual free (brane.revoke_all, vacuole
75// free, etc). Returns the cell_id on success or -1 if empty.
76
77func nx_lysosome_drain_one(l: *NxLysosome) -> nx_int {
78 if l.count == 0 { return -1 }
79 let e: *NxLysosomeEntry = _lyso_at(l, l.tail)
80 let id: nx_int = e.cell_id
81 l.tail = l.tail + 1
82 if l.tail >= l.capacity { l.tail = 0 }
83 l.count = l.count - 1
84 l.total_drained = l.total_drained + 1
85 return id
86}
87
88func nx_lysosome_count(l: *NxLysosome) -> nx_size {
89 return l.count
90}
91
92func nx_lysosome_total_drained(l: *NxLysosome) -> nx_int {
93 return l.total_drained
94}
95
96func nx_lysosome_is_empty(l: *NxLysosome) -> nx_int {
97 if l.count == 0 { return 1 }
98 return 0
99}