Branch Coverage

deque.h
Criterion Covered Total %
branch 152 288 52.7


line true false branch
116 1 6 if (dl->tv_nsec >= 1000000000L) { dl->tv_sec++; dl->tv_nsec -= 1000000000L; }
124 3720 15367 if (rem->tv_nsec < 0) { rem->tv_sec--; rem->tv_nsec += 1000000000L; }
155 127 0 if (DEQ_SLOT_STATE(c) == DEQ_SLOT_EMPTY) {
157 127 0 if (__atomic_compare_exchange_n(ctl_word, &c, nc,
185 18066 0 if (DEQ_SLOT_STATE(c) == DEQ_SLOT_FILLED) {
187 18066 0 if (__atomic_compare_exchange_n(ctl_word, &c, nc,
214 5 117 if ((uint32_t)(t - hd) >= cap) return 0;
216 117 0 if (__atomic_compare_exchange_n(&hdr->cursor, &c, nc,
223 0 117 if (cp < sz) memset(deq_slot(h, t) + cp, 0, sz - cp);
228 0 117 if (__atomic_load_n(&hdr->waiters_pop, __ATOMIC_RELAXED) > 0) {
247 5 10 if ((uint32_t)(t - hd) >= cap) return 0;
250 10 0 if (__atomic_compare_exchange_n(&hdr->cursor, &c, nc,
257 0 10 if (cp < sz) memset(deq_slot(h, new_hd) + cp, 0, sz - cp);
262 0 10 if (__atomic_load_n(&hdr->waiters_pop, __ATOMIC_RELAXED) > 0) {
281 6 18056 if ((uint32_t)(t - hd) == 0) return 0;
283 18056 0 if (__atomic_compare_exchange_n(&hdr->cursor, &c, nc,
292 0 18056 if (__atomic_load_n(&hdr->waiters_push, __ATOMIC_RELAXED) > 0) {
311 4 10 if ((uint32_t)(t - hd) == 0) return 0;
313 10 0 if (__atomic_compare_exchange_n(&hdr->cursor, &c, nc,
322 0 10 if (__atomic_load_n(&hdr->waiters_push, __ATOMIC_RELAXED) > 0) {
338 1 1 front ? deq_try_push_front : deq_try_push_back;
339 0 2 if (try_fn(h, val, vlen)) return 1;
340 0 2 if (timeout == 0) return 0;
345 2 0 if (has_dl) deq_make_deadline(timeout, &dl);
356 2 0 if (DEQ_CURSOR_SIZE(c) >= cap) {
358 2 0 if (has_dl) {
359 0 2 if (!deq_remaining(&dl, &rem)) {
369 0 2 if (try_fn(h, val, vlen)) return 1;
370 2 0 if (has_dl && !deq_remaining(&dl, &rem)) {
2 0 if (has_dl && !deq_remaining(&dl, &rem)) {
379 1 2 back ? deq_try_pop_back : deq_try_pop_front;
380 0 3 if (try_fn(h, out)) return 1;
381 0 3 if (timeout == 0) return 0;
386 3 0 if (has_dl) deq_make_deadline(timeout, &dl);
396 3 0 if (DEQ_CURSOR_SIZE(c) == 0) {
398 3 0 if (has_dl) {
399 0 3 if (!deq_remaining(&dl, &rem)) {
409 1 2 if (try_fn(h, out)) return 1;
410 2 0 if (has_dl && !deq_remaining(&dl, &rem)) {
2 0 if (has_dl && !deq_remaining(&dl, &rem)) {
457 0 20 if (!h) { munmap(base, ms); return NULL; }
463 7 13 h->path = path ? strdup(path) : NULL;
472 1 5 if (hdr->magic != DEQ_MAGIC) return 0;
473 0 5 if (hdr->version != DEQ_VERSION) return 0;
474 0 5 if (hdr->variant_id != expected_variant) return 0;
475 5 0 if (hdr->elem_size == 0 || hdr->capacity == 0) return 0;
0 5 if (hdr->elem_size == 0 || hdr->capacity == 0) return 0;
476 0 5 if (hdr->capacity > 0x80000000u) return 0;
481 3 2 if (expected_variant == DEQ_VAR_INT && hdr->elem_size != sizeof(int64_t))
1 2 if (expected_variant == DEQ_VAR_INT && hdr->elem_size != sizeof(int64_t))
483 2 2 if (expected_variant == DEQ_VAR_STR && hdr->elem_size < sizeof(uint32_t) + 1)
1 1 if (expected_variant == DEQ_VAR_STR && hdr->elem_size < sizeof(uint32_t) + 1)
485 0 3 if (hdr->total_size != file_size) return 0;
486 0 3 if (hdr->data_off != sizeof(DeqHeader)) return 0;
487 0 3 if (hdr->ctl_off != deq_ctl_offset(hdr->elem_size, hdr->capacity)) return 0;
488 0 3 if (hdr->total_size != deq_total_size(hdr->elem_size, hdr->capacity)) return 0;
496 1 21 if (n <= 1) return 1;
509 10 0 for (int attempt = 0; attempt < 100; attempt++) {
511 5 5 if (fd >= 0) { (void)fchmod(fd, mode); return fd; } /* exact mode: umask narrowed the O_EXCL create */
512 0 5 if (errno != EEXIST) { DEQ_ERR("create %s: %s", path, strerror(errno)); return -1; }
0 0 if (errno != EEXIST) { DEQ_ERR("create %s: %s", path, strerror(errno)); return -1; }
514 5 0 if (fd >= 0) return fd;
515 0 0 if (errno == ENOENT) continue; /* creator unlinked between our two opens; retry */
516 0 0 DEQ_ERR("open %s: %s", path, strerror(errno)); /* ELOOP => symlink rejected */
519 0 0 DEQ_ERR("open %s: create/attach kept racing", path);
526 21 0 if (errbuf) errbuf[0] = '\0';
527 0 21 if (capacity == 0) { DEQ_ERR("capacity must be > 0"); return NULL; }
0 0 if (capacity == 0) { DEQ_ERR("capacity must be > 0"); return NULL; }
528 0 21 if (elem_size == 0) { DEQ_ERR("elem_size must be > 0"); return NULL; }
0 0 if (elem_size == 0) { DEQ_ERR("elem_size must be > 0"); return NULL; }
530 21 0 if (capacity == 0 || capacity > 0x80000000u) {
0 21 if (capacity == 0 || capacity > 0x80000000u) {
531 0 0 DEQ_ERR("capacity must be <= 2^31 (32-bit cursor halves)"); return NULL;
540 11 10 if (anonymous) {
543 0 11 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); return NULL; }
0 0 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); return NULL; }
546 0 10 if (fd < 0) return NULL;
547 0 10 if (flock(fd, LOCK_EX) < 0) { DEQ_ERR("flock: %s", strerror(errno)); close(fd); return NULL; }
0 0 if (flock(fd, LOCK_EX) < 0) { DEQ_ERR("flock: %s", strerror(errno)); close(fd); return NULL; }
549 0 10 if (fstat(fd, &st) < 0) {
550 0 0 DEQ_ERR("fstat: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL;
553 5 5 if (!is_new && (uint64_t)st.st_size < sizeof(DeqHeader)) {
0 5 if (!is_new && (uint64_t)st.st_size < sizeof(DeqHeader)) {
554 0 0 DEQ_ERR("%s: file too small (%lld)", path, (long long)st.st_size);
557 5 5 if (is_new && ftruncate(fd, (off_t)total) < 0) {
0 5 if (is_new && ftruncate(fd, (off_t)total) < 0) {
558 0 0 DEQ_ERR("ftruncate: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL;
560 5 5 map_size = is_new ? (size_t)total : (size_t)st.st_size;
562 0 10 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; }
0 0 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; }
563 5 5 if (!is_new) {
566 3 2 if (!deq_validate_header(&snap, (uint64_t)st.st_size, variant_id)) {
567 3 0 DEQ_ERR("invalid deque file"); munmap(base, map_size); flock(fd, LOCK_UN); close(fd); return NULL;
575 5 11 if (fd >= 0) { flock(fd, LOCK_UN); close(fd); }
584 1 0 if (errbuf) errbuf[0] = '\0';
585 0 1 if (capacity == 0) { DEQ_ERR("capacity must be > 0"); return NULL; }
0 0 if (capacity == 0) { DEQ_ERR("capacity must be > 0"); return NULL; }
586 0 1 if (elem_size == 0) { DEQ_ERR("elem_size must be > 0"); return NULL; }
0 0 if (elem_size == 0) { DEQ_ERR("elem_size must be > 0"); return NULL; }
588 1 0 if (capacity == 0 || capacity > 0x80000000u) {
0 1 if (capacity == 0 || capacity > 0x80000000u) {
589 0 0 DEQ_ERR("capacity must be <= 2^31 (32-bit cursor halves)"); return NULL;
592 1 0 int fd = memfd_create(name ? name : "deque", MFD_CLOEXEC | MFD_ALLOW_SEALING);
593 0 1 if (fd < 0) { DEQ_ERR("memfd_create: %s", strerror(errno)); return NULL; }
0 0 if (fd < 0) { DEQ_ERR("memfd_create: %s", strerror(errno)); return NULL; }
594 0 1 if (ftruncate(fd, (off_t)total) < 0) { DEQ_ERR("ftruncate: %s", strerror(errno)); close(fd); return NULL; }
0 0 if (ftruncate(fd, (off_t)total) < 0) { DEQ_ERR("ftruncate: %s", strerror(errno)); close(fd); return NULL; }
597 0 1 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); close(fd); return NULL; }
0 0 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); close(fd); return NULL; }
605 1 0 if (errbuf) errbuf[0] = '\0';
607 0 1 if (fstat(fd, &st) < 0) { DEQ_ERR("fstat: %s", strerror(errno)); return NULL; }
0 0 if (fstat(fd, &st) < 0) { DEQ_ERR("fstat: %s", strerror(errno)); return NULL; }
608 0 1 if ((uint64_t)st.st_size < sizeof(DeqHeader)) { DEQ_ERR("too small"); return NULL; }
0 0 if ((uint64_t)st.st_size < sizeof(DeqHeader)) { DEQ_ERR("too small"); return NULL; }
611 0 1 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); return NULL; }
0 0 if (base == MAP_FAILED) { DEQ_ERR("mmap: %s", strerror(errno)); return NULL; }
614 0 1 if (!deq_validate_header(&snap, (uint64_t)st.st_size, variant_id)) {
615 0 0 DEQ_ERR("invalid deque"); munmap(base, ms); return NULL;
618 0 1 if (myfd < 0) { DEQ_ERR("fcntl: %s", strerror(errno)); munmap(base, ms); return NULL; }
0 0 if (myfd < 0) { DEQ_ERR("fcntl: %s", strerror(errno)); munmap(base, ms); return NULL; }
624 0 20 if (!h) return;
625 2 18 if (h->notify_fd >= 0) close(h->notify_fd);
626 2 18 if (h->backing_fd >= 0) close(h->backing_fd);
627 20 0 if (h->hdr) munmap(h->hdr, h->mmap_size);
642 0 3 if (__atomic_load_n(&h->hdr->waiters_push, __ATOMIC_RELAXED) > 0) {
648 0 3 if (__atomic_load_n(&h->hdr->waiters_pop, __ATOMIC_RELAXED) > 0) {
683 13 4 while (drained < target) {
686 0 13 if ((uint32_t)(t - hd) == 0) break; /* emptied by a concurrent consumer */
688 0 13 if (!__atomic_compare_exchange_n(&hdr->cursor, &c, nc,
700 11 1220992 if (DEQ_SLOT_STATE(cw) == DEQ_SLOT_FILLED) {
702 11 0 if (__atomic_compare_exchange_n(ctl_word, &cw, nw,
712 19078 1201914 if ((++spins & 0x3F) == 0) {
713 2 19076 if (!dl_set) { deq_make_deadline((double)DEQ_DRAIN_RECOVERY_SEC, &dl); dl_set = 1; }
715 2 19076 if (!deq_remaining(&dl, &rem)) {
717 2 0 if (__atomic_compare_exchange_n(ctl_word, &cw, nw,
725 2 11 if (recovered) __atomic_add_fetch(&hdr->stat_recoveries, 1, __ATOMIC_RELAXED);
728 3 1 if (drained > 0) {
731 0 3 if (__atomic_load_n(&hdr->waiters_push, __ATOMIC_RELAXED) > 0) {
733 0 0 syscall(SYS_futex, &hdr->push_wake_seq, FUTEX_WAKE,
741 0 2 if (h->notify_fd >= 0) return h->notify_fd;
743 0 2 if (efd < 0) return -1;
747 0 2 if (h->notify_fd < 0) return 0;
751 0 2 if (h->notify_fd < 0) return -1;
753 0 2 if (read(h->notify_fd, &v, sizeof(v)) != sizeof(v)) return -1;