Branch Coverage

pool.h
Criterion Covered Total %
branch 144 284 50.7


line true false branch
107 0 22 if (pid == 0) return 1;
108 21 1 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
0 21 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
115 0 2 if (deadline->tv_nsec >= 1000000000L) {
127 2 1 if (remaining->tv_nsec < 0) {
159 955 16 for (uint32_t i = 0; i < nwords; i++) {
163 944 11 while (word != ~(uint64_t)0) {
166 17 927 if (slot >= cap) break;
169 927 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
176 10 1 h->scan_hint = (new_word == ~(uint64_t)0 && nwords > 1)
177 11 916 ? (widx + 1) % nwords : widx;
198 919 3 if (slot >= 0) return slot;
199 1 2 if (timeout == 0) return -1;
204 2 0 if (has_deadline) pool_make_deadline(timeout, &deadline);
210 0 2 if ((uint64_t)cur_used < hdr->capacity) {
212 0 0 if (slot >= 0) return slot;
218 2 0 if ((uint64_t)cur_used >= hdr->capacity) {
220 2 0 if (has_deadline) {
221 0 2 if (!pool_remaining_time(&deadline, &remaining)) {
234 1 1 if (slot >= 0) return slot;
236 1 0 if (has_deadline) {
237 1 0 if (!pool_remaining_time(&deadline, &remaining)) {
251 0 691 if (slot >= hdr->capacity) return 0;
259 2 689 if (!(word & mask)) return 0;
262 689 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
267 0 689 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
282 7 3 for (uint32_t i = 0; i < count; i++) {
284 0 7 if (slot >= hdr->capacity) continue;
292 0 7 if (!(word & mask)) break;
294 7 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
303 3 0 if (freed > 0) {
306 0 3 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) {
307 0 0 int wake = freed < (uint32_t)INT_MAX ? (int)freed : INT_MAX;
320 0 2 if (count == 0) return 1;
322 1 1 if (timeout == 0) {
323 2 0 for (uint32_t i = 0; i < count; i++) {
325 1 1 if (slot < 0) {
326 1 0 if (i > 0) pool_free_n(h, out, i);
336 0 1 if (has_deadline) pool_make_deadline(timeout, &deadline);
338 3 1 for (uint32_t i = 0; i < count; i++) {
340 0 3 if (has_deadline) {
341 0 0 if (!pool_remaining_time(&deadline, &remaining)) {
343 0 0 if (i > 0) pool_free_n(h, out, i);
349 0 3 if (slot < 0) {
350 0 0 if (i > 0) pool_free_n(h, out, i);
366 264 3 for (uint64_t slot = 0; slot < cap; slot++) {
367 242 22 if (!pool_is_allocated(h, slot)) continue;
369 22 0 if (owner == 0 || pool_pid_alive(owner)) continue;
1 21 if (owner == 0 || pool_pid_alive(owner)) continue;
373 0 21 if (!__atomic_compare_exchange_n(&h->owners[slot], &owner, 0,
398 0 21 if (!(word & mask)) break;
401 0 21 if (__atomic_load_n(&h->owners[slot], __ATOMIC_ACQUIRE) != 0)
405 21 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
410 0 21 if (__atomic_load_n(&h->owners[slot], __ATOMIC_ACQUIRE) != 0)
418 21 0 while (cur > 0 && !__atomic_compare_exchange_n(&h->hdr->used,
419 0 21 &cur, cur - 1, 1, __ATOMIC_RELEASE, __ATOMIC_RELAXED))
422 0 21 if (__atomic_load_n(&h->hdr->waiters, __ATOMIC_RELAXED) > 0)
430 2 1 if (recovered > 0)
488 0 7 if (hdr->magic != POOL_MAGIC) return 0;
489 0 7 if (hdr->version != POOL_VERSION) return 0;
490 0 7 if (hdr->variant_id != expected_variant) return 0;
491 7 0 if (hdr->capacity == 0 || hdr->capacity > POOL_MAX_CAPACITY) return 0;
0 7 if (hdr->capacity == 0 || hdr->capacity > POOL_MAX_CAPACITY) return 0;
492 0 7 if (hdr->elem_size == 0) return 0;
493 0 7 if (hdr->capacity > (UINT64_MAX - sizeof(PoolHeader)) / hdr->elem_size) return 0;
494 0 7 if (hdr->total_size != file_size) return 0;
499 0 7 if (hdr->bitmap_off != bm_off) return 0;
500 0 7 if (hdr->owners_off != own_off) return 0;
501 0 7 if (hdr->data_off != dat_off) return 0;
502 0 7 if (hdr->total_size != total) return 0;
510 0 58 if (!h) { munmap(base, map_size); return NULL; }
518 12 46 h->path = path ? strdup(path) : NULL;
529 47 0 if (errbuf) errbuf[0] = '\0';
531 0 47 if (capacity == 0) { POOL_ERR("capacity must be > 0"); return NULL; }
0 0 if (capacity == 0) { POOL_ERR("capacity must be > 0"); return NULL; }
532 0 47 if (elem_size == 0) { POOL_ERR("elem_size must be > 0"); return NULL; }
0 0 if (elem_size == 0) { POOL_ERR("elem_size must be > 0"); return NULL; }
533 0 47 if (capacity > POOL_MAX_CAPACITY) { POOL_ERR("capacity too large"); return NULL; }
0 0 if (capacity > POOL_MAX_CAPACITY) { POOL_ERR("capacity too large"); return NULL; }
534 0 47 if (capacity > (UINT64_MAX - sizeof(PoolHeader)) / elem_size) {
535 0 0 POOL_ERR("capacity * elem_size overflow"); return NULL;
546 35 12 if (anonymous) {
550 0 35 if (base == MAP_FAILED) {
551 0 0 POOL_ERR("mmap(anonymous): %s", strerror(errno));
556 0 12 if (fd < 0) { POOL_ERR("open(%s): %s", path, strerror(errno)); return NULL; }
0 0 if (fd < 0) { POOL_ERR("open(%s): %s", path, strerror(errno)); return NULL; }
558 0 12 if (flock(fd, LOCK_EX) < 0) {
559 0 0 POOL_ERR("flock(%s): %s", path, strerror(errno));
564 0 12 if (fstat(fd, &st) < 0) {
565 0 0 POOL_ERR("fstat(%s): %s", path, strerror(errno));
571 2 10 if (!is_new && (uint64_t)st.st_size < sizeof(PoolHeader)) {
0 2 if (!is_new && (uint64_t)st.st_size < sizeof(PoolHeader)) {
572 0 0 POOL_ERR("%s: file too small (%lld)", path, (long long)st.st_size);
576 10 2 if (is_new) {
577 0 10 if (ftruncate(fd, (off_t)total) < 0) {
578 0 0 POOL_ERR("ftruncate(%s): %s", path, strerror(errno));
583 2 10 map_size = is_new ? (size_t)total : (size_t)st.st_size;
585 0 12 if (base == MAP_FAILED) {
586 0 0 POOL_ERR("mmap(%s): %s", path, strerror(errno));
590 2 10 if (!is_new) {
591 0 2 if (!pool_validate_header((PoolHeader *)base, (uint64_t)st.st_size, variant_id)) {
592 0 0 POOL_ERR("%s: invalid or incompatible pool file", path);
605 10 35 if (fd >= 0) {
616 6 0 if (errbuf) errbuf[0] = '\0';
618 0 6 if (capacity == 0) { POOL_ERR("capacity must be > 0"); return NULL; }
0 0 if (capacity == 0) { POOL_ERR("capacity must be > 0"); return NULL; }
619 0 6 if (elem_size == 0) { POOL_ERR("elem_size must be > 0"); return NULL; }
0 0 if (elem_size == 0) { POOL_ERR("elem_size must be > 0"); return NULL; }
620 0 6 if (capacity > POOL_MAX_CAPACITY) { POOL_ERR("capacity too large"); return NULL; }
0 0 if (capacity > POOL_MAX_CAPACITY) { POOL_ERR("capacity too large"); return NULL; }
621 0 6 if (capacity > (UINT64_MAX - sizeof(PoolHeader)) / elem_size) {
622 0 0 POOL_ERR("capacity * elem_size overflow"); return NULL;
628 6 0 int fd = memfd_create(name ? name : "pool", MFD_CLOEXEC | MFD_ALLOW_SEALING);
629 0 6 if (fd < 0) { POOL_ERR("memfd_create: %s", strerror(errno)); return NULL; }
0 0 if (fd < 0) { POOL_ERR("memfd_create: %s", strerror(errno)); return NULL; }
631 0 6 if (ftruncate(fd, (off_t)total) < 0) {
632 0 0 POOL_ERR("ftruncate(memfd): %s", strerror(errno));
641 0 6 if (base == MAP_FAILED) {
642 0 0 POOL_ERR("mmap(memfd): %s", strerror(errno));
653 5 0 if (errbuf) errbuf[0] = '\0';
656 0 5 if (fstat(fd, &st) < 0) {
657 0 0 POOL_ERR("fstat(fd=%d): %s", fd, strerror(errno));
661 0 5 if ((uint64_t)st.st_size < sizeof(PoolHeader)) {
662 0 0 POOL_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size);
668 0 5 if (base == MAP_FAILED) {
669 0 0 POOL_ERR("mmap(fd=%d): %s", fd, strerror(errno));
673 0 5 if (!pool_validate_header((PoolHeader *)base, (uint64_t)st.st_size, variant_id)) {
674 0 0 POOL_ERR("fd %d: invalid or incompatible pool", fd);
680 0 5 if (myfd < 0) {
681 0 0 POOL_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno));
690 0 58 if (!h) return;
691 2 56 if (h->notify_fd >= 0) close(h->notify_fd);
692 11 47 if (h->backing_fd >= 0) close(h->backing_fd);
693 58 0 if (h->hdr) munmap(h->hdr, h->mmap_size);
703 1 2 if (h->notify_fd >= 0) return h->notify_fd;
705 0 2 if (efd < 0) return -1;
711 0 4 if (h->notify_fd < 0) return 0;
717 0 4 if (h->notify_fd < 0) return -1;
719 1 3 if (read(h->notify_fd, &val, sizeof(val)) != sizeof(val)) return -1;
811 0 11 if (len > max_len) len = max_len;
822 2 6 if (len > max_len) len = max_len;
837 0 10 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)