File Coverage

Shared.xs
Criterion Covered Total %
statement 335 370 90.5
branch 391 734 53.2
condition n/a
subroutine n/a
pod n/a
total 726 1104 65.7


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 "sync.h"
8              
9             #define EXTRACT_HANDLE(classname, sv) \
10             if (!sv_isobject(sv) || !sv_derived_from(sv, classname)) \
11             croak("Expected a %s object", classname); \
12             SyncHandle *h = INT2PTR(SyncHandle*, SvIV(SvRV(sv))); \
13             if (!h) croak("Attempted to use a destroyed %s object", classname)
14              
15             #define MAKE_OBJ(class, handle) \
16             SV *obj = newSViv(PTR2IV(handle)); \
17             SV *ref = newRV_noinc(obj); \
18             sv_bless(ref, gv_stashpv(class, GV_ADD)); \
19             RETVAL = ref
20              
21             MODULE = Data::Sync::Shared PACKAGE = Data::Sync::Shared::Semaphore
22              
23             PROTOTYPES: DISABLE
24              
25             SV *
26             new(class, path, max, ...)
27             const char *class
28             SV *path
29             UV max
30             PREINIT:
31             char errbuf[SYNC_ERR_BUFLEN];
32             CODE:
33 25 100         uint32_t initial = (items > 3) ? (uint32_t)SvUV(ST(3)) : (uint32_t)max;
34 25 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
35 25           SyncHandle *h = sync_create(p, SYNC_TYPE_SEMAPHORE, (uint32_t)max, initial, errbuf);
36 25 100         if (!h) croak("Data::Sync::Shared::Semaphore->new: %s", errbuf);
37 22           MAKE_OBJ(class, h);
38             OUTPUT:
39             RETVAL
40              
41             SV *
42             new_memfd(class, name, max, ...)
43             const char *class
44             const char *name
45             UV max
46             PREINIT:
47             char errbuf[SYNC_ERR_BUFLEN];
48             CODE:
49 2 50         uint32_t initial = (items > 3) ? (uint32_t)SvUV(ST(3)) : (uint32_t)max;
50 2           SyncHandle *h = sync_create_memfd(name, SYNC_TYPE_SEMAPHORE, (uint32_t)max, initial, errbuf);
51 2 50         if (!h) croak("Data::Sync::Shared::Semaphore->new_memfd: %s", errbuf);
52 2           MAKE_OBJ(class, h);
53             OUTPUT:
54             RETVAL
55              
56             SV *
57             new_from_fd(class, fd)
58             const char *class
59             int fd
60             PREINIT:
61             char errbuf[SYNC_ERR_BUFLEN];
62             CODE:
63 2           SyncHandle *h = sync_open_fd(fd, SYNC_TYPE_SEMAPHORE, errbuf);
64 2 100         if (!h) croak("Data::Sync::Shared::Semaphore->new_from_fd: %s", errbuf);
65 1           MAKE_OBJ(class, h);
66             OUTPUT:
67             RETVAL
68              
69             void
70             DESTROY(self)
71             SV *self
72             PREINIT:
73 26 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    100          
74             CODE:
75 25           sv_setiv(SvRV(self), 0);
76 25           sync_destroy(h);
77              
78             bool
79             acquire(self, ...)
80             SV *self
81             PREINIT:
82 4 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
83 4           double timeout = -1;
84             CODE:
85 4 100         if (items > 1) timeout = SvNV(ST(1));
86 4 100         RETVAL = sync_sem_acquire(h, timeout);
87             OUTPUT:
88             RETVAL
89              
90             bool
91             try_acquire(self)
92             SV *self
93             PREINIT:
94 24 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
95             CODE:
96 24 100         RETVAL = sync_sem_try_acquire(h);
97             OUTPUT:
98             RETVAL
99              
100             bool
101             acquire_n(self, n, ...)
102             SV *self
103             UV n
104             PREINIT:
105 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
106 3           double timeout = -1;
107             CODE:
108 3 100         if (items > 2) timeout = SvNV(ST(2));
109 3 100         RETVAL = sync_sem_acquire_n(h, (uint32_t)n, timeout);
110             OUTPUT:
111             RETVAL
112              
113             bool
114             try_acquire_n(self, n)
115             SV *self
116             UV n
117             PREINIT:
118 6 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
119             CODE:
120 6 100         RETVAL = sync_sem_try_acquire_n(h, (uint32_t)n);
121             OUTPUT:
122             RETVAL
123              
124             void
125             release(self, ...)
126             SV *self
127             PREINIT:
128 17 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
129             CODE:
130 17 100         if (items > 1) {
131 10           uint32_t n = (uint32_t)SvUV(ST(1));
132 10           sync_sem_release_n(h, n);
133             } else {
134 7           sync_sem_release(h);
135             }
136              
137             UV
138             drain(self)
139             SV *self
140             PREINIT:
141 4 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
142             CODE:
143 4 50         RETVAL = sync_sem_drain(h);
144             OUTPUT:
145             RETVAL
146              
147             UV
148             value(self)
149             SV *self
150             PREINIT:
151 33 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    100          
152             CODE:
153 32 100         RETVAL = sync_sem_value(h);
154             OUTPUT:
155             RETVAL
156              
157             UV
158             max(self)
159             SV *self
160             PREINIT:
161 4 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
162             CODE:
163 4 50         RETVAL = h->hdr->param;
164             OUTPUT:
165             RETVAL
166              
167             SV *
168             path(self)
169             SV *self
170             PREINIT:
171 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
172             CODE:
173 2 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
174             OUTPUT:
175             RETVAL
176              
177             IV
178             memfd(self)
179             SV *self
180             PREINIT:
181 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
182             CODE:
183 2 50         RETVAL = h->backing_fd;
184             OUTPUT:
185             RETVAL
186              
187             IV
188             eventfd(self)
189             SV *self
190             PREINIT:
191 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
192             CODE:
193 3 50         RETVAL = sync_create_eventfd(h);
194             OUTPUT:
195             RETVAL
196              
197             void
198             eventfd_set(self, fd)
199             SV *self
200             int fd
201             PREINIT:
202 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
203             CODE:
204 1 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    50          
205 1           h->notify_fd = fd;
206              
207             IV
208             fileno(self)
209             SV *self
210             PREINIT:
211 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
212             CODE:
213 3 50         RETVAL = h->notify_fd;
214             OUTPUT:
215             RETVAL
216              
217             bool
218             notify(self)
219             SV *self
220             PREINIT:
221 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
222             CODE:
223 2 50         RETVAL = sync_notify(h);
224             OUTPUT:
225             RETVAL
226              
227             SV *
228             eventfd_consume(self)
229             SV *self
230             PREINIT:
231 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
232             CODE:
233 3           int64_t v = sync_eventfd_consume(h);
234 3 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
235             OUTPUT:
236             RETVAL
237              
238             void
239             sync(self)
240             SV *self
241             PREINIT:
242 0 0         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    0          
    0          
