skip to content
[readonly]
==> src/native_internal.h <==
1/* The native executor's internals, shared by its source files. */
2#ifndef MESH_NATIVE_INTERNAL_H
3#define MESH_NATIVE_INTERNAL_H
4
5#include "mesh/cpuuse.h"
6#include "mesh/log.h"
7#include "mesh/mailbox.h"
8#include "mesh/native.h"
9#include "mesh/proc_usage.h"
10#include "mesh/spawn.h"
11#include "mesh/text.h"
12
13#include <pthread.h>
14#include <stdatomic.h>
15#include <stdlib.h>
16
17/* How long proc_kill waits for a SIGKILLed process to be reaped. */
18#define KILL_REAP_MS 500u
19
20uint64_t mesh_native_now_ns(void);
21void mesh_native_sleep_us(unsigned us);
22
23/* One worker process (refcounted: the host's list, an image's run, its reader threads). */
24typedef struct proc {
25    atomic_int refs;
26    pid_t pid;
27    char *name;
28    pthread_mutex_t stdin_mu;
29    int stdin_fd;
30    /* What the status pipe told. */
31    _Atomic uint32_t ready, halted_gen;
32    atomic_bool eof;
33    _Atomic uint32_t outs_done; /* stdout and stderr readers at EOF (2: every line is in the tail) */
34    pthread_mutex_t tail_mu;
35    char *tail[MESH_NATIVE_TAIL];
36    size_t tail_head, tail_len;
37    pthread_mutex_t status_mu;
38    bool exited;
39    int status;
40    pthread_mutex_t sample_mu;
41    uint64_t sample_t, sample_cpu, sample_rss;
42    float sample_pct;
43    uint32_t limits;
44    atomic_bool exit_sent;
45} proc;
46
47void proc_ref(proc *p);
48void proc_unref(proc *p);
49bool proc_send(proc *p, const char *line);
50void proc_tell_exit(proc *p);
51bool proc_exited(proc *p, int *status);
52void proc_kill(proc *p);
53char *proc_tail_text(proc *p);
54void proc_sample(proc *p, uint64_t *cpu, uint64_t *rss, float *pct);
55void proc_last(proc *p, uint64_t *cpu, uint64_t *rss, float *pct);
56void proc_retire(proc *p, mesh_native_host *h);
57void mesh_native_status_line(proc *p, const char *l);
58
59struct mesh_native_host {
60    mesh_mailbox mb;
61    mesh_shm shm;
62    char *logs;
63    mesh_worker_cfg cfg;
64    pthread_mutex_t mu;
65    proc **procs;
66    size_t nprocs;
67    _Atomic uint32_t spawns, crashes;
68};
69
70/* What a spawn needs (refcounted: shared with the thread that spawns). */
71typedef struct {
72    atomic_int refs;
73    char *name;
74    char *bin;
75    mesh_native_limits limits;
76    bool gpu; /* manifest device = "gpu" */
77    _Atomic uint32_t spawns;
78} spec;
79
80void host_forget(mesh_native_host *h, proc *p);
81/* A new worker process for s, up to its `ready` (blocks: call it off the driver thread). */
82bool host_spawn(mesh_native_host *h, spec *s, proc **out, char **err);
83
84static inline _Noreturn void mesh_worker_fatal_thread(void) {
85    mesh_error("native: thread: cannot start one");
86    abort();
87}
88
89#endif