/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. This file is part of the StarForth project. Licensed under the StarForth License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: https://github.com/star.4th@proton.me/StarForth/LICENSE.txt This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. See the License for the specific language governing permissions and limitations under the License. */ /** * session.h - Per-VM session (FABRIC-3.md §H, decided 2026-09-02/03) * * A session is a Stadium patron (FABRIC-3.md §H.1) -- registering a session * IS admitting a patron to the Stadium, not a new parallel bookkeeping * structure. This struct is the piece that sits ALONGSIDE the patron, * referencing it by VMUuid rather than being indexed by Stadium cell index * or grown as inline fields on StadiumPatronHeader/struct VM (deliberately * its own header, mirroring VMUuid's/VMIdentity's own precedent -- standing * instruction: give real-shaped data its own header and integrate as a * field, don't grow existing structs ad hoc). * * Fields (FABRIC-3.md §H.2, all five confirmed 2026-09-02/03): * vm_id -- the patron this session references. * pinned -- session is AUTHORITATIVE over Stadium's STADIUM_FLAG_PIN * bit (§H.10): the sole read/write path for pin state is * session_set_pinned()/session_is_pinned() below, nothing * else (including existing Stadium code) may touch * STADIUM_FLAG_PIN directly. * parent -- who birthed this session (Hera -> Hermes/Artemis, etc). * name -- canonical human-readable name; feeds console.c's * g_active_vm_name prefix, does not replace the * console-binding mechanism itself. * identity -- embedded VMIdentity (FABRIC-3.md §H.4's VM card is * effectively VMIdentity's existing ownership check; reused * directly here, not reinvented). * * Explicit user framing (2026-09-02), still true: "we're gonna be * revisiting this part of it around and around for a while" -- treat this * shape as a live working draft, not permanently locked. */ #ifndef STARKERNEL_SESSION_H #define STARKERNEL_SESSION_H #ifdef __STARKERNEL__ #include #include #include "starkernel/vm_uuid.h" #include "starkernel/vm_identity.h" /* Matches console.c's CONSOLE_VM_NAME_BUF precedent -- same order of * magnitude for the same kind of data (a short human-readable VM name). */ #define SESSION_NAME_BUF 64 /* Sentinel meaning "no Stadium cell recorded yet" -- same shape as * STADIUM_CELL_NONE (stadium.c), duplicated here rather than pulled in via * stadium.h to avoid this header depending on Stadium's internal cell-index * type. Session's own callers set stadium_cell after their own * stadium_admit() call returns a real index (§H.12 step 3 doc). */ #define SESSION_STADIUM_CELL_NONE ((size_t)-1) typedef struct { VMUuid vm_id; /* the patron this session references */ int pinned; /* authoritative over STADIUM_FLAG_PIN; see * session_set_pinned()/session_is_pinned() */ VMUuid parent; /* who birthed this session */ char name[SESSION_NAME_BUF]; /* canonical human-readable name */ VMIdentity identity; /* embedded, not referenced -- see vm_identity.h */ size_t stadium_cell; /* index of this session's own patron cell in * stadium_cells() -- SESSION_STADIUM_CELL_NONE * until the caller that admits this session's * patron (stadium_admit()'s return value) sets it. * session_set_pinned()/session_is_pinned() need * this to reach the right patron header; added * §H.12 step 3, not part of the original H.2 field * list -- necessary plumbing, not a new session- * level concept, so not itself renegotiated. */ } Session; /* * session_boot_init - Boot-time allocation, mirroring stadium_boot_init()'s * own kmalloc-sized-from-budget shape rather than a fixed compile-time * array (stadium.c's own StadiumVMQuota table was moved off a fixed array * for the same reason -- population isn't knowable in advance). Must run * after stadium_boot_init() (session slot count is sized from * stadium_max_vm_count()) and before the first session is registered. * No callers yet (§H.12 step 2) -- wiring into the boot sequence happens * in a later punch-list step. * * @return 0 on success, -1 if kmalloc failed or stadium_max_vm_count() is 0 * (Stadium not yet initialized). */ int session_boot_init(void); /* * session_find - Look up a session by the VMUuid of the patron it * references. Linear scan, same shape as stadium.c's own * quota_slot_for_vm() -- the population this searches is small (one entry * per VM, not per word/block). * * @return Pointer to the live session, or NULL if none is registered for * vm_id. */ Session *session_find(VMUuid vm_id); /* * session_register - Register a new session for vm_id. identity starts * zeroed (VMIdentity's own documented default: installed=0, "no lock, * allow freely" -- §H.12 Correction 2). pinned starts 0 (unpinned); use * session_set_pinned() separately to pin, keeping this function's job to * "create the session record" only, not "create and also decide pin * policy" -- callers (e.g. the capsule-birth admission path, §H.12 phase 2) * decide pinning themselves. * * @param vm_id The patron this session references. Must not already have * a registered session (session_find(vm_id) must be NULL). * @param parent Who birthed this session (vm_uuid_hera() for Hera's own * self-registration -- self-referential, matching the * existing parent_vm_id convention documented in * capsule_run.h). * @param name Copied into the new session's name buffer, truncated to * SESSION_NAME_BUF - 1 if longer. * @return Pointer to the new session, or NULL if the slot table is full, * not yet initialized, or vm_id is already registered. */ Session *session_register(VMUuid vm_id, VMUuid parent, const char *name); /* * session_set_pinned / session_is_pinned - The pin-authority choke point * (FABRIC-3.md §H.2/§H.10, decided 2026-09-02: "full choke point at the * session level, both directions"). Session is authoritative for every * EXTERNAL reader -- nothing else, including existing Stadium code, reads * or writes STADIUM_FLAG_PIN on a patron header directly anymore. * * session_is_pinned() answers from the session's own `pinned` field * directly (the authoritative copy) -- it does not re-derive the answer * from Stadium. session_set_pinned() writes both: the session's own * `pinned` field (authoritative) AND the mirrored STADIUM_FLAG_PIN bit on * the session's own patron header (stadium_cells()[session->stadium_cell]), * so the Stadium engine's own internal eviction/admission logic -- which * must stay self-contained and cannot call back into session.c -- keeps * seeing a correct, in-sync bit. * * Both no-op (return 0 / do nothing) if vm_id has no registered session, or * if stadium_cell is still SESSION_STADIUM_CELL_NONE (patron not admitted * yet) for the set path. */ void session_set_pinned(VMUuid vm_id, int pinned); int session_is_pinned(VMUuid vm_id); #endif /* __STARKERNEL__ */ #endif /* STARKERNEL_SESSION_H */