File Coverage

Shared.xs
Criterion Covered Total %
statement 284 296 95.9
branch 311 558 55.7
condition n/a
subroutine n/a
pod n/a
total 595 854 69.6


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 5 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
57 5           PoolHandle *h = pool_create(p, capacity, (uint32_t)elem_size, POOL_VAR_RAW, errbuf);
58 5 50         if (!h) croak("Data::Pool::Shared->new: %s", errbuf);
59 5           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 49 50         if (!SvROK(self)) return;
96 49           PoolHandle *h = INT2PTR(PoolHandle*, SvIV(SvRV(self)));
97 49 50         if (!h) return;
98 49           sv_setiv(SvRV(self), 0);
99 49           pool_destroy(h);
100              
101             SV *
102             alloc(self, ...)
103             SV *self
104             PREINIT:
105 908 50         EXTRACT_POOL(self);
    50          
    50          
106 908           double timeout = -1;
107             CODE:
108 908 100         if (items > 1) timeout = SvNV(ST(1));
109 908           int64_t slot = pool_alloc(h, timeout);
110 908 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 36 50         EXTRACT_POOL(self);
    50          
    50          
205             CODE:
206 36 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 2 50         EXTRACT_POOL(self);
    50          
    50          
237             CODE:
238 2 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             SV *
251             path(self)
252             SV *self
253             PREINIT:
254 3 50         EXTRACT_POOL(self);
    50          
    50          
255             CODE:
256 3 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
257             OUTPUT:
258             RETVAL
259              
260             IV
261             memfd(self)
262             SV *self
263             PREINIT:
264 5 50         EXTRACT_POOL(self);
    50          
    50          
265             CODE:
266 5 50         RETVAL = h->backing_fd;
267             OUTPUT:
268             RETVAL
269              
270             IV
271             eventfd(self)
272             SV *self
273             PREINIT:
274 3 50         EXTRACT_POOL(self);
    50          
    50          
275             CODE:
276 3           RETVAL = pool_create_eventfd(h);
277 3 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
278             OUTPUT:
279             RETVAL
280              
281             void
282             eventfd_set(self, fd)
283             SV *self
284             int fd
285             PREINIT:
286 3 50         EXTRACT_POOL(self);
    50          
    50          
287             CODE:
288 3 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    100          
289 3           h->notify_fd = fd;
290              
291             IV
292             fileno(self)
293             SV *self
294             PREINIT:
295 6 50         EXTRACT_POOL(self);
    50          
    50          
296             CODE:
297 6 50         RETVAL = h->notify_fd;
298             OUTPUT:
299             RETVAL
300              
301             bool
302             notify(self)
303             SV *self
304             PREINIT:
305 4 50         EXTRACT_POOL(self);
    50          
    50          
306             CODE:
307 4 50         RETVAL = pool_notify(h);
308             OUTPUT:
309             RETVAL
310              
311             SV *
312             eventfd_consume(self)
313             SV *self
314             PREINIT:
315 4 50         EXTRACT_POOL(self);
    50          
    50          
316             CODE:
317 4           int64_t v = pool_eventfd_consume(h);
318 4 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
319             OUTPUT:
320             RETVAL
321              
322             void
323             sync(self)
324             SV *self
325             PREINIT:
326 1 50         EXTRACT_POOL(self);
    50          
    50          
327             CODE:
328 1 50         if (pool_msync(h) != 0) croak("msync: %s", strerror(errno));
329              
330             void
331             unlink(self_or_class, ...)
332             SV *self_or_class
333             CODE:
334             const char *p;
335 3 100         if (sv_isobject(self_or_class)) {
336 2           PoolHandle *h = INT2PTR(PoolHandle*, SvIV(SvRV(self_or_class)));
337 2 50         if (!h) croak("Attempted to use a destroyed object");
338 2           p = h->path;
339             } else {
340 1 50         if (items < 2) croak("Usage: ...->unlink($path)");
341 1           p = SvPV_nolen(ST(1));
342             }
343 3 100         if (!p) croak("cannot unlink anonymous or memfd object");
344 2 50         if (unlink(p) != 0)
345 0           croak("unlink(%s): %s", p, strerror(errno));
346              
347             SV *
348             stats(self)
349             SV *self
350             PREINIT:
351 1 50         EXTRACT_POOL(self);
    50          
    50          
