Files
LithosAnanake/src/starkernel/vm/session.c
T
Robert Allan JamesandClaude Opus 5 a621131ef6 §H.12 step 3: session_set_pinned/session_is_pinned pin-authority choke point
session_is_pinned() reads Session.pinned directly (authoritative, no
Stadium re-derivation); session_set_pinned() writes both Session.pinned
and the mirrored STADIUM_FLAG_PIN bit on the session's own patron cell,
keeping Stadium's internal eviction/admission logic (which must stay
self-contained) in sync without it calling back into session.c.

Added Session.stadium_cell (index into stadium_cells()) -- necessary
plumbing not in the original H.2 field list; the choke point can't reach
the right patron header without it. Moved STADIUM_FLAG_PIN from a
stadium.c-private #define to stadium.h (public) so session.c can
reference it without a duplicate definition.

Verified 3-arch boot to ok> (amd64/aarch64/riscv64).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 06:10:11 -04:00

158 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 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.c - Per-VM session bookkeeping (FABRIC-3.md §H.12 steps 2-3)
*
* Slot table sized from stadium_max_vm_count() at session_boot_init() time,
* mirroring stadium.c's own StadiumVMQuota table (kmalloc'd to a
* budget-computed count, not a fixed compile-time array -- population isn't
* knowable in advance, same reasoning stadium.c's own history already
* settled). No callers yet; wiring into the boot sequence and into
* stadium_birth_hera()/capsule_birth.c's admission path are later
* §H.12 steps.
*
* session_set_pinned()/session_is_pinned() (step 3) are the pin-authority
* choke point -- see their own doc comments in session.h for the
* authoritative-session-mirrored-Stadium-bit split.
*/
#ifdef __STARKERNEL__
#include "starkernel/session.h"
#include "starkernel/vm/stadium.h"
#include "starkernel/kmalloc.h"
static Session *g_sessions = (Session *)0;
static size_t g_session_slots = 0; /* capacity, from stadium_max_vm_count() */
static size_t g_session_count = 0; /* slots actually in use, 0..g_session_slots */
int session_boot_init(void)
{
size_t max_vm_count = stadium_max_vm_count();
Session *slots;
size_t i;
if (max_vm_count == 0) return -1; /* Stadium not yet initialized */
slots = (Session *)kmalloc(max_vm_count * sizeof(Session));
if (!slots) return -1;
for (i = 0; i < max_vm_count; i++) {
uint8_t *raw = (uint8_t *)&slots[i];
size_t j;
for (j = 0; j < sizeof(Session); j++) raw[j] = 0;
slots[i].vm_id = vm_uuid_none();
slots[i].parent = vm_uuid_none();
}
g_sessions = slots;
g_session_slots = max_vm_count;
g_session_count = 0;
return 0;
}
Session *session_find(VMUuid vm_id)
{
size_t i;
if (!g_sessions) return (Session *)0;
for (i = 0; i < g_session_slots; i++) {
if (!vm_uuid_is_none(g_sessions[i].vm_id) &&
vm_uuid_equal(g_sessions[i].vm_id, vm_id)) {
return &g_sessions[i];
}
}
return (Session *)0;
}
Session *session_register(VMUuid vm_id, VMUuid parent, const char *name)
{
size_t i;
Session *slot = (Session *)0;
if (!g_sessions) return (Session *)0;
if (session_find(vm_id)) return (Session *)0; /* already registered */
for (i = 0; i < g_session_slots; i++) {
if (vm_uuid_is_none(g_sessions[i].vm_id)) {
slot = &g_sessions[i];
break;
}
}
if (!slot) return (Session *)0; /* table full */
slot->vm_id = vm_id;
slot->parent = parent;
slot->pinned = 0;
slot->stadium_cell = SESSION_STADIUM_CELL_NONE;
{
size_t j = 0;
if (name) {
for (; j < SESSION_NAME_BUF - 1u && name[j]; j++) slot->name[j] = name[j];
}
slot->name[j] = '\0';
}
{
uint8_t *raw = (uint8_t *)&slot->identity;
size_t j;
for (j = 0; j < sizeof(VMIdentity); j++) raw[j] = 0;
}
g_session_count++;
return slot;
}
void session_set_pinned(VMUuid vm_id, int pinned)
{
Session *s = session_find(vm_id);
StadiumCell *cells;
if (!s) return;
s->pinned = pinned ? 1 : 0;
if (s->stadium_cell == SESSION_STADIUM_CELL_NONE) return;
if (s->stadium_cell >= stadium_cell_count()) return;
cells = stadium_cells();
if (!cells) return;
if (pinned) {
cells[s->stadium_cell].header.flags |= STADIUM_FLAG_PIN;
} else {
cells[s->stadium_cell].header.flags &= (uint8_t)~STADIUM_FLAG_PIN;
}
}
int session_is_pinned(VMUuid vm_id)
{
Session *s = session_find(vm_id);
if (!s) return 0;
return s->pinned;
}
#endif /* __STARKERNEL__ */