1/* @ajax/mesh-abi-words: Word and byte access to the mailbox at mailbox offsets: the interface pipes run over.
2 *
3 * Part of alpha-c-mesh, a C port of alpha-rust-mesh (README.md says from where). */
4#ifndef MESH_ABI_WORDS_H
5#define MESH_ABI_WORDS_H
67#include <stdbool.h>
8#include <stddef.h>
9#include <stdint.h>
10#include <stdatomic.h>
1112/* Word access to the mailbox, at mailbox offsets (every runtime maps the
13 * offsets to its own addresses): Rust's `Words` trait (and `Bytes`, its byte
14 * copies for the host runtimes), as a table of functions over a context.
15 * A GPU runtime fills it with its own atomics; static inline callers given a
16 * constant table are devirtualised by the compiler. */
17typedef struct mesh_words {
18 void *ctx;
19 uint32_t (*load_acquire)(void *ctx, size_t a);
20 void (*store_release)(void *ctx, size_t a, uint32_t v);
21 /* Returns the old value. */
22 uint32_t (*cas)(void *ctx, size_t a, uint32_t cmp, uint32_t desired);
23 /* Returns the old value. */
24 uint32_t (*add)(void *ctx, size_t a, uint32_t v);
25 /* A sequentially consistent fence (a store before it is ordered before a
26 * load after it). NULL: atomic_thread_fence(memory_order_seq_cst). */
27 void (*fence)(void *ctx);
28 /* Bytes: copies for the host runtimes (wasm lanes, native workers); a GPU
29 * warp copies with all its lanes between reserve and commit instead. NULL
30 * where only words are used. */
31 void (*read)(void *ctx, size_t a, uint8_t *out, size_t n);
32 void (*write)(void *ctx, size_t a, const uint8_t *b, size_t n);
33} mesh_words;
3435static inline uint32_t mesh_words_load(const mesh_words *w, size_t a) { return w->load_acquire(w->ctx, a); }
36static inline void mesh_words_store(const mesh_words *w, size_t a, uint32_t v) { w->store_release(w->ctx, a, v); }
37static inline uint32_t mesh_words_cas(const mesh_words *w, size_t a, uint32_t cmp, uint32_t desired) {
38 return w->cas(w->ctx, a, cmp, desired);
39}
40static inline uint32_t mesh_words_add(const mesh_words *w, size_t a, uint32_t v) { return w->add(w->ctx, a, v); }
41static inline void mesh_words_fence(const mesh_words *w) {
42 if (w->fence) w->fence(w->ctx);
43 else atomic_thread_fence(memory_order_seq_cst);
44}
45static inline void mesh_words_read(const mesh_words *w, size_t a, uint8_t *out, size_t n) { w->read(w->ctx, a, out, n); }
46static inline void mesh_words_write(const mesh_words *w, size_t a, const uint8_t *b, size_t n) { w->write(w->ctx, a, b, n); }
4748#endif