File Coverage

Shared.xs
Criterion Covered Total %
statement 285 297 95.9
branch 314 564 55.6
condition n/a
subroutine n/a
pod n/a
total 599 861 69.5


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "ppport.h"
7             #include "pool.h"
8              
9             /* slot_sv lifetime magic: returned scalar pins the pool object alive by
10             * holding an incremented refcount, released when the scalar is freed. */
11 4           static int pool_scalar_magic_free(pTHX_ SV *sv, MAGIC *mg) {
12             PERL_UNUSED_ARG(sv);
13 4 50         if (mg->mg_obj) SvREFCNT_dec(mg->mg_obj);
14 4           return 0;
15             }
16              
17             static const MGVTBL pool_scalar_magic_vtbl = {
18             NULL, NULL, NULL, NULL, pool_scalar_magic_free, NULL, NULL, NULL
19             };
20              
21             #define EXTRACT_POOL(sv) \
22             if (!sv_isobject(sv) || !sv_derived_from(sv, "Data::Pool::Shared")) \
23             croak("Expected a Data::Pool::Shared object"); \
24             PoolHandle *h = INT2PTR(PoolHandle*, SvIV(SvRV(sv))); \
25             if (!h) croak("Attempted to use a destroyed Data::Pool::Shared object")
26              
27             #define MAKE_OBJ(class, handle) \
28             SV *obj = newSViv(PTR2IV(handle)); \
29             SV *ref = newRV_noinc(obj); \
30             sv_bless(ref, gv_stashpv(class, GV_ADD)); \
31             RETVAL = ref
32              
33             #define CHECK_SLOT(h, slot) \
34             if ((UV)(slot) >= (h)->hdr->capacity) \
35             croak("slot %" UVuf " out of range (capacity %" UVuf ")", \
36             (UV)(slot), (UV)(h)->hdr->capacity)
37              
38             #define CHECK_ALLOCATED(h, slot) \
39             if (!pool_is_allocated(h, slot)) \
40             croak("slot %" UVuf " is not allocated", (UV)(slot))
41              
42              
43             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared
44              
45             PROTOTYPES: DISABLE
46              
47             SV *
48             new(class, path, capacity, elem_size)
49             const char *class
50             SV *path
51             UV capacity
52             UV elem_size
53             PREINIT:
54             char errbuf[POOL_ERR_BUFLEN];
55             CODE:
56 11 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
57 11           PoolHandle *h = pool_create(p, capacity, (uint32_t)elem_size, POOL_VAR_RAW, errbuf);
58 11 50         if (!h) croak("Data::Pool::Shared->new: %s", errbuf);
59 11           MAKE_OBJ(class, h);
60             OUTPUT:
61             RETVAL
62              
63             SV *
64             new_memfd(class, name, capacity, elem_size)
65             const char *class
66             const char *name
67             UV capacity
68             UV elem_size
69             PREINIT:
70             char errbuf[POOL_ERR_BUFLEN];
71             CODE:
72 1           PoolHandle *h = pool_create_memfd(name, capacity, (uint32_t)elem_size, POOL_VAR_RAW, errbuf);
73 1 50         if (!h) croak("Data::Pool::Shared->new_memfd: %s", errbuf);
74 1           MAKE_OBJ(class, h);
75             OUTPUT:
76             RETVAL
77              
78             SV *
79             new_from_fd(class, fd)
80             const char *class
81             int fd
82             PREINIT:
83             char errbuf[POOL_ERR_BUFLEN];
84             CODE:
85 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_RAW, errbuf);
86 1 50         if (!h) croak("Data::Pool::Shared->new_from_fd: %s", errbuf);
87 1           MAKE_OBJ(class, h);
88             OUTPUT:
89             RETVAL
90              
91             void
92             DESTROY(self)
93             SV *self
94             CODE:
95 58 50         if (!SvROK(self)) return;
96 58           PoolHandle *h = INT2PTR(PoolHandle*, SvIV(SvRV(self)));
97 58 50         if (!h) return;
98 58           sv_setiv(SvRV(self), 0);
99 58           pool_destroy(h);
100              
101             SV *
102             alloc(self, ...)
103             SV *self
104             PREINIT:
105 919 50         EXTRACT_POOL(self);
    50          
    50          
106 919           double timeout = -1;
107             CODE:
108 919 100         if (items > 1) timeout = SvNV(ST(1));
109 919           int64_t slot = pool_alloc(h, timeout);
110 919 100         RETVAL = (slot >= 0) ? newSViv((IV)slot) : &PL_sv_undef;
111             OUTPUT:
112             RETVAL
113              
114             SV *
115             try_alloc(self)
116             SV *self
117             PREINIT:
118 17 50         EXTRACT_POOL(self);
    50          
    50          
