File Coverage

Shared.xs
Criterion Covered Total %
statement 77 92 83.7
branch 86 192 44.7
condition n/a
subroutine n/a
pod n/a
total 163 284 57.3


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             #include "ppport.h"
6             #include "ring.h"
7              
8             #define EXTRACT_RING(sv) \
9             if (!sv_isobject(sv) || !sv_derived_from(sv, "Data::RingBuffer::Shared")) \
10             croak("Expected a Data::RingBuffer::Shared object"); \
11             RingHandle *h = INT2PTR(RingHandle*, SvIV(SvRV(sv))); \
12             if (!h) croak("Attempted to use a destroyed Data::RingBuffer::Shared object")
13              
14             #define MAKE_OBJ(class, handle) \
15             SV *obj = newSViv(PTR2IV(handle)); \
16             SV *ref = newRV_noinc(obj); \
17             sv_bless(ref, gv_stashpv(class, GV_ADD)); \
18             RETVAL = ref
19              
20             MODULE = Data::RingBuffer::Shared PACKAGE = Data::RingBuffer::Shared
21              
22             PROTOTYPES: DISABLE
23              
24             void
25             DESTROY(self)
26             SV *self
27             CODE:
28 8 50         if (!SvROK(self)) return;
29 8           RingHandle *h = INT2PTR(RingHandle*, SvIV(SvRV(self)));
30 8 50         if (!h) return;
31 8           sv_setiv(SvRV(self), 0);
32 8           ring_destroy(h);
33              
34             UV
35             size(self)
36             SV *self
37             PREINIT:
38 8 50         EXTRACT_RING(self);
    50          
    50          
39             CODE:
40 8           RETVAL = (UV)ring_size(h);
41             OUTPUT:
42             RETVAL
43              
44             UV
45             capacity(self)
46             SV *self
47             PREINIT:
48 1 50         EXTRACT_RING(self);
    50          
    50          
49             CODE:
50 1 50         RETVAL = (UV)h->hdr->capacity;
51             OUTPUT:
52             RETVAL
53              
54             UV
55             head(self)
56             SV *self
57             PREINIT:
58 1 50         EXTRACT_RING(self);
    50          
    50          
59             CODE:
60 1           RETVAL = (UV)ring_head(h);
61             OUTPUT:
62             RETVAL
63              
64             UV
65             count(self)
66             SV *self
67             PREINIT:
68 1 50         EXTRACT_RING(self);
    50          
    50          
69             CODE:
70 1 50         RETVAL = (UV)__atomic_load_n(&h->hdr->count, __ATOMIC_ACQUIRE);
71             OUTPUT:
72             RETVAL
73              
74             bool
75             wait_for(self, expected_count, ...)
76             SV *self
77             UV expected_count
78             PREINIT:
79 2 50         EXTRACT_RING(self);
    50          
    50          
80 2           double timeout = -1;
81             CODE:
82 2 50         if (items > 2) timeout = SvNV(ST(2));
83 2 100         RETVAL = ring_wait(h, expected_count, timeout);
84             OUTPUT:
85             RETVAL
86              
87             void
88             clear(self)
89             SV *self
90             PREINIT:
91 1 50         EXTRACT_RING(self);
    50          
    50          
92             CODE:
93 1           ring_clear(h);
94              
95             SV *
96             path(self)
97             SV *self
98             PREINIT:
99 1 50         EXTRACT_RING(self);
    50          
    50          
100             CODE:
101 1 50         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
102             OUTPUT:
103             RETVAL
104              
105             IV
106             memfd(self)
107             SV *self
108             PREINIT:
109 1 50         EXTRACT_RING(self);
    50          
    50          
110             CODE:
111 1 50         RETVAL = h->backing_fd;
112             OUTPUT:
113             RETVAL
114              
115             IV
116             eventfd(self)
117             SV *self
118             PREINIT:
119 1 50         EXTRACT_RING(self);
    50          
    50          
120             CODE:
121 1 50         RETVAL = ring_create_eventfd(h);
122             OUTPUT:
123             RETVAL
124              
125             void
126             eventfd_set(self, fd)
127             SV *self
128             int fd
129             PREINIT:
130 0 0         EXTRACT_RING(self);
    0          
    0          
