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