| 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) |