skip to content
[readonly]
==> src/driver_int.h <==
1/* The driver's state (driver.rs Driver, programs.rs Image/Slot/Phase), shared by its source files. */
2#ifndef MESH_DRIVER_INT_H
3#define MESH_DRIVER_INT_H
4
5#include "mesh/driver.h"
6
7#include "mesh/abi.h"
8#include "mesh/buf.h"
9#include "mesh/jobs/frame.h"
10#include "mesh/jobs/ranges.h"
11#include "mesh/log.h"
12#include "mesh/manifest_encode.h"
13#include "mesh/prog_table.h"
14#include "mesh/publish.h"
15#include "mesh/view_alloc.h"
16
17#include <stdbool.h>
18#include <stddef.h>
19#include <stdint.h>
20
21/* Ticks and bounds, ns. */
22#define TICK_NS 500000ll
23#define FAST_TICK_NS 50000ll
24#define DRAIN_NS 3000000000ll
25#define HALT_NS 3000000000ll
26#define ONLINE_NS 2000000000ll
27#define MAX_QUEUED 256
28#define PIPE_SAMPLE_NS 2000000ll
29#define PIPE_DEADLINE_NS 500000000ll
30
31/* A program image loaded into the context (programs.rs Image). */
32typedef struct {
33    mesh_manifest manifest;
34    char *dir;
35    mesh_kernel *kernel;
36    uint64_t hash;
37    uint32_t code_bytes, regs, per_sm, reg_cap, local, rt_abi, exec;
38} dimage;
39
40typedef enum { PH_STOPPED, PH_STARTING, PH_RUNNING, PH_DRAINING, PH_HALTING } dphase;
41
42typedef struct {
43    uint32_t op, arg;
44    mesh_reply *reply;
45} dtask;
46
47typedef struct {
48    uint8_t *bytes;
49    size_t len;
50    mesh_reply *reply;
51} dreq;
52
53typedef struct {
54    dimage image;
55    bool has_prev;
56    dimage prev;
57    mesh_stream *stream;
58    uint32_t view_off, loads, reads_mask, feeds_mask, fed_mask;
59    dphase phase;
60    int64_t phase_t0;
61    bool want_run;
62    uint32_t run_seq;
63    bool needs_init;
64    char *failed; /* NULL: not failed */
65    bool unloading;
66    mesh_pring ring;
67    int64_t last_auto;
68    uint32_t last_done;
69    float rate;
70    dtask *tasks;
71    size_t ntasks, ctasks;
72    dreq *reqs;
73    size_t nreqs, creqs;
74} dslot;
75
76/* Lifecycle work that needs the JIT worker first. */
77typedef struct {
78    bool upgrade;
79    mesh_src src;
80    int run;        /* load: -1 none, 0, 1 */
81    uint32_t slot;  /* upgrade */
82    mesh_reply *reply;
83} djob;
84
85typedef enum { OP_LOAD, OP_UPGRADE, OP_ROLLBACK, OP_RESET, OP_FREE, OP_REBIND } dop_kind;
86
87typedef struct {
88    dop_kind k;
89    mesh_prepared *p; /* LOAD, UPGRADE */
90    int run;          /* LOAD */
91    uint32_t slot;    /* UPGRADE, ROLLBACK, RESET */
92    mesh_reply *reply;
93    bool has_scope;   /* false: the whole GPU context */
94    uint32_t scope;
95    uint32_t exec;
96    int64_t since;
97} dblink;
98
99typedef struct {
100    uint32_t slot;
101    bool on, unload, now;
102    mesh_reply *reply;
103    int64_t t0;
104} dwaiter;
105
106typedef struct {
107    mesh_kernel *kernel; /* NULL: only a view */
108    uint32_t view_off, view_bytes;
109    uint32_t exec;
110    bool has_inbox; /* the view held an inbox */
111    uint32_t fed;
112    int64_t since;
113    bool warned;
114} dzombie;
115
116typedef struct {
117    uint32_t consumer;
118    mesh_pipe_inbox inbox;
119    uint32_t side, producer, pos;
120} ddead;
121
122typedef struct {
123    uint64_t lease, job;
124    uint32_t op;
125    mj_setup *setup;
126    size_t nsetup;
127    mj_ranges items;
128} dlease;
129
130typedef struct {
131    dlease *q;
132    size_t n, cap;
133    bool has_ctx;
134    uint64_t ctx_job, ctx_window;
135    mesh_setup_state setup;
136    uint32_t inflight;
137} djobslot;
138
139struct mesh_driver {
140    mesh_shared *sh;
141    mesh_backend *gpu;
142    mesh_backend **cpus;
143    size_t ncpus;
144    mesh_driver_config cfg;
145    int64_t last_stats, last_log;
146    char *fault; /* a kernel faulted: the CUDA context is lost */
147    dslot *slots[MESH_PROG_SLOTS];
148    mesh_view_heap heap;
149    dzombie *zombies;
150    size_t nzombies, czombies;
151    djob *jobs; /* FIFO */
152    size_t njobs, cjobs;
153    bool working;
154    mesh_reply *work_rx;
155    djob work_job;
156    dblink *blinks; /* FIFO */
157    size_t nblinks, cblinks;
158    dwaiter *waiters;
159    size_t nwaiters, cwaiters;
160    uint32_t epoch;
161    uint32_t lock_hi, lock_lo;
162    bool state_dirty, restoring;
163    /* A GET /load/<name> from the http program: its slot, HV_LOAD_SEQ, the load's answer. */
164    bool gpu_load;
165    uint32_t gpu_load_slot, gpu_load_seq;
166    mesh_reply *gpu_load_rx;
167    bool halting;
168    int64_t halting_t;
169    char *startup_error;
170    struct { uintptr_t key; uint64_t cpu; } native_cpu[MESH_PROG_SLOTS];
171    uint32_t me, n;
172    uint32_t fleet_up;
173    bool has_fleet_leader;
174    uint32_t fleet_leader;
175    djobslot jobw[MESH_PROG_SLOTS];
176    ddead *dead;
177    size_t ndead, cdead;
178};
179
180/* driver.c */
181uint32_t drv_gpu_kind(const mesh_driver *d);
182mesh_backend *drv_be(const mesh_driver *d, uint32_t exec);
183uint32_t drv_exec_of(const mesh_driver *d, uint32_t s);
184bool drv_in_scope(const mesh_driver *d, bool has_scope, uint32_t scope, uint32_t s);
185int drv_find(const mesh_driver *d, const char *name);
186const char *drv_name(const dslot *x);
187bool drv_live(const dslot *x);
188uint32_t drv_state(const dslot *x);
189void drv_entry(const dslot *x, uint8_t out[MESH_PT_BYTES]);
190void drv_pipe(const dslot *x, uint8_t out[MESH_PP_BYTES]);
191void drv_ext(const dslot *x, uint8_t out[MESH_PX_BYTES]);
192bool drv_view_compatible(const mesh_manifest *a, const mesh_manifest *b);
193void drv_answer(mesh_reply *reply, bool ok, const char *text);
194void drv_startup_failed(mesh_driver *d, const mesh_reply *reply, const char *e);
195void drv_image_free(dimage *im);
196void drv_push_blink(mesh_driver *d, dblink b);
197void drv_push_job(mesh_driver *d, djob j);
198void drv_program_cmd(mesh_driver *d, mesh_cmd *c);
199
200/* lifecycle.c */
201void drv_programs_tick(mesh_driver *d, int64_t now);
202void drv_phase_step(mesh_driver *d, uint32_t s, int64_t now, bool in_blink);
203bool drv_halted(mesh_driver *d, uint32_t s, bool *halted, char **err);
204bool drv_launch_slot(mesh_driver *d, uint32_t s, char **err);
205void drv_running(mesh_driver *d, uint32_t s, int64_t t0);
206void drv_stopped(mesh_driver *d, uint32_t s);
207void drv_fail(mesh_driver *d, uint32_t s, char *why);
208void drv_resolve(mesh_driver *d, uint32_t s, bool on, bool ok, const char *text);
209void drv_remove(mesh_driver *d, uint32_t s);
210void drv_collect(mesh_driver *d, uint32_t s);
211void drv_context_fault(mesh_driver *d, const char *e);
212void drv_not_run(mesh_driver *d, uint32_t s, mesh_out *outs, size_t n);
213int drv_input(mesh_driver *d, uint32_t s, const uint8_t *bytes, size_t n, char **text);
214void drv_producer_stopped(mesh_driver *d, uint32_t s);
215uint32_t drv_pipe_quiet(mesh_driver *d, uint32_t fed, int64_t limit_ns);
216void drv_zero_exchange(mesh_driver *d);
217void drv_connect_pipes(mesh_driver *d);
218bool drv_pipe_check(mesh_driver *d, const mesh_manifest *m, bool has_except, uint32_t except, char **err);
219
220/* blink.c */
221void drv_jobs_tick(mesh_driver *d);
222void drv_blink_tick(mesh_driver *d);
223bool drv_op_reset(mesh_driver *d, uint32_t s, char **text);
224bool drv_precheck(mesh_driver *d, const mesh_manifest *m, char **err);
225
226/* jobs.c */
227void drv_publish_jobs(mesh_driver *d, uint32_t s);
228void drv_job_done(mesh_driver *d, uint64_t lease, uint64_t job, uint64_t item, uint32_t status, uint32_t result, const char *out);
229void drv_jobs_returned(mesh_driver *d, const dlease *l, uint32_t status, const char *why);
230void drv_lease_free(dlease *l);
231uint32_t drv_job_cap(const mesh_manifest *m, uint32_t exec);
232
233#endif