==> 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}