> ## Documentation Index
> Fetch the complete documentation index at: https://zinc.ossl.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Region Header Layout

> The 64-byte header at the start of every shared memory region

Every mapped Zinc region begins with a 64-byte header occupying one CPU cache line. The header is `#[repr(C, align(64))]` in Rust, meaning its layout is stable and exactly 64 bytes. The data area begins at offset 64.

## Layout

```
Offset  Size    Type          Field        Description
------  ------  ------------  -----------  -----------------------------------
0       8       u64           magic        Magic number for corruption detection
8       2       u16           version      Breaking-change guard (currently 1)
10      2       u16           flags        Reserved
12      4       AtomicU32     notify_seq   Notification/futex signal counter
16      8       u64           capacity     Usable bytes after header
24      4       AtomicU32     ref_count    Open handle count
28      4       AtomicI32     owner_pid    PID of creating process
32      8       u64           created_at   Unix timestamp (nanoseconds)
40      8       u64           name_hash    FNV-1a hash of region name
48      8       AtomicU64     ring_head    Notification ring write position
56      8       AtomicU64     ring_tail    Notification ring read position
```

Total: 64 bytes. Not a single byte more.

## Fields

### magic (offset 0, 8 bytes)

Fixed to `0x5A494E435F524547`, which spells `"ZINC_REG"` in ASCII. Checked on open to detect corrupted regions or segments that were overwritten by non-Zinc code. Any process could theoretically write a valid magic number at this offset; this field is a sanity check, not a security boundary.

### version (offset 8, 2 bytes)

Currently 1. Incremented when the header layout changes in a backward-incompatible way. When a region is opened, the opener's library version must match the stored version. A mismatch returns `CorruptedRegion`.

### flags (offset 10, 2 bytes)

Reserved for future use. Currently always 0. Writers should not depend on this field being zero, as future versions may use it for feature flags.

### notify\_seq (offset 12, 4 bytes)

The atomic counter used by `notify()` and `wait()`. Incremented on every `notify()` call. On Linux, the address of this field is passed as the `futex` word. On other platforms, it is polled in the adaptive wait loop.

### capacity (offset 16, 8 bytes)

The number of usable bytes in the data area. Set at creation time and immutable for the lifetime of the region. This is the total mapping size minus 64 bytes.

### ref\_count (offset 24, 4 bytes)

Tracks the number of open handles on this region. Incremented on `zinc_open`, decremented on `zinc_close`. When the creator's handle closes and the count reaches zero, the region is unlinked.

### owner\_pid (offset 28, 4 bytes)

The PID of the process that called `create`. Stored for diagnostic purposes. Not used by the library logic, but helpful when debugging leaked regions.

### created\_at (offset 32, 8 bytes)

Unix timestamp in nanoseconds at the time of creation. Set from `SystemTime::now().duration_since(UNIX_EPOCH)`. Useful for ordering or deduplication of regions with the same name.

### name\_hash (offset 40, 8 bytes)

FNV-1a hash of the region name. Stored to allow quick equality checks without string comparison across processes. Not used by the current implementation but reserved for future use.

### ring\_head / ring\_tail (offset 48 / 56, 8 bytes each)

The head and tail cursors of the internal lock-free notification ring. This ring is used for lightweight event delivery (sequence numbers, not data). The ring has 256 slots and uses a standard MPSC (multi-producer, single-consumer) protocol on these atomic counters.

## Stability guarantees

The header layout is versioned. Version 1 will never change. If a future version needs to add fields, it can reuse the reserved `flags` field or extend into the data area with a new version number. The `magic` and `version` fields are always at offset 0 and 8 for forward compatibility.

## Access from user code

There is no public API to read the header fields from adapter code. The header is an internal implementation detail. However, if you need to inspect it for debugging (for example, to verify that two processes see the same header), you can read the raw bytes at offset 0 through the data pointer:

```rust theme={null}
// Rust: read the header directly (unsafe, for debugging only)
let hdr: &RegionHeader = unsafe {
    &*(region.as_ptr().sub(64) as *const RegionHeader)
};
println!("magic: 0x{:x}, owner_pid: {}", hdr.magic, hdr.owner_pid);
```

This is not recommended in production code. The header format is not part of the public API commitment and may change with version bumps.