243             CODE:
244 0           sync_msync(h);
245              
246             void
247             unlink(self_or_class, ...)
248             SV *self_or_class
249             CODE:
250             const char *p;
251 4 100         if (sv_isobject(self_or_class)) {
252 3           SyncHandle *h = INT2PTR(SyncHandle*, SvIV(SvRV(self_or_class)));
253 3 50         if (!h) croak("Attempted to use a destroyed object");
254 3           p = h->path;
255             } else {
256 1 50         if (items < 2) croak("Usage: ...->unlink($path)");
257 0           p = SvPV_nolen(ST(1));
258             }
259 3 100         if (!p) croak("cannot unlink anonymous or memfd object");
260 2 50         if (unlink(p) != 0)
261 0           croak("unlink(%s): %s", p, strerror(errno));
262              
263             SV *
264             stats(self)
265             SV *self
266             PREINIT:
267 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Semaphore", self);
    50          
    50          
268             CODE:
269 1           HV *hv = newHV();
270 1           SyncHeader *hdr = h->hdr;
271 1           hv_store(hv, "value", 5, newSVuv(sync_sem_value(h)), 0);
272 1           hv_store(hv, "max", 3, newSVuv(hdr->param), 0);
273 1           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
274 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
275 1           hv_store(hv, "acquires", 8, newSVuv((UV)hdr->stat_acquires), 0);
276 1           hv_store(hv, "releases", 8, newSVuv((UV)hdr->stat_releases), 0);
277 1           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
278 1           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
279 1           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
280 1           RETVAL = newRV_noinc((SV *)hv);
281             OUTPUT:
282             RETVAL
283              
284             MODULE = Data::Sync::Shared PACKAGE = Data::Sync::Shared::Barrier
285              
286             PROTOTYPES: DISABLE
287              
288             SV *
289             new(class, path, parties)
290             const char *class
291             SV *path
292             UV parties
293             PREINIT:
294             char errbuf[SYNC_ERR_BUFLEN];
295             CODE:
296 13 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
297 13           SyncHandle *h = sync_create(p, SYNC_TYPE_BARRIER, (uint32_t)parties, 0, errbuf);
298 13 100         if (!h) croak("Data::Sync::Shared::Barrier->new: %s", errbuf);
299 10           MAKE_OBJ(class, h);
300             OUTPUT:
301             RETVAL
302              
303             SV *
304             new_memfd(class, name, parties)
305             const char *class
306             const char *name
307             UV parties
308             PREINIT:
309             char errbuf[SYNC_ERR_BUFLEN];
310             CODE:
311 1           SyncHandle *h = sync_create_memfd(name, SYNC_TYPE_BARRIER, (uint32_t)parties, 0, errbuf);
312 1 50         if (!h) croak("Data::Sync::Shared::Barrier->new_memfd: %s", errbuf);
313 1           MAKE_OBJ(class, h);
314             OUTPUT:
315             RETVAL
316              
317             SV *
318             new_from_fd(class, fd)
319             const char *class
320             int fd
321             PREINIT:
322             char errbuf[SYNC_ERR_BUFLEN];
323             CODE:
324 1           SyncHandle *h = sync_open_fd(fd, SYNC_TYPE_BARRIER, errbuf);
325 1 50         if (!h) croak("Data::Sync::Shared::Barrier->new_from_fd: %s", errbuf);
326 0           MAKE_OBJ(class, h);
327             OUTPUT:
328             RETVAL
329              
330             void
331             DESTROY(self)
332             SV *self
333             PREINIT:
334 11 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
335             CODE:
336 11           sv_setiv(SvRV(self), 0);
337 11           sync_destroy(h);
338              
339             IV
340             wait(self, ...)
341             SV *self
342             PREINIT:
343 8 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
344 8 50         double timeout = -1;
345             CODE:
346 8 50         if (items > 1) timeout = SvNV(ST(1));
347 8 100         RETVAL = sync_barrier_wait(h, timeout);
348             OUTPUT:
349             RETVAL
350              
351             UV
352             generation(self)
353             SV *self
354             PREINIT:
355 5 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
356             CODE:
357 5 100         RETVAL = sync_barrier_generation(h);
358             OUTPUT:
359             RETVAL
360              
361             UV
362             arrived(self)
363             SV *self
364             PREINIT:
365 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
366             CODE:
367 3 50         RETVAL = sync_barrier_arrived(h);
368             OUTPUT:
369             RETVAL
370              
371             UV
372             parties(self)
373             SV *self
374             PREINIT:
375 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
376             CODE:
377 1 50         RETVAL = h->hdr->param;
378             OUTPUT:
379             RETVAL
380              
381             void
382             reset(self)
383             SV *self
384             PREINIT:
385 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
386             CODE:
387 1           sync_barrier_reset(h);
388              
389             SV *
390             path(self)
391             SV *self
392             PREINIT:
393 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
394             CODE:
395 2 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
396             OUTPUT:
397             RETVAL
398              
399             IV
400             memfd(self)
401             SV *self
402             PREINIT:
403 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
404             CODE:
405 1 50         RETVAL = h->backing_fd;
406             OUTPUT:
407             RETVAL
408              
409             IV
410             eventfd(self)
411             SV *self
412             PREINIT:
413 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
414             CODE:
415 2 50         RETVAL = sync_create_eventfd(h);
416             OUTPUT:
417             RETVAL
418              
419             void
420             eventfd_set(self, fd)
421             SV *self
422             int fd
423             PREINIT:
424 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
425             CODE:
426 1 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    50          
427 1           h->notify_fd = fd;
428              
429             IV
430             fileno(self)
431             SV *self
432             PREINIT:
433 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
434             CODE:
435 3 50         RETVAL = h->notify_fd;
436             OUTPUT:
437             RETVAL
438              
439             bool
440             notify(self)
441             SV *self
442             PREINIT:
443 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
444             CODE:
445 2 50         RETVAL = sync_notify(h);
446             OUTPUT:
447             RETVAL
448              
449             SV *
450             eventfd_consume(self)
451             SV *self
452             PREINIT:
453 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
454             CODE:
455 2           int64_t v = sync_eventfd_consume(h);
456 2 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
457             OUTPUT:
458             RETVAL
459              
460             void
461             sync(self)
462             SV *self
463             PREINIT:
464 0 0         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    0          
    0          
