Data-Pool-Shared
view release on metacpan or search on metacpan
my $n = $pool->eventfd_consume; # drain counter
STATS
stats() returns a hashref with diagnostic counters. All values are
approximate under concurrency.
"capacity" â total slot count (immutable)
"elem_size" â bytes per slot (immutable)
"used" â currently allocated slot count
"available" â currently free slot count ("capacity - used")
"waiters" â processes currently blocked on "alloc"
"mmap_size" â total mmap region size in bytes
"allocs" â cumulative successful allocations
"frees" â cumulative frees (including stale recovery)
"waits" â "alloc" calls that entered the retry loop
"timeouts" â "alloc" calls that timed out
"recoveries" â slots freed by "recover_stale"
SECURITY
The shared memory region (mmap) is writable by all processes that open
it. A malicious process with write access to the backing file or memfd
lib/Data/Pool/Shared.pm view on Meta::CPAN
=over
=item C<capacity> â total slot count (immutable)
=item C<elem_size> â bytes per slot (immutable)
=item C<used> â currently allocated slot count
=item C<available> â currently free slot count (C<capacity - used>)
=item C<waiters> â processes currently blocked on C<alloc>
=item C<mmap_size> â total mmap region size in bytes
=item C<allocs> â cumulative successful allocations
=item C<frees> â cumulative frees (including stale recovery)
=item C<waits> â C<alloc> calls that entered the retry loop
=item C<timeouts> â C<alloc> calls that timed out
uint32_t variant_id; /* 12 */
uint64_t capacity; /* 16: number of slots */
uint64_t total_size; /* 24: total mmap size */
uint64_t data_off; /* 32: offset to slot data */
uint64_t bitmap_off; /* 40: offset to allocation bitmap */
uint64_t owners_off; /* 48: offset to per-slot owner PIDs */
uint8_t _pad0[8]; /* 56-63 */
/* ---- Cache line 1 (64-127): mutable state ---- */
uint32_t used; /* 64: allocated count (futex word) */
uint32_t waiters; /* 68: blocked on alloc */
uint8_t _pad1[8]; /* 72-79 */
uint64_t stat_allocs; /* 80 */
uint64_t stat_frees; /* 88 */
uint64_t stat_waits; /* 96 */
uint64_t stat_timeouts; /* 104 */
uint64_t stat_recoveries;/* 112 */
uint8_t _pad2[8]; /* 120-127 */
} PoolHeader;
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
t/02-multiprocess.t view on Meta::CPAN
$pid = fork;
die "fork: $!" unless defined $pid;
if ($pid == 0) {
my $c = Data::Pool::Shared::I64->new($path, 100);
select(undef, undef, undef, 0.1); # sleep 100ms
$c->free($fill[0]); # free one slot
_exit(0);
}
# Parent blocks on alloc, should wake when child frees
my $blocked = $pool->alloc(2.0);
ok defined $blocked, 'blocking alloc succeeded after child freed';
waitpid($pid, 0);
$pool->reset;
# --- Timeout ---
for (1..100) { $pool->alloc }
my $t0 = time;
my $to = $pool->alloc(0.2);
ok !defined $to, 'alloc timed out';
xt/atomic_alignment.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
# Alignment of atomic fields in the header. __atomic_* on
# non-naturally-aligned addresses falls back to locked paths (or
# crashes on some architectures). Verify the header layout keeps
# atomic fields at natural alignment.
use Data::Pool::Shared;
my $p = Data::Pool::Shared::I64->new_memfd("align", 16);
# PoolHeader layout, as documented in pool.h:
# magic(u32, off 0) â non-atomic after init
# version(u32, off 4) â non-atomic after init
( run in 1.605 second using v1.01-cache-2.11-cpan-e1769b4cff6 )