119             CODE:
120 17           int64_t slot = pool_try_alloc(h);
121 17 100         RETVAL = (slot >= 0) ? newSViv((IV)slot) : &PL_sv_undef;
122             OUTPUT:
123             RETVAL
124              
125             bool
126             free(self, slot)
127             SV *self
128             UV slot
129             PREINIT:
130 692 50         EXTRACT_POOL(self);
    50          
    50          
131             CODE:
132 692 100         CHECK_SLOT(h, slot);
133 691 100         RETVAL = pool_free_slot(h, slot);
134             OUTPUT:
135             RETVAL
136              
137             SV *
138             get(self, slot)
139             SV *self
140             UV slot
141             PREINIT:
142 4 50         EXTRACT_POOL(self);
    50          
    50          
143             CODE:
144 4 100         CHECK_SLOT(h, slot);
145 3 100         CHECK_ALLOCATED(h, slot);
146 2           RETVAL = newSVpvn((const char *)pool_slot_ptr(h, slot), h->hdr->elem_size);
147             OUTPUT:
148             RETVAL
149              
150             void
151             set(self, slot, data)
152             SV *self
153             UV slot
154             SV *data
155             PREINIT:
156 6 50         EXTRACT_POOL(self);
    50          
    50          
157             CODE:
158 6 100         CHECK_SLOT(h, slot);
159 5 50         CHECK_ALLOCATED(h, slot);
160             STRLEN len;
161 5           const char *bytes = SvPV(data, len);
162 5 50         if (len > h->hdr->elem_size)
163 0           len = h->hdr->elem_size;
164 5           memcpy(pool_slot_ptr(h, slot), bytes, len);
165 5 100         if (len < h->hdr->elem_size)
166 1           memset(pool_slot_ptr(h, slot) + len, 0, h->hdr->elem_size - len);
167              
168             bool
169             is_allocated(self, slot)
170             SV *self
171             UV slot
172             PREINIT:
173 6 50         EXTRACT_POOL(self);
    50          
    50          
174             CODE:
175 6 100         CHECK_SLOT(h, slot);
176 5 100         RETVAL = pool_is_allocated(h, slot);
177             OUTPUT:
178             RETVAL
179              
180             UV
181             capacity(self)
182             SV *self
183             PREINIT:
184 11 50         EXTRACT_POOL(self);
    50          
    50          
185             CODE:
186 11 100         RETVAL = (UV)h->hdr->capacity;
187             OUTPUT:
188             RETVAL
189              
190             UV
191             elem_size(self)
192             SV *self
193             PREINIT:
194 3 50         EXTRACT_POOL(self);
    50          
    50          
195             CODE:
196 3 50         RETVAL = h->hdr->elem_size;
197             OUTPUT:
198             RETVAL
199              
200             UV
201             used(self)
202             SV *self
203             PREINIT:
204 38 50         EXTRACT_POOL(self);
    50          
    50          
205             CODE:
206 38 100         RETVAL = __atomic_load_n(&h->hdr->used, __ATOMIC_RELAXED);
207             OUTPUT:
208             RETVAL
209              
210             UV
211             available(self)
212             SV *self
213             PREINIT:
214 2 50         EXTRACT_POOL(self);
    50          
    50          
215             CODE:
216 2 50         RETVAL = (UV)h->hdr->capacity - __atomic_load_n(&h->hdr->used, __ATOMIC_RELAXED);
217             OUTPUT:
218             RETVAL
219              
220             UV
221             owner(self, slot)
222             SV *self
223             UV slot
224             PREINIT:
225 2 50         EXTRACT_POOL(self);
    50          
    50          
226             CODE:
227 2 100         CHECK_SLOT(h, slot);
228 1 50         RETVAL = __atomic_load_n(&h->owners[slot], __ATOMIC_RELAXED);
229             OUTPUT:
230             RETVAL
231              
232             UV
233             recover_stale(self)
234             SV *self
235             PREINIT:
236 3 50         EXTRACT_POOL(self);
    50          
    50          
237             CODE:
238 3 50         RETVAL = pool_recover_stale(h);
239             OUTPUT:
240             RETVAL
241              
242             void
243             reset(self)
244             SV *self
245             PREINIT:
246 10 50         EXTRACT_POOL(self);
    50          
    50          
