Branch Coverage

sync.h
Criterion Covered Total %
branch 251 494 50.8


line true false branch
124 0 3 if (pid == 0) return 1;
125 1 2 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
0 1 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
133 1 16 if (deadline->tv_nsec >= 1000000000L) {
146 12 8 if (remaining->tv_nsec < 0) {
164 0 0 if (!__atomic_compare_exchange_n(&hdr->mutex, &observed, 0,
168 0 0 if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0)
176 15 0 if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
179 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
185 0 0 if (cur != 0) {
188 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
191 0 0 if (val >= SYNC_MUTEX_WRITER_BIT) {
193 0 0 if (!sync_pid_alive(pid))
207 0 16 if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0)
227 0 0 if (!__atomic_compare_exchange_n(&hdr->value, &observed, 0,
231 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
242 1 6 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
1 0 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
243 1 0 if (__atomic_compare_exchange_n(lock, &cur, cur + 1,
246 6 0 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
6 0 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
247 6 0 if (__atomic_compare_exchange_n(lock, &cur, 1,
251 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
258 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
261 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
263 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
265 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
267 0 0 if (!sync_pid_alive(pid))
275 0 0 while (wc > 0 && !__atomic_compare_exchange_n(
276 0 0 writers_waiting, &wc, wc - 1,
293 0 3 if (timeout == 0) {
301 3 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
306 65 2 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
0 65 if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) {
307 0 0 if (__atomic_compare_exchange_n(lock, &cur, cur + 1,
310 2 65 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
2 0 } else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) {
311 2 0 if (__atomic_compare_exchange_n(lock, &cur, 1,
315 63 2 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
321 0 2 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) {
325 2 0 if (has_deadline) {
326 1 1 if (!sync_remaining_time(&deadline, &remaining)) {
330 0 1 if (remaining.tv_sec >= SYNC_LOCK_TIMEOUT_SEC)
338 1 0 if (rc == -1 && errno == ETIMEDOUT) {
1 0 if (rc == -1 && errno == ETIMEDOUT) {
340 1 0 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
342 1 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
344 0 1 if (!sync_pid_alive(pid))
351 0 0 while (wc > 0 && !__atomic_compare_exchange_n(
352 0 0 writers_waiting, &wc, wc - 1,
366 1 2 if (cur >= SYNC_RWLOCK_WRITER_BIT) return 0;
373 10 2 if (prev == 0 && __atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
0 10 if (prev == 0 && __atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
384 5 0 if (__atomic_compare_exchange_n(lock, &expected, mypid,
387 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
394 0 0 if (cur != 0) {
397 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
401 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
403 0 0 if (!sync_pid_alive(pid))
418 3 1 if (sync_rwlock_try_wrlock(hdr)) return 1;
419 0 1 if (timeout == 0) return 0;
427 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
431 0 65 if (__atomic_compare_exchange_n(lock, &expected, mypid,
434 63 2 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
441 2 0 if (cur != 0) {
445 2 0 if (has_deadline) {
446 1 1 if (!sync_remaining_time(&deadline, &remaining)) {
451 0 1 if (remaining.tv_sec >= SYNC_LOCK_TIMEOUT_SEC)
459 1 0 if (rc == -1 && errno == ETIMEDOUT) {
1 0 if (rc == -1 && errno == ETIMEDOUT) {
463 1 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
465 0 1 if (!sync_pid_alive(pid))
487 0 8 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
494 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
509 5 24 if (cur == 0) return 0;
510 24 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1,
519 1 9 if (n == 0) return 1;
523 4 5 if (cur < n) return 0;
524 5 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n,
533 0 3 if (n == 0) return 1;
534 2 1 if (sync_sem_try_acquire_n(h, n)) return 1;
535 0 1 if (timeout == 0) return 0;
540 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
546 0 1 if (cur >= n) {
547 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n,
558 1 0 if (has_deadline) {
559 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
570 0 1 if (sync_sem_try_acquire_n(h, n)) return 1;
572 1 0 if (has_deadline) {
573 1 0 if (!sync_remaining_time(&deadline, &remaining)) {
582 2 2 if (sync_sem_try_acquire(h)) return 1;
583 1 1 if (timeout == 0) return 0;
588 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
594 0 1 if (cur > 0) {
595 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1,
606 1 0 if (has_deadline) {
607 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
619 0 1 if (sync_sem_try_acquire(h)) return 1;
621 1 0 if (has_deadline) {
622 1 0 if (!sync_remaining_time(&deadline, &remaining)) {
636 1 6 if (next > max_val) next = max_val; /* clamp at max */
637 7 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, next,
640 0 7 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
648 1 9 if (n == 0) return;
653 8 1 uint32_t next = (n > max_val - cur) ? max_val : cur + n;
654 9 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, next,
657 0 9 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) {
670 1 3 if (cur == 0) return 0;
700 1 8 if (timeout == 0) return -1; /* non-blocking probe: can't rendezvous instantly */
703 1 7 if (gen_raw & SYNC_BARRIER_BROKEN_BIT) return -1; /* already broken */
707 0 7 if (arrived == parties) {
712 0 0 if (old_g & SYNC_BARRIER_BROKEN_BIT) {
714 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
719 0 0 if (__atomic_compare_exchange_n(&hdr->generation, &old_g, new_g,
724 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
734 7 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
738 0 14 if (cur_raw & SYNC_BARRIER_BROKEN_BIT) return -1; /* broken */
739 5 9 if (cur_raw != gen_raw) return 0; /* barrier tripped */
744 9 0 if (has_deadline) {
745 2 7 if (!sync_remaining_time(&deadline, &remaining)) {
754 0 2 gen_raw | SYNC_BARRIER_BROKEN_BIT,
756 0 0 && !(g & SYNC_BARRIER_BROKEN_BIT)) {
791 2 0 if (__atomic_compare_exchange_n(&hdr->generation, &old_g, new_g,
795 0 2 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
821 1 0 if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
834 1 3 if (timeout == 0) return 0; /* non-blocking: no wait */
844 3 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
849 0 3 if (cur != seq) { signaled = 1; break; }
854 3 0 if (has_deadline) {
855 0 3 if (!sync_remaining_time(&deadline, &remaining)) {
867 1 2 if (cur != seq) { signaled = 1; break; }
869 2 0 if (rc == -1 && errno == ETIMEDOUT && has_deadline) {
2 0 if (rc == -1 && errno == ETIMEDOUT && has_deadline) {
2 0 if (rc == -1 && errno == ETIMEDOUT && has_deadline) {
884 1 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
892 1 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
919 4 4 if (__atomic_compare_exchange_n(&hdr->value, &expected, mypid,
924 1 3 if (expected == SYNC_ONCE_DONE) return 0;
935 3 3 if (r == 1) return 1;
936 1 2 if (r == 0) return 0;
937 1 1 if (timeout == 0) return 0;
941 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
947 1 1 if (r == 1) return 1; /* caller is initializer */
948 0 1 if (r == 0) return 0; /* already done */
952 0 1 if (val == SYNC_ONCE_DONE) return 0;
953 0 1 if (val == SYNC_ONCE_INIT) continue; /* race: was reset, retry */
956 1 0 if (val >= SYNC_MUTEX_WRITER_BIT) {
958 1 0 if (!sync_pid_alive(pid)) {
959 1 0 if (__atomic_compare_exchange_n(&hdr->value, &val, SYNC_ONCE_INIT,
962 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
974 0 0 if (has_deadline) {
975 0 0 if (!sync_remaining_time(&deadline, &remaining)) {
980 0 0 if (remaining.tv_sec < SYNC_LOCK_TIMEOUT_SEC)
993 1 3 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1000 0 2 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
1012 74 0 if (errbuf) errbuf[0] = '\0';
1014 0 74 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
0 0 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
1015 25 49 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1 24 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1 0 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1016 24 49 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
2 22 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
2 0 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
1017 13 58 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
2 11 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
2 0 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
1024 53 16 if (anonymous) {
1028 0 53 if (base == MAP_FAILED) {
1029 0 0 SYNC_ERR("mmap(anonymous): %s", strerror(errno));
1039 17 36 if (type == SYNC_TYPE_SEMAPHORE)
1045 0 16 if (fd < 0) { SYNC_ERR("open(%s): %s", path, strerror(errno)); return NULL; }
0 0 if (fd < 0) { SYNC_ERR("open(%s): %s", path, strerror(errno)); return NULL; }
1047 0 16 if (flock(fd, LOCK_EX) < 0) {
1048 0 0 SYNC_ERR("flock(%s): %s", path, strerror(errno));
1053 0 16 if (fstat(fd, &st) < 0) {
1054 0 0 SYNC_ERR("fstat(%s): %s", path, strerror(errno));
1060 9 7 if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) {
0 9 if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) {
1061 0 0 SYNC_ERR("%s: file too small (%lld)", path, (long long)st.st_size);
1065 7 9 if (is_new) {
1066 0 7 if (ftruncate(fd, (off_t)total_size) < 0) {
1067 0 0 SYNC_ERR("ftruncate(%s): %s", path, strerror(errno));
1072 9 7 map_size = is_new ? (size_t)total_size : (size_t)st.st_size;
1074 0 16 if (base == MAP_FAILED) {
1075 0 0 SYNC_ERR("mmap(%s): %s", path, strerror(errno));
1081 9 7 if (!is_new) {
1083 9 0 hdr->version == SYNC_VERSION &&
1084 9 0 hdr->type == type &&
6 3 hdr->type == type &&
1085 6 0 hdr->total_size == (uint64_t)st.st_size);
1086 3 6 if (!valid) {
1087 3 0 SYNC_ERR("%s: invalid or incompatible sync file", path);
1102 3 4 if (type == SYNC_TYPE_SEMAPHORE)
1114 0 66 if (!h) { munmap(base, map_size); return NULL; }
1118 13 53 h->path = path ? strdup(path) : NULL;
1129 6 0 if (errbuf) errbuf[0] = '\0';
1131 0 6 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
0 0 if (type > SYNC_TYPE_ONCE) { SYNC_ERR("unknown type %u", type); return NULL; }
1132 2 4 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
0 2 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
0 0 if (type == SYNC_TYPE_SEMAPHORE && param == 0) { SYNC_ERR("semaphore max must be > 0"); return NULL; }
1133 2 4 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
0 2 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
0 0 if (type == SYNC_TYPE_SEMAPHORE && initial > param) { SYNC_ERR("initial (%u) > max (%u)", initial, param); return NULL; }
1134 1 5 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
0 1 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
0 0 if (type == SYNC_TYPE_BARRIER && param < 2) { SYNC_ERR("barrier count must be >= 2"); return NULL; }
1138 6 0 int fd = memfd_create(name ? name : "sync", MFD_CLOEXEC | MFD_ALLOW_SEALING);
1139 0 6 if (fd < 0) { SYNC_ERR("memfd_create: %s", strerror(errno)); return NULL; }
0 0 if (fd < 0) { SYNC_ERR("memfd_create: %s", strerror(errno)); return NULL; }
1141 0 6 if (ftruncate(fd, (off_t)total_size) < 0) {
1142 0 0 SYNC_ERR("ftruncate(memfd): %s", strerror(errno));
1148 0 6 if (base == MAP_FAILED) {
1149 0 0 SYNC_ERR("mmap(memfd): %s", strerror(errno));
1161 2 4 if (type == SYNC_TYPE_SEMAPHORE)
1167 0 6 if (!h) { munmap(base, (size_t)total_size); close(fd); return NULL; }
1179 5 0 if (errbuf) errbuf[0] = '\0';
1182 1 4 if (fstat(fd, &st) < 0) {
1183 1 0 SYNC_ERR("fstat(fd=%d): %s", fd, strerror(errno));
1187 0 4 if ((uint64_t)st.st_size < sizeof(SyncHeader)) {
1188 0 0 SYNC_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size);
1194 0 4 if (base == MAP_FAILED) {
1195 0 0 SYNC_ERR("mmap(fd=%d): %s", fd, strerror(errno));
1201 4 0 hdr->version == SYNC_VERSION &&
1202 4 0 hdr->type == type &&
3 1 hdr->type == type &&
1203 3 0 hdr->total_size == (uint64_t)st.st_size);
1204 1 3 if (!valid) {
1205 1 0 SYNC_ERR("fd %d: invalid or incompatible sync", fd);
1211 0 3 if (myfd < 0) {
1212 0 0 SYNC_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno));
1218 0 3 if (!h) { munmap(base, map_size); close(myfd); return NULL; }
1230 0 75 if (!h) return;
1231 11 64 if (h->notify_fd >= 0) close(h->notify_fd);
1232 9 66 if (h->backing_fd >= 0) close(h->backing_fd);
1233 75 0 if (h->hdr) munmap(h->hdr, h->mmap_size);
1243 0 11 if (h->notify_fd >= 0) return h->notify_fd;
1245 0 11 if (efd < 0) return -1;
1251 0 10 if (h->notify_fd < 0) return 0;
1257 0 11 if (h->notify_fd < 0) return -1;
1259 5 6 if (read(h->notify_fd, &val, sizeof(val)) != sizeof(val)) return -1;