352             CODE:
353 1           HV *hv = newHV();
354 1           PoolHeader *hdr = h->hdr;
355 1           hv_store(hv, "capacity", 8, newSVuv((UV)hdr->capacity), 0);
356 1           hv_store(hv, "elem_size", 9, newSVuv(hdr->elem_size), 0);
357 1           hv_store(hv, "used", 4, newSVuv((UV)__atomic_load_n(&hdr->used, __ATOMIC_RELAXED)), 0);
358 1           hv_store(hv, "available", 9,
359             newSVuv((UV)hdr->capacity - (UV)__atomic_load_n(&hdr->used, __ATOMIC_RELAXED)), 0);
360 1           hv_store(hv, "waiters", 7, newSVuv((UV)__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED)), 0);
361 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
362 1           hv_store(hv, "allocs", 6, newSVuv((UV)__atomic_load_n(&hdr->stat_allocs, __ATOMIC_RELAXED)), 0);
363 1           hv_store(hv, "frees", 5, newSVuv((UV)__atomic_load_n(&hdr->stat_frees, __ATOMIC_RELAXED)), 0);
364 1           hv_store(hv, "waits", 5, newSVuv((UV)__atomic_load_n(&hdr->stat_waits, __ATOMIC_RELAXED)), 0);
365 1           hv_store(hv, "timeouts", 8, newSVuv((UV)__atomic_load_n(&hdr->stat_timeouts, __ATOMIC_RELAXED)), 0);
366 1           hv_store(hv, "recoveries", 10, newSVuv((UV)__atomic_load_n(&hdr->stat_recoveries, __ATOMIC_RELAXED)), 0);
367 1           RETVAL = newRV_noinc((SV *)hv);
368             OUTPUT:
369             RETVAL
370              
371              
372             SV *
373             alloc_n(self, count, ...)
374             SV *self
375             UV count
376             PREINIT:
377 3 50         EXTRACT_POOL(self);
    50          
    50          
378 3           double timeout = -1;
379             CODE:
380 3 100         if (items > 2) timeout = SvNV(ST(2));
381 3 100         if (count == 0) {
382 1           RETVAL = newRV_noinc((SV *)newAV());
383             } else {
384             uint64_t *buf;
385 2 50         Newx(buf, count, uint64_t);
386 2 100         if (pool_alloc_n(h, buf, (uint32_t)count, timeout)) {
387 1           AV *av = newAV();
388 1           av_extend(av, count - 1);
389 4 100         for (UV i = 0; i < count; i++)
390 3           av_push(av, newSViv((IV)buf[i]));
391 1           RETVAL = newRV_noinc((SV *)av);
392             } else {
393 1           RETVAL = &PL_sv_undef;
394             }
395 2           Safefree(buf);
396             }
397             OUTPUT:
398             RETVAL
399              
400             UV
401             free_n(self, slots_av)
402             SV *self
403             SV *slots_av
404             PREINIT:
405 6 50         EXTRACT_POOL(self);
    50          
    50          
406             CODE:
407 6 100         if (!SvROK(slots_av) || SvTYPE(SvRV(slots_av)) != SVt_PVAV)
    50          
408 1           croak("free_n: expected arrayref");
409 5           AV *av = (AV *)SvRV(slots_av);
410 5 50         SSize_t len = av_top_index(av) + 1;
411 5 100         if (len <= 0) {
412 1           RETVAL = 0;
413             } else {
414             uint64_t *buf;
415 4 50         Newx(buf, len, uint64_t);
416 11 100         for (SSize_t i = 0; i < len; i++) {
417 9           SV **svp = av_fetch(av, i, 0);
418 9 50         if (!svp || !SvOK(*svp)) {
    100          
419 2           Safefree(buf);
420 2           croak("free_n: undef slot at index %ld", (long)i);
421             }
422 7           buf[i] = (uint64_t)SvUV(*svp);
423             }
424 2           RETVAL = pool_free_n(h, buf, (uint32_t)len);
425 2           Safefree(buf);
426             }
427             OUTPUT:
428             RETVAL
429              
430             SV *
431             allocated_slots(self)
432             SV *self
433             PREINIT:
434 6 50         EXTRACT_POOL(self);
    50          
    50          
