Data-Pool-Shared
view release on metacpan or search on metacpan
lib/Data/Pool/Shared.pm view on Meta::CPAN
my $idx = $pool->alloc(0); # non-blocking
my $idx = $pool->try_alloc; # non-blocking (alias)
Returns slot index on success, C<undef> on failure/timeout.
$pool->free($idx); # release slot (returns true/false)
=head2 Batch Operations
my $slots = $pool->alloc_n($n); # allocate N slots (blocking)
my $slots = $pool->alloc_n($n, $timeout); # with timeout
my $slots = $pool->alloc_n($n, 0); # non-blocking
# returns arrayref of indices, or undef (all-or-nothing)
my $freed = $pool->free_n(\@indices); # batch free, returns count freed
# single used-decrement + single futex wake (faster than N individual frees)
my $slots = $pool->allocated_slots; # arrayref of all allocated indices
=head2 Data Access
my $val = $pool->get($idx); # read slot
$pool->set($idx, $val); # write slot
For I64/I32 variants:
my $ok = $pool->cas($idx, $old, $new); # atomic CAS, returns bool
my $old = $pool->cmpxchg($idx, $old, $new); # atomic CAS, returns old value
my $old = $pool->xchg($idx, $val); # atomic exchange, returns old
my $val = $pool->add($idx, $delta); # atomic add, returns new value
my $val = $pool->incr($idx); # atomic increment
my $val = $pool->decr($idx); # atomic decrement
For Str variant:
my $max = $pool->max_len; # maximum string length
=head2 Raw Pointers
my $ptr = $pool->ptr($idx); # raw C pointer to slot data (UV)
my $ptr = $pool->data_ptr; # pointer to start of data section
C<ptr> returns the memory address of a slot's data as an unsigned
integer. Use with L<FFI::Platypus>, OpenGL C<_c> functions, or XS
code that needs a C<void*>.
C<data_ptr> returns the base of the contiguous data region. Slots
are laid out as C<data_ptr + idx * elem_size>.
B<Warning>: The returned pointer becomes dangling if the pool object
is destroyed. Do not use after the pool goes out of scope.
=head2 Zero-Copy Access
my $sv = $pool->slot_sv($idx); # SV backed by slot memory
Returns a read-only scalar whose PV points directly into the shared
memory slot. Reading the scalar reads the slot with no C<memcpy>.
Useful for large slots where avoiding copy matters.
The scalar holds a reference to the pool object, keeping it alive
for as long as the scalar (or any copy of it) is live. However, the
scalar still reflects the current contents of the slot: if the slot
is C<free()>d and later re-allocated, reads will see the new data.
To modify the slot, use C<set()>.
=head2 Status
my $ok = $pool->is_allocated($idx);
my $cap = $pool->capacity;
my $esz = $pool->elem_size;
my $n = $pool->used; # allocated count
my $n = $pool->available; # free count
my $pid = $pool->owner($idx); # PID of allocator
=head2 Recovery
my $n = $pool->recover_stale; # free slots owned by dead PIDs
$pool->reset; # free all slots (exclusive access only)
=head2 Guards
my ($idx, $guard) = $pool->alloc_guard; # auto-free on scope exit
my ($idx, $guard) = $pool->alloc_guard($timeout);
my ($idx, $guard) = $pool->try_alloc_guard; # non-blocking
=head2 Convenience
my $idx = $pool->alloc_set($val); # alloc + set
my $idx = $pool->alloc_set($val, $timeout); # with timeout
my $idx = $pool->try_alloc_set($val); # non-blocking
$pool->each_allocated(sub { my $idx = shift; ... });
=head2 Common Methods
my $p = $pool->path; # backing file (undef if anon)
my $fd = $pool->memfd; # memfd fd (-1 if not memfd)
$pool->sync; # msync to disk
$pool->unlink; # remove backing file
my $s = $pool->stats; # diagnostic hashref
=head3 eventfd Integration
my $fd = $pool->eventfd; # create eventfd
$pool->eventfd_set($fd); # use existing fd
my $fd = $pool->fileno; # current eventfd (-1 if none)
$pool->notify; # signal eventfd
my $n = $pool->eventfd_consume; # drain counter
=head1 STATS
C<stats()> returns a hashref with diagnostic counters. All values are
approximate under concurrency.
=over
=item C<capacity> â total slot count (immutable)
=item C<elem_size> â bytes per slot (immutable)
( run in 0.588 second using v1.01-cache-2.11-cpan-39bf76dae61 )