247             CODE:
248 10           pool_reset(h);
249              
250             void
251             scan_from(self, slot)
252             SV *self
253             UV slot
254             PREINIT:
255 8 50         EXTRACT_POOL(self);
    50          
    50          
256             CODE:
257 8           pool_scan_from(h, (uint64_t)slot);
258              
259             SV *
260             path(self)
261             SV *self
262             PREINIT:
263 3 50         EXTRACT_POOL(self);
    50          
    50          
264             CODE:
265 3 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
266             OUTPUT:
267             RETVAL
268              
269             IV
270             memfd(self)
271             SV *self
272             PREINIT:
273 5 50         EXTRACT_POOL(self);
    50          
    50          
274             CODE:
275 5 50         RETVAL = h->backing_fd;
276             OUTPUT:
277             RETVAL
278              
279             IV
280             eventfd(self)
281             SV *self
282             PREINIT:
283 3 50         EXTRACT_POOL(self);
    50          
    50          
284             CODE:
285 3           RETVAL = pool_create_eventfd(h);
286 3 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
287             OUTPUT:
288             RETVAL
289              
290             void
291             eventfd_set(self, fd)
292             SV *self
293             int fd
294             PREINIT:
295 3 50         EXTRACT_POOL(self);
    50          
    50          
296             CODE:
297 3 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    100          
298 3           h->notify_fd = fd;
299              
300             IV
301             fileno(self)
302             SV *self
303             PREINIT:
304 6 50         EXTRACT_POOL(self);
    50          
    50          
305             CODE:
306 6 50         RETVAL = h->notify_fd;
307             OUTPUT:
308             RETVAL
309              
310             bool
311             notify(self)
312             SV *self
313             PREINIT:
314 4 50         EXTRACT_POOL(self);
    50          
    50          
315             CODE:
316 4 50         RETVAL = pool_notify(h);
317             OUTPUT:
318             RETVAL
319              
320             SV *
321             eventfd_consume(self)
322             SV *self
323             PREINIT:
324 4 50         EXTRACT_POOL(self);
    50          
    50          
325             CODE:
326 4           int64_t v = pool_eventfd_consume(h);
327 4 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
328             OUTPUT:
329             RETVAL
330              
331             void
332             sync(self)
333             SV *self
334             PREINIT:
335 1 50         EXTRACT_POOL(self);
    50          
    50          
336             CODE:
337 1 50         if (pool_msync(h) != 0) croak("msync: %s", strerror(errno));
338              
339             void
340             unlink(self_or_class, ...)
341             SV *self_or_class
342             CODE:
343             const char *p;
344 3 100         if (sv_isobject(self_or_class)) {
345 2           PoolHandle *h = INT2PTR(PoolHandle*, SvIV(SvRV(self_or_class)));
346 2 50         if (!h) croak("Attempted to use a destroyed object");
347 2           p = h->path;
348             } else {
349 1 50         if (items < 2) croak("Usage: ...->unlink($path)");
350 1           p = SvPV_nolen(ST(1));
351             }
352 3 100         if (!p) croak("cannot unlink anonymous or memfd object");
353 2 50         if (unlink(p) != 0)
354 0           croak("unlink(%s): %s", p, strerror(errno));
355              
356             SV *
357             stats(self)
358             SV *self
359             PREINIT:
360 1 50         EXTRACT_POOL(self);
    50          
    50          
361             CODE:
362 1           HV *hv = newHV();
363 1           PoolHeader *hdr = h->hdr;
364 1           hv_store(hv, "capacity", 8, newSVuv((UV)hdr->capacity), 0);
365 1           hv_store(hv, "elem_size", 9, newSVuv(hdr->elem_size), 0);
366 1           hv_store(hv, "used", 4, newSVuv((UV)__atomic_load_n(&hdr->used, __ATOMIC_RELAXED)), 0);
367 1           hv_store(hv, "available", 9,
368             newSVuv((UV)hdr->capacity - (UV)__atomic_load_n(&hdr->used, __ATOMIC_RELAXED)), 0);
369 1           hv_store(hv, "waiters", 7, newSVuv((UV)__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED)), 0);
370 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
371 1           hv_store(hv, "allocs", 6, newSVuv((UV)__atomic_load_n(&hdr->stat_allocs, __ATOMIC_RELAXED)), 0);
372 1           hv_store(hv, "frees", 5, newSVuv((UV)__atomic_load_n(&hdr->stat_frees, __ATOMIC_RELAXED)), 0);
373 1           hv_store(hv, "waits", 5, newSVuv((UV)__atomic_load_n(&hdr->stat_waits, __ATOMIC_RELAXED)), 0);
374 1           hv_store(hv, "timeouts", 8, newSVuv((UV)__atomic_load_n(&hdr->stat_timeouts, __ATOMIC_RELAXED)), 0);
375 1           hv_store(hv, "recoveries", 10, newSVuv((UV)__atomic_load_n(&hdr->stat_recoveries, __ATOMIC_RELAXED)), 0);
376 1           RETVAL = newRV_noinc((SV *)hv);
377             OUTPUT:
378             RETVAL
379              
380              
381             SV *
382             alloc_n(self, count, ...)
383             SV *self
384             UV count
385             PREINIT:
386 3 50         EXTRACT_POOL(self);
    50          
    50          