465             CODE:
466 0           sync_msync(h);
467              
468             void
469             unlink(self_or_class, ...)
470             SV *self_or_class
471             CODE:
472             const char *p;
473 1 50         if (sv_isobject(self_or_class)) {
474 1           SyncHandle *h = INT2PTR(SyncHandle*, SvIV(SvRV(self_or_class)));
475 1 50         if (!h) croak("Attempted to use a destroyed object");
476 1           p = h->path;
477             } else {
478 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
479 0           p = SvPV_nolen(ST(1));
480             }
481 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
482 1 50         if (unlink(p) != 0)
483 0           croak("unlink(%s): %s", p, strerror(errno));
484              
485             SV *
486             stats(self)
487             SV *self
488             PREINIT:
489 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Barrier", self);
    50          
    50          
490             CODE:
491 1           HV *hv = newHV();
492 1           SyncHeader *hdr = h->hdr;
493 1           hv_store(hv, "parties", 7, newSVuv(hdr->param), 0);
494 1           hv_store(hv, "arrived", 7, newSVuv(sync_barrier_arrived(h)), 0);
495 1           hv_store(hv, "generation", 10, newSVuv(sync_barrier_generation(h)), 0);
496 1           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
497 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
498 1           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
499 1           hv_store(hv, "releases", 8, newSVuv((UV)hdr->stat_releases), 0);
500 1           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
501 1           RETVAL = newRV_noinc((SV *)hv);
502             OUTPUT:
503             RETVAL
504              
505             MODULE = Data::Sync::Shared PACKAGE = Data::Sync::Shared::RWLock
506              
507             PROTOTYPES: DISABLE
508              
509             SV *
510             new(class, path)
511             const char *class
512             SV *path
513             PREINIT:
514             char errbuf[SYNC_ERR_BUFLEN];
515             CODE:
516 13 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
517 13           SyncHandle *h = sync_create(p, SYNC_TYPE_RWLOCK, 0, 0, errbuf);
518 13 100         if (!h) croak("Data::Sync::Shared::RWLock->new: %s", errbuf);
519 12           MAKE_OBJ(class, h);
520             OUTPUT:
521             RETVAL
522              
523             SV *
524             new_memfd(class, name)
525             const char *class
526             const char *name
527             PREINIT:
528             char errbuf[SYNC_ERR_BUFLEN];
529             CODE:
530 1           SyncHandle *h = sync_create_memfd(name, SYNC_TYPE_RWLOCK, 0, 0, errbuf);
531 1 50         if (!h) croak("Data::Sync::Shared::RWLock->new_memfd: %s", errbuf);
532 1           MAKE_OBJ(class, h);
533             OUTPUT:
534             RETVAL
535              
536             SV *
537             new_from_fd(class, fd)
538             const char *class
539             int fd
540             PREINIT:
541             char errbuf[SYNC_ERR_BUFLEN];
542             CODE:
543 1           SyncHandle *h = sync_open_fd(fd, SYNC_TYPE_RWLOCK, errbuf);
544 1 50         if (!h) croak("Data::Sync::Shared::RWLock->new_from_fd: %s", errbuf);
545 1           MAKE_OBJ(class, h);
546             OUTPUT:
547             RETVAL
548              
549             void
550             DESTROY(self)
551             SV *self
552             PREINIT:
553 15 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    100          
554             CODE:
555 14           sv_setiv(SvRV(self), 0);
556 14           sync_destroy(h);
557              
558             void
559             rdlock(self, ...)
560             SV *self
561             PREINIT:
562 8 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    100          
563             CODE:
564 7 50         if (items > 1) {
565 0           double timeout = SvNV(ST(1));
566 0 0         if (!sync_rwlock_rdlock_timed(h->hdr, timeout))
567 0           croak("rdlock: timeout");
568             } else {
569 7           sync_rwlock_rdlock(h->hdr);
570             }
571 7           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
572              
573             bool
574             try_rdlock(self)
575             SV *self
576             PREINIT:
577 3 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
578             CODE:
579 3           RETVAL = sync_rwlock_try_rdlock(h->hdr);
580 3 100         if (RETVAL)
581 2           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
582             OUTPUT:
583             RETVAL
584              
585             bool
586             rdlock_timed(self, timeout)
587             SV *self
588             double timeout
589             PREINIT:
590 1 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
591             CODE:
592 1           RETVAL = sync_rwlock_rdlock_timed(h->hdr, timeout);
593 1 50         if (RETVAL)
594 1           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
595             OUTPUT:
596             RETVAL
597              
598             void
599             rdunlock(self)
600             SV *self
601             PREINIT:
602 11 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
603             CODE:
604 11           sync_rwlock_rdunlock(h->hdr);
605 11           __atomic_add_fetch(&h->hdr->stat_releases, 1, __ATOMIC_RELAXED);
606              
607             void
608             wrlock(self, ...)
609             SV *self
610             PREINIT:
611 5 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
612             CODE:
613 5 50         if (items > 1) {
614 0           double timeout = SvNV(ST(1));
615 0 0         if (!sync_rwlock_wrlock_timed(h->hdr, timeout))
616 0           croak("wrlock: timeout");
617             } else {
618 5           sync_rwlock_wrlock(h->hdr);
619             }
620 5           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
621              
622             bool
623             try_wrlock(self)
624             SV *self
625             PREINIT:
626 3 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
627             CODE:
628 3           RETVAL = sync_rwlock_try_wrlock(h->hdr);
629 3 100         if (RETVAL)
630 1           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
631             OUTPUT:
632             RETVAL
633              
634             bool
635             wrlock_timed(self, timeout)
636             SV *self
637             double timeout
638             PREINIT:
639 1 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
640             CODE:
641 1           RETVAL = sync_rwlock_wrlock_timed(h->hdr, timeout);
642 1 50         if (RETVAL)
643 1           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
644             OUTPUT:
645             RETVAL
646              
647             void
648             wrunlock(self)
649             SV *self
650             PREINIT:
651 6 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
652             CODE:
653 6           sync_rwlock_wrunlock(h->hdr);
654 6           __atomic_add_fetch(&h->hdr->stat_releases, 1, __ATOMIC_RELAXED);
655              
656             void
657             downgrade(self)
658             SV *self
659             PREINIT:
660 1 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
661             CODE:
662 1           sync_rwlock_downgrade(h->hdr);
663 1           __atomic_add_fetch(&h->hdr->stat_releases, 1, __ATOMIC_RELAXED);
664 1           __atomic_add_fetch(&h->hdr->stat_acquires, 1, __ATOMIC_RELAXED);
665              
666             SV *
667             path(self)
668             SV *self
669             PREINIT:
670 2 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
671             CODE:
672 2 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
673             OUTPUT:
674             RETVAL
675              
676             IV
677             memfd(self)
678             SV *self
679             PREINIT:
680 2 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
681             CODE:
682 2 50         RETVAL = h->backing_fd;
683             OUTPUT:
684             RETVAL
685              
686             IV
687             eventfd(self)
688             SV *self
689             PREINIT:
690 2 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
691             CODE:
692 2 50         RETVAL = sync_create_eventfd(h);
693             OUTPUT:
694             RETVAL
695              
696             void
697             eventfd_set(self, fd)
698             SV *self
699             int fd
700             PREINIT:
701 1 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
702             CODE:
703 1 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    50          
704 1           h->notify_fd = fd;
705              
706             IV
707             fileno(self)
708             SV *self
709             PREINIT:
710 3 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
711             CODE:
712 3 50         RETVAL = h->notify_fd;
713             OUTPUT:
714             RETVAL
715              
716             bool
717             notify(self)
718             SV *self
719             PREINIT:
720 2 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
721             CODE:
722 2 50         RETVAL = sync_notify(h);
723             OUTPUT:
724             RETVAL
725              
726             SV *
727             eventfd_consume(self)
728             SV *self
729             PREINIT:
730 2 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
731             CODE:
732 2           int64_t v = sync_eventfd_consume(h);
733 2 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
734             OUTPUT:
735             RETVAL
736              
737             void
738             sync(self)
739             SV *self
740             PREINIT:
741 0 0         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    0          
    0          
