Branch Coverage

sync.h
Criterion Covered Total %
branch 207 450 46.0


line true false branch
123 0 1 if (pid == 0) return 1;
124 1 0 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
0 1 return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH);
132 1 12 if (deadline->tv_nsec >= 1000000000L) {
145 10 6 if (remaining->tv_nsec < 0) {
163 0 0 if (!__atomic_compare_exchange_n(&hdr->mutex, &observed, 0,
167 0 0 if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0)
175 15 0 if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
178 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
184 0 0 if (cur != 0) {
187 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
190 0 0 if (val >= SYNC_MUTEX_WRITER_BIT) {
192 0 0 if (!sync_pid_alive(pid))
206 0 16 if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0)
226 0 0 if (!__atomic_compare_exchange_n(&hdr->value, &observed, 0,
230 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
239 7 0 if (cur < SYNC_RWLOCK_WRITER_BIT) {
240 7 0 if (__atomic_compare_exchange_n(lock, &cur, cur + 1,
244 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
250 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
253 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
256 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
258 0 0 if (!sync_pid_alive(pid))
272 1 0 if (sync_rwlock_try_rdlock(hdr)) return 1;
273 0 0 if (timeout == 0) return 0;
279 0 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
283 0 0 if (cur < SYNC_RWLOCK_WRITER_BIT) {
284 0 0 if (__atomic_compare_exchange_n(lock, &cur, cur + 1,
288 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
294 0 0 if (cur >= SYNC_RWLOCK_WRITER_BIT) {
296 0 0 if (has_deadline) {
297 0 0 if (!sync_remaining_time(&deadline, &remaining)) {
306 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
308 0 0 if (!has_deadline) {
310 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
312 0 0 if (!sync_pid_alive(pid))
327 1 3 if (cur >= SYNC_RWLOCK_WRITER_BIT) return 0;
334 9 2 if (prev == 0 && __atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
0 9 if (prev == 0 && __atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
344 5 0 if (__atomic_compare_exchange_n(lock, &expected, mypid,
347 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
353 0 0 if (cur != 0) {
356 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
359 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
361 0 0 if (!sync_pid_alive(pid))
375 1 0 if (sync_rwlock_try_wrlock(hdr)) return 1;
376 0 0 if (timeout == 0) return 0;
383 0 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
387 0 0 if (__atomic_compare_exchange_n(lock, &expected, mypid,
390 0 0 if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) {
396 0 0 if (cur != 0) {
398 0 0 if (has_deadline) {
399 0 0 if (!sync_remaining_time(&deadline, &remaining)) {
408 0 0 if (rc == -1 && errno == ETIMEDOUT) {
0 0 if (rc == -1 && errno == ETIMEDOUT) {
410 0 0 if (!has_deadline) {
412 0 0 if (val >= SYNC_RWLOCK_WRITER_BIT) {
414 0 0 if (!sync_pid_alive(pid))
436 0 6 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
443 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
458 5 24 if (cur == 0) return 0;
459 24 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1,
468 1 9 if (n == 0) return 1;
472 4 5 if (cur < n) return 0;
473 5 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n,
482 0 3 if (n == 0) return 1;
483 2 1 if (sync_sem_try_acquire_n(h, n)) return 1;
484 0 1 if (timeout == 0) return 0;
489 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
495 0 1 if (cur >= n) {
496 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n,
507 1 0 if (has_deadline) {
508 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
519 0 1 if (sync_sem_try_acquire_n(h, n)) return 1;
521 1 0 if (has_deadline) {
522 1 0 if (!sync_remaining_time(&deadline, &remaining)) {
531 2 2 if (sync_sem_try_acquire(h)) return 1;
532 1 1 if (timeout == 0) return 0;
537 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
543 0 1 if (cur > 0) {
544 0 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1,
555 1 0 if (has_deadline) {
556 0 1 if (!sync_remaining_time(&deadline, &remaining)) {
568 0 1 if (sync_sem_try_acquire(h)) return 1;
570 1 0 if (has_deadline) {
571 1 0 if (!sync_remaining_time(&deadline, &remaining)) {
585 1 6 if (next > max_val) next = max_val; /* clamp at max */
586 7 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, next,
589 0 7 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
597 1 9 if (n == 0) return;
602 8 1 uint32_t next = (n > max_val - cur) ? max_val : cur + n;
603 9 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, next,
606 0 9 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) {
620 1 3 if (cur == 0) return 0;
621 3 0 if (__atomic_compare_exchange_n(&hdr->value, &cur, 0,
645 1 7 if (timeout == 0) return -1; /* non-blocking probe: can't rendezvous instantly */
650 0 7 if (arrived == parties) {
656 0 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
666 7 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
670 5 9 if (cur_gen != gen) return 0; /* barrier tripped */
675 9 0 if (has_deadline) {
676 2 7 if (!sync_remaining_time(&deadline, &remaining)) {
685 2 0 gen + 1, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) {
710 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
736 1 0 if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid,
749 1 3 if (timeout == 0) return 0; /* non-blocking: no wait */
759 3 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
764 0 3 if (cur != seq) { signaled = 1; break; }
769 3 0 if (has_deadline) {
770 0 3 if (!sync_remaining_time(&deadline, &remaining)) {
782 1 2 if (cur != seq) { signaled = 1; break; }
784 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) {
799 1 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
807 1 0 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
834 4 4 if (__atomic_compare_exchange_n(&hdr->value, &expected, mypid,
839 1 3 if (expected == SYNC_ONCE_DONE) return 0;
850 3 3 if (r == 1) return 1;
851 1 2 if (r == 0) return 0;
852 1 1 if (timeout == 0) return 0;
856 1 0 if (has_deadline) sync_make_deadline(timeout, &deadline);
862 1 1 if (r == 1) return 1; /* caller is initializer */
863 0 1 if (r == 0) return 0; /* already done */
867 0 1 if (val == SYNC_ONCE_DONE) return 0;
868 0 1 if (val == SYNC_ONCE_INIT) continue; /* race: was reset, retry */
871 1 0 if (val >= SYNC_MUTEX_WRITER_BIT) {
873 1 0 if (!sync_pid_alive(pid)) {
874 1 0 if (__atomic_compare_exchange_n(&hdr->value, &val, SYNC_ONCE_INIT,
877 0 1 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
887 0 0 if (has_deadline) {
888 0 0 if (!sync_remaining_time(&deadline, &remaining)) {
905 1 3 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
912 0 2 if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0)
924 73 0 if (errbuf) errbuf[0] = '\0';
926 0 73 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; }
927 25 48 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; }
928 24 48 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; }
929 13 57 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; }
936 52 16 if (anonymous) {
940 0 52 if (base == MAP_FAILED) {
941 0 0 SYNC_ERR("mmap(anonymous): %s", strerror(errno));
951 17 35 if (type == SYNC_TYPE_SEMAPHORE)
957 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; }
959 0 16 if (flock(fd, LOCK_EX) < 0) {
960 0 0 SYNC_ERR("flock(%s): %s", path, strerror(errno));
965 0 16 if (fstat(fd, &st) < 0) {
966 0 0 SYNC_ERR("fstat(%s): %s", path, strerror(errno));
972 9 7 if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) {
0 9 if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) {
973 0 0 SYNC_ERR("%s: file too small (%lld)", path, (long long)st.st_size);
977 7 9 if (is_new) {
978 0 7 if (ftruncate(fd, (off_t)total_size) < 0) {
979 0 0 SYNC_ERR("ftruncate(%s): %s", path, strerror(errno));
984 9 7 map_size = is_new ? (size_t)total_size : (size_t)st.st_size;
986 0 16 if (base == MAP_FAILED) {
987 0 0 SYNC_ERR("mmap(%s): %s", path, strerror(errno));
993 9 7 if (!is_new) {
995 9 0 hdr->version == SYNC_VERSION &&
996 9 0 hdr->type == type &&
6 3 hdr->type == type &&
997 6 0 hdr->total_size == (uint64_t)st.st_size);
998 3 6 if (!valid) {
999 3 0 SYNC_ERR("%s: invalid or incompatible sync file", path);
1014 3 4 if (type == SYNC_TYPE_SEMAPHORE)
1026 0 65 if (!h) { munmap(base, map_size); return NULL; }
1030 13 52 h->path = path ? strdup(path) : NULL;
1041 6 0 if (errbuf) errbuf[0] = '\0';
1043 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; }
1044 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; }
1045 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; }
1046 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; }
1050 6 0 int fd = memfd_create(name ? name : "sync", MFD_CLOEXEC);
1051 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; }
1053 0 6 if (ftruncate(fd, (off_t)total_size) < 0) {
1054 0 0 SYNC_ERR("ftruncate(memfd): %s", strerror(errno));
1059 0 6 if (base == MAP_FAILED) {
1060 0 0 SYNC_ERR("mmap(memfd): %s", strerror(errno));
1072 2 4 if (type == SYNC_TYPE_SEMAPHORE)
1078 0 6 if (!h) { munmap(base, (size_t)total_size); close(fd); return NULL; }
1090 5 0 if (errbuf) errbuf[0] = '\0';
1093 1 4 if (fstat(fd, &st) < 0) {
1094 1 0 SYNC_ERR("fstat(fd=%d): %s", fd, strerror(errno));
1098 0 4 if ((uint64_t)st.st_size < sizeof(SyncHeader)) {
1099 0 0 SYNC_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size);
1105 0 4 if (base == MAP_FAILED) {
1106 0 0 SYNC_ERR("mmap(fd=%d): %s", fd, strerror(errno));
1112 4 0 hdr->version == SYNC_VERSION &&
1113 4 0 hdr->type == type &&
3 1 hdr->type == type &&
1114 3 0 hdr->total_size == (uint64_t)st.st_size);
1115 1 3 if (!valid) {
1116 1 0 SYNC_ERR("fd %d: invalid or incompatible sync", fd);
1122 0 3 if (myfd < 0) {
1123 0 0 SYNC_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno));
1129 0 3 if (!h) { munmap(base, map_size); close(myfd); return NULL; }
1141 0 74 if (!h) return;
1142 11 63 if (h->notify_fd >= 0) close(h->notify_fd);
1143 9 65 if (h->backing_fd >= 0) close(h->backing_fd);
1144 74 0 if (h->hdr) munmap(h->hdr, h->mmap_size);
1154 0 11 if (h->notify_fd >= 0) close(h->notify_fd);
1156 0 11 if (efd < 0) return -1;
1162 0 10 if (h->notify_fd < 0) return 0;
1168 0 11 if (h->notify_fd < 0) return -1;
1170 5 6 if (read(h->notify_fd, &val, sizeof(val)) != sizeof(val)) return -1;