==> 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