742             CODE:
743 0           sync_msync(h);
744              
745             void
746             unlink(self_or_class, ...)
747             SV *self_or_class
748             CODE:
749             const char *p;
750 1 50         if (sv_isobject(self_or_class)) {
751 1           SyncHandle *h = INT2PTR(SyncHandle*, SvIV(SvRV(self_or_class)));
752 1 50         if (!h) croak("Attempted to use a destroyed object");
753 1           p = h->path;
754             } else {
755 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
756 0           p = SvPV_nolen(ST(1));
757             }
758 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
759 1 50         if (unlink(p) != 0)
760 0           croak("unlink(%s): %s", p, strerror(errno));
761              
762             SV *
763             stats(self)
764             SV *self
765             PREINIT:
766 13 50         EXTRACT_HANDLE("Data::Sync::Shared::RWLock", self);
    50          
    50          
767             CODE:
768 13           HV *hv = newHV();
769 13           SyncHeader *hdr = h->hdr;
770 13           uint32_t val = __atomic_load_n(&hdr->value, __ATOMIC_RELAXED);
771             const char *state;
772 13 100         if (val == 0) state = "unlocked";
773 8 100         else if (val < SYNC_RWLOCK_WRITER_BIT) state = "read_locked";
774 3           else state = "write_locked";
775 13           hv_store(hv, "state", 5, newSVpv(state, 0), 0);
776 13           hv_store(hv, "readers", 7,
777             newSVuv(val < SYNC_RWLOCK_WRITER_BIT ? val : 0), 0);
778 13           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
779 13           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
780 13           hv_store(hv, "acquires", 8, newSVuv((UV)hdr->stat_acquires), 0);
781 13           hv_store(hv, "releases", 8, newSVuv((UV)hdr->stat_releases), 0);
782 13           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
783 13           RETVAL = newRV_noinc((SV *)hv);
784             OUTPUT:
785             RETVAL
786              
787             MODULE = Data::Sync::Shared PACKAGE = Data::Sync::Shared::Condvar
788              
789             PROTOTYPES: DISABLE
790              
791             SV *
792             new(class, path)
793             const char *class
794             SV *path
795             PREINIT:
796             char errbuf[SYNC_ERR_BUFLEN];
797             CODE:
798 13 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
799 13           SyncHandle *h = sync_create(p, SYNC_TYPE_CONDVAR, 0, 0, errbuf);
800 13 50         if (!h) croak("Data::Sync::Shared::Condvar->new: %s", errbuf);
801 13           MAKE_OBJ(class, h);
802             OUTPUT:
803             RETVAL
804              
805             SV *
806             new_memfd(class, name)
807             const char *class
808             const char *name
809             PREINIT:
810             char errbuf[SYNC_ERR_BUFLEN];
811             CODE:
812 1           SyncHandle *h = sync_create_memfd(name, SYNC_TYPE_CONDVAR, 0, 0, errbuf);
813 1 50         if (!h) croak("Data::Sync::Shared::Condvar->new_memfd: %s", errbuf);
814 1           MAKE_OBJ(class, h);
815             OUTPUT:
816             RETVAL
817              
818             SV *
819             new_from_fd(class, fd)
820             const char *class
821             int fd
822             PREINIT:
823             char errbuf[SYNC_ERR_BUFLEN];
824             CODE:
825 0           SyncHandle *h = sync_open_fd(fd, SYNC_TYPE_CONDVAR, errbuf);
826 0 0         if (!h) croak("Data::Sync::Shared::Condvar->new_from_fd: %s", errbuf);
827 0           MAKE_OBJ(class, h);
828             OUTPUT:
829             RETVAL
830              
831             void
832             DESTROY(self)
833             SV *self
834             PREINIT:
835 14 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
836             CODE:
837 14           sv_setiv(SvRV(self), 0);
838 14           sync_destroy(h);
839              
840             void
841             lock(self)
842             SV *self
843             PREINIT:
844 12 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
845             CODE:
846 12           sync_condvar_lock(h);
847              
848             bool
849             try_lock(self)
850             SV *self
851             PREINIT:
852 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
853             CODE:
854 1 50         RETVAL = sync_condvar_try_lock(h);
855             OUTPUT:
856             RETVAL
857              
858             void
859             unlock(self)
860             SV *self
861             PREINIT:
862 13 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
863             CODE:
864 13           sync_condvar_unlock(h);
865              
866             bool
867             wait(self, ...)
868             SV *self
869             PREINIT:
870 4 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
871 4           double timeout = -1;
872             CODE:
873 4 50         if (items > 1) timeout = SvNV(ST(1));
874 4 100         RETVAL = sync_condvar_wait(h, timeout);
875             OUTPUT:
876             RETVAL
877              
878             void
879             signal(self)
880             SV *self
881             PREINIT:
882 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
883             CODE:
884 1           sync_condvar_signal(h);
885              
886             void
887             broadcast(self)
888             SV *self
889             PREINIT:
890 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
891             CODE:
892 1           sync_condvar_broadcast(h);
893              
894             SV *
895             path(self)
896             SV *self
897             PREINIT:
898 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
899             CODE:
900 2 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
901             OUTPUT:
902             RETVAL
903              
904             IV
905             memfd(self)
906             SV *self
907             PREINIT:
908 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
909             CODE:
910 1 50         RETVAL = h->backing_fd;
911             OUTPUT:
912             RETVAL
913              
914             IV
915             eventfd(self)
916             SV *self
917             PREINIT:
918 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
919             CODE:
920 2 50         RETVAL = sync_create_eventfd(h);
921             OUTPUT:
922             RETVAL
923              
924             void
925             eventfd_set(self, fd)
926             SV *self
927             int fd
928             PREINIT:
929 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
930             CODE:
931 1 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    50          
932 1           h->notify_fd = fd;
933              
934             IV
935             fileno(self)
936             SV *self
937             PREINIT:
938 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
939             CODE:
940 3 50         RETVAL = h->notify_fd;
941             OUTPUT:
942             RETVAL
943              
944             bool
945             notify(self)
946             SV *self
947             PREINIT:
948 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
949             CODE:
950 2 50         RETVAL = sync_notify(h);
951             OUTPUT:
952             RETVAL
953              
954             SV *
955             eventfd_consume(self)
956             SV *self
957             PREINIT:
958 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
959             CODE:
960 2           int64_t v = sync_eventfd_consume(h);
961 2 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
962             OUTPUT:
963             RETVAL
964              
965             void
966             sync(self)
967             SV *self
968             PREINIT:
969 0 0         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    0          
    0          
