/* Shared-memory capture ring: the proxy (Windows PE inside wine, sole
 * producer) and the relay (Linux, sole consumer) map the same tmpfs file
 * (/dev/shm/w3cs-ring-seatN; the proxy reaches it as Z:\dev\shm\...).
 * Wine's CreateFileMapping over a regular file is a real MAP_SHARED mmap,
 * so both sides see the same pages and ordinary acquire/release atomics
 * carry the ordering.
 *
 * The ring replaces the append-only capture file for the SAME byte
 * stream: length-prefixed w3cs envelopes, exactly what the proxy's
 * queued messages already contain and what the relay's tail parser
 * already reads. It removes ~30 Mbps of disk writeback plus the read
 * syscalls on the other side, and it removes torn tails: write_pos is
 * published once per complete message, so a killed writer can never
 * leave a partial packet visible.
 *
 * Positions are free-running uint32 byte counters (mod 2^32); the data
 * offset is pos & (capacity - 1) with capacity a power of two. Bytes may
 * wrap the boundary (two memcpys); there are no markers or padding.
 *
 * Lifecycle: the seat launcher deletes the ring file at unit boot, the
 * relay creates and initializes it (magic written last, release), and
 * the proxy attaches read-write, retrying until the header validates. A
 * relay restart adopts the stored positions and loses nothing. The
 * producer re-reads write_pos from the header on every message - never
 * cached across calls - so a CRIU-restored proxy continues exactly where
 * the live ring stands. */

#ifndef W3CS_RING_H
#define W3CS_RING_H

#include <stdint.h>

#define W3CS_RING_MAGIC 0x42523357u /* "W3RB" little-endian */
#define W3CS_RING_VERSION 1u
#define W3CS_RING_HEADER_BYTES 4096u
#define W3CS_RING_CAPACITY (32u * 1024u * 1024u)

struct w3cs_ring_header {
    uint32_t magic;
    uint32_t version;
    uint32_t capacity;
    uint32_t reserved[13];
    /* Producer-owned cache line. */
    volatile uint32_t write_pos;
    uint32_t producer_pad[15];
    /* Consumer-owned cache line. */
    volatile uint32_t read_pos;
    uint32_t consumer_pad[15];
};

#ifdef __cplusplus
static_assert(sizeof(struct w3cs_ring_header) == 192,
              "ring header layout is part of the shared contract");
#else
_Static_assert(sizeof(struct w3cs_ring_header) == 192,
               "ring header layout is part of the shared contract");
#endif

static inline int w3cs_ring_valid(const struct w3cs_ring_header *header,
                                  uint32_t file_size)
{
    return header->magic == W3CS_RING_MAGIC &&
           header->version == W3CS_RING_VERSION &&
           header->capacity >= 1024u * 1024u &&
           (header->capacity & (header->capacity - 1u)) == 0u &&
           file_size >= W3CS_RING_HEADER_BYTES + header->capacity;
}

#endif /* W3CS_RING_H */
