skip to content
==> src/net_counters.c <==
1/* Relaxed atomic counters, copied little-endian into the host block. */
2#include "mesh/net_counters.h"
3#include "mesh/abi/host_net.h"
4
5#include <string.h>
6
7void mesh_net_counters_init(mesh_net_counters *c) {
8    for (size_t k = 0; k < MESH_MAX_SYSTEMS; k++) {
9        mesh_link_counters *l = &c->links[k];
10        atomic_init(&l->rx_bytes, 0);
11        atomic_init(&l->tx_bytes, 0);
12        for (size_t i = 0; i < MESH_NET_KINDS; i++) { atomic_init(&l->rx[i], 0); atomic_init(&l->tx[i], 0); }
13    }
14    for (size_t i = 0; i < 3; i++) { atomic_init(&c->ctl[i], 0); atomic_init(&c->http[i], 0); }
15}
16
17static void add(_Atomic uint64_t *a, uint64_t n) { atomic_fetch_add_explicit(a, n, memory_order_relaxed); }
18
19void mesh_net_counters_rx(mesh_net_counters *c, uint32_t k, uint8_t ty, size_t bytes) {
20    mesh_link_counters *l = &c->links[k];
21    add(&l->rx_bytes, bytes);
22    add(&l->rx[mesh_frame_kind(ty)], 1);
23}
24
25void mesh_net_counters_tx(mesh_net_counters *c, uint32_t k, const uint8_t *f, size_t len) {
26    mesh_link_counters *l = &c->links[k];
27    add(&l->tx_bytes, len);
28    add(&l->tx[mesh_frame_kind(f[0])], 1);
29}
30
31void mesh_net_counters_ctl(mesh_net_counters *c, size_t rx, size_t tx) {
32    add(&c->ctl[0], rx);
33    add(&c->ctl[1], tx);
34    add(&c->ctl[2], 1);
35}
36
37void mesh_net_counters_http(mesh_net_counters *c, size_t rx, size_t tx) {
38    add(&c->http[0], rx);
39    add(&c->http[1], tx);
40    add(&c->http[2], 1);
41}
42
43static void put(uint8_t *b, size_t off, _Atomic uint64_t *a) {
44    uint64_t v = atomic_load_explicit(a, memory_order_relaxed);
45    for (int i = 0; i < 8; i++) b[off + (size_t)i] = (uint8_t)(v >> (8 * i));
46}
47
48void mesh_net_counters_fill(mesh_net_counters *c, uint8_t *b) {
49    for (uint32_t k = 0; k < MESH_MAX_SYSTEMS; k++) {
50        mesh_link_counters *l = &c->links[k];
51        size_t at = mesh_link(k);
52        put(b, at + MESH_L_RX_BYTES, &l->rx_bytes);
53        put(b, at + MESH_L_TX_BYTES, &l->tx_bytes);
54        for (size_t i = 0; i < MESH_NET_KINDS; i++) {
55            put(b, at + MESH_L_RX_FRAMES + 8 * i, &l->rx[i]);
56            put(b, at + MESH_L_TX_FRAMES + 8 * i, &l->tx[i]);
57        }
58    }
59    const size_t ctl[3] = {MESH_S_CTL_RX, MESH_S_CTL_TX, MESH_S_CTL_REQS};
60    const size_t http[3] = {MESH_S_HTTP_RX, MESH_S_HTTP_TX, MESH_S_HTTP_CONNS};
61    for (size_t i = 0; i < 3; i++) { put(b, ctl[i], &c->ctl[i]); put(b, http[i], &c->http[i]); }
62}