387 3           double timeout = -1;
388             CODE:
389 3 100         if (items > 2) timeout = SvNV(ST(2));
390 3 100         if (count == 0) {
391 1           RETVAL = newRV_noinc((SV *)newAV());
392             } else {
393             uint64_t *buf;
394 2 50         Newx(buf, count, uint64_t);
395 2           SAVEFREEPV(buf); /* freed on scope exit, incl. a croak from newSViv/av_push */
396 2 100         if (pool_alloc_n(h, buf, (uint32_t)count, timeout)) {
397 1           AV *av = newAV();
398 1           av_extend(av, count - 1);
399 4 100         for (UV i = 0; i < count; i++)
400 3           av_push(av, newSViv((IV)buf[i]));
401 1           RETVAL = newRV_noinc((SV *)av);
402             } else {
403 1           RETVAL = &PL_sv_undef;
404             }
405             }
406             OUTPUT:
407             RETVAL
408              
409             UV
410             free_n(self, slots_av)
411             SV *self
412             SV *slots_av
413             PREINIT:
414 6 50         EXTRACT_POOL(self);
    50          
    50          
415             CODE:
416 6 100         if (!SvROK(slots_av) || SvTYPE(SvRV(slots_av)) != SVt_PVAV)
    50          
417 1           croak("free_n: expected arrayref");
418 5           AV *av = (AV *)SvRV(slots_av);
419 5 50         SSize_t len = av_top_index(av) + 1;
420 5 100         if (len <= 0) {
421 1           RETVAL = 0;
422             } else {
423             uint64_t *buf;
424 4 50         Newx(buf, len, uint64_t);
425 4           SAVEFREEPV(buf); /* freed on scope exit, incl. a croak from SvUV magic */
426 11 100         for (SSize_t i = 0; i < len; i++) {
427 9           SV **svp = av_fetch(av, i, 0);
428 9 50         if (!svp || !SvOK(*svp))
    100          
429 2           croak("free_n: undef slot at index %ld", (long)i);
430 7           buf[i] = (uint64_t)SvUV(*svp);
431             }
432 2           RETVAL = pool_free_n(h, buf, (uint32_t)len);
433             }
434             OUTPUT:
435             RETVAL
436              
437             SV *
438             allocated_slots(self)
439             SV *self
440             PREINIT:
441 7 50         EXTRACT_POOL(self);
    50          
    50          
442             CODE:
443 7           AV *av = newAV();
444 7           uint64_t cap = h->hdr->capacity;
445 7           uint32_t nwords = h->bitmap_words;
446 15 100         for (uint32_t widx = 0; widx < nwords; widx++) {
447 8           uint64_t word = __atomic_load_n(&h->bitmap[widx], __ATOMIC_RELAXED);
448 37 100         while (word) {
449 29           int bit = __builtin_ctzll(word);
450 29           uint64_t slot = (uint64_t)widx * 64 + bit;
451 29 50         if (slot < cap)
452 29           av_push(av, newSViv((IV)slot));
453 29           word &= word - 1;
454             }
455             }
456 7           RETVAL = newRV_noinc((SV *)av);
457             OUTPUT:
458             RETVAL
459              
460             UV
461             ptr(self, slot)
462             SV *self
463             UV slot
464             PREINIT:
465 3 50         EXTRACT_POOL(self);
    50          
    50          
466             CODE:
467 3 100         CHECK_SLOT(h, slot);
468 2 100         CHECK_ALLOCATED(h, slot);
469 1 50         RETVAL = PTR2UV(pool_slot_ptr(h, slot));
470             OUTPUT:
471             RETVAL
472              
473             UV
474             data_ptr(self)
475             SV *self
476             PREINIT:
477 1 50         EXTRACT_POOL(self);
    50          
    50          