131             CODE:
132 0 0         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    0          
133 0           h->notify_fd = fd;
134              
135             IV
136             fileno(self)
137             SV *self
138             PREINIT:
139 0 0         EXTRACT_RING(self);
    0          
    0          
140             CODE:
141 0 0         RETVAL = h->notify_fd;
142             OUTPUT:
143             RETVAL
144              
145             bool
146             notify(self)
147             SV *self
148             PREINIT:
149 1 50         EXTRACT_RING(self);
    50          
    50          
150             CODE:
151 1 50         RETVAL = ring_notify(h);
152             OUTPUT:
153             RETVAL
154              
155             SV *
156             eventfd_consume(self)
157             SV *self
158             PREINIT:
159 1 50         EXTRACT_RING(self);
    50          
    50          
160             CODE:
161 1           int64_t v = ring_eventfd_consume(h);
162 1 50         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
163             OUTPUT:
164             RETVAL
165              
166             void
167             sync(self)
168             SV *self
169             PREINIT:
170 1 50         EXTRACT_RING(self);
    50          
    50          
171             CODE:
172 1           ring_msync(h);
173              
174             void
175             unlink(self_or_class, ...)
176             SV *self_or_class
177             CODE:
178             const char *p;
179 1 50         if (sv_isobject(self_or_class)) {
180 1           RingHandle *h = INT2PTR(RingHandle*, SvIV(SvRV(self_or_class)));
181 1 50         if (!h) croak("destroyed object");
182 1           p = h->path;
183             } else {
184 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
185 0           p = SvPV_nolen(ST(1));
186             }
187 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
188 1 50         if (unlink(p) != 0) croak("unlink(%s): %s", p, strerror(errno));
189              
190             SV *
191             stats(self)
192             SV *self
193             PREINIT:
194 1 50         EXTRACT_RING(self);
    50          
    50          
195             CODE:
196 1           HV *hv = newHV();
197 1           RingHeader *hdr = h->hdr;
198 1           hv_store(hv, "size", 4, newSVuv((UV)ring_size(h)), 0);
199 1           hv_store(hv, "capacity", 8, newSVuv((UV)hdr->capacity), 0);
200 1           hv_store(hv, "head", 4, newSVuv((UV)ring_head(h)), 0);
201 1           hv_store(hv, "count", 5, newSVuv((UV)__atomic_load_n(&hdr->count, __ATOMIC_RELAXED)), 0);
202 1           hv_store(hv, "writes", 6, newSVuv((UV)hdr->stat_writes), 0);
203 1           hv_store(hv, "overwrites", 10, newSVuv((UV)hdr->stat_overwrites), 0);
204 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
205 1           RETVAL = newRV_noinc((SV *)hv);
206             OUTPUT:
207             RETVAL
208              
209              
210             MODULE = Data::RingBuffer::Shared PACKAGE = Data::RingBuffer::Shared::Int
211              
212             PROTOTYPES: DISABLE
213              
214             SV *
215             new(class, path, capacity)
216             const char *class
217             SV *path
218             UV capacity
219             PREINIT:
220             char errbuf[RING_ERR_BUFLEN];
221             CODE:
222 5 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
223 5           RingHandle *h = ring_create(p, capacity, sizeof(int64_t), RING_VAR_INT, errbuf);
224 5 50         if (!h) croak("Data::RingBuffer::Shared::Int->new: %s", errbuf);
225 5           MAKE_OBJ(class, h);
226             OUTPUT:
227             RETVAL
228              
229             SV *
230             new_memfd(class, name, capacity)
231             const char *class
232             const char *name
233             UV capacity
234             PREINIT:
235             char errbuf[RING_ERR_BUFLEN];
236             CODE:
237 1           RingHandle *h = ring_create_memfd(name, capacity, sizeof(int64_t), RING_VAR_INT, errbuf);
238 1 50         if (!h) croak("Data::RingBuffer::Shared::Int->new_memfd: %s", errbuf);
239 1           MAKE_OBJ(class, h);
240             OUTPUT:
241             RETVAL
242              
243             SV *
244             new_from_fd(class, fd)
245             const char *class
246             int fd
247             PREINIT:
248             char errbuf[RING_ERR_BUFLEN];
249             CODE:
250 1           RingHandle *h = ring_open_fd(fd, RING_VAR_INT, errbuf);
251 1 50         if (!h) croak("Data::RingBuffer::Shared::Int->new_from_fd: %s", errbuf);
252 1           MAKE_OBJ(class, h);
253             OUTPUT:
254             RETVAL
255              
256             UV
257             write(self, val)
258             SV *self
259             IV val
260             PREINIT:
261 11 50         EXTRACT_RING(self);
    50          
    50          