435             CODE:
436 6           AV *av = newAV();
437 6           uint64_t cap = h->hdr->capacity;
438 6           uint32_t nwords = h->bitmap_words;
439 13 100         for (uint32_t widx = 0; widx < nwords; widx++) {
440 7           uint64_t word = __atomic_load_n(&h->bitmap[widx], __ATOMIC_RELAXED);
441 36 100         while (word) {
442 29           int bit = __builtin_ctzll(word);
443 29           uint64_t slot = (uint64_t)widx * 64 + bit;
444 29 50         if (slot < cap)
445 29           av_push(av, newSViv((IV)slot));
446 29           word &= word - 1;
447             }
448             }
449 6           RETVAL = newRV_noinc((SV *)av);
450             OUTPUT:
451             RETVAL
452              
453             UV
454             ptr(self, slot)
455             SV *self
456             UV slot
457             PREINIT:
458 3 50         EXTRACT_POOL(self);
    50          
    50          
459             CODE:
460 3 100         CHECK_SLOT(h, slot);
461 2 100         CHECK_ALLOCATED(h, slot);
462 1 50         RETVAL = PTR2UV(pool_slot_ptr(h, slot));
463             OUTPUT:
464             RETVAL
465              
466             UV
467             data_ptr(self)
468             SV *self
469             PREINIT:
470 1 50         EXTRACT_POOL(self);
    50          
    50          
471             CODE:
472 1 50         RETVAL = PTR2UV(h->data);
473             OUTPUT:
474             RETVAL
475              
476             SV *
477             slot_sv(self, slot)
478             SV *self
479             UV slot
480             PREINIT:
481 5 50         EXTRACT_POOL(self);
    50          
    50          
482             CODE:
483 5 50         CHECK_SLOT(h, slot);
484 5 100         CHECK_ALLOCATED(h, slot);
485 4           RETVAL = newSV(0);
486 4           sv_upgrade(RETVAL, SVt_PV);
487 4           SvPV_set(RETVAL, (char *)pool_slot_ptr(h, slot));
488 4           SvLEN_set(RETVAL, 0);
489 4           SvCUR_set(RETVAL, h->hdr->elem_size);
490 4           SvPOK_on(RETVAL);
491             /* Pin pool alive while this SV is referenced — magic before READONLY */
492 4           MAGIC *mg = sv_magicext(RETVAL, NULL, PERL_MAGIC_ext, &pool_scalar_magic_vtbl, NULL, 0);
493 4           mg->mg_obj = SvREFCNT_inc_simple_NN(self);
494 4           SvREADONLY_on(RETVAL);
495             OUTPUT:
496             RETVAL
497              
498              
499             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::I64
500              
501             PROTOTYPES: DISABLE
502              
503             SV *
504             new(class, path, capacity)
505             const char *class
506             SV *path
507             UV capacity
508             PREINIT:
509             char errbuf[POOL_ERR_BUFLEN];
510             CODE:
511 24 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
512 24           PoolHandle *h = pool_create(p, capacity, sizeof(int64_t), POOL_VAR_I64, errbuf);
513 24 50         if (!h) croak("Data::Pool::Shared::I64->new: %s", errbuf);
514 24           MAKE_OBJ(class, h);
515             OUTPUT:
516             RETVAL
517              
518             SV *
519             new_memfd(class, name, capacity)
520             const char *class
521             const char *name
522             UV capacity
523             PREINIT:
524             char errbuf[POOL_ERR_BUFLEN];
525             CODE:
526 2           PoolHandle *h = pool_create_memfd(name, capacity, sizeof(int64_t), POOL_VAR_I64, errbuf);
527 2 50         if (!h) croak("Data::Pool::Shared::I64->new_memfd: %s", errbuf);
528 2           MAKE_OBJ(class, h);
529             OUTPUT:
530             RETVAL
531              
532             SV *
533             new_from_fd(class, fd)
534             const char *class
535             int fd
536             PREINIT:
537             char errbuf[POOL_ERR_BUFLEN];
538             CODE:
539 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_I64, errbuf);
540 1 50         if (!h) croak("Data::Pool::Shared::I64->new_from_fd: %s", errbuf);
541 1           MAKE_OBJ(class, h);
542             OUTPUT:
543             RETVAL
544              
545             IV
546             get(self, slot)
547             SV *self
548             UV slot
549             PREINIT:
550 64 50         EXTRACT_POOL(self);
    50          
    50          