478             CODE:
479 1 50         RETVAL = PTR2UV(h->data);
480             OUTPUT:
481             RETVAL
482              
483             SV *
484             slot_sv(self, slot)
485             SV *self
486             UV slot
487             PREINIT:
488 5 50         EXTRACT_POOL(self);
    50          
    50          
489             CODE:
490 5 50         CHECK_SLOT(h, slot);
491 5 100         CHECK_ALLOCATED(h, slot);
492 4           RETVAL = newSV(0);
493 4           sv_upgrade(RETVAL, SVt_PV);
494 4           SvPV_set(RETVAL, (char *)pool_slot_ptr(h, slot));
495 4           SvLEN_set(RETVAL, 0);
496 4           SvCUR_set(RETVAL, h->hdr->elem_size);
497 4           SvPOK_on(RETVAL);
498             /* Pin pool alive while this SV is referenced — magic before READONLY */
499 4           MAGIC *mg = sv_magicext(RETVAL, NULL, PERL_MAGIC_ext, &pool_scalar_magic_vtbl, NULL, 0);
500 4           mg->mg_obj = SvREFCNT_inc_simple_NN(self);
501 4           SvREADONLY_on(RETVAL);
502             OUTPUT:
503             RETVAL
504              
505              
506             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::I64
507              
508             PROTOTYPES: DISABLE
509              
510             SV *
511             new(class, path, capacity)
512             const char *class
513             SV *path
514             UV capacity
515             PREINIT:
516             char errbuf[POOL_ERR_BUFLEN];
517             CODE:
518 27 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
519 27           PoolHandle *h = pool_create(p, capacity, sizeof(int64_t), POOL_VAR_I64, errbuf);
520 27 50         if (!h) croak("Data::Pool::Shared::I64->new: %s", errbuf);
521 27           MAKE_OBJ(class, h);
522             OUTPUT:
523             RETVAL
524              
525             SV *
526             new_memfd(class, name, capacity)
527             const char *class
528             const char *name
529             UV capacity
530             PREINIT:
531             char errbuf[POOL_ERR_BUFLEN];
532             CODE:
533 2           PoolHandle *h = pool_create_memfd(name, capacity, sizeof(int64_t), POOL_VAR_I64, errbuf);
534 2 50         if (!h) croak("Data::Pool::Shared::I64->new_memfd: %s", errbuf);
535 2           MAKE_OBJ(class, h);
536             OUTPUT:
537             RETVAL
538              
539             SV *
540             new_from_fd(class, fd)
541             const char *class
542             int fd
543             PREINIT:
544             char errbuf[POOL_ERR_BUFLEN];
545             CODE:
546 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_I64, errbuf);
547 1 50         if (!h) croak("Data::Pool::Shared::I64->new_from_fd: %s", errbuf);
548 1           MAKE_OBJ(class, h);
549             OUTPUT:
550             RETVAL
551              
552             IV
553             get(self, slot)
554             SV *self
555             UV slot
556             PREINIT:
557 64 50         EXTRACT_POOL(self);
    50          
    50          
558             CODE:
559 64 100         CHECK_SLOT(h, slot);
560 63 100         CHECK_ALLOCATED(h, slot);
561 62           RETVAL = (IV)pool_get_i64(h, slot);
562             OUTPUT:
563             RETVAL
564              
565             void
566             set(self, slot, val)
567             SV *self
568             UV slot
569             IV val
570             PREINIT:
571 615 50         EXTRACT_POOL(self);
    50          
    50          
572             CODE:
573 615 100         CHECK_SLOT(h, slot);
574 614 100         CHECK_ALLOCATED(h, slot);
575 613           pool_set_i64(h, slot, (int64_t)val);
576              
577             bool
578             cas(self, slot, expected, desired)
579             SV *self
580             UV slot
581             IV expected
582             IV desired
583             PREINIT:
584 4 50         EXTRACT_POOL(self);
    50          
    50          
585             CODE:
586 4 50         CHECK_SLOT(h, slot);
587 4 100         CHECK_ALLOCATED(h, slot);
588 3 100         RETVAL = pool_cas_i64(h, slot, (int64_t)expected, (int64_t)desired);
589             OUTPUT:
590             RETVAL
591              
592             IV
593             cmpxchg(self, slot, expected, desired)
594             SV *self
595             UV slot
596             IV expected
597             IV desired
598             PREINIT:
599 2 50         EXTRACT_POOL(self);
    50          
    50          