262             CODE:
263 11           int64_t v = (int64_t)val;
264 11           RETVAL = (UV)ring_write(h, &v, sizeof(v));
265             OUTPUT:
266             RETVAL
267              
268             SV *
269             latest(self, ...)
270             SV *self
271             PREINIT:
272 15 50         EXTRACT_RING(self);
    50          
    50          
273             CODE:
274 15 100         uint32_t n = (items > 1) ? (uint32_t)SvUV(ST(1)) : 0;
275             int64_t v;
276 15 100         RETVAL = ring_read_latest(h, n, &v) ? newSViv((IV)v) : &PL_sv_undef;
277             OUTPUT:
278             RETVAL
279              
280             SV *
281             read_seq(self, seq)
282             SV *self
283             UV seq
284             PREINIT:
285 5 50         EXTRACT_RING(self);
    50          
    50          
286             CODE:
287             int64_t v;
288 5 100         RETVAL = ring_read_seq(h, seq, &v) ? newSViv((IV)v) : &PL_sv_undef;
289             OUTPUT:
290             RETVAL
291              
292              
293             MODULE = Data::RingBuffer::Shared PACKAGE = Data::RingBuffer::Shared::F64
294              
295             PROTOTYPES: DISABLE
296              
297             SV *
298             new(class, path, capacity)
299             const char *class
300             SV *path
301             UV capacity
302             PREINIT:
303             char errbuf[RING_ERR_BUFLEN];
304             CODE:
305 1 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
306 1           RingHandle *h = ring_create(p, capacity, sizeof(double), RING_VAR_F64, errbuf);
307 1 50         if (!h) croak("Data::RingBuffer::Shared::F64->new: %s", errbuf);
308 1           MAKE_OBJ(class, h);
309             OUTPUT:
310             RETVAL
311              
312             SV *
313             new_memfd(class, name, capacity)
314             const char *class
315             const char *name
316             UV capacity
317             PREINIT:
318             char errbuf[RING_ERR_BUFLEN];
319             CODE:
320 0           RingHandle *h = ring_create_memfd(name, capacity, sizeof(double), RING_VAR_F64, errbuf);
321 0 0         if (!h) croak("Data::RingBuffer::Shared::F64->new_memfd: %s", errbuf);
322 0           MAKE_OBJ(class, h);
323             OUTPUT:
324             RETVAL
325              
326             SV *
327             new_from_fd(class, fd)
328             const char *class
329             int fd
330             PREINIT:
331             char errbuf[RING_ERR_BUFLEN];
332             CODE:
333 0           RingHandle *h = ring_open_fd(fd, RING_VAR_F64, errbuf);
334 0 0         if (!h) croak("Data::RingBuffer::Shared::F64->new_from_fd: %s", errbuf);
335 0           MAKE_OBJ(class, h);
336             OUTPUT:
337             RETVAL
338              
339             UV
340             write(self, val)
341             SV *self
342             NV val
343             PREINIT:
344 2 50         EXTRACT_RING(self);
    50          
    50          
345             CODE:
346 2           double v = (double)val;
347 2           RETVAL = (UV)ring_write(h, &v, sizeof(v));
348             OUTPUT:
349             RETVAL
350              
351             SV *
352             latest(self, ...)
353             SV *self
354             PREINIT:
355 2 50         EXTRACT_RING(self);
    50          
    50          
356             CODE:
357 2 100         uint32_t n = (items > 1) ? (uint32_t)SvUV(ST(1)) : 0;
358             double v;
359 2 50         RETVAL = ring_read_latest(h, n, &v) ? newSVnv(v) : &PL_sv_undef;
360             OUTPUT:
361             RETVAL
362              
363             SV *
364             read_seq(self, seq)
365             SV *self
366             UV seq
367             PREINIT:
368 0 0         EXTRACT_RING(self);
    0          
    0          
369             CODE:
370             double v;
371 0 0         RETVAL = ring_read_seq(h, seq, &v) ? newSVnv(v) : &PL_sv_undef;
372             OUTPUT:
373             RETVAL