551             CODE:
552 64 100         CHECK_SLOT(h, slot);
553 63 100         CHECK_ALLOCATED(h, slot);
554 62           RETVAL = (IV)pool_get_i64(h, slot);
555             OUTPUT:
556             RETVAL
557              
558             void
559             set(self, slot, val)
560             SV *self
561             UV slot
562             IV val
563             PREINIT:
564 615 50         EXTRACT_POOL(self);
    50          
    50          
565             CODE:
566 615 100         CHECK_SLOT(h, slot);
567 614 100         CHECK_ALLOCATED(h, slot);
568 613           pool_set_i64(h, slot, (int64_t)val);
569              
570             bool
571             cas(self, slot, expected, desired)
572             SV *self
573             UV slot
574             IV expected
575             IV desired
576             PREINIT:
577 4 50         EXTRACT_POOL(self);
    50          
    50          
578             CODE:
579 4 50         CHECK_SLOT(h, slot);
580 4 100         CHECK_ALLOCATED(h, slot);
581 3 100         RETVAL = pool_cas_i64(h, slot, (int64_t)expected, (int64_t)desired);
582             OUTPUT:
583             RETVAL
584              
585             IV
586             cmpxchg(self, slot, expected, desired)
587             SV *self
588             UV slot
589             IV expected
590             IV desired
591             PREINIT:
592 2 50         EXTRACT_POOL(self);
    50          
    50          
593             CODE:
594 2 50         CHECK_SLOT(h, slot);
595 2 50         CHECK_ALLOCATED(h, slot);
596 2           RETVAL = (IV)pool_cmpxchg_i64(h, slot, (int64_t)expected, (int64_t)desired);
597             OUTPUT:
598             RETVAL
599              
600             IV
601             xchg(self, slot, val)
602             SV *self
603             UV slot
604             IV val
605             PREINIT:
606 1 50         EXTRACT_POOL(self);
    50          
    50          
607             CODE:
608 1 50         CHECK_SLOT(h, slot);
609 1 50         CHECK_ALLOCATED(h, slot);
610 1           RETVAL = (IV)pool_xchg_i64(h, slot, (int64_t)val);
611             OUTPUT:
612             RETVAL
613              
614             IV
615             add(self, slot, delta)
616             SV *self
617             UV slot
618             IV delta
619             PREINIT:
620 3 50         EXTRACT_POOL(self);
    50          
    50          
621             CODE:
622 3 50         CHECK_SLOT(h, slot);
623 3 100         CHECK_ALLOCATED(h, slot);
624 2           RETVAL = (IV)pool_add_i64(h, slot, (int64_t)delta);
625             OUTPUT:
626             RETVAL
627              
628             IV
629             incr(self, slot)
630             SV *self
631             UV slot
632             PREINIT:
633 4 50         EXTRACT_POOL(self);
    50          
    50          
634             CODE:
635 4 50         CHECK_SLOT(h, slot);
636 4 100         CHECK_ALLOCATED(h, slot);
637 3           RETVAL = (IV)pool_add_i64(h, slot, 1);
638             OUTPUT:
639             RETVAL
640              
641             IV
642             decr(self, slot)
643             SV *self
644             UV slot
645             PREINIT:
646 3 50         EXTRACT_POOL(self);
    50          
    50          