970             CODE:
971 0           sync_msync(h);
972              
973             void
974             unlink(self_or_class, ...)
975             SV *self_or_class
976             CODE:
977             const char *p;
978 1 50         if (sv_isobject(self_or_class)) {
979 1           SyncHandle *h = INT2PTR(SyncHandle*, SvIV(SvRV(self_or_class)));
980 1 50         if (!h) croak("Attempted to use a destroyed object");
981 1           p = h->path;
982             } else {
983 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
984 0           p = SvPV_nolen(ST(1));
985             }
986 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
987 1 50         if (unlink(p) != 0)
988 0           croak("unlink(%s): %s", p, strerror(errno));
989              
990             SV *
991             stats(self)
992             SV *self
993             PREINIT:
994 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Condvar", self);
    50          
    50          
995             CODE:
996 1           HV *hv = newHV();
997 1           SyncHeader *hdr = h->hdr;
998 1           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
999 1           hv_store(hv, "signals", 7, newSVuv(hdr->stat_signals), 0);
1000 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
1001 1           hv_store(hv, "acquires", 8, newSVuv((UV)hdr->stat_acquires), 0);
1002 1           hv_store(hv, "releases", 8, newSVuv((UV)hdr->stat_releases), 0);
1003 1           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
1004 1           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
1005 1           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
1006 1           RETVAL = newRV_noinc((SV *)hv);
1007             OUTPUT:
1008             RETVAL
1009              
1010             MODULE = Data::Sync::Shared PACKAGE = Data::Sync::Shared::Once
1011              
1012             PROTOTYPES: DISABLE
1013              
1014             SV *
1015             new(class, path)
1016             const char *class
1017             SV *path
1018             PREINIT:
1019             char errbuf[SYNC_ERR_BUFLEN];
1020             CODE:
1021 9 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
1022 9           SyncHandle *h = sync_create(p, SYNC_TYPE_ONCE, 0, 0, errbuf);
1023 9 100         if (!h) croak("Data::Sync::Shared::Once->new: %s", errbuf);
1024 8           MAKE_OBJ(class, h);
1025             OUTPUT:
1026             RETVAL
1027              
1028             SV *
1029             new_memfd(class, name)
1030             const char *class
1031             const char *name
1032             PREINIT:
1033             char errbuf[SYNC_ERR_BUFLEN];
1034             CODE:
1035 1           SyncHandle *h = sync_create_memfd(name, SYNC_TYPE_ONCE, 0, 0, errbuf);
1036 1 50         if (!h) croak("Data::Sync::Shared::Once->new_memfd: %s", errbuf);
1037 1           MAKE_OBJ(class, h);
1038             OUTPUT:
1039             RETVAL
1040              
1041             SV *
1042             new_from_fd(class, fd)
1043             const char *class
1044             int fd
1045             PREINIT:
1046             char errbuf[SYNC_ERR_BUFLEN];
1047             CODE:
1048 1           SyncHandle *h = sync_open_fd(fd, SYNC_TYPE_ONCE, errbuf);
1049 1 50         if (!h) croak("Data::Sync::Shared::Once->new_from_fd: %s", errbuf);
1050 1           MAKE_OBJ(class, h);
1051             OUTPUT:
1052             RETVAL
1053              
1054             void
1055             DESTROY(self)
1056             SV *self
1057             PREINIT:
1058 10 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1059             CODE:
1060 10           sv_setiv(SvRV(self), 0);
1061 10           sync_destroy(h);
1062              
1063             bool
1064             enter(self, ...)
1065             SV *self
1066             PREINIT:
1067 6 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1068 6           double timeout = -1;
1069             CODE:
1070 6 100         if (items > 1) timeout = SvNV(ST(1));
1071 6 100         RETVAL = sync_once_enter(h, timeout);
1072             OUTPUT:
1073             RETVAL
1074              
1075             void
1076             done(self)
1077             SV *self
1078             PREINIT:
1079 4 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1080             CODE:
1081 4           sync_once_done(h);
1082              
1083             bool
1084             is_done(self)
1085             SV *self
1086             PREINIT:
1087 8 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1088             CODE:
1089 8 100         RETVAL = sync_once_is_done(h);
1090             OUTPUT:
1091             RETVAL
1092              
1093             void
1094             reset(self)
1095             SV *self
1096             PREINIT:
1097 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1098             CODE:
1099 2           sync_once_reset(h);
1100              
1101             SV *
1102             path(self)
1103             SV *self
1104             PREINIT:
1105 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1106             CODE:
1107 2 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
1108             OUTPUT:
1109             RETVAL
1110              
1111             IV
1112             memfd(self)
1113             SV *self
1114             PREINIT:
1115 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1116             CODE:
1117 2 50         RETVAL = h->backing_fd;
1118             OUTPUT:
1119             RETVAL
1120              
1121             IV
1122             eventfd(self)
1123             SV *self
1124             PREINIT:
1125 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1126             CODE:
1127 2 50         RETVAL = sync_create_eventfd(h);
1128             OUTPUT:
1129             RETVAL
1130              
1131             void
1132             eventfd_set(self, fd)
1133             SV *self
1134             int fd
1135             PREINIT:
1136 1 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1137             CODE:
1138 1 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    50          
1139 1           h->notify_fd = fd;
1140              
1141             IV
1142             fileno(self)
1143             SV *self
1144             PREINIT:
1145 3 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1146             CODE:
1147 3 50         RETVAL = h->notify_fd;
1148             OUTPUT:
1149             RETVAL
1150              
1151             bool
1152             notify(self)
1153             SV *self
1154             PREINIT:
1155 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1156             CODE:
1157 2 50         RETVAL = sync_notify(h);
1158             OUTPUT:
1159             RETVAL
1160              
1161             SV *
1162             eventfd_consume(self)
1163             SV *self
1164             PREINIT:
1165 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1166             CODE:
1167 2           int64_t v = sync_eventfd_consume(h);
1168 2 100         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
1169             OUTPUT:
1170             RETVAL
1171              
1172             void
1173             sync(self)
1174             SV *self
1175             PREINIT:
1176 0 0         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    0          
    0          
