| line |
true |
false |
branch |
|
160
|
0 |
0 |
if (pid == 0) return 1; /* no owner recorded, assume alive */ |
|
161
|
0 |
0 |
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH); |
|
|
0 |
0 |
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH); |
|
171
|
0 |
0 |
if (!__atomic_compare_exchange_n(&hdr->rwlock, &observed_rwlock, |
|
177
|
0 |
0 |
if (__atomic_load_n(&hdr->rwlock_waiters, __ATOMIC_RELAXED) > 0) |
|
201
|
321197 |
37 |
if (__builtin_expect(cur_gen == h->cached_fork_gen && h->my_slot_idx != UINT32_MAX, 1)) |
|
|
321197 |
0 |
if (__builtin_expect(cur_gen == h->cached_fork_gen && h->my_slot_idx != UINT32_MAX, 1)) |
|
212
|
41 |
0 |
for (uint32_t i = 0; i < HIST_READER_SLOTS; i++) { |
|
215
|
37 |
4 |
if (__atomic_compare_exchange_n(&h->reader_slots[s].pid, |
|
235
|
0 |
0 |
if (!sub) return; |
|
238
|
0 |
0 |
uint32_t want = (cur > sub) ? cur - sub : 0; |
|
239
|
0 |
0 |
if (__atomic_compare_exchange_n(p, &cur, want, |
|
262
|
0 |
0 |
if (!__atomic_compare_exchange_n(&h->reader_slots[i].pid, &expected, 0, |
|
267
|
0 |
0 |
if (wp) hist_atomic_sub_cap(&hdr->rwlock_waiters, wp); |
|
268
|
0 |
0 |
if (writp) hist_atomic_sub_cap(&hdr->rwlock_writers_waiting, writp); |
|
282
|
0 |
0 |
if (!h->reader_slots) return; |
|
295
|
0 |
0 |
for (uint32_t i = 0; i < HIST_READER_SLOTS; i++) { |
|
297
|
0 |
0 |
if (pid == 0) continue; |
|
299
|
0 |
0 |
if (hist_pid_alive(pid)) { |
|
300
|
0 |
0 |
if (sc > 0) any_live_reader = 1; |
|
303
|
0 |
0 |
if (sc > 0) { found_dead_reader = 1; continue; } |
|
320
|
0 |
0 |
if (found_dead_reader && !any_live_reader) { |
|
|
0 |
0 |
if (found_dead_reader && !any_live_reader) { |
|
322
|
0 |
0 |
if (cur > 0 && cur < HIST_RWLOCK_WRITER_BIT) { |
|
|
0 |
0 |
if (cur > 0 && cur < HIST_RWLOCK_WRITER_BIT) { |
|
323
|
0 |
0 |
if (__atomic_compare_exchange_n(&hdr->rwlock, &cur, 0, |
|
325
|
0 |
0 |
if (__atomic_load_n(&hdr->rwlock_waiters, __ATOMIC_RELAXED) > 0) |
|
329
|
0 |
0 |
for (uint32_t i = 0; i < HIST_READER_SLOTS; i++) { |
|
331
|
0 |
0 |
if (pid == 0 || hist_pid_alive(pid)) continue; |
|
|
0 |
0 |
if (pid == 0 || hist_pid_alive(pid)) continue; |
|
344
|
0 |
0 |
if (val >= HIST_RWLOCK_WRITER_BIT) { |
|
346
|
0 |
0 |
if (!hist_pid_alive(pid)) |
|
358
|
0 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
364
|
0 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
368
|
0 |
0 |
if (h->my_slot_idx != UINT32_MAX) { |
|
378
|
0 |
0 |
if (h->my_slot_idx != UINT32_MAX) { |
|
396
|
113 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
403
|
0 |
113 |
if (cur > 0 && cur < HIST_RWLOCK_WRITER_BIT) { |
|
|
0 |
0 |
if (cur > 0 && cur < HIST_RWLOCK_WRITER_BIT) { |
|
404
|
0 |
0 |
if (__atomic_compare_exchange_n(lock, &cur, cur + 1, |
|
407
|
113 |
0 |
} else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) { |
|
|
113 |
0 |
} else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) { |
|
408
|
113 |
0 |
if (__atomic_compare_exchange_n(lock, &cur, 1, |
|
412
|
0 |
0 |
if (__builtin_expect(spin < HIST_RWLOCK_SPIN_LIMIT, 1)) { |
|
419
|
0 |
0 |
if (cur >= HIST_RWLOCK_WRITER_BIT || cur == 0) { |
|
|
0 |
0 |
if (cur >= HIST_RWLOCK_WRITER_BIT || cur == 0) { |
|
422
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
442
|
113 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
444
|
113 |
0 |
if (after == 0 && __atomic_load_n(&hdr->rwlock_waiters, __ATOMIC_RELAXED) > 0) |
|
|
0 |
113 |
if (after == 0 && __atomic_load_n(&hdr->rwlock_waiters, __ATOMIC_RELAXED) > 0) |
|
457
|
321121 |
0 |
if (__atomic_compare_exchange_n(lock, &expected, mypid, |
|
460
|
0 |
0 |
if (__builtin_expect(spin < HIST_RWLOCK_SPIN_LIMIT, 1)) { |
|
466
|
0 |
0 |
if (cur != 0) { |
|
469
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
484
|
0 |
321121 |
if (__atomic_load_n(&hdr->rwlock_waiters, __ATOMIC_RELAXED) > 0) |
|
537
|
56 |
3 |
if (errbuf) errbuf[0] = '\0'; |
|
538
|
2 |
57 |
if (lowest < 1) { HIST_ERR("lowest must be >= 1"); return 0; } |
|
|
2 |
0 |
if (lowest < 1) { HIST_ERR("lowest must be >= 1"); return 0; } |
|
539
|
1 |
56 |
if (highest < 2 * lowest) { HIST_ERR("highest must be >= 2 * lowest"); return 0; } |
|
|
1 |
0 |
if (highest < 2 * lowest) { HIST_ERR("highest must be >= 2 * lowest"); return 0; } |
|
540
|
55 |
1 |
if (sig_figs < HIST_MIN_SIG || sig_figs > HIST_MAX_SIG) { |
|
|
2 |
53 |
if (sig_figs < HIST_MIN_SIG || sig_figs > HIST_MAX_SIG) { |
|
541
|
3 |
0 |
HIST_ERR("sig_figs must be between %d and %d", HIST_MIN_SIG, HIST_MAX_SIG); return 0; |
|
546
|
0 |
53 |
if (sbc_magnitude < 1) sbc_magnitude = 1; |
|
548
|
1 |
52 |
if (unit_magnitude + shc_magnitude > 61) { |
|
549
|
1 |
0 |
HIST_ERR("lowest too large for sig_figs (unit_magnitude %d + sub_bucket_half_count_magnitude %d exceeds 61)", unit_magnitude, shc_magnitude); |
|
559
|
450 |
52 |
while (smallest_untrackable <= highest) { |
|
560
|
0 |
450 |
if (smallest_untrackable > (INT64_MAX / 2)) { bucket_count++; break; } |
|
612
|
0 |
49 |
if (!h) { |
|
614
|
0 |
0 |
if (backing_fd >= 0) close(backing_fd); |
|
621
|
5 |
44 |
h->path = path ? strdup(path) : NULL; |
|
632
|
0 |
3 |
if (hdr->magic != HIST_MAGIC) return 0; |
|
633
|
0 |
3 |
if (hdr->version != HIST_VERSION) return 0; |
|
634
|
3 |
0 |
if (hdr->sig_figs < HIST_MIN_SIG || hdr->sig_figs > HIST_MAX_SIG) return 0; |
|
|
0 |
3 |
if (hdr->sig_figs < HIST_MIN_SIG || hdr->sig_figs > HIST_MAX_SIG) return 0; |
|
635
|
0 |
3 |
if (hdr->lowest < 1) return 0; |
|
636
|
0 |
3 |
if (hdr->highest < 2 * hdr->lowest) return 0; |
|
639
|
0 |
3 |
if (!hist_validate_create_args(hdr->lowest, hdr->highest, hdr->sig_figs, &g, NULL)) |
|
641
|
0 |
3 |
if (hdr->unit_magnitude != g.unit_magnitude) return 0; |
|
642
|
0 |
3 |
if (hdr->sub_bucket_count_magnitude != g.sub_bucket_count_magnitude) return 0; |
|
643
|
0 |
3 |
if (hdr->sub_bucket_half_count_magnitude != g.sub_bucket_half_count_magnitude) return 0; |
|
644
|
0 |
3 |
if (hdr->sub_bucket_count != g.sub_bucket_count) return 0; |
|
645
|
0 |
3 |
if (hdr->sub_bucket_half_count != g.sub_bucket_half_count) return 0; |
|
646
|
0 |
3 |
if (hdr->sub_bucket_mask != g.sub_bucket_mask) return 0; |
|
647
|
0 |
3 |
if (hdr->bucket_count != g.bucket_count) return 0; |
|
648
|
0 |
3 |
if (hdr->counts_len != g.counts_len) return 0; |
|
650
|
0 |
3 |
if (hdr->total_size != file_size) return 0; |
|
651
|
0 |
3 |
if (hdr->total_size != hist_total_size(hdr->counts_len)) return 0; |
|
653
|
0 |
3 |
if (hdr->reader_slots_off != L.reader_slots) return 0; |
|
654
|
0 |
3 |
if (hdr->counts_off != L.counts) return 0; |
|
661
|
5 |
47 |
if (!hist_validate_create_args(lowest, highest, sig_figs, &g, errbuf)) return NULL; |
|
669
|
41 |
6 |
if (anonymous) { |
|
672
|
0 |
41 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); return NULL; } |
|
675
|
0 |
6 |
if (fd < 0) { HIST_ERR("open: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { HIST_ERR("open: %s", strerror(errno)); return NULL; } |
|
676
|
0 |
6 |
if (flock(fd, LOCK_EX) < 0) { HIST_ERR("flock: %s", strerror(errno)); close(fd); return NULL; } |
|
|
0 |
0 |
if (flock(fd, LOCK_EX) < 0) { HIST_ERR("flock: %s", strerror(errno)); close(fd); return NULL; } |
|
678
|
0 |
6 |
if (fstat(fd, &st) < 0) { HIST_ERR("fstat: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
|
0 |
0 |
if (fstat(fd, &st) < 0) { HIST_ERR("fstat: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
680
|
3 |
3 |
if (!is_new && (uint64_t)st.st_size < sizeof(HistHeader)) { |
|
|
1 |
2 |
if (!is_new && (uint64_t)st.st_size < sizeof(HistHeader)) { |
|
681
|
1 |
0 |
HIST_ERR("%s: file too small (%lld)", path, (long long)st.st_size); |
|
684
|
3 |
2 |
if (is_new && ftruncate(fd, (off_t)total) < 0) { |
|
|
0 |
3 |
if (is_new && ftruncate(fd, (off_t)total) < 0) { |
|
685
|
0 |
0 |
HIST_ERR("ftruncate: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; |
|
687
|
2 |
3 |
map_size = is_new ? (size_t)total : (size_t)st.st_size; |
|
689
|
0 |
5 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
690
|
2 |
3 |
if (!is_new) { |
|
691
|
0 |
2 |
if (!hist_validate_header((HistHeader *)base, (uint64_t)st.st_size)) { |
|
692
|
0 |
0 |
HIST_ERR("invalid histogram file"); munmap(base, map_size); flock(fd, LOCK_UN); close(fd); return NULL; |
|
699
|
3 |
41 |
if (fd >= 0) { flock(fd, LOCK_UN); close(fd); } |
|
706
|
2 |
2 |
if (!hist_validate_create_args(lowest, highest, sig_figs, &g, errbuf)) return NULL; |
|
709
|
1 |
1 |
int fd = memfd_create(name ? name : "hist", MFD_CLOEXEC | MFD_ALLOW_SEALING); |
|
710
|
0 |
2 |
if (fd < 0) { HIST_ERR("memfd_create: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { HIST_ERR("memfd_create: %s", strerror(errno)); return NULL; } |
|
711
|
0 |
2 |
if (ftruncate(fd, (off_t)total) < 0) { |
|
712
|
0 |
0 |
HIST_ERR("ftruncate: %s", strerror(errno)); close(fd); return NULL; |
|
716
|
0 |
2 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); close(fd); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); close(fd); return NULL; } |
|
722
|
2 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
724
|
0 |
2 |
if (fstat(fd, &st) < 0) { HIST_ERR("fstat: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fstat(fd, &st) < 0) { HIST_ERR("fstat: %s", strerror(errno)); return NULL; } |
|
725
|
1 |
1 |
if ((uint64_t)st.st_size < sizeof(HistHeader)) { HIST_ERR("too small"); return NULL; } |
|
|
1 |
0 |
if ((uint64_t)st.st_size < sizeof(HistHeader)) { HIST_ERR("too small"); return NULL; } |
|
728
|
0 |
1 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { HIST_ERR("mmap: %s", strerror(errno)); return NULL; } |
|
729
|
0 |
1 |
if (!hist_validate_header((HistHeader *)base, (uint64_t)st.st_size)) { |
|
730
|
0 |
0 |
HIST_ERR("invalid histogram table"); munmap(base, ms); return NULL; |
|
733
|
0 |
1 |
if (myfd < 0) { HIST_ERR("fcntl: %s", strerror(errno)); munmap(base, ms); return NULL; } |
|
|
0 |
0 |
if (myfd < 0) { HIST_ERR("fcntl: %s", strerror(errno)); munmap(base, ms); return NULL; } |
|
738
|
0 |
49 |
if (!h) return; |
|
739
|
3 |
46 |
if (h->backing_fd >= 0) close(h->backing_fd); |
|
740
|
49 |
0 |
if (h->base) munmap(h->base, h->mmap_size); |
|
746
|
2 |
0 |
if (!h || !h->base) return 0; |
|
|
0 |
2 |
if (!h || !h->base) return 0; |
|
782
|
7110 |
20022 |
if (bi < 0) { sbi -= h->hdr->sub_bucket_half_count; bi = 0; } |
|
789
|
0 |
13566 |
int32_t adj = (sbi >= h->hdr->sub_bucket_count) ? bi + 1 : bi; |
|
810
|
322647 |
0 |
if (bi < 0 || bi >= h->hdr->bucket_count) return -1; |
|
|
4 |
322643 |
if (bi < 0 || bi >= h->hdr->bucket_count) return -1; |
|
813
|
322643 |
0 |
if (idx < 0 || idx >= h->hdr->counts_len) return -1; |
|
|
0 |
322643 |
if (idx < 0 || idx >= h->hdr->counts_len) return -1; |
|
828
|
33 |
322579 |
if (value < h->hdr->min_value) h->hdr->min_value = value; |
|
829
|
322582 |
30 |
if (value > h->hdr->max_value) h->hdr->max_value = value; |
|
836
|
1 |
38 |
if (total == 0) return 0; |
|
838
|
0 |
38 |
if (want < 1) want = 1; |
|
839
|
0 |
38 |
if (want > total) want = total; |
|
843
|
190360 |
0 |
for (int64_t idx = 0; idx < len; idx++) { |
|
844
|
39160 |
151200 |
if (!counts[idx]) continue; /* skip empty cells (sparse); a 0 cell can never be the first to reach want */ |
|
846
|
38 |
151162 |
if (running >= want) |
|
856
|
0 |
5 |
if (total == 0) return 0.0; |
|
860
|
56320 |
5 |
for (int64_t idx = 0; idx < len; idx++) { |
|
862
|
13528 |
42792 |
if (c) |
|
871
|
45056 |
4 |
for (int64_t i = 0; i < counts_len; i++) { |
|
872
|
43977 |
1079 |
if (src[i] <= 0) continue; /* counts are non-negative; skip empty cells */ |
|
873
|
0 |
1079 |
if (dst[i] > INT64_MAX - src[i]) dst[i] = INT64_MAX; /* saturate */ |