File Coverage

Shared.xs
Criterion Covered Total %
statement 86 93 92.4
branch 98 194 50.5
condition n/a
subroutine n/a
pod n/a
total 184 287 64.1


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 18 50         if (!SvROK(self)) return;
29 18           RingHandle *h = INT2PTR(RingHandle*, SvIV(SvRV(self)));
30 18 50         if (!h) return;
31 18           sv_setiv(SvRV(self), 0);
32 18           ring_destroy(h);
33              
34             UV
35             size(self)
36             SV *self
37             PREINIT:
38 9 50         EXTRACT_RING(self);
    50          
    50          
39             CODE:
40 9           RETVAL = (UV)ring_size(h);
41             OUTPUT:
42             RETVAL
43              
44             UV
45             capacity(self)
46             SV *self
47             PREINIT:
48 3 50         EXTRACT_RING(self);
    50          
    50          
49             CODE:
50 3 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 4 50         EXTRACT_RING(self);
    50          
    50          
69             CODE:
70 4 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 2 50         EXTRACT_RING(self);
    50          
    50          
120             CODE:
121 2           RETVAL = ring_create_eventfd(h);
122 2 50         if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
123             OUTPUT:
124             RETVAL
125              
126             void
127             eventfd_set(self, fd)
128             SV *self
129             int fd
130             PREINIT:
131 3 50         EXTRACT_RING(self);
    50          
    50          
132             CODE:
133 3 50         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    100          
134 3           h->notify_fd = fd;
135              
136             IV
137             fileno(self)
138             SV *self
139             PREINIT:
140 3 50         EXTRACT_RING(self);
    50          
    50          
141             CODE:
142 3 50         RETVAL = h->notify_fd;
143             OUTPUT:
144             RETVAL
145              
146             bool
147             notify(self)
148             SV *self
149             PREINIT:
150 2 50         EXTRACT_RING(self);
    50          
    50          
151             CODE:
152 2 50         RETVAL = ring_notify(h);
153             OUTPUT:
154             RETVAL
155              
156             SV *
157             eventfd_consume(self)
158             SV *self
159             PREINIT:
160 2 50         EXTRACT_RING(self);
    50          
    50          
161             CODE:
162 2           int64_t v = ring_eventfd_consume(h);
163 2 50         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
164             OUTPUT:
165             RETVAL
166              
167             void
168             sync(self)
169             SV *self
170             PREINIT:
171 1 50         EXTRACT_RING(self);
    50          
    50          
172             CODE:
173 1 50         if (ring_msync(h) != 0) croak("msync: %s", strerror(errno));
174              
175             void
176             unlink(self_or_class, ...)
177             SV *self_or_class
178             CODE:
179             const char *p;
180 1 50         if (sv_isobject(self_or_class)) {
181 1           RingHandle *h = INT2PTR(RingHandle*, SvIV(SvRV(self_or_class)));
182 1 50         if (!h) croak("Attempted to use a destroyed object");
183 1           p = h->path;
184             } else {
185 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
186 0           p = SvPV_nolen(ST(1));
187             }
188 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
189 1 50         if (unlink(p) != 0) croak("unlink(%s): %s", p, strerror(errno));
190              
191             SV *
192             stats(self)
193             SV *self
194             PREINIT:
195 3 50         EXTRACT_RING(self);
    50          
    50          
196             CODE:
197 3           HV *hv = newHV();
198 3           RingHeader *hdr = h->hdr;
199 3           hv_store(hv, "size", 4, newSVuv((UV)ring_size(h)), 0);
200 3           hv_store(hv, "capacity", 8, newSVuv((UV)hdr->capacity), 0);
201 3           hv_store(hv, "head", 4, newSVuv((UV)ring_head(h)), 0);
202 3           hv_store(hv, "count", 5, newSVuv((UV)__atomic_load_n(&hdr->count, __ATOMIC_ACQUIRE)), 0);
203 3           hv_store(hv, "writes", 6, newSVuv((UV)__atomic_load_n(&hdr->stat_writes, __ATOMIC_RELAXED)), 0);
204 3           hv_store(hv, "overwrites", 10, newSVuv((UV)__atomic_load_n(&hdr->stat_overwrites, __ATOMIC_RELAXED)), 0);
205 3           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
206 3           RETVAL = newRV_noinc((SV *)hv);
207             OUTPUT:
208             RETVAL
209              
210              
211             MODULE = Data::RingBuffer::Shared PACKAGE = Data::RingBuffer::Shared::Int
212              
213             PROTOTYPES: DISABLE
214              
215             SV *
216             new(class, path, capacity)
217             const char *class
218             SV *path
219             UV capacity
220             PREINIT:
221             char errbuf[RING_ERR_BUFLEN];
222             CODE:
223 8 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
224 8           RingHandle *h = ring_create(p, capacity, sizeof(int64_t), RING_VAR_INT, errbuf);
225 8 50         if (!h) croak("Data::RingBuffer::Shared::Int->new: %s", errbuf);
226 8           MAKE_OBJ(class, h);
227             OUTPUT:
228             RETVAL
229              
230             SV *
231             new_memfd(class, name, capacity)
232             const char *class
233             const char *name
234             UV capacity
235             PREINIT:
236             char errbuf[RING_ERR_BUFLEN];
237             CODE:
238 6           RingHandle *h = ring_create_memfd(name, capacity, sizeof(int64_t), RING_VAR_INT, errbuf);
239 6 50         if (!h) croak("Data::RingBuffer::Shared::Int->new_memfd: %s", errbuf);
240 6           MAKE_OBJ(class, h);
241             OUTPUT:
242             RETVAL
243              
244             SV *
245             new_from_fd(class, fd)
246             const char *class
247             int fd
248             PREINIT:
249             char errbuf[RING_ERR_BUFLEN];
250             CODE:
251 1           RingHandle *h = ring_open_fd(fd, RING_VAR_INT, errbuf);
252 1 50         if (!h) croak("Data::RingBuffer::Shared::Int->new_from_fd: %s", errbuf);
253 1           MAKE_OBJ(class, h);
254             OUTPUT:
255             RETVAL
256              
257             UV
258             write(self, val)
259             SV *self
260             IV val
261             PREINIT:
262 100 50         EXTRACT_RING(self);
    50          
    50          