600             CODE:
601 2 50         CHECK_SLOT(h, slot);
602 2 50         CHECK_ALLOCATED(h, slot);
603 2           RETVAL = (IV)pool_cmpxchg_i64(h, slot, (int64_t)expected, (int64_t)desired);
604             OUTPUT:
605             RETVAL
606              
607             IV
608             xchg(self, slot, val)
609             SV *self
610             UV slot
611             IV val
612             PREINIT:
613 1 50         EXTRACT_POOL(self);
    50          
    50          
614             CODE:
615 1 50         CHECK_SLOT(h, slot);
616 1 50         CHECK_ALLOCATED(h, slot);
617 1           RETVAL = (IV)pool_xchg_i64(h, slot, (int64_t)val);
618             OUTPUT:
619             RETVAL
620              
621             IV
622             add(self, slot, delta)
623             SV *self
624             UV slot
625             IV delta
626             PREINIT:
627 3 50         EXTRACT_POOL(self);
    50          
    50          
628             CODE:
629 3 50         CHECK_SLOT(h, slot);
630 3 100         CHECK_ALLOCATED(h, slot);
631 2           RETVAL = (IV)pool_add_i64(h, slot, (int64_t)delta);
632             OUTPUT:
633             RETVAL
634              
635             IV
636             incr(self, slot)
637             SV *self
638             UV slot
639             PREINIT:
640 4 50         EXTRACT_POOL(self);
    50          
    50          
641             CODE:
642 4 50         CHECK_SLOT(h, slot);
643 4 100         CHECK_ALLOCATED(h, slot);
644 3           RETVAL = (IV)pool_add_i64(h, slot, 1);
645             OUTPUT:
646             RETVAL
647              
648             IV
649             decr(self, slot)
650             SV *self
651             UV slot
652             PREINIT:
653 3 50         EXTRACT_POOL(self);
    50          
    50          
654             CODE:
655 3 50         CHECK_SLOT(h, slot);
656 3 100         CHECK_ALLOCATED(h, slot);
657 2           RETVAL = (IV)pool_add_i64(h, slot, -1);
658             OUTPUT:
659             RETVAL
660              
661              
662             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::F64
663              
664             PROTOTYPES: DISABLE
665              
666             SV *
667             new(class, path, capacity)
668             const char *class
669             SV *path
670             UV capacity
671             PREINIT:
672             char errbuf[POOL_ERR_BUFLEN];
673             CODE:
674 2 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
675 2           PoolHandle *h = pool_create(p, capacity, sizeof(double), POOL_VAR_F64, errbuf);
676 2 50         if (!h) croak("Data::Pool::Shared::F64->new: %s", errbuf);
677 2           MAKE_OBJ(class, h);
678             OUTPUT:
679             RETVAL
680              
681             SV *
682             new_memfd(class, name, capacity)
683             const char *class
684             const char *name
685             UV capacity
686             PREINIT:
687             char errbuf[POOL_ERR_BUFLEN];
688             CODE:
689 1           PoolHandle *h = pool_create_memfd(name, capacity, sizeof(double), POOL_VAR_F64, errbuf);
690 1 50         if (!h) croak("Data::Pool::Shared::F64->new_memfd: %s", errbuf);
691 1           MAKE_OBJ(class, h);
692             OUTPUT:
693             RETVAL
694              
695             SV *
696             new_from_fd(class, fd)
697             const char *class
698             int fd
699             PREINIT:
700             char errbuf[POOL_ERR_BUFLEN];
701             CODE:
702 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_F64, errbuf);
703 1 50         if (!h) croak("Data::Pool::Shared::F64->new_from_fd: %s", errbuf);
704 1           MAKE_OBJ(class, h);
705             OUTPUT:
706             RETVAL
707              
708             NV
709             get(self, slot)
710             SV *self
711             UV slot
712             PREINIT:
713 7 50         EXTRACT_POOL(self);
    50          
    50          
714             CODE:
715 7 50         CHECK_SLOT(h, slot);
716 7 50         CHECK_ALLOCATED(h, slot);
717 7           RETVAL = pool_get_f64(h, slot);
718             OUTPUT:
719             RETVAL
720              
721             void
722             set(self, slot, val)
723             SV *self
724             UV slot
725             NV val
726             PREINIT:
727 7 50         EXTRACT_POOL(self);
    50          
    50          
