File Coverage

Shared.xs
Criterion Covered Total %
statement 75 82 91.4
branch 80 170 47.0
condition n/a
subroutine n/a
pod n/a
total 155 252 61.5


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5             #include "ppport.h"
6             #include "heap.h"
7              
8             #define EXTRACT_HEAP(sv) \
9             if (!sv_isobject(sv) || !sv_derived_from(sv, "Data::Heap::Shared")) \
10             croak("Expected a Data::Heap::Shared object"); \
11             HeapHandle *h = INT2PTR(HeapHandle*, SvIV(SvRV(sv))); \
12             if (!h) croak("Attempted to use a destroyed Data::Heap::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::Heap::Shared PACKAGE = Data::Heap::Shared
21              
22             PROTOTYPES: DISABLE
23              
24             SV *
25             new(class, path, capacity)
26             const char *class
27             SV *path
28             UV capacity
29             PREINIT:
30             char errbuf[HEAP_ERR_BUFLEN];
31             CODE:
32 5 100         const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
33 5           HeapHandle *h = heap_create(p, capacity, errbuf);
34 5 50         if (!h) croak("Data::Heap::Shared->new: %s", errbuf);
35 5           MAKE_OBJ(class, h);
36             OUTPUT:
37             RETVAL
38              
39             SV *
40             new_memfd(class, name, capacity)
41             const char *class
42             const char *name
43             UV capacity
44             PREINIT:
45             char errbuf[HEAP_ERR_BUFLEN];
46             CODE:
47 1           HeapHandle *h = heap_create_memfd(name, capacity, errbuf);
48 1 50         if (!h) croak("Data::Heap::Shared->new_memfd: %s", errbuf);
49 1           MAKE_OBJ(class, h);
50             OUTPUT:
51             RETVAL
52              
53             SV *
54             new_from_fd(class, fd)
55             const char *class
56             int fd
57             PREINIT:
58             char errbuf[HEAP_ERR_BUFLEN];
59             CODE:
60 1           HeapHandle *h = heap_open_fd(fd, errbuf);
61 1 50         if (!h) croak("Data::Heap::Shared->new_from_fd: %s", errbuf);
62 1           MAKE_OBJ(class, h);
63             OUTPUT:
64             RETVAL
65              
66             void
67             DESTROY(self)
68             SV *self
69             CODE:
70 7 50         if (!SvROK(self)) return;
71 7           HeapHandle *h = INT2PTR(HeapHandle*, SvIV(SvRV(self)));
72 7 50         if (!h) return;
73 7           sv_setiv(SvRV(self), 0);
74 7           heap_destroy(h);
75              
76             bool
77             push(self, priority, value)
78             SV *self
79             IV priority
80             IV value
81             PREINIT:
82 27 50         EXTRACT_HEAP(self);
    50          
    50          
83             CODE:
84 27 100         RETVAL = heap_push(h, (int64_t)priority, (int64_t)value);
85             OUTPUT:
86             RETVAL
87              
88             void
89             pop(self)
90             SV *self
91             PREINIT:
92 11 50         EXTRACT_HEAP(self);
    50          
    50          
93             PPCODE:
94             int64_t p, v;
95 11 100         if (heap_pop(h, &p, &v)) {
96 10 50         EXTEND(SP, 2);
97 10           PUSHs(sv_2mortal(newSViv((IV)p)));
98 10           PUSHs(sv_2mortal(newSViv((IV)v)));
99             }
100              
101             void
102             pop_wait(self, ...)
103             SV *self
104             PREINIT:
105 2 50         EXTRACT_HEAP(self);
    50          
    50          
106 2           double timeout = -1;
107             PPCODE:
108 2 50         if (items > 1) timeout = SvNV(ST(1));
109             int64_t p, v;
110 2 100         if (heap_pop_wait(h, &p, &v, timeout)) {
111 1 50         EXTEND(SP, 2);
112 1           PUSHs(sv_2mortal(newSViv((IV)p)));
113 1           PUSHs(sv_2mortal(newSViv((IV)v)));
114             }
115              
116             void
117             peek(self)
118             SV *self
119             PREINIT:
120 1 50         EXTRACT_HEAP(self);
    50          
    50          
121             PPCODE:
122             int64_t p, v;
123 1 50         if (heap_peek(h, &p, &v)) {
124 1 50         EXTEND(SP, 2);
125 1           PUSHs(sv_2mortal(newSViv((IV)p)));
126 1           PUSHs(sv_2mortal(newSViv((IV)v)));
127             }
128              
129             UV
130             size(self)
131             SV *self
132             PREINIT:
133 5 50         EXTRACT_HEAP(self);
    50          
    50          
134             CODE:
135 5 50         RETVAL = heap_size(h);
136             OUTPUT:
137             RETVAL
138              
139             UV
140             capacity(self)
141             SV *self
142             PREINIT:
143 0 0         EXTRACT_HEAP(self);
    0          
    0          
144             CODE:
145 0 0         RETVAL = (UV)h->hdr->capacity;
146             OUTPUT:
147             RETVAL
148              
149             bool
150             is_empty(self)
151             SV *self
152             PREINIT:
153 2 50         EXTRACT_HEAP(self);
    50          
    50          
154             CODE:
155 2 50         RETVAL = heap_size(h) == 0;
156             OUTPUT:
157             RETVAL
158              
159             bool
160             is_full(self)
161             SV *self
162             PREINIT:
163 1 50         EXTRACT_HEAP(self);
    50          
    50          
164             CODE:
165 1 50         RETVAL = heap_size(h) >= (UV)h->hdr->capacity;
166             OUTPUT:
167             RETVAL
168              
169             void
170             clear(self)
171             SV *self
172             PREINIT:
173 3 50         EXTRACT_HEAP(self);
    50          
    50          
174             CODE:
175 3           heap_clear(h);
176              
177             SV *
178             path(self)
179             SV *self
180             PREINIT:
181 2 50         EXTRACT_HEAP(self);
    50          
    50          
182             CODE:
183 2 100         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
184             OUTPUT:
185             RETVAL
186              
187             IV
188             memfd(self)
189             SV *self
190             PREINIT:
191 1 50         EXTRACT_HEAP(self);
    50          
    50          
192             CODE:
193 1 50         RETVAL = h->backing_fd;
194             OUTPUT:
195             RETVAL
196              
197             IV
198             eventfd(self)
199             SV *self
200             PREINIT:
201 1 50         EXTRACT_HEAP(self);
    50          
    50          
202             CODE:
203 1 50         RETVAL = heap_create_eventfd(h);
204             OUTPUT:
205             RETVAL
206              
207             void
208             eventfd_set(self, fd)
209             SV *self
210             int fd
211             PREINIT:
212 0 0         EXTRACT_HEAP(self);
    0          
    0          
213             CODE:
214 0 0         if (h->notify_fd >= 0 && h->notify_fd != fd) close(h->notify_fd);
    0          
215 0           h->notify_fd = fd;
216              
217             IV
218             fileno(self)
219             SV *self
220             PREINIT:
221 1 50         EXTRACT_HEAP(self);
    50          
    50          
222             CODE:
223 1 50         RETVAL = h->notify_fd;
224             OUTPUT:
225             RETVAL
226              
227             bool
228             notify(self)
229             SV *self
230             PREINIT:
231 1 50         EXTRACT_HEAP(self);
    50          
    50          
232             CODE:
233 1 50         RETVAL = heap_notify(h);
234             OUTPUT:
235             RETVAL
236              
237             SV *
238             eventfd_consume(self)
239             SV *self
240             PREINIT:
241 1 50         EXTRACT_HEAP(self);
    50          
    50          
242             CODE:
243 1           int64_t v = heap_eventfd_consume(h);
244 1 50         RETVAL = (v >= 0) ? newSViv((IV)v) : &PL_sv_undef;
245             OUTPUT:
246             RETVAL
247              
248             void
249             sync(self)
250             SV *self
251             PREINIT:
252 1 50         EXTRACT_HEAP(self);
    50          
    50          
253             CODE:
254 1           heap_msync(h);
255              
256             void
257             unlink(self_or_class, ...)
258             SV *self_or_class
259             CODE:
260             const char *p;
261 1 50         if (sv_isobject(self_or_class)) {
262 1           HeapHandle *h = INT2PTR(HeapHandle*, SvIV(SvRV(self_or_class)));
263 1 50         if (!h) croak("destroyed object");
264 1           p = h->path;
265             } else {
266 0 0         if (items < 2) croak("Usage: ...->unlink($path)");
267 0           p = SvPV_nolen(ST(1));
268             }
269 1 50         if (!p) croak("cannot unlink anonymous or memfd object");
270 1 50         if (unlink(p) != 0) croak("unlink(%s): %s", p, strerror(errno));
271              
272             SV *
273             stats(self)
274             SV *self
275             PREINIT:
276 1 50         EXTRACT_HEAP(self);
    50          
    50          
277             CODE:
278 1           HV *hv = newHV();
279 1           HeapHeader *hdr = h->hdr;
280 1           hv_store(hv, "size", 4, newSVuv(heap_size(h)), 0);
281 1           hv_store(hv, "capacity", 8, newSVuv((UV)hdr->capacity), 0);
282 1           hv_store(hv, "pushes", 6, newSVuv((UV)hdr->stat_pushes), 0);
283 1           hv_store(hv, "pops", 4, newSVuv((UV)hdr->stat_pops), 0);
284 1           hv_store(hv, "waits", 5, newSVuv((UV)hdr->stat_waits), 0);
285 1           hv_store(hv, "timeouts", 8, newSVuv((UV)hdr->stat_timeouts), 0);
286 1           hv_store(hv, "recoveries", 10, newSVuv(hdr->stat_recoveries), 0);
287 1           hv_store(hv, "mmap_size", 9, newSVuv((UV)h->mmap_size), 0);
288 1           RETVAL = newRV_noinc((SV *)hv);
289             OUTPUT:
290             RETVAL