skip to content
==> tests/pipesrc.c <==
1/* pipesrc-n on exec's node loop: msgs into pipehash's inbox in order (mode
2 * 0), digests straight into a sink (mode 1), backpressure when full, `gone`
3 * without a consumer, and its ops. */
4#include "harness.h"
5#include "../src/pipesrc.h"
6
7#include "mesh/abi/pipe.h"
8#include "mesh/abi/view_pipedemo.h"
9
10#define SRC 2
11#define HASH 0
12#define SINK 1
13
14int main(void) {
15    mesh_mailbox mb = mesh_mailbox_test();
16    mesh_words w = mesh_mailbox_words(mb);
17    h_install(mb, SRC, "pipesrc-n", 1, 0x100000, 0x100);
18    h_install(mb, HASH, "pipehash", 1, 0x110000, 0x16000);
19    h_inbox(mb, HASH, MESH_PIPEDEMO_H_INBOX, 128, 64, MESH_PIPEDEMO_MSG_TYPE);
20    h_feed(mb, SRC, HASH);
21    h_slot h = {.mb = mb, .slot = SRC, .prog = {pipesrc_init, pipesrc_task, NULL}};
22    h_start(&h);
23    CHECK_U(h_call(&h, MESH_OP_INIT, 0), MESH_R_NONE);
24    size_t v = 0x100000;
25    CHECK_U(mesh_mailbox_get(mb, v + MESH_PIPEDEMO_S_BATCH), MESH_PIPEDEMO_SRC_BATCH);
26    /* Mode 0: one batch of 64 msgs, in seq order on the CPU side. */
27    CHECK_U(h_call(&h, MESH_OP_TASK, 0), 64);
28    CHECK_U(mesh_mailbox_get(mb, v + MESH_PIPEDEMO_S_DST), HASH + 1);
29    uint8_t rec[64];
30    for (uint32_t s = 0; s < 64; s++) {
31        CHECK_I(mesh_pipe_pop(&w, HASH, rec, 64), 1);
32        uint32_t seq = (uint32_t)rec[0] | (uint32_t)rec[1] << 8 | (uint32_t)rec[2] << 16 | (uint32_t)rec[3] << 24;
33        CHECK_U(seq, s);
34        CHECK_U(rec[12], MESH_PIPEDEMO_ORIGIN_NATIVE);
35    }
36    /* Backpressure: the CPU side holds 64; the second batch of 64 fills it, the third is refused. */
37    CHECK_U(h_call(&h, MESH_OP_TASK, 0), 64);
38    CHECK_U(h_call(&h, MESH_OP_TASK, 0), 0);
39    CHECK_U(mesh_mailbox_get(mb, v + MESH_PIPEDEMO_S_FULL), 1);
40    CHECK_U(mesh_mailbox_get(mb, v + MESH_PIPEDEMO_S_SENT), 128);
41    /* Mode 1 with no sink: gone. Then a sink: digests of msgs 128.. */
42    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_MODE, MESH_PIPEDEMO_MODE_DIRECT), 0);
43    CHECK_U(h_call(&h, MESH_OP_TASK, 0), 0);
44    CHECK_U(mesh_mailbox_get(mb, v + MESH_PIPEDEMO_S_GONE), 1);
45    h_install(mb, SINK, "pipesink", 1, 0x130000, 0x3d000);
46    h_inbox(mb, SINK, MESH_PIPEDEMO_K_INBOX, 256, 48, MESH_PIPEDEMO_DIGEST_TYPE);
47    h_feed(mb, SRC, SINK);
48    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_BATCH, 5), 0);
49    CHECK_U(h_call(&h, MESH_OP_TASK, 0), 5);
50    uint8_t d[48];
51    CHECK_I(mesh_pipe_pop(&w, SINK, d, 48), 1);
52    uint32_t seq = (uint32_t)d[0] | (uint32_t)d[1] << 8 | (uint32_t)d[2] << 16 | (uint32_t)d[3] << 24;
53    CHECK_U(seq, 128);
54    /* Ops. */
55    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_MODE, 9), MESH_R_BAD_OP);
56    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_BATCH, 0), MESH_R_BAD_OP);
57    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_INTERVAL, 500), 0);
58    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_RESET, 0), 0);
59    CHECK_U(mesh_mailbox_get(mb, v + MESH_PIPEDEMO_S_SENT), 0);
60    CHECK_U(h_call(&h, MESH_PIPEDEMO_OP_MODE, MESH_PIPEDEMO_MODE_OFF), 0);
61    CHECK_U(h_call(&h, MESH_OP_TASK, 0), 0);
62    h_stop(&h);
63    free(mb.base);
64    return mesh_check_done();
65}