647             CODE:
648 3 50         CHECK_SLOT(h, slot);
649 3 100         CHECK_ALLOCATED(h, slot);
650 2           RETVAL = (IV)pool_add_i64(h, slot, -1);
651             OUTPUT:
652             RETVAL
653              
654              
655             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::F64
656              
657             PROTOTYPES: DISABLE
658              
659             SV *
660             new(class, path, capacity)
661             const char *class
662             SV *path
663             UV capacity
664             PREINIT:
665             char errbuf[POOL_ERR_BUFLEN];
666             CODE:
667 2 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
668 2           PoolHandle *h = pool_create(p, capacity, sizeof(double), POOL_VAR_F64, errbuf);
669 2 50         if (!h) croak("Data::Pool::Shared::F64->new: %s", errbuf);
670 2           MAKE_OBJ(class, h);
671             OUTPUT:
672             RETVAL
673              
674             SV *
675             new_memfd(class, name, capacity)
676             const char *class
677             const char *name
678             UV capacity
679             PREINIT:
680             char errbuf[POOL_ERR_BUFLEN];
681             CODE:
682 1           PoolHandle *h = pool_create_memfd(name, capacity, sizeof(double), POOL_VAR_F64, errbuf);
683 1 50         if (!h) croak("Data::Pool::Shared::F64->new_memfd: %s", errbuf);
684 1           MAKE_OBJ(class, h);
685             OUTPUT:
686             RETVAL
687              
688             SV *
689             new_from_fd(class, fd)
690             const char *class
691             int fd
692             PREINIT:
693             char errbuf[POOL_ERR_BUFLEN];
694             CODE:
695 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_F64, errbuf);
696 1 50         if (!h) croak("Data::Pool::Shared::F64->new_from_fd: %s", errbuf);
697 1           MAKE_OBJ(class, h);
698             OUTPUT:
699             RETVAL
700              
701             NV
702             get(self, slot)
703             SV *self
704             UV slot
705             PREINIT:
706 7 50         EXTRACT_POOL(self);
    50          
    50          
707             CODE:
708 7 50         CHECK_SLOT(h, slot);
709 7 50         CHECK_ALLOCATED(h, slot);
710 7           RETVAL = pool_get_f64(h, slot);
711             OUTPUT:
712             RETVAL
713              
714             void
715             set(self, slot, val)
716             SV *self
717             UV slot
718             NV val
719             PREINIT:
720 7 50         EXTRACT_POOL(self);
    50          
    50          
721             CODE:
722 7 50         CHECK_SLOT(h, slot);
723 7 50         CHECK_ALLOCATED(h, slot);
724 7           pool_set_f64(h, slot, (double)val);
725              
726              
727             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::I32
728              
729             PROTOTYPES: DISABLE
730              
731             SV *
732             new(class, path, capacity)
733             const char *class
734             SV *path
735             UV capacity
736             PREINIT:
737             char errbuf[POOL_ERR_BUFLEN];
738             CODE:
739 3 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
740 3           PoolHandle *h = pool_create(p, capacity, sizeof(int32_t), POOL_VAR_I32, errbuf);
741 3 50         if (!h) croak("Data::Pool::Shared::I32->new: %s", errbuf);
742 3           MAKE_OBJ(class, h);
743             OUTPUT:
744             RETVAL
745              
746             SV *
747             new_memfd(class, name, capacity)
748             const char *class
749             const char *name
750             UV capacity
751             PREINIT:
752             char errbuf[POOL_ERR_BUFLEN];
753             CODE:
754 1           PoolHandle *h = pool_create_memfd(name, capacity, sizeof(int32_t), POOL_VAR_I32, errbuf);
755 1 50         if (!h) croak("Data::Pool::Shared::I32->new_memfd: %s", errbuf);
756 1           MAKE_OBJ(class, h);
757             OUTPUT:
758             RETVAL
759              
760             SV *
761             new_from_fd(class, fd)
762             const char *class
763             int fd
764             PREINIT:
765             char errbuf[POOL_ERR_BUFLEN];
766             CODE:
767 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_I32, errbuf);
768 1 50         if (!h) croak("Data::Pool::Shared::I32->new_from_fd: %s", errbuf);
769 1           MAKE_OBJ(class, h);
770             OUTPUT:
771             RETVAL
772              
773             IV
774             get(self, slot)
775             SV *self
776             UV slot
777             PREINIT:
778 5 50         EXTRACT_POOL(self);
    50          
    50          
