==> src/main.c <==1/* The native lifecycle fixture (mesh-worker src/bin/test_worker.rs; mesh-native's
2 * tests, mesh-lifecheck --native): op 0: arg * 3 + 7 (+ 1000 x param, so two
3 * images tell apart); OP_INIT: the view magic; 3: sleep arg ms; 4: param; 5:
4 * the pid; 9: panic; 10: allocate and touch arg MiB (a memory cap kills it);
5 * 11: read past the view (a fault); 12: spin arg ms (CPU); 13: SIGTERM itself
6 * if arg == 0, else exit(arg), mid-task (no core dump). Its setup sleeps
7 * MESH_TEST_SETUP_MS (a slow model load). */
8#include "mesh/worker.h"
9
10#include "mesh/abi/ops.h"
11
12#include <signal.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <time.h>
17#include <unistd.h>
18
19#define MAGIC 0x57544e4eu /* "NNTW" */
20
21static void sleep_ms(uint64_t ms) {
22 struct timespec t = {(time_t)(ms / 1000), (long)(ms % 1000) * 1000000L};
23 nanosleep(&t, NULL);
24}
25
26static void init(const mesh_worker_ctx *ctx, void *u) {
27 (void)u;
28 mesh_ctx_set_u32(ctx, 0, MAGIC);
29 mesh_ctx_set_u32(ctx, 4, 0);
30}
31
32static uint32_t task(const mesh_worker_ctx *ctx, uint32_t op, uint32_t arg, void *u) {
33 (void)u;
34 switch (op) {
35 case MESH_OP_TASK:
36 mesh_ctx_count(ctx, 0, 1);
37 mesh_ctx_set_u32(ctx, 4, arg);
38 return arg * 3 + 7 + 1000 * mesh_ctx_param(ctx);
39 case 3:
40 sleep_ms(arg);
41 return arg;
42 case 4: return mesh_ctx_param(ctx);
43 case 5: return (uint32_t)getpid();
44 case 9: mesh_worker_panic("deliberate crash (op 9, arg %u)", (unsigned)arg);
45 case 10: {
46 size_t n = (size_t)arg << 20;
47 volatile uint8_t *v = calloc(n ? n : 1, 1);
48 if (!v) mesh_worker_panic("out of memory (%u MiB)", (unsigned)arg);
49 for (size_t i = 0; i < n; i += 4096) v[i] = 1;
50 free((void *)v);
51 return (uint32_t)(n >> 20);
52 }
53 case 11: return mesh_ctx_view_u32(ctx, mesh_ctx_view_len(ctx));
54 case 12: {
55 uint64_t t0 = mesh_worker_now_ns();
56 volatile uint64_t x = 0;
57 while (mesh_worker_now_ns() - t0 < (uint64_t)arg * 1000000u) x = x * 6364136223846793005u + 1;
58 return (uint32_t)x;
59 }
60 case 13:
61 if (arg == 0) raise(SIGTERM);
62 exit((int)arg);
63 default: return MESH_R_BAD_OP;
64 }
65}
66
67int main(void) {
68 const char *ms = getenv("MESH_TEST_SETUP_MS");
69 if (ms) sleep_ms(strtoull(ms, NULL, 10));
70 printf("test worker %d set up\n", (int)getpid());
71 fflush(stdout);
72 mesh_worker_run(&(mesh_worker_program){init, task, NULL});
73}