263             CODE:
264 100           int64_t v = (int64_t)val;
265 100           RETVAL = (UV)ring_write(h, &v, sizeof(v));
266             OUTPUT:
267             RETVAL
268              
269             SV *
270             latest(self, ...)
271             SV *self
272             PREINIT:
273 44 50         EXTRACT_RING(self);
    50          
    50          
274             CODE:
275 44 100         uint32_t n = (items > 1) ? (uint32_t)SvUV(ST(1)) : 0;
276             int64_t v;
277 44 100         RETVAL = ring_read_latest(h, n, &v) ? newSViv((IV)v) : &PL_sv_undef;
278             OUTPUT:
279             RETVAL
280              
281             SV *
282             read_seq(self, seq)
283             SV *self
284             UV seq
285             PREINIT:
286 5 50         EXTRACT_RING(self);
    50          
    50          
287             CODE:
288             int64_t v;
289 5 100         RETVAL = ring_read_seq(h, seq, &v) ? newSViv((IV)v) : &PL_sv_undef;
290             OUTPUT:
291             RETVAL
292              
293              
294             MODULE = Data::RingBuffer::Shared PACKAGE = Data::RingBuffer::Shared::F64
295              
296             PROTOTYPES: DISABLE
297              
298             SV *
299             new(class, path, capacity)
300             const char *class
301             SV *path
302             UV capacity
303             PREINIT:
304             char errbuf[RING_ERR_BUFLEN];
305             CODE:
306 2 50         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
307 2           RingHandle *h = ring_create(p, capacity, sizeof(double), RING_VAR_F64, errbuf);
308 2 50         if (!h) croak("Data::RingBuffer::Shared::F64->new: %s", errbuf);
309 2           MAKE_OBJ(class, h);
310             OUTPUT:
311             RETVAL
312              
313             SV *
314             new_memfd(class, name, capacity)
315             const char *class
316             const char *name
317             UV capacity
318             PREINIT:
319             char errbuf[RING_ERR_BUFLEN];
320             CODE:
321 1           RingHandle *h = ring_create_memfd(name, capacity, sizeof(double), RING_VAR_F64, errbuf);
322 1 50         if (!h) croak("Data::RingBuffer::Shared::F64->new_memfd: %s", errbuf);
323 1           MAKE_OBJ(class, h);
324             OUTPUT:
325             RETVAL
326              
327             SV *
328             new_from_fd(class, fd)
329             const char *class
330             int fd
331             PREINIT:
332             char errbuf[RING_ERR_BUFLEN];
333             CODE:
334 0           RingHandle *h = ring_open_fd(fd, RING_VAR_F64, errbuf);
335 0 0         if (!h) croak("Data::RingBuffer::Shared::F64->new_from_fd: %s", errbuf);
336 0           MAKE_OBJ(class, h);
337             OUTPUT:
338             RETVAL
339              
340             UV
341             write(self, val)
342             SV *self
343             NV val
344             PREINIT:
345 8 50         EXTRACT_RING(self);
    50          
    50          
346             CODE:
347 8           double v = (double)val;
348 8           RETVAL = (UV)ring_write(h, &v, sizeof(v));
349             OUTPUT:
350             RETVAL
351              
352             SV *
353             latest(self, ...)
354             SV *self
355             PREINIT:
356 12 50         EXTRACT_RING(self);
    50          
    50          
357             CODE:
358 12 100         uint32_t n = (items > 1) ? (uint32_t)SvUV(ST(1)) : 0;
359             double v;
360 12 50         RETVAL = ring_read_latest(h, n, &v) ? newSVnv(v) : &PL_sv_undef;
361             OUTPUT:
362             RETVAL
363              
364             SV *
365             read_seq(self, seq)
366             SV *self
367             UV seq
368             PREINIT:
369 0 0         EXTRACT_RING(self);
    0          
    0          
370             CODE:
371             double v;
372 0 0         RETVAL = ring_read_seq(h, seq, &v) ? newSVnv(v) : &PL_sv_undef;
373             OUTPUT:
374             RETVAL