Branch Coverage

pool.h
Criterion Covered Total %
branch 139 276 50.3


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 1 1 if (deadline->tv_nsec >= 1000000000L) {
127 3 0 if (remaining->tv_nsec < 0) {
159 944 16 for (uint32_t i = 0; i < nwords; i++) {
163 933 11 while (word != ~(uint64_t)0) {
166 17 916 if (slot >= cap) break;
169 916 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 905 ? (widx + 1) % nwords : widx;
189 908 3 if (slot >= 0) return slot;
190 1 2 if (timeout == 0) return -1;
195 2 0 if (has_deadline) pool_make_deadline(timeout, &deadline);
201 0 2 if (cur_used < (uint32_t)hdr->capacity) {
203 0 0 if (slot >= 0) return slot;
209 2 0 if (cur_used >= (uint32_t)hdr->capacity) {
211 2 0 if (has_deadline) {
212 0 2 if (!pool_remaining_time(&deadline, &remaining)) {
225 1 1 if (slot >= 0) return slot;
227 1 0 if (has_deadline) {
228 1 0 if (!pool_remaining_time(&deadline, &remaining)) {
242 0 691 if (slot >= hdr->capacity) return 0;
250 2 689 if (!(word & mask)) return 0;
253 689 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
258 0 689 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
273 7 3 for (uint32_t i = 0; i < count; i++) {
275 0 7 if (slot >= hdr->capacity) continue;
283 0 7 if (!(word & mask)) break;
285 7 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
294 3 0 if (freed > 0) {
297 0 3 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) {
298 0 0 int wake = freed < (uint32_t)INT_MAX ? (int)freed : INT_MAX;
311 0 2 if (count == 0) return 1;
313 1 1 if (timeout == 0) {
314 2 0 for (uint32_t i = 0; i < count; i++) {
316 1 1 if (slot < 0) {
317 1 0 if (i > 0) pool_free_n(h, out, i);
327 0 1 if (has_deadline) pool_make_deadline(timeout, &deadline);
329 3 1 for (uint32_t i = 0; i < count; i++) {
331 0 3 if (has_deadline) {
332 0 0 if (!pool_remaining_time(&deadline, &remaining)) {
334 0 0 if (i > 0) pool_free_n(h, out, i);
340 0 3 if (slot < 0) {
341 0 0 if (i > 0) pool_free_n(h, out, i);
357 200 2 for (uint64_t slot = 0; slot < cap; slot++) {
358 178 22 if (!pool_is_allocated(h, slot)) continue;
360 22 0 if (owner == 0 || pool_pid_alive(owner)) continue;
1 21 if (owner == 0 || pool_pid_alive(owner)) continue;
364 0 21 if (!__atomic_compare_exchange_n(&h->owners[slot], &owner, 0,
375 0 21 if (!(word & mask)) break;
377 21 0 if (__atomic_compare_exchange_n(&h->bitmap[widx], &word, new_word,
381 0 21 if (__atomic_load_n(&h->hdr->waiters, __ATOMIC_RELAXED) > 0)
389 2 0 if (recovered > 0)
447 0 7 if (hdr->magic != POOL_MAGIC) return 0;
448 0 7 if (hdr->version != POOL_VERSION) return 0;
449 0 7 if (hdr->variant_id != expected_variant) return 0;
450 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;
451 0 7 if (hdr->elem_size == 0) return 0;
452 0 7 if (hdr->capacity > (UINT64_MAX - sizeof(PoolHeader)) / hdr->elem_size) return 0;
453 0 7 if (hdr->total_size != file_size) return 0;
458 0 7 if (hdr->bitmap_off != bm_off) return 0;
459 0 7 if (hdr->owners_off != own_off) return 0;
460 0 7 if (hdr->data_off != dat_off) return 0;
461 0 7 if (hdr->total_size != total) return 0;
469 0 49 if (!h) { munmap(base, map_size); return NULL; }
477 11 38 h->path = path ? strdup(path) : NULL;
488 38 0 if (errbuf) errbuf[0] = '\0';
490 0 38 if (capacity == 0) { POOL_ERR("capacity must be > 0"); return NULL; }
0 0 if (capacity == 0) { POOL_ERR("capacity must be > 0"); return NULL; }
491 0 38 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; }
492 0 38 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; }
493 0 38 if (capacity > (UINT64_MAX - sizeof(PoolHeader)) / elem_size) {
494 0 0 POOL_ERR("capacity * elem_size overflow"); return NULL;
505 27 11 if (anonymous) {
509 0 27 if (base == MAP_FAILED) {
510 0 0 POOL_ERR("mmap(anonymous): %s", strerror(errno));
515 0 11 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; }
517 0 11 if (flock(fd, LOCK_EX) < 0) {
518 0 0 POOL_ERR("flock(%s): %s", path, strerror(errno));
523 0 11 if (fstat(fd, &st) < 0) {
524 0 0 POOL_ERR("fstat(%s): %s", path, strerror(errno));
530 2 9 if (!is_new && (uint64_t)st.st_size < sizeof(PoolHeader)) {
0 2 if (!is_new && (uint64_t)st.st_size < sizeof(PoolHeader)) {
531 0 0 POOL_ERR("%s: file too small (%lld)", path, (long long)st.st_size);
535 9 2 if (is_new) {
536 0 9 if (ftruncate(fd, (off_t)total) < 0) {
537 0 0 POOL_ERR("ftruncate(%s): %s", path, strerror(errno));
542 2 9 map_size = is_new ? (size_t)total : (size_t)st.st_size;
544 0 11 if (base == MAP_FAILED) {
545 0 0 POOL_ERR("mmap(%s): %s", path, strerror(errno));
549 2 9 if (!is_new) {
550 0 2 if (!pool_validate_header((PoolHeader *)base, (uint64_t)st.st_size, variant_id)) {
551 0 0 POOL_ERR("%s: invalid or incompatible pool file", path);
564 9 27 if (fd >= 0) {
575 6 0 if (errbuf) errbuf[0] = '\0';
577 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; }
578 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; }
579 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; }
580 0 6 if (capacity > (UINT64_MAX - sizeof(PoolHeader)) / elem_size) {
581 0 0 POOL_ERR("capacity * elem_size overflow"); return NULL;
587 6 0 int fd = memfd_create(name ? name : "pool", MFD_CLOEXEC | MFD_ALLOW_SEALING);
588 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; }
590 0 6 if (ftruncate(fd, (off_t)total) < 0) {
591 0 0 POOL_ERR("ftruncate(memfd): %s", strerror(errno));
600 0 6 if (base == MAP_FAILED) {
601 0 0 POOL_ERR("mmap(memfd): %s", strerror(errno));
612 5 0 if (errbuf) errbuf[0] = '\0';
615 0 5 if (fstat(fd, &st) < 0) {
616 0 0 POOL_ERR("fstat(fd=%d): %s", fd, strerror(errno));
620 0 5 if ((uint64_t)st.st_size < sizeof(PoolHeader)) {
621 0 0 POOL_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size);
627 0 5 if (base == MAP_FAILED) {
628 0 0 POOL_ERR("mmap(fd=%d): %s", fd, strerror(errno));
632 0 5 if (!pool_validate_header((PoolHeader *)base, (uint64_t)st.st_size, variant_id)) {
633 0 0 POOL_ERR("fd %d: invalid or incompatible pool", fd);
639 0 5 if (myfd < 0) {
640 0 0 POOL_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno));
649 0 49 if (!h) return;
650 2 47 if (h->notify_fd >= 0) close(h->notify_fd);
651 11 38 if (h->backing_fd >= 0) close(h->backing_fd);
652 49 0 if (h->hdr) munmap(h->hdr, h->mmap_size);
662 1 2 if (h->notify_fd >= 0) return h->notify_fd;
664 0 2 if (efd < 0) return -1;
670 0 4 if (h->notify_fd < 0) return 0;
676 0 4 if (h->notify_fd < 0) return -1;
678 1 3 if (read(h->notify_fd, &val, sizeof(val)) != sizeof(val)) return -1;
770 0 11 if (len > max_len) len = max_len;
781 2 6 if (len > max_len) len = max_len;
796 0 10 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)