==> tests/shm.c <==1/* shm.rs's tests: two mappings share words; a child's writes land in the parent's mapping. */
2#include "mesh/check.h"
3#include "mesh/shm.h"
4
5#include <fcntl.h>
6#include <stdatomic.h>
7#include <stdint.h>
8#include <stdlib.h>
9#include <sys/mman.h>
10#include <sys/wait.h>
11#include <unistd.h>
12
13int main(void) {
14 mesh_shm s;
15 char *err = NULL;
16 CHECK(mesh_shm_with_len(1 << 16, &s, &err));
17 CHECK_U((uintptr_t)s.base % 4096, 0);
18 int fd = dup(s.fd);
19 uint8_t *q = mmap(NULL, 1 << 16, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
20 CHECK(q != MAP_FAILED);
21 _Atomic uint32_t *a = (_Atomic uint32_t *)(s.base + 0x100), *b = (_Atomic uint32_t *)(q + 0x100);
22 CHECK_U(atomic_load(b), 0);
23 atomic_store(a, 0xfeed);
24 CHECK_U(atomic_load(b), 0xfeed);
25 atomic_fetch_add(b, 1);
26 CHECK_U(atomic_load(a), 0xfeee);
27 /* close-on-exec: children get it only by dup2 */
28 CHECK((fcntl(s.fd, F_GETFD) & FD_CLOEXEC) != 0);
29 munmap(q, 1 << 16);
30 close(fd);
31 /* across a fork */
32 _Atomic uint32_t *w = (_Atomic uint32_t *)(s.base + 0x40);
33 pid_t pid = fork();
34 if (pid == 0) {
35 atomic_store(w, 77);
36 _exit(0);
37 }
38 int st;
39 waitpid(pid, &st, 0);
40 CHECK_U(atomic_load(w), 77);
41 char *path = mesh_shm_path(&s);
42 int pfd = open(path, O_RDWR);
43 CHECK(pfd >= 0);
44 close(pfd);
45 free(path);
46 mesh_shm_close(&s);
47 /* The full mailbox. */
48 mesh_shm mb;
49 CHECK(mesh_shm_new(&mb, &err));
50 CHECK_U(mb.len, 0x800000);
51 mesh_shm_close(&mb);
52 return mesh_check_done();
53}