728             CODE:
729 7 50         CHECK_SLOT(h, slot);
730 7 50         CHECK_ALLOCATED(h, slot);
731 7           pool_set_f64(h, slot, (double)val);
732              
733              
734             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::I32
735              
736             PROTOTYPES: DISABLE
737              
738             SV *
739             new(class, path, capacity)
740             const char *class
741             SV *path
742             UV capacity
743             PREINIT:
744             char errbuf[POOL_ERR_BUFLEN];
745             CODE:
746 3 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
747 3           PoolHandle *h = pool_create(p, capacity, sizeof(int32_t), POOL_VAR_I32, errbuf);
748 3 50         if (!h) croak("Data::Pool::Shared::I32->new: %s", errbuf);
749 3           MAKE_OBJ(class, h);
750             OUTPUT:
751             RETVAL
752              
753             SV *
754             new_memfd(class, name, capacity)
755             const char *class
756             const char *name
757             UV capacity
758             PREINIT:
759             char errbuf[POOL_ERR_BUFLEN];
760             CODE:
761 1           PoolHandle *h = pool_create_memfd(name, capacity, sizeof(int32_t), POOL_VAR_I32, errbuf);
762 1 50         if (!h) croak("Data::Pool::Shared::I32->new_memfd: %s", errbuf);
763 1           MAKE_OBJ(class, h);
764             OUTPUT:
765             RETVAL
766              
767             SV *
768             new_from_fd(class, fd)
769             const char *class
770             int fd
771             PREINIT:
772             char errbuf[POOL_ERR_BUFLEN];
773             CODE:
774 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_I32, errbuf);
775 1 50         if (!h) croak("Data::Pool::Shared::I32->new_from_fd: %s", errbuf);
776 1           MAKE_OBJ(class, h);
777             OUTPUT:
778             RETVAL
779              
780             IV
781             get(self, slot)
782             SV *self
783             UV slot
784             PREINIT:
785 5 50         EXTRACT_POOL(self);
    50          
    50          
786             CODE:
787 5 50         CHECK_SLOT(h, slot);
788 5 50         CHECK_ALLOCATED(h, slot);
789 5 50         RETVAL = (IV)pool_get_i32(h, slot);
790             OUTPUT:
791             RETVAL
792              
793             void
794             set(self, slot, val)
795             SV *self
796             UV slot
797             IV val
798             PREINIT:
799 6 50         EXTRACT_POOL(self);
    50          
    50          
800             CODE:
801 6 50         CHECK_SLOT(h, slot);
802 6 50         CHECK_ALLOCATED(h, slot);
803 6           pool_set_i32(h, slot, (int32_t)val);
804              
805             bool
806             cas(self, slot, expected, desired)
807             SV *self
808             UV slot
809             IV expected
810             IV desired
811             PREINIT:
812 1 50         EXTRACT_POOL(self);
    50          
    50          
813             CODE:
814 1 50         CHECK_SLOT(h, slot);
815 1 50         CHECK_ALLOCATED(h, slot);
816 1 50         RETVAL = pool_cas_i32(h, slot, (int32_t)expected, (int32_t)desired);
817             OUTPUT:
818             RETVAL
819              
820             IV
821             cmpxchg(self, slot, expected, desired)
822             SV *self
823             UV slot
824             IV expected
825             IV desired
826             PREINIT:
827 2 50         EXTRACT_POOL(self);
    50          
    50          
828             CODE:
829 2 50         CHECK_SLOT(h, slot);
830 2 50         CHECK_ALLOCATED(h, slot);
831 2 50         RETVAL = (IV)pool_cmpxchg_i32(h, slot, (int32_t)expected, (int32_t)desired);
832             OUTPUT:
833             RETVAL
834              
835             IV
836             xchg(self, slot, val)
837             SV *self
838             UV slot
839             IV val
840             PREINIT:
841 1 50         EXTRACT_POOL(self);
    50          
    50          
842             CODE:
843 1 50         CHECK_SLOT(h, slot);
844 1 50         CHECK_ALLOCATED(h, slot);
845 1 50         RETVAL = (IV)pool_xchg_i32(h, slot, (int32_t)val);
846             OUTPUT:
847             RETVAL
848              
849             IV
850             add(self, slot, delta)
851             SV *self
852             UV slot
853             IV delta
854             PREINIT:
855 2 50         EXTRACT_POOL(self);
    50          
    50          
856             CODE:
857 2 50         CHECK_SLOT(h, slot);
858 2 50         CHECK_ALLOCATED(h, slot);
859 2 50         RETVAL = (IV)pool_add_i32(h, slot, (int32_t)delta);
860             OUTPUT:
861             RETVAL
862              
863             IV
864             incr(self, slot)
865             SV *self
866             UV slot
867             PREINIT:
868 0 0         EXTRACT_POOL(self);
    0          
    0          
