1/* @ajax/mesh-prog-table: the program table as meshd writes it (programs.rs).
2 *
3 * meshd is the table's only writer. It rewrites an entry only while that
4 * slot's kernel is not running (load, upgrade, rollback, reset happen with it
5 * halted), state changes excepted. Rewrites go under the entry's PT_GEN
6 * seqlock (odd while writing); every change bumps H_PROG_SEQ so viewers know
7 * to re-read. Readers on any thread take a stable copy (read_entry). */
8#ifndef MESH_PROG_TABLE_H
9#define MESH_PROG_TABLE_H
1011#include "mesh/abi.h"
12#include "mesh/mailbox.h"
1314#include <stdbool.h>
15#include <stdint.h>
1617/* Rewrites slot s's entry (all but PT_STATE/PT_GEN), its manifest extension
18 * and its state under the seqlock: PT_GEN odd, the bytes, PT_GEN even. */
19void mesh_pt_write_entry(mesh_mailbox mb, uint32_t s, const uint8_t entry[MESH_PT_BYTES], const uint8_t ext[MESH_PX_BYTES],
20 uint32_t state);
21/* The state word alone (it may change while the kernel runs); unchanged: nothing. */
22void mesh_pt_set_state(mesh_mailbox mb, uint32_t s, uint32_t state);
23/* An EMPTY slot: the entry, extension and pipe block zeroed (seqlocked). */
24void mesh_pt_clear(mesh_mailbox mb, uint32_t s);
25/* Slot s's pipe block (PP_*), under its seqlock, in place while it runs.
26 * PP_FLIGHT and PP_FLIGHT1 are the executor's words: never written. Unchanged: nothing. */
27void mesh_pt_write_pipe(mesh_mailbox mb, uint32_t s, const uint8_t b[MESH_PP_BYTES]);
28/* Holds (or releases) slot s's inbox: pushes answer "full" while held. */
29void mesh_pt_set_hold(mesh_mailbox mb, uint32_t s, bool on);
30/* Producer slot s's pushes in flight counted in its word of `parity`. */
31uint32_t mesh_pt_flight(mesh_mailbox mb, uint32_t s, uint32_t parity);
32/* Starts a quiescence period (H_PIPE_EPOCH bumped, then a fence): the old parity, whose words now only drain. */
33uint32_t mesh_pt_flight_epoch(mesh_mailbox mb);
34/* Slot s runs no code: its pushes in flight are none. */
35void mesh_pt_flight_clear(mesh_mailbox mb, uint32_t s);
36/* Fresh per-slot words for a new program: control block (all but the GPU's P_RUN_REQ), node records, trace. */
37void mesh_pt_reset_slot(mesh_mailbox mb, uint32_t s);
38/* The name as the table stores it (NUL-terminated; invalid UTF-8 replaced as Rust's from_utf8_lossy would not matter: names are [a-z0-9-]). */
39void mesh_pt_name_of(mesh_mailbox mb, uint32_t s, char out[MESH_NAME_BYTES + 1]);
40/* The non-empty slot whose entry holds name; false when none. */
41bool mesh_pt_find(mesh_mailbox mb, const char *name, uint32_t *slot);
42/* One stable copy of slot s's entry (retries while the writer holds the seqlock). */
43void mesh_pt_read_entry(mesh_mailbox mb, uint32_t s, uint8_t out[MESH_PT_BYTES]);
4445#endif