1/* @ajax/mesh-native: native worker processes (mesh-host native.rs). A
2 * program whose manifest says `backends = ["native"]` is an executable built
3 * for this machine's target (`<catalog dir>/<target triple>/<name>`, linking
4 * @ajax/mesh-worker). It runs as its own process beside the GPU backend,
5 * maps meshd's mailbox and plays mesh-rt's node loop on its slot's ring.
6 *
7 * An image (mesh_native_worker, a mesh_kernel of exec BACKEND_NATIVE) owns at
8 * most one process at a time:
9 * - prepare (the JIT thread): manifest, the binary for this target, the image
10 * hash (manifest + source.hash), the limits' availability;
11 * - launch: `run <gen> <slot>` to that process, or a new one is spawned off
12 * the driver thread (a start after a stop) -- P_ONLINE says when it is up;
13 * - P_SHUTDOWN = SHUTDOWN_HALT (a blink, an upgrade, rollback, rebind): the
14 * nodes halt, the process stays and waits for the next `run`;
15 * - P_SHUTDOWN = SHUTDOWN_EXIT (stop, unload, FAILED, meshd's exit): the
16 * process halts and exits; it is reaped, and killed after EXIT_GRACE;
17 * - a process that dies while it runs fails the slot (FAILED) with its exit
18 * status and the tail of its output; meshd and every other program go on. */
19#ifndef MESH_NATIVE_H
20#define MESH_NATIVE_H
2122#include "mesh/backend.h"
23#include "mesh/native_limits.h"
24#include "mesh/shm.h"
2526#include <stdbool.h>
27#include <stdint.h>
28#include <sys/types.h>
2930/* Spawn to `ready`, the program's own setup included. */
31#define MESH_NATIVE_READY_MS 60000u
32/* A launch whose process is not up by then fails (the driver's ONLINE for native slots). */
33#define MESH_NATIVE_ONLINE_MS 60000u
34/* A worker told to exit is killed when it is still there this long after. */
35#define MESH_NATIVE_EXIT_GRACE_MS 3000u
36/* Output lines kept per process for a crash report. */
37#define MESH_NATIVE_TAIL 30
3839/* The executable format of this target: an ELF of this machine (a refusal names the file). */
40bool mesh_native_check_format(const char *name, const char *path, const uint8_t *b, size_t n, char **err);
4142/* How workers that use the GPU (manifest `device = "gpu"`) reach it. */
43typedef enum {
44 MESH_GPU_ACCESS_NONE, /* no GPU (--backend wasm): refused at load */
45 MESH_GPU_ACCESS_BLINK, /* CUDA in blink mode: refused at load (time-sliced against the resident kernels) */
46 MESH_GPU_ACCESS_MPS, /* CUDA under --isolation mps: a client of meshd's server, checked after `ready` */
47 MESH_GPU_ACCESS_METAL,
48} mesh_gpu_access_kind;
4950/* What every worker of this meshd is started with. */
51typedef struct {
52 char **env; /* extra "K=V" entries (MESH_SERVICE_BASE, MESH_MODELS, MESH_SYSTEM), NULL-terminated or NULL */
53 mesh_gpu_access_kind gpu;
54 char *mps_pipe_dir; /* MPS: CUDA_MPS_PIPE_DIRECTORY for GPU workers */
55 /* MPS: checks that a GPU worker that said `ready` is a client of meshd's server
56 * (@ajax/mesh-mps's mesh_mps_check_native); NULL: none. */
57 bool (*check_gpu_client)(pid_t pid, char **err);
58} mesh_worker_cfg;
5960/* Shared by every native image of a meshd: the mailbox every worker maps, where logs go. */
61typedef struct mesh_native_host mesh_native_host;
6263/* logs: each program's output goes to <logs>/<name>.log. cfg is copied. */
64mesh_native_host *mesh_native_host_new(const mesh_shm *shm, const char *logs, const mesh_worker_cfg *cfg);
6566/* Machine totals for the host block. */
67typedef struct {
68 uint32_t procs;
69 float cpu_pct;
70 uint64_t rss;
71 uint32_t spawns, crashes;
72} mesh_native_totals;
7374/* Live processes, spawns and crashes now (no sampling). */
75void mesh_native_host_counts(mesh_native_host *h, uint32_t *live, uint32_t *spawns, uint32_t *crashes);
76/* Samples every live worker: the machine's totals (about once a second). */
77mesh_native_totals mesh_native_host_totals(mesh_native_host *h);
7879/* One image's numbers for its slot's control words. */
80typedef struct {
81 pid_t pid;
82 float cpu_pct;
83 uint64_t rss, cpu_ns;
84 uint32_t spawns, crashes, exit, limits;
85} mesh_native_stats;
8687/* A native program image (behind a mesh_kernel). */
88typedef struct mesh_native_worker mesh_native_worker;
8990const char *mesh_native_worker_name(const mesh_native_worker *w);
91const char *mesh_native_worker_bin(const mesh_native_worker *w);
92uint64_t mesh_native_worker_bin_hash(const mesh_native_worker *w);
93uint64_t mesh_native_worker_bin_bytes(const mesh_native_worker *w);
94/* Starts its process now and waits for `ready` (the JIT thread). */
95bool mesh_native_worker_warm(mesh_native_worker *w, char **err);
96/* Launch on slot: `run` to its process, or a new one spawned off this thread. */
97bool mesh_native_worker_launch(mesh_native_worker *w, uint32_t slot, char **err);
98/* The last launch is over (halted, or its process gone). */
99bool mesh_native_worker_query(mesh_native_worker *w);
100/* A failure of the running launch, reported once (malloc'd), or NULL. */
101char *mesh_native_worker_crashed(mesh_native_worker *w);
102/* Its numbers (call after mesh_native_host_totals, which samples every process). */
103mesh_native_stats mesh_native_worker_stats(mesh_native_worker *w);
104/* Unload: its process (if any) exits, reaped off this thread. */
105void mesh_native_worker_release(mesh_native_worker *w);
106/* The pid of its live process, 0 if none. */
107pid_t mesh_native_worker_pid(mesh_native_worker *w);
108109/* The native executor beside the GPU backend: isolated, not resident. The
110 * backend owns the host. Registers mesh_native_cleanup with mesh-backend. */
111mesh_backend *mesh_native_backend_new(const mesh_shm *shm, const char *logs, const mesh_worker_cfg *cfg);
112mesh_native_host *mesh_native_backend_host(const mesh_backend *b);
113/* Every worker of every host: asked to exit, then killed and reaped (meshd's exit paths). */
114void mesh_native_cleanup(void);
115116#endif