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 )