skip to content
==> include/mesh/words_host.h <==
1/* @ajax/mesh-words-host: mesh_words over a host mapping of the mailbox (or any
2 * 4-byte-aligned memory), with C11 atomics: loads acquire, stores release,
3 * read-modify-writes acq_rel, byte copies relaxed word by word (little-endian),
4 * as the Rust host runtimes and tests access the mailbox. Header-only. */
5#ifndef MESH_WORDS_HOST_H
6#define MESH_WORDS_HOST_H
7
8#include "mesh/abi/words.h"
9
10#include <stdatomic.h>
11#include <stddef.h>
12#include <stdint.h>
13
14static inline _Atomic uint32_t *mesh_words_host_at_(void *base, size_t a) { return (_Atomic uint32_t *)base + a / 4; }
15
16static inline uint32_t mesh_words_host_load_(void *c, size_t a) {
17    return atomic_load_explicit(mesh_words_host_at_(c, a), memory_order_acquire);
18}
19static inline void mesh_words_host_store_(void *c, size_t a, uint32_t v) {
20    atomic_store_explicit(mesh_words_host_at_(c, a), v, memory_order_release);
21}
22static inline uint32_t mesh_words_host_cas_(void *c, size_t a, uint32_t cmp, uint32_t desired) {
23    uint32_t seen = cmp;
24    atomic_compare_exchange_strong_explicit(mesh_words_host_at_(c, a), &seen, desired, memory_order_acq_rel,
25                                            memory_order_acquire);
26    return seen;
27}
28static inline uint32_t mesh_words_host_add_(void *c, size_t a, uint32_t v) {
29    return atomic_fetch_add_explicit(mesh_words_host_at_(c, a), v, memory_order_acq_rel);
30}
31static inline void mesh_words_host_read_(void *c, size_t a, uint8_t *out, size_t n) {
32    for (size_t i = 0; 4 * i < n; i++) {
33        uint32_t v = atomic_load_explicit(mesh_words_host_at_(c, a + 4 * i), memory_order_relaxed);
34        for (size_t k = 0; k < 4 && 4 * i + k < n; k++) out[4 * i + k] = (uint8_t)(v >> (8 * k));
35    }
36}
37static inline void mesh_words_host_write_(void *c, size_t a, const uint8_t *b, size_t n) {
38    for (size_t i = 0; 4 * i < n; i++) {
39        uint32_t v = 0;
40        for (size_t k = 0; k < 4 && 4 * i + k < n; k++) v |= (uint32_t)b[4 * i + k] << (8 * k);
41        atomic_store_explicit(mesh_words_host_at_(c, a + 4 * i), v, memory_order_relaxed);
42    }
43}
44
45/* mesh_words over base: offset a is the word at base + a (a multiple of 4).
46 * base must be 4-byte aligned and outlive the table. */
47static inline mesh_words mesh_words_host(void *base) {
48    mesh_words w = {base, mesh_words_host_load_, mesh_words_host_store_, mesh_words_host_cas_, mesh_words_host_add_,
49                    NULL, mesh_words_host_read_, mesh_words_host_write_};
50    return w;
51}
52
53#endif