NAME Data::Buffer::Shared - Type-specialized shared-memory buffers for multiprocess access SYNOPSIS use Data::Buffer::Shared::I64; # Create or open a shared buffer (file-backed mmap) my $buf = Data::Buffer::Shared::I64->new('/tmp/mybuf.shm', 1024); # Keyword API (fastest) buf_i64_set $buf, 0, 42; my $val = buf_i64_get $buf, 0; # Method API $buf->set(0, 42); my $v = $buf->get(0); # Lock-free atomic operations (integer types) buf_i64_incr $buf, 0; buf_i64_add $buf, 0, 10; buf_i64_cas $buf, 0, 52, 100; # Multiprocess if (fork() == 0) { my $child = Data::Buffer::Shared::I64->new('/tmp/mybuf.shm', 1024); buf_i64_incr $child, 0; # atomic, visible to parent exit; } wait; DESCRIPTION Data::Buffer::Shared provides type-specialized fixed-capacity buffers stored in file-backed shared memory (mmap(MAP_SHARED)), enabling efficient multiprocess data sharing on Linux. Linux-only. Requires 64-bit Perl. Features * File-backed mmap for cross-process sharing * Lock-free atomic get/set for numeric types (single-element) * Lock-free atomic counters: incr/decr/add/cas (integer types) * Seqlock-guarded bulk operations (slice, fill) * Futex-based read-write lock with stale lock recovery * Keyword API via XS::Parse::Keyword * Presized: fixed capacity, no growing Variants Data::Buffer::Shared::I8 - int8 Data::Buffer::Shared::U8 - uint8 Data::Buffer::Shared::I16 - int16 Data::Buffer::Shared::U16 - uint16 Data::Buffer::Shared::I32 - int32 Data::Buffer::Shared::U32 - uint32 Data::Buffer::Shared::I64 - int64 Data::Buffer::Shared::U64 - uint64 Data::Buffer::Shared::F32 - float Data::Buffer::Shared::F64 - double Data::Buffer::Shared::Str - fixed-length string Constructors my $buf = Data::Buffer::Shared::I64->new($path, $capacity); # file-backed my $buf = Data::Buffer::Shared::I64->new_anon($capacity); # anonymous my $buf = Data::Buffer::Shared::I64->new_memfd($name, $capacity); # memfd my $buf = Data::Buffer::Shared::I64->new_from_fd($fd); # reopen memfd The "Str" variant takes an additional $max_len argument giving the per-element fixed byte width: my $buf = Data::Buffer::Shared::Str->new($path, $capacity, $max_len); my $buf = Data::Buffer::Shared::Str->new_anon($capacity, $max_len); my $buf = Data::Buffer::Shared::Str->new_memfd($name, $capacity, $max_len); my $buf = Data::Buffer::Shared::Str->new_from_fd($fd, $max_len); "new_from_fd" duplicates the caller's fd internally; the caller keeps ownership of the passed fd. The "Str" variant requires the same $max_len the original was created with — there is no header field storing it. Lifecycle my $p = $buf->path; # backing file path, or undef for anon/memfd my $fd = $buf->fd; # memfd fd, or undef for anon/file-backed my $fd = $buf->memfd; # alias of fd() for sibling-module parity $buf->sync; # msync(MS_SYNC) mmap to backing store $buf->unlink; # remove backing file my $h = $buf->stats; # diagnostic hashref API Replace "xx" with variant prefix: "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "f32", "f64", "str". buf_xx_set $buf, $idx, $value; # set element (lock-free atomic for numeric) my $v = buf_xx_get $buf, $idx; # get element (lock-free atomic for numeric) my @v = buf_xx_slice $buf, $from, $count; # bulk read (seqlock) buf_xx_fill $buf, $value; # fill all elements (write-locked) Integer variants also have: my $n = buf_xx_incr $buf, $idx; # atomic increment, returns new value my $n = buf_xx_decr $buf, $idx; # atomic decrement my $n = buf_xx_add $buf, $idx, $delta; # atomic add my $ok = buf_xx_cas $buf, $idx, $old, $new; # compare-and-swap my $p = buf_xx_cmpxchg $buf, $idx, $old, $new; # CAS, returns prior value my $n = buf_xx_atomic_and $buf, $idx, $mask; # atomic AND (integer variants) my $n = buf_xx_atomic_or $buf, $idx, $mask; # atomic OR my $n = buf_xx_atomic_xor $buf, $idx, $mask; # atomic XOR Raw / bulk: my $raw = buf_xx_get_raw $buf, $from, $count; # bulk bytes, seqlock-guarded buf_xx_set_raw $buf, $from, $raw; # bulk bytes, write-locked $buf->add_slice($from, \@deltas); # batch atomic add (integer variants) my $ptr = buf_xx_ptr $buf; # raw pointer to data, for FFI use my $ptr = buf_xx_ptr_at $buf, $idx; # pointer to element at index Zero-copy (numeric variants): my $sv = $buf->as_scalar; # mmap-aliased read-only scalar ref Diagnostics: my $c = buf_xx_capacity $buf; my $s = buf_xx_mmap_size $buf; my $e = buf_xx_elem_size $buf; my $h = $buf->stats; # hashref: capacity/elem_size/mmap_size/variant_id/recoveries Persistence: $buf->sync; # msync(MS_SYNC) mmap to backing store Explicit locking (for batch operations): buf_xx_lock_wr $buf; # write lock + seqlock begin buf_xx_unlock_wr $buf; # seqlock end + write unlock buf_xx_lock_rd $buf; # read lock buf_xx_unlock_rd $buf; # read unlock SEE ALSO Data::HashMap::Shared - concurrent hash table Data::Queue::Shared - FIFO queue Data::PubSub::Shared - publish-subscribe ring Data::ReqRep::Shared - request-reply Data::Sync::Shared - synchronization primitives Data::Pool::Shared - fixed-size object pool Data::Stack::Shared - LIFO stack Data::Deque::Shared - double-ended queue Data::Log::Shared - append-only log (WAL) Data::Heap::Shared - priority queue Data::Graph::Shared - directed weighted graph Data::RingBuffer::Shared - fixed-size overwriting ring buffer Data::BitSet::Shared - shared bitset (lock-free per-bit ops) AUTHOR vividsnow LICENSE This is free software; you can redistribute it and/or modify it under the same terms as Perl itself.