869             CODE:
870 0 0         CHECK_SLOT(h, slot);
871 0 0         CHECK_ALLOCATED(h, slot);
872 0 0         RETVAL = (IV)pool_add_i32(h, slot, 1);
873             OUTPUT:
874             RETVAL
875              
876             IV
877             decr(self, slot)
878             SV *self
879             UV slot
880             PREINIT:
881 0 0         EXTRACT_POOL(self);
    0          
    0          
882             CODE:
883 0 0         CHECK_SLOT(h, slot);
884 0 0         CHECK_ALLOCATED(h, slot);
885 0 0         RETVAL = (IV)pool_add_i32(h, slot, -1);
886             OUTPUT:
887             RETVAL
888              
889              
890             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::Str
891              
892             PROTOTYPES: DISABLE
893              
894             SV *
895             new(class, path, capacity, max_len)
896             const char *class
897             SV *path
898             UV capacity
899             UV max_len
900             PREINIT:
901             char errbuf[POOL_ERR_BUFLEN];
902             CODE:
903 4 50         if (max_len == 0) croak("Data::Pool::Shared::Str->new: max_len must be > 0");
904 4 50         if (max_len > (UV)(UINT32_MAX - sizeof(uint32_t)))
905 0           croak("Data::Pool::Shared::Str->new: max_len too large");
906 4           uint32_t elem_size = (uint32_t)(sizeof(uint32_t) + max_len);
907 4 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
908 4           PoolHandle *h = pool_create(p, capacity, elem_size, POOL_VAR_STR, errbuf);
909 4 50         if (!h) croak("Data::Pool::Shared::Str->new: %s", errbuf);
910 4           MAKE_OBJ(class, h);
911             OUTPUT:
912             RETVAL
913              
914             SV *
915             new_memfd(class, name, capacity, max_len)
916             const char *class
917             const char *name
918             UV capacity
919             UV max_len
920             PREINIT:
921             char errbuf[POOL_ERR_BUFLEN];
922             CODE:
923 1 50         if (max_len == 0) croak("Data::Pool::Shared::Str->new_memfd: max_len must be > 0");
924 1 50         if (max_len > (UV)(UINT32_MAX - sizeof(uint32_t)))
925 0           croak("Data::Pool::Shared::Str->new_memfd: max_len too large");
926 1           uint32_t elem_size = (uint32_t)(sizeof(uint32_t) + max_len);
927 1           PoolHandle *h = pool_create_memfd(name, capacity, elem_size, POOL_VAR_STR, errbuf);
928 1 50         if (!h) croak("Data::Pool::Shared::Str->new_memfd: %s", errbuf);
929 1           MAKE_OBJ(class, h);
930             OUTPUT:
931             RETVAL
932              
933             SV *
934             new_from_fd(class, fd)
935             const char *class
936             int fd
937             PREINIT:
938             char errbuf[POOL_ERR_BUFLEN];
939             CODE:
940 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_STR, errbuf);
941 1 50         if (!h) croak("Data::Pool::Shared::Str->new_from_fd: %s", errbuf);
942 1           MAKE_OBJ(class, h);
943             OUTPUT:
944             RETVAL
945              
946             SV *
947             get(self, slot)
948             SV *self
949             UV slot
950             PREINIT:
951 11 50         EXTRACT_POOL(self);
    50          
    50          
952             CODE:
953 11 50         CHECK_SLOT(h, slot);
954 11 50         CHECK_ALLOCATED(h, slot);
955 11           uint32_t len = pool_get_str_len(h, slot);
956 11           RETVAL = newSVpvn(pool_get_str_ptr(h, slot), len);
957             OUTPUT:
958             RETVAL
959              
960             void
961             set(self, slot, val)
962             SV *self
963             UV slot
964             SV *val
965             PREINIT:
966 8 50         EXTRACT_POOL(self);
    50          
    50          
967             CODE:
968 8 50         CHECK_SLOT(h, slot);
969 8 50         CHECK_ALLOCATED(h, slot);
970             STRLEN len;
971 8           const char *str = SvPV(val, len);
972 8           pool_set_str(h, slot, str, (uint32_t)len);
973              
974             UV
975             max_len(self)
976             SV *self
977             PREINIT:
978 1 50         EXTRACT_POOL(self);
    50          
    50          
979             CODE:
980 1 50         RETVAL = h->hdr->elem_size - sizeof(uint32_t);
981             OUTPUT:
982             RETVAL