Channel table + common channel, inert (B1) -- FABRIC-3.6.md task 3.2
Adds SkHermesChannel: a channel is an index into a boot-time, stadium_max_vm_count()-sized table (same sizing pattern task 3.1 established for the switch table -- no separate numeric rule was ruled for this table, so task 3.1's bound is extended directly, flagged as such rather than restated as a new ruling). No name field, mirroring messaging.4th's own nameless CH-ARENA. The common channel (index 0) is created at boot and permanent. Hera subscribes explicitly in kernel_main.c (she is the one VM never born through capsule_birth_baby()); every other VM -- Tripod fleet and future WIREBIND identities alike -- subscribes inside capsule_birth_baby() itself, the single choke point every other birth already passes through. Inert: no publish, no dispatch, no ACK/NACK, no ACL hook (tasks 3.3, 3.6, 3.7). Verified live on all three architectures: channel table sized to 50/202/50 slots (matching switch-signal's own per-arch sizing), common-channel fleet self-test confirms all four Tripod members are members, and a synthetic create/subscribe/unsubscribe/ destroy round-trip against a private topic passes, including refusing to destroy the common channel. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
c19ef365fe
commit
a4afdfa591
@@ -279,6 +279,101 @@ uint64_t sk_hermes_audit_failure_count(void);
|
||||
uint64_t sk_hermes_scan_held(size_t *live_count);
|
||||
int sk_hermes_scan_check(void);
|
||||
|
||||
/*
|
||||
* Channel table (FABRIC-3.6.md task 3.2, B1 / FABRIC-3.5.md SXLV.1): B1
|
||||
* overrules SXXXIII.5's single flat broadcast list -- messaging is
|
||||
* publish/subscribe, one permanent common channel every VM joins at
|
||||
* birth, private channels created by request/grant/deny (task 3.6, not
|
||||
* this one). SkHermesMembership (task 2.1) becomes per-channel: one
|
||||
* instance per SkHermesChannel table entry instead of one global list.
|
||||
*
|
||||
* INERT, same posture as task 2.1: this task wires channel existence and
|
||||
* membership bookkeeping only. No publish, no dispatch, no ACK/NACK, no
|
||||
* ACL hook (tasks 3.3, 3.6, 3.7) -- creating/destroying/subscribing a
|
||||
* channel here changes no VM's dictionary and delivers no message.
|
||||
*
|
||||
* Sizing: SXLV.1 says the channel table has "no fixed channel maximum,
|
||||
* same reasoning as SXLV.2" -- SXLV.2/task 3.1's own ruling is boot-time,
|
||||
* RAM-derived sizing (Stadium's stadium_max_vm_count_val pattern), not a
|
||||
* literal unbounded/growable table. No separate numeric sizing rule was
|
||||
* ruled for the channel table specifically (task 3.0's five sub-items
|
||||
* covered ACK cadence/ACL-hook-location/switch-table-sizing/chunk-
|
||||
* framing/drain-cadence, not this). Extending task 3.1's already-ruled
|
||||
* pattern directly -- same stadium_max_vm_count() bound, same
|
||||
* kmalloc-at-boot shape -- is the smallest choice consistent with what
|
||||
* was ruled, flagged here as an engineering extrapolation, not restated
|
||||
* as a separate Captain Bob ruling.
|
||||
*/
|
||||
|
||||
/* SK_HERMES_CHANNEL_COMMON - the permanent common channel's fixed index.
|
||||
* Exists (in_use, empty membership) from sk_hermes_channels_boot_init()
|
||||
* itself, before any VM is born -- every VM joins it at birth (task 3.2's
|
||||
* own kernel_main.c/capsule_birth.c wiring), never destroyed. */
|
||||
#define SK_HERMES_CHANNEL_COMMON 0
|
||||
|
||||
/*
|
||||
* SkHermesChannel - one channel/topic: its membership plus an occupancy
|
||||
* flag for the dynamic table below. No name field -- messaging.4th's own
|
||||
* channel abstraction (CH-ARENA) has none either; a channel is identified
|
||||
* by its table index, the same way a Stadium quota slot or a switch-
|
||||
* signal slot is identified by index, not by string.
|
||||
*/
|
||||
typedef struct {
|
||||
SkHermesMembership membership;
|
||||
int in_use;
|
||||
} SkHermesChannel;
|
||||
|
||||
/* Boot-time allocation: kmalloc's the channel table to
|
||||
* stadium_max_vm_count() entries (see this section's own sizing note
|
||||
* above) and creates the common channel (index SK_HERMES_CHANNEL_COMMON,
|
||||
* in_use, empty membership -- members join at birth, not pre-populated
|
||||
* here). Must run after stadium_boot_init() (that bound is 0, and this
|
||||
* fails, until Stadium has computed it). Soft failure -- returns -1 and
|
||||
* leaves the table unallocated (capacity 0, so every call below simply
|
||||
* refuses) rather than halting boot, same posture as
|
||||
* stadium_boot_init()/session_boot_init()/sk_vm_switch_signal_boot_init().
|
||||
* Idempotent-unsafe: calling twice leaks the first allocation, so callers
|
||||
* must call it exactly once. */
|
||||
int sk_hermes_channels_boot_init(void);
|
||||
|
||||
/* sk_hermes_channel_create - allocate a new, empty, inert channel.
|
||||
* Returns its table index, or -1 if the table is full or
|
||||
* sk_hermes_channels_boot_init() was never called/failed. */
|
||||
int sk_hermes_channel_create(void);
|
||||
|
||||
/* sk_hermes_channel_destroy - tear down a channel created by
|
||||
* sk_hermes_channel_create(). Refuses (-1, no effect) if channel_id is
|
||||
* SK_HERMES_CHANNEL_COMMON (the common channel is permanent, SXLV.1),
|
||||
* out of range, or not in use. Clears membership. */
|
||||
int sk_hermes_channel_destroy(int channel_id);
|
||||
|
||||
/* sk_hermes_channel_subscribe - add vm_id to channel_id's membership.
|
||||
* Refuses (-1, no effect) if channel_id is invalid/not in use, vm_id is
|
||||
* already a member, or the channel's membership is already at
|
||||
* SK_HERMES_MEMBER_MAX. Idempotent in effect (a second call with the
|
||||
* same args refuses rather than duplicating), not in return value. */
|
||||
int sk_hermes_channel_subscribe(int channel_id, VMUuid vm_id);
|
||||
|
||||
/* sk_hermes_channel_unsubscribe - remove vm_id from channel_id's
|
||||
* membership (compacts the list, same shape as
|
||||
* sk_vm_switch_signal_unregister()). Refuses (-1, no effect) if
|
||||
* channel_id is invalid/not in use or vm_id is not a member. */
|
||||
int sk_hermes_channel_unsubscribe(int channel_id, VMUuid vm_id);
|
||||
|
||||
/* sk_hermes_channel_is_member - nonzero iff vm_id is currently a member
|
||||
* of channel_id. Zero (not an error signal) if channel_id is invalid/not
|
||||
* in use. */
|
||||
int sk_hermes_channel_is_member(int channel_id, VMUuid vm_id);
|
||||
|
||||
/* sk_hermes_channel_member_count - current membership size of channel_id,
|
||||
* or -1 if channel_id is invalid/not in use. */
|
||||
int sk_hermes_channel_member_count(int channel_id);
|
||||
|
||||
/* sk_hermes_channel_capacity - the table's boot-time-computed capacity
|
||||
* (0 if sk_hermes_channels_boot_init() was never called or failed) --
|
||||
* DoE/test observability, mirrors sk_vm_switch_signal_slot_capacity(). */
|
||||
int sk_hermes_channel_capacity(void);
|
||||
|
||||
#endif /* __STARKERNEL__ */
|
||||
|
||||
#endif /* STARKERNEL_VM_KERNEL_HERMES_H */
|
||||
|
||||
Reference in New Issue
Block a user