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