| line |
true |
false |
branch |
|
147
|
0 |
1 |
if (pid == 0) return 1; |
|
148
|
1 |
0 |
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH); |
|
|
0 |
1 |
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH); |
|
156
|
1 |
16 |
if (deadline->tv_nsec >= 1000000000L) { |
|
169
|
10 |
8 |
if (remaining->tv_nsec < 0) { |
|
187
|
0 |
0 |
if (!__atomic_compare_exchange_n(&hdr->mutex, &observed, 0, |
|
191
|
0 |
0 |
if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0) |
|
199
|
15 |
0 |
if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid, |
|
202
|
0 |
0 |
if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) { |
|
208
|
0 |
0 |
if (cur != 0) { |
|
211
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
214
|
0 |
0 |
if (val >= SYNC_MUTEX_WRITER_BIT) { |
|
216
|
0 |
0 |
if (!sync_pid_alive(pid)) |
|
230
|
0 |
16 |
if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0) |
|
250
|
0 |
0 |
if (!__atomic_compare_exchange_n(&hdr->value, &observed, 0, |
|
254
|
0 |
0 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
274
|
0 |
20 |
if (!h->reader_slots) return; |
|
277
|
0 |
20 |
if (h->cached_fork_gen != cur_gen) { |
|
281
|
12 |
8 |
if (h->my_slot_idx != UINT32_MAX) return; |
|
285
|
8 |
0 |
for (uint32_t i = 0; i < SYNC_READER_SLOTS; i++) { |
|
288
|
8 |
0 |
if (__atomic_compare_exchange_n(&h->reader_slots[s].pid, |
|
304
|
0 |
0 |
if (!sub) return; |
|
307
|
0 |
0 |
uint32_t want = (cur > sub) ? cur - sub : 0; |
|
308
|
0 |
0 |
if (__atomic_compare_exchange_n(p, &cur, want, |
|
321
|
0 |
0 |
if (!__atomic_compare_exchange_n(&h->reader_slots[i].pid, &expected, 0, |
|
327
|
0 |
0 |
if (wp) { sync_atomic_sub_cap(&hdr->waiters, wp); drained = 1; } |
|
328
|
0 |
0 |
if (writp) { sync_atomic_sub_cap(&hdr->rwlock_writers_waiting, writp); drained = 1; } |
|
335
|
0 |
0 |
if (!h->reader_slots) return; |
|
345
|
0 |
0 |
for (uint32_t i = 0; i < SYNC_READER_SLOTS; i++) { |
|
347
|
0 |
0 |
if (pid == 0) continue; |
|
349
|
0 |
0 |
if (sync_pid_alive(pid)) { |
|
350
|
0 |
0 |
if (sc > 0) any_live_reader = 1; |
|
353
|
0 |
0 |
if (sc > 0) { found_dead_reader = 1; continue; } |
|
354
|
0 |
0 |
if (sync_drain_dead_slot(h, i, pid)) any_recovery = 1; |
|
360
|
0 |
0 |
if (found_dead_reader && !any_live_reader) { |
|
|
0 |
0 |
if (found_dead_reader && !any_live_reader) { |
|
362
|
0 |
0 |
if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) { |
|
|
0 |
0 |
if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) { |
|
363
|
0 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, 0, |
|
366
|
0 |
0 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
370
|
0 |
0 |
for (uint32_t i = 0; i < SYNC_READER_SLOTS; i++) { |
|
372
|
0 |
0 |
if (pid == 0) continue; |
|
373
|
0 |
0 |
if (sync_pid_alive(pid)) continue; |
|
374
|
0 |
0 |
if (sync_drain_dead_slot(h, i, pid)) any_recovery = 1; |
|
377
|
0 |
0 |
if (any_recovery) |
|
385
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
390
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
396
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) { |
|
404
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) { |
|
421
|
0 |
0 |
if (val >= SYNC_RWLOCK_WRITER_BIT) { |
|
423
|
0 |
0 |
if (!sync_pid_alive(pid)) |
|
437
|
7 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
442
|
1 |
6 |
if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) { |
|
|
1 |
0 |
if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) { |
|
443
|
1 |
0 |
if (__atomic_compare_exchange_n(lock, &cur, cur + 1, |
|
446
|
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)) { |
|
447
|
6 |
0 |
if (__atomic_compare_exchange_n(lock, &cur, 1, |
|
451
|
0 |
0 |
if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) { |
|
458
|
0 |
0 |
if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) { |
|
|
0 |
0 |
if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) { |
|
461
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
463
|
0 |
0 |
if (cur >= SYNC_RWLOCK_WRITER_BIT) { |
|
470
|
0 |
0 |
while (wc > 0 && !__atomic_compare_exchange_n( |
|
471
|
0 |
0 |
writers_waiting, &wc, wc - 1, |
|
496
|
0 |
3 |
if (timeout == 0) { |
|
505
|
3 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
509
|
3 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
515
|
33 |
2 |
if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) { |
|
|
0 |
33 |
if (cur > 0 && cur < SYNC_RWLOCK_WRITER_BIT) { |
|
516
|
0 |
0 |
if (__atomic_compare_exchange_n(lock, &cur, cur + 1, |
|
519
|
2 |
33 |
} else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) { |
|
|
2 |
0 |
} else if (cur == 0 && !__atomic_load_n(writers_waiting, __ATOMIC_RELAXED)) { |
|
520
|
2 |
0 |
if (__atomic_compare_exchange_n(lock, &cur, 1, |
|
524
|
32 |
1 |
if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) { |
|
530
|
0 |
1 |
if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) { |
|
|
0 |
0 |
if (cur >= SYNC_RWLOCK_WRITER_BIT || cur == 0) { |
|
535
|
1 |
0 |
if (has_deadline) { |
|
536
|
0 |
1 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
538
|
0 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
542
|
0 |
1 |
if (remaining.tv_sec >= SYNC_LOCK_TIMEOUT_SEC) { |
|
553
|
1 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
1 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
558
|
1 |
0 |
if (!capped) { |
|
559
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
563
|
0 |
0 |
if (cur >= SYNC_RWLOCK_WRITER_BIT) { |
|
569
|
0 |
0 |
while (wc > 0 && !__atomic_compare_exchange_n( |
|
570
|
0 |
0 |
writers_waiting, &wc, wc - 1, |
|
589
|
3 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
592
|
1 |
2 |
if (cur >= SYNC_RWLOCK_WRITER_BIT) { |
|
593
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
597
|
2 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, cur + 1, |
|
600
|
0 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
611
|
12 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
613
|
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) |
|
624
|
5 |
0 |
if (__atomic_compare_exchange_n(lock, &expected, mypid, |
|
627
|
0 |
0 |
if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) { |
|
633
|
0 |
0 |
if (cur != 0) { |
|
636
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
650
|
3 |
1 |
if (sync_rwlock_try_wrlock(h)) return 1; |
|
651
|
0 |
1 |
if (timeout == 0) return 0; |
|
659
|
1 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
663
|
0 |
33 |
if (__atomic_compare_exchange_n(lock, &expected, mypid, |
|
666
|
32 |
1 |
if (__builtin_expect(spin < SYNC_SPIN_LIMIT, 1)) { |
|
672
|
1 |
0 |
if (cur != 0) { |
|
677
|
1 |
0 |
if (has_deadline) { |
|
678
|
0 |
1 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
682
|
0 |
1 |
if (remaining.tv_sec >= SYNC_LOCK_TIMEOUT_SEC) { |
|
693
|
1 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
1 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
695
|
1 |
0 |
if (!capped) return 0; /* user deadline expired */ |
|
717
|
0 |
8 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
727
|
1 |
0 |
if (h->my_slot_idx != UINT32_MAX) |
|
730
|
0 |
1 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
745
|
5 |
24 |
if (cur == 0) return 0; |
|
746
|
24 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1, |
|
755
|
1 |
9 |
if (n == 0) return 1; |
|
759
|
4 |
5 |
if (cur < n) return 0; |
|
760
|
5 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n, |
|
769
|
0 |
3 |
if (n == 0) return 1; |
|
770
|
2 |
1 |
if (sync_sem_try_acquire_n(h, n)) return 1; |
|
771
|
0 |
1 |
if (timeout == 0) return 0; |
|
776
|
1 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
782
|
0 |
1 |
if (cur >= n) { |
|
783
|
0 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - n, |
|
794
|
1 |
0 |
if (has_deadline) { |
|
795
|
0 |
1 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
806
|
0 |
1 |
if (sync_sem_try_acquire_n(h, n)) return 1; |
|
808
|
1 |
0 |
if (has_deadline) { |
|
809
|
1 |
0 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
818
|
2 |
2 |
if (sync_sem_try_acquire(h)) return 1; |
|
819
|
1 |
1 |
if (timeout == 0) return 0; |
|
824
|
1 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
830
|
0 |
1 |
if (cur > 0) { |
|
831
|
0 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, cur - 1, |
|
842
|
1 |
0 |
if (has_deadline) { |
|
843
|
0 |
1 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
855
|
0 |
1 |
if (sync_sem_try_acquire(h)) return 1; |
|
857
|
1 |
0 |
if (has_deadline) { |
|
858
|
1 |
0 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
872
|
1 |
6 |
if (next > max_val) next = max_val; /* clamp at max */ |
|
873
|
7 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, next, |
|
876
|
0 |
7 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
884
|
1 |
9 |
if (n == 0) return; |
|
889
|
8 |
1 |
uint32_t next = (n > max_val - cur) ? max_val : cur + n; |
|
890
|
9 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &cur, next, |
|
893
|
0 |
9 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) { |
|
906
|
1 |
3 |
if (cur == 0) return 0; |
|
936
|
1 |
8 |
if (timeout == 0) return -1; /* non-blocking probe: can't rendezvous instantly */ |
|
939
|
1 |
7 |
if (gen_raw & SYNC_BARRIER_BROKEN_BIT) return -1; /* already broken */ |
|
943
|
0 |
7 |
if (arrived == parties) { |
|
948
|
0 |
0 |
if (old_g & SYNC_BARRIER_BROKEN_BIT) { |
|
950
|
0 |
0 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
955
|
0 |
0 |
if (__atomic_compare_exchange_n(&hdr->generation, &old_g, new_g, |
|
960
|
0 |
0 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
970
|
7 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
974
|
0 |
14 |
if (cur_raw & SYNC_BARRIER_BROKEN_BIT) return -1; /* broken */ |
|
975
|
5 |
9 |
if (cur_raw != gen_raw) return 0; /* barrier tripped */ |
|
980
|
9 |
0 |
if (has_deadline) { |
|
981
|
2 |
7 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
990
|
0 |
2 |
gen_raw | SYNC_BARRIER_BROKEN_BIT, |
|
992
|
0 |
0 |
&& !(g & SYNC_BARRIER_BROKEN_BIT)) { |
|
1027
|
2 |
0 |
if (__atomic_compare_exchange_n(&hdr->generation, &old_g, new_g, |
|
1031
|
0 |
2 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
1057
|
1 |
0 |
if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid, |
|
1070
|
1 |
3 |
if (timeout == 0) return 0; /* non-blocking: no wait */ |
|
1080
|
3 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
1085
|
0 |
3 |
if (cur != seq) { signaled = 1; break; } |
|
1090
|
3 |
0 |
if (has_deadline) { |
|
1091
|
0 |
3 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
1103
|
1 |
2 |
if (cur != seq) { signaled = 1; break; } |
|
1105
|
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) { |
|
1120
|
1 |
0 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
1128
|
1 |
0 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
1155
|
4 |
4 |
if (__atomic_compare_exchange_n(&hdr->value, &expected, mypid, |
|
1160
|
1 |
3 |
if (expected == SYNC_ONCE_DONE) return 0; |
|
1171
|
3 |
3 |
if (r == 1) return 1; |
|
1172
|
1 |
2 |
if (r == 0) return 0; |
|
1173
|
1 |
1 |
if (timeout == 0) return 0; |
|
1177
|
1 |
0 |
if (has_deadline) sync_make_deadline(timeout, &deadline); |
|
1183
|
1 |
1 |
if (r == 1) return 1; /* caller is initializer */ |
|
1184
|
0 |
1 |
if (r == 0) return 0; /* already done */ |
|
1188
|
0 |
1 |
if (val == SYNC_ONCE_DONE) return 0; |
|
1189
|
0 |
1 |
if (val == SYNC_ONCE_INIT) continue; /* race: was reset, retry */ |
|
1192
|
1 |
0 |
if (val >= SYNC_MUTEX_WRITER_BIT) { |
|
1194
|
1 |
0 |
if (!sync_pid_alive(pid)) { |
|
1195
|
1 |
0 |
if (__atomic_compare_exchange_n(&hdr->value, &val, SYNC_ONCE_INIT, |
|
1198
|
0 |
1 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
1210
|
0 |
0 |
if (has_deadline) { |
|
1211
|
0 |
0 |
if (!sync_remaining_time(&deadline, &remaining)) { |
|
1216
|
0 |
0 |
if (remaining.tv_sec < SYNC_LOCK_TIMEOUT_SEC) |
|
1229
|
1 |
3 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
1236
|
0 |
2 |
if (__atomic_load_n(&hdr->waiters, __ATOMIC_RELAXED) > 0) |
|
1255
|
15 |
60 |
if (type == SYNC_TYPE_RWLOCK) |
|
1261
|
15 |
60 |
return (type == SYNC_TYPE_RWLOCK) ? sizeof(SyncHeader) : 0; |
|
1266
|
74 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
1268
|
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; } |
|
1269
|
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; } |
|
1270
|
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; } |
|
1271
|
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; } |
|
1279
|
53 |
16 |
if (anonymous) { |
|
1283
|
0 |
53 |
if (base == MAP_FAILED) { |
|
1284
|
0 |
0 |
SYNC_ERR("mmap(anonymous): %s", strerror(errno)); |
|
1295
|
17 |
36 |
if (type == SYNC_TYPE_SEMAPHORE) |
|
1302
|
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; } |
|
1304
|
0 |
16 |
if (flock(fd, LOCK_EX) < 0) { |
|
1305
|
0 |
0 |
SYNC_ERR("flock(%s): %s", path, strerror(errno)); |
|
1310
|
0 |
16 |
if (fstat(fd, &st) < 0) { |
|
1311
|
0 |
0 |
SYNC_ERR("fstat(%s): %s", path, strerror(errno)); |
|
1317
|
9 |
7 |
if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) { |
|
|
0 |
9 |
if (!is_new && (uint64_t)st.st_size < sizeof(SyncHeader)) { |
|
1318
|
0 |
0 |
SYNC_ERR("%s: file too small (%lld)", path, (long long)st.st_size); |
|
1322
|
7 |
9 |
if (is_new) { |
|
1323
|
0 |
7 |
if (ftruncate(fd, (off_t)total_size) < 0) { |
|
1324
|
0 |
0 |
SYNC_ERR("ftruncate(%s): %s", path, strerror(errno)); |
|
1329
|
9 |
7 |
map_size = is_new ? (size_t)total_size : (size_t)st.st_size; |
|
1331
|
0 |
16 |
if (base == MAP_FAILED) { |
|
1332
|
0 |
0 |
SYNC_ERR("mmap(%s): %s", path, strerror(errno)); |
|
1338
|
9 |
7 |
if (!is_new) { |
|
1340
|
9 |
0 |
hdr->version == SYNC_VERSION && |
|
1341
|
9 |
0 |
hdr->type == type && |
|
|
6 |
3 |
hdr->type == type && |
|
1342
|
6 |
0 |
hdr->total_size == (uint64_t)st.st_size); |
|
1343
|
6 |
3 |
if (valid && type == SYNC_TYPE_RWLOCK) { |
|
|
1 |
5 |
if (valid && type == SYNC_TYPE_RWLOCK) { |
|
1347
|
1 |
0 |
if (hdr->reader_slots_off != sizeof(SyncHeader) || |
|
1348
|
0 |
1 |
(uint64_t)st.st_size < need) |
|
1351
|
3 |
6 |
if (!valid) { |
|
1352
|
3 |
0 |
SYNC_ERR("%s: invalid or incompatible sync file", path); |
|
1368
|
3 |
4 |
if (type == SYNC_TYPE_SEMAPHORE) |
|
1380
|
0 |
66 |
if (!h) { munmap(base, map_size); return NULL; } |
|
1384
|
13 |
53 |
h->path = path ? strdup(path) : NULL; |
|
1389
|
13 |
53 |
: NULL; |
|
1399
|
6 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
1401
|
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; } |
|
1402
|
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; } |
|
1403
|
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; } |
|
1404
|
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; } |
|
1409
|
6 |
0 |
int fd = memfd_create(name ? name : "sync", MFD_CLOEXEC | MFD_ALLOW_SEALING); |
|
1410
|
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; } |
|
1412
|
0 |
6 |
if (ftruncate(fd, (off_t)total_size) < 0) { |
|
1413
|
0 |
0 |
SYNC_ERR("ftruncate(memfd): %s", strerror(errno)); |
|
1419
|
0 |
6 |
if (base == MAP_FAILED) { |
|
1420
|
0 |
0 |
SYNC_ERR("mmap(memfd): %s", strerror(errno)); |
|
1433
|
2 |
4 |
if (type == SYNC_TYPE_SEMAPHORE) |
|
1439
|
0 |
6 |
if (!h) { munmap(base, (size_t)total_size); close(fd); return NULL; } |
|
1448
|
1 |
5 |
: NULL; |
|
1455
|
5 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
1458
|
1 |
4 |
if (fstat(fd, &st) < 0) { |
|
1459
|
1 |
0 |
SYNC_ERR("fstat(fd=%d): %s", fd, strerror(errno)); |
|
1463
|
0 |
4 |
if ((uint64_t)st.st_size < sizeof(SyncHeader)) { |
|
1464
|
0 |
0 |
SYNC_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size); |
|
1470
|
0 |
4 |
if (base == MAP_FAILED) { |
|
1471
|
0 |
0 |
SYNC_ERR("mmap(fd=%d): %s", fd, strerror(errno)); |
|
1477
|
4 |
0 |
hdr->version == SYNC_VERSION && |
|
1478
|
4 |
0 |
hdr->type == type && |
|
|
3 |
1 |
hdr->type == type && |
|
1479
|
3 |
0 |
hdr->total_size == (uint64_t)st.st_size); |
|
1480
|
3 |
1 |
if (valid && type == SYNC_TYPE_RWLOCK) { |
|
|
1 |
2 |
if (valid && type == SYNC_TYPE_RWLOCK) { |
|
1483
|
1 |
0 |
if (hdr->reader_slots_off != sizeof(SyncHeader) || |
|
1484
|
0 |
1 |
(uint64_t)st.st_size < need) |
|
1487
|
1 |
3 |
if (!valid) { |
|
1488
|
1 |
0 |
SYNC_ERR("fd %d: invalid or incompatible sync", fd); |
|
1494
|
0 |
3 |
if (myfd < 0) { |
|
1495
|
0 |
0 |
SYNC_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno)); |
|
1501
|
0 |
3 |
if (!h) { munmap(base, map_size); close(myfd); return NULL; } |
|
1510
|
1 |
2 |
: NULL; |
|
1517
|
0 |
75 |
if (!h) return; |
|
1521
|
15 |
60 |
if (h->reader_slots && h->my_slot_idx != UINT32_MAX && h->cached_pid && |
|
|
8 |
7 |
if (h->reader_slots && h->my_slot_idx != UINT32_MAX && h->cached_pid && |
|
|
8 |
0 |
if (h->reader_slots && h->my_slot_idx != UINT32_MAX && h->cached_pid && |
|
1522
|
8 |
0 |
h->cached_fork_gen == __atomic_load_n(&sync_fork_gen, __ATOMIC_RELAXED)) { |
|
1531
|
11 |
64 |
if (h->notify_fd >= 0) close(h->notify_fd); |
|
1532
|
9 |
66 |
if (h->backing_fd >= 0) close(h->backing_fd); |
|
1533
|
75 |
0 |
if (h->hdr) munmap(h->hdr, h->mmap_size); |
|
1543
|
0 |
11 |
if (h->notify_fd >= 0) return h->notify_fd; |
|
1545
|
0 |
11 |
if (efd < 0) return -1; |
|
1551
|
0 |
10 |
if (h->notify_fd < 0) return 0; |
|
1557
|
0 |
11 |
if (h->notify_fd < 0) return -1; |
|
1559
|
5 |
6 |
if (read(h->notify_fd, &val, sizeof(val)) != sizeof(val)) return -1; |