779             CODE:
780 5 50         CHECK_SLOT(h, slot);
781 5 50         CHECK_ALLOCATED(h, slot);
782 5 50         RETVAL = (IV)pool_get_i32(h, slot);
783             OUTPUT:
784             RETVAL
785              
786             void
787             set(self, slot, val)
788             SV *self
789             UV slot
790             IV val
791             PREINIT:
792 6 50         EXTRACT_POOL(self);
    50          
    50          
793             CODE:
794 6 50         CHECK_SLOT(h, slot);
795 6 50         CHECK_ALLOCATED(h, slot);
796 6           pool_set_i32(h, slot, (int32_t)val);
797              
798             bool
799             cas(self, slot, expected, desired)
800             SV *self
801             UV slot
802             IV expected
803             IV desired
804             PREINIT:
805 1 50         EXTRACT_POOL(self);
    50          
    50          
806             CODE:
807 1 50         CHECK_SLOT(h, slot);
808 1 50         CHECK_ALLOCATED(h, slot);
809 1 50         RETVAL = pool_cas_i32(h, slot, (int32_t)expected, (int32_t)desired);
810             OUTPUT:
811             RETVAL
812              
813             IV
814             cmpxchg(self, slot, expected, desired)
815             SV *self
816             UV slot
817             IV expected
818             IV desired
819             PREINIT:
820 2 50         EXTRACT_POOL(self);
    50          
    50          
821             CODE:
822 2 50         CHECK_SLOT(h, slot);
823 2 50         CHECK_ALLOCATED(h, slot);
824 2 50         RETVAL = (IV)pool_cmpxchg_i32(h, slot, (int32_t)expected, (int32_t)desired);
825             OUTPUT:
826             RETVAL
827              
828             IV
829             xchg(self, slot, val)
830             SV *self
831             UV slot
832             IV val
833             PREINIT:
834 1 50         EXTRACT_POOL(self);
    50          
    50          
835             CODE:
836 1 50         CHECK_SLOT(h, slot);
837 1 50         CHECK_ALLOCATED(h, slot);
838 1 50         RETVAL = (IV)pool_xchg_i32(h, slot, (int32_t)val);
839             OUTPUT:
840             RETVAL
841              
842             IV
843             add(self, slot, delta)
844             SV *self
845             UV slot
846             IV delta
847             PREINIT:
848 2 50         EXTRACT_POOL(self);
    50          
    50          
849             CODE:
850 2 50         CHECK_SLOT(h, slot);
851 2 50         CHECK_ALLOCATED(h, slot);
852 2 50         RETVAL = (IV)pool_add_i32(h, slot, (int32_t)delta);
853             OUTPUT:
854             RETVAL
855              
856             IV
857             incr(self, slot)
858             SV *self
859             UV slot
860             PREINIT:
861 0 0         EXTRACT_POOL(self);
    0          
    0          
862             CODE:
863 0 0         CHECK_SLOT(h, slot);
864 0 0         CHECK_ALLOCATED(h, slot);
865 0 0         RETVAL = (IV)pool_add_i32(h, slot, 1);
866             OUTPUT:
867             RETVAL
868              
869             IV
870             decr(self, slot)
871             SV *self
872             UV slot
873             PREINIT:
874 0 0         EXTRACT_POOL(self);
    0          
    0          
