skip to content
==> include/mesh/publish.h <==
1/* @ajax/mesh-publish: the generic task publisher (publish.rs; contract v2).
2 *
3 * One ring per program slot, and the manifest's policy deciding what meshd
4 * publishes on its own: continuous (a batch whenever the previous one
5 * completed, or topped up to `fanout` in flight with in_flight = "free"),
6 * periodic (`fanout` tasks at `hz`), on_demand (nothing; only task/req). The
7 * arg is the index 0..fanout or the view's u32 at `arg_off` (+ index).
8 * Nothing here knows any program: a new program needs no meshd change.
9 *
10 * Ticket rules: ticket t uses ring entry and completion slot t % 64; t may be
11 * published only once no outstanding ticket is 64 or more behind. */
12#ifndef MESH_PUBLISH_H
13#define MESH_PUBLISH_H
14
15#include "mesh/abi.h"
16#include "mesh/mailbox.h"
17#include "mesh/manifest.h"
18#include "mesh/reply.h"
19
20#include <stdbool.h>
21#include <stddef.h>
22#include <stdint.h>
23
24/* Who waits for a ticket (publish.rs Kind). */
25typedef enum {
26    MESH_TK_AUTO,      /* published by the policy */
27    MESH_TK_INIT,      /* OP_INIT before anything else */
28    MESH_TK_TASK,      /* `task <name> <op> <arg>`: reply gets the result */
29    MESH_TK_REQ,       /* a byte request (OP_REQ) with its P_REQ_SEQ: reply gets the response */
30    MESH_TK_FOLLOW,    /* placement: a part of a split frame (OP_FOLLOW) */
31    MESH_TK_JOB,       /* a job's item: lease, job, item */
32    MESH_TK_JOB_SETUP, /* a job's setup task: job, op, arg */
33} mesh_tk;
34
35typedef struct {
36    mesh_tk tk;
37    mesh_reply *reply; /* TASK, REQ: the waiter (owned) */
38    uint64_t seq;      /* REQ */
39    uint64_t lease, job, item; /* JOB (job also for JOB_SETUP) */
40    uint32_t op, arg;          /* JOB_SETUP */
41} mesh_kind;
42
43typedef struct {
44    uint32_t ticket;
45    mesh_kind kind;
46} mesh_out;
47
48/* A completed ticket and its result. */
49typedef struct {
50    mesh_out out;
51    uint32_t result;
52} mesh_done;
53
54/* Slot s's ring, host side; the driver thread is its only publisher. */
55typedef struct {
56    size_t ctl;
57    uint32_t tail; /* the next ticket to publish */
58    mesh_out *inflight; /* in publication order */
59    size_t n, cap;
60} mesh_pring;
61
62static inline mesh_kind mesh_kind_of(mesh_tk tk) {
63    mesh_kind k = {tk, NULL, 0, 0, 0, 0, 0, 0};
64    return k;
65}
66
67/* A fresh ring (the control block was zeroed). */
68void mesh_pring_init(mesh_pring *r, uint32_t slot);
69void mesh_pring_free(mesh_pring *r); /* drops outstanding waiters unanswered */
70/* Tickets publishable now (the oldest outstanding one bounds the window). */
71uint32_t mesh_pring_room(const mesh_pring *r);
72bool mesh_pring_can_publish(const mesh_pring *r);
73/* Publishes; true with *ticket. False when full: the kind stays the caller's. */
74bool mesh_pring_publish(mesh_pring *r, mesh_mailbox mb, uint32_t op, uint32_t arg, mesh_kind kind, uint32_t *ticket);
75/* Completed tickets with their results, in publication order: *done (free it), *n. */
76void mesh_pring_collect(mesh_pring *r, mesh_mailbox mb, mesh_done **done, size_t *n);
77bool mesh_pring_idle(const mesh_pring *r);
78uint32_t mesh_pring_auto_in_flight(const mesh_pring *r);
79uint32_t mesh_pring_follow_in_flight(const mesh_pring *r);
80size_t mesh_pring_in_flight(const mesh_pring *r);
81bool mesh_pring_has_req(const mesh_pring *r);
82bool mesh_pring_has_init(const mesh_pring *r);
83/* Every node halted: the outstanding tickets will never run. They are
84 * returned (*outs, free it), and P_RING_HEAD goes back to the tail. */
85void mesh_pring_rewind(mesh_pring *r, mesh_mailbox mb, mesh_out **outs, size_t *n);
86
87/* How many auto tasks the policy wants published now (of a batch of n);
88 * advances *last (the periodic clock, ns) when it publishes. */
89uint32_t mesh_due(const mesh_manifest *m, uint32_t n, const mesh_pring *r, int64_t *last, int64_t now);
90/* Publishes what due asks for; returns the count. A batch goes out whole or
91 * waits for ring room; in_flight = "free" publishes what fits. */
92uint32_t mesh_publish_auto(mesh_mailbox mb, const mesh_manifest *m, uint32_t view_off, mesh_pring *r, int64_t *last, int64_t now);
93/* publish_auto for the args in `parts` (bit b: arg b) of each batch only, ascending. */
94uint32_t mesh_publish_parts(mesh_mailbox mb, const mesh_manifest *m, uint32_t view_off, mesh_pring *r, int64_t *last,
95                            int64_t now, uint32_t parts);
96
97#endif