1177             CODE:
1178 0           sync_msync(h);
1179              
1180             void
1181             unlink(self_or_class, ...)
1182             SV *self_or_class
1183             CODE:
1184             const char *p;
1185 1 50         if (sv_isobject(self_or_class)) {
1186 1           SyncHandle *h = INT2PTR(SyncHandle*, SvIV(SvRV(self_or_class)));
1187 1 50         if (!h) croak("Attempted to use a destroyed object");
1188 1           p = h->path;
1189             } else {
1190 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
1191 0           p = SvPV_nolen(ST(1));
1192             }
1193 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
1194 1 50         if (unlink(p) != 0)
1195 0           croak("unlink(%s): %s", p, strerror(errno));
1196              
1197             SV *
1198             stats(self)
1199             SV *self
1200             PREINIT:
1201 2 50         EXTRACT_HANDLE("Data::Sync::Shared::Once", self);
    50          
    50          
1202             CODE:
1203 2           HV *hv = newHV();
1204 2           SyncHeader *hdr = h->hdr;
1205             const char *state;
1206 2           uint32_t val = __atomic_load_n(&hdr->value, __ATOMIC_RELAXED);
1207 2 100         if (val == SYNC_ONCE_INIT) state = "init";
1208 1 50         else if (val == SYNC_ONCE_DONE) state = "done";
1209 0           else state = "running";
1210 2           hv_store(hv, "state", 5, newSVpv(state, 0), 0);
1211 2           hv_store(hv, "is_done", 7, newSVuv(val == SYNC_ONCE_DONE), 0);
1212 2           hv_store(hv, "waiters", 7, newSVuv(hdr->waiters), 0);
1213 2           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
1214 2           hv_store(hv, "acquires", 8, newSVuv((UV)hdr->stat_acquires), 0);
1215 2           hv_store(hv, "releases", 8, newSVuv((UV)hdr->stat_releases), 0);
1216 2           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
1217 2           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
1218 2           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
1219 2           RETVAL = newRV_noinc((SV *)hv);
1220             OUTPUT:
1221             RETVAL