875             CODE:
876 0 0         CHECK_SLOT(h, slot);
877 0 0         CHECK_ALLOCATED(h, slot);
878 0 0         RETVAL = (IV)pool_add_i32(h, slot, -1);
879             OUTPUT:
880             RETVAL
881              
882              
883             MODULE = Data::Pool::Shared PACKAGE = Data::Pool::Shared::Str
884              
885             PROTOTYPES: DISABLE
886              
887             SV *
888             new(class, path, capacity, max_len)
889             const char *class
890             SV *path
891             UV capacity
892             UV max_len
893             PREINIT:
894             char errbuf[POOL_ERR_BUFLEN];
895             CODE:
896 4 50         if (max_len == 0) croak("Data::Pool::Shared::Str->new: max_len must be > 0");
897 4 50         if (max_len > (UV)(UINT32_MAX - sizeof(uint32_t)))
898 0           croak("Data::Pool::Shared::Str->new: max_len too large");
899 4           uint32_t elem_size = (uint32_t)(sizeof(uint32_t) + max_len);
900 4 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
901 4           PoolHandle *h = pool_create(p, capacity, elem_size, POOL_VAR_STR, errbuf);
902 4 50         if (!h) croak("Data::Pool::Shared::Str->new: %s", errbuf);
903 4           MAKE_OBJ(class, h);
904             OUTPUT:
905             RETVAL
906              
907             SV *
908             new_memfd(class, name, capacity, max_len)
909             const char *class
910             const char *name
911             UV capacity
912             UV max_len
913             PREINIT:
914             char errbuf[POOL_ERR_BUFLEN];
915             CODE:
916 1 50         if (max_len == 0) croak("Data::Pool::Shared::Str->new_memfd: max_len must be > 0");
917 1 50         if (max_len > (UV)(UINT32_MAX - sizeof(uint32_t)))
918 0           croak("Data::Pool::Shared::Str->new_memfd: max_len too large");
919 1           uint32_t elem_size = (uint32_t)(sizeof(uint32_t) + max_len);
920 1           PoolHandle *h = pool_create_memfd(name, capacity, elem_size, POOL_VAR_STR, errbuf);
921 1 50         if (!h) croak("Data::Pool::Shared::Str->new_memfd: %s", errbuf);
922 1           MAKE_OBJ(class, h);
923             OUTPUT:
924             RETVAL
925              
926             SV *
927             new_from_fd(class, fd)
928             const char *class
929             int fd
930             PREINIT:
931             char errbuf[POOL_ERR_BUFLEN];
932             CODE:
933 1           PoolHandle *h = pool_open_fd(fd, POOL_VAR_STR, errbuf);
934 1 50         if (!h) croak("Data::Pool::Shared::Str->new_from_fd: %s", errbuf);
935 1           MAKE_OBJ(class, h);
936             OUTPUT:
937             RETVAL
938              
939             SV *
940             get(self, slot)
941             SV *self
942             UV slot
943             PREINIT:
944 11 50         EXTRACT_POOL(self);
    50          
    50          
945             CODE:
946 11 50         CHECK_SLOT(h, slot);
947 11 50         CHECK_ALLOCATED(h, slot);
948 11           uint32_t len = pool_get_str_len(h, slot);
949 11           RETVAL = newSVpvn(pool_get_str_ptr(h, slot), len);
950             OUTPUT:
951             RETVAL
952              
953             void
954             set(self, slot, val)
955             SV *self
956             UV slot
957             SV *val
958             PREINIT:
959 8 50         EXTRACT_POOL(self);
    50          
    50          
960             CODE:
961 8 50         CHECK_SLOT(h, slot);
962 8 50         CHECK_ALLOCATED(h, slot);
963             STRLEN len;
964 8           const char *str = SvPV(val, len);
965 8           pool_set_str(h, slot, str, (uint32_t)len);
966              
967             UV
968             max_len(self)
969             SV *self
970             PREINIT:
971 1 50         EXTRACT_POOL(self);
    50          
    50          
972             CODE:
973 1 50         RETVAL = h->hdr->elem_size - sizeof(uint32_t);
974             OUTPUT:
975             RETVAL