| line |
true |
false |
branch |
|
174
|
0 |
58 |
if (v < 2) return 2; |
|
175
|
0 |
58 |
if (v > 0x80000000U) return 0; |
|
192
|
4826 |
65 |
if (needed <= h->copy_buf_cap) return 1; |
|
193
|
0 |
65 |
uint32_t ns = h->copy_buf_cap ? h->copy_buf_cap : 64; |
|
194
|
0 |
7 |
while (ns < needed) { uint32_t n2 = ns * 2; if (n2 <= ns) { ns = needed; break; } ns = n2; } |
|
|
7 |
65 |
while (ns < needed) { uint32_t n2 = ns * 2; if (n2 <= ns) { ns = needed; break; } ns = n2; } |
|
196
|
0 |
65 |
if (!nb) return 0; |
|
215
|
0 |
4 |
if (pid == 0) return 1; |
|
216
|
0 |
4 |
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH); |
|
|
0 |
0 |
return !(kill((pid_t)pid, 0) == -1 && errno == ESRCH); |
|
222
|
0 |
0 |
if (!__atomic_compare_exchange_n(&hdr->mutex, &observed, 0, |
|
226
|
0 |
0 |
if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0) |
|
234
|
6251 |
159 |
if (__atomic_compare_exchange_n(&hdr->mutex, &expected, mypid, |
|
237
|
159 |
0 |
if (__builtin_expect(spin < REQREP_SPIN_LIMIT, 1)) { |
|
243
|
0 |
0 |
if (cur != 0) { |
|
246
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) { |
|
249
|
0 |
0 |
if (val >= REQREP_MUTEX_WRITER_BIT) { |
|
251
|
0 |
0 |
if (!reqrep_pid_alive(pid)) |
|
265
|
0 |
6251 |
if (__atomic_load_n(&hdr->mutex_waiters, __ATOMIC_RELAXED) > 0) |
|
270
|
1467 |
1431 |
if (__atomic_load_n(&hdr->recv_waiters, __ATOMIC_RELAXED) > 0) { |
|
277
|
0 |
2277 |
if (__atomic_load_n(&hdr->send_waiters, __ATOMIC_RELAXED) > 0) { |
|
284
|
0 |
2886 |
if (__atomic_load_n(&hdr->slot_waiters, __ATOMIC_RELAXED) > 0) { |
|
296
|
2336 |
7 |
if (remaining->tv_nsec < 0) { |
|
307
|
1796 |
2409 |
if (deadline->tv_nsec >= 1000000000L) { |
|
322
|
3134 |
2 |
for (uint32_t i = 0; i < n; i++) { |
|
326
|
2902 |
232 |
if (__atomic_compare_exchange_n(&slot->state, &expected, RESP_ACQUIRED, |
|
336
|
4 |
2 |
for (uint32_t i = 0; i < n; i++) { |
|
339
|
0 |
4 |
if (state == RESP_ACQUIRED || state == RESP_READY) { |
|
|
0 |
0 |
if (state == RESP_ACQUIRED || state == RESP_READY) { |
|
341
|
4 |
0 |
if (pid && !reqrep_pid_alive(pid)) { |
|
|
0 |
4 |
if (pid && !reqrep_pid_alive(pid)) { |
|
342
|
0 |
0 |
if (__atomic_compare_exchange_n(&slot->state, &state, RESP_FREE, |
|
346
|
0 |
0 |
if (__atomic_compare_exchange_n(&slot->state, &expected, RESP_ACQUIRED, |
|
378
|
0 |
111 |
if (!h) return NULL; |
|
391
|
103 |
8 |
h->path = path ? strdup(path) : NULL; |
|
400
|
0 |
55 |
if (hdr->magic != REQREP_MAGIC) return 0; |
|
401
|
0 |
55 |
if (hdr->version != REQREP_VERSION) return 0; |
|
402
|
0 |
55 |
if (hdr->mode != expected_mode) return 0; |
|
403
|
55 |
0 |
if (hdr->req_cap == 0 || (hdr->req_cap & (hdr->req_cap - 1)) != 0) return 0; |
|
|
0 |
55 |
if (hdr->req_cap == 0 || (hdr->req_cap & (hdr->req_cap - 1)) != 0) return 0; |
|
404
|
0 |
55 |
if (hdr->total_size != (uint64_t)file_size) return 0; |
|
405
|
0 |
55 |
if (hdr->req_slots_off != sizeof(ReqRepHeader)) return 0; |
|
406
|
0 |
55 |
if (hdr->resp_slots == 0) return 0; |
|
407
|
0 |
55 |
if (hdr->resp_stride < sizeof(RespSlotHeader)) return 0; |
|
408
|
45 |
10 |
if (expected_mode == REQREP_MODE_STR) { |
|
409
|
0 |
45 |
if ((uint64_t)hdr->req_arena_off + hdr->req_arena_cap > hdr->total_size) return 0; |
|
411
|
0 |
55 |
if ((uint64_t)hdr->resp_off + (uint64_t)hdr->resp_slots * hdr->resp_stride > hdr->total_size) return 0; |
|
435
|
894 |
49 |
for (uint32_t i = 0; i < resp_slots_n; i++) { |
|
453
|
14 |
36 |
if (req_arena_cap < 4096) req_arena_cap = 4096; |
|
471
|
47 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
474
|
0 |
47 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
|
0 |
0 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
475
|
0 |
47 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
|
0 |
0 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
477
|
45 |
2 |
if (arena_hint == 0) arena_hint = (uint64_t)req_cap * 256; |
|
489
|
0 |
47 |
if (anonymous) { |
|
493
|
0 |
0 |
if (base == MAP_FAILED) { |
|
494
|
0 |
0 |
REQREP_ERR("mmap(anonymous): %s", strerror(errno)); |
|
499
|
0 |
47 |
if (fd < 0) { REQREP_ERR("open(%s): %s", path, strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { REQREP_ERR("open(%s): %s", path, strerror(errno)); return NULL; } |
|
501
|
0 |
47 |
if (flock(fd, LOCK_EX) < 0) { |
|
502
|
0 |
0 |
REQREP_ERR("flock(%s): %s", path, strerror(errno)); |
|
507
|
0 |
47 |
if (fstat(fd, &st) < 0) { |
|
508
|
0 |
0 |
REQREP_ERR("fstat(%s): %s", path, strerror(errno)); |
|
514
|
1 |
46 |
if (!is_new && (uint64_t)st.st_size < sizeof(ReqRepHeader)) { |
|
|
0 |
1 |
if (!is_new && (uint64_t)st.st_size < sizeof(ReqRepHeader)) { |
|
515
|
0 |
0 |
REQREP_ERR("%s: file too small (%lld)", path, (long long)st.st_size); |
|
519
|
46 |
1 |
if (is_new) { |
|
520
|
0 |
46 |
if (ftruncate(fd, (off_t)total_size) < 0) { |
|
521
|
0 |
0 |
REQREP_ERR("ftruncate(%s): %s", path, strerror(errno)); |
|
526
|
1 |
46 |
map_size = is_new ? (size_t)total_size : (size_t)st.st_size; |
|
528
|
0 |
47 |
if (base == MAP_FAILED) { |
|
529
|
0 |
0 |
REQREP_ERR("mmap(%s): %s", path, strerror(errno)); |
|
533
|
1 |
46 |
if (!is_new) { |
|
534
|
0 |
1 |
if (!reqrep_validate_header((ReqRepHeader *)base, (size_t)st.st_size, REQREP_MODE_STR)) { |
|
535
|
0 |
0 |
REQREP_ERR("%s: invalid or incompatible reqrep file", path); |
|
541
|
0 |
1 |
if (!h) { munmap(base, map_size); return NULL; } |
|
554
|
0 |
46 |
if (!h) { munmap(base, map_size); return NULL; } |
|
559
|
49 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
560
|
0 |
49 |
if (!path) { REQREP_ERR("path required"); return NULL; } |
|
|
0 |
0 |
if (!path) { REQREP_ERR("path required"); return NULL; } |
|
563
|
0 |
49 |
if (fd < 0) { REQREP_ERR("open(%s): %s", path, strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { REQREP_ERR("open(%s): %s", path, strerror(errno)); return NULL; } |
|
565
|
0 |
49 |
if (flock(fd, LOCK_EX) < 0) { |
|
566
|
0 |
0 |
REQREP_ERR("flock(%s): %s", path, strerror(errno)); |
|
571
|
0 |
49 |
if (fstat(fd, &st) < 0) { |
|
572
|
0 |
0 |
REQREP_ERR("fstat(%s): %s", path, strerror(errno)); |
|
576
|
0 |
49 |
if ((uint64_t)st.st_size < sizeof(ReqRepHeader)) { |
|
577
|
0 |
0 |
REQREP_ERR("%s: file too small or not initialized", path); |
|
583
|
0 |
49 |
if (base == MAP_FAILED) { |
|
584
|
0 |
0 |
REQREP_ERR("mmap(%s): %s", path, strerror(errno)); |
|
588
|
0 |
49 |
if (!reqrep_validate_header((ReqRepHeader *)base, map_size, mode)) { |
|
589
|
0 |
0 |
REQREP_ERR("%s: invalid or incompatible reqrep file", path); |
|
597
|
0 |
49 |
if (!h) { munmap(base, map_size); return NULL; } |
|
604
|
3 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
607
|
0 |
3 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
|
0 |
0 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
608
|
0 |
3 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
|
0 |
0 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
610
|
3 |
0 |
if (arena_hint == 0) arena_hint = (uint64_t)req_cap * 256; |
|
618
|
3 |
0 |
int fd = memfd_create(name ? name : "reqrep", MFD_CLOEXEC); |
|
619
|
0 |
3 |
if (fd < 0) { REQREP_ERR("memfd_create: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { REQREP_ERR("memfd_create: %s", strerror(errno)); return NULL; } |
|
621
|
0 |
3 |
if (ftruncate(fd, (off_t)total_size) < 0) { |
|
622
|
0 |
0 |
REQREP_ERR("ftruncate(memfd): %s", strerror(errno)); |
|
627
|
0 |
3 |
if (base == MAP_FAILED) { |
|
628
|
0 |
0 |
REQREP_ERR("mmap(memfd): %s", strerror(errno)); |
|
637
|
0 |
3 |
if (!h) { munmap(base, (size_t)total_size); close(fd); return NULL; } |
|
642
|
4 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
645
|
0 |
4 |
if (fstat(fd, &st) < 0) { |
|
646
|
0 |
0 |
REQREP_ERR("fstat(fd=%d): %s", fd, strerror(errno)); |
|
650
|
0 |
4 |
if ((uint64_t)st.st_size < sizeof(ReqRepHeader)) { |
|
651
|
0 |
0 |
REQREP_ERR("fd %d: too small (%lld)", fd, (long long)st.st_size); |
|
657
|
0 |
4 |
if (base == MAP_FAILED) { |
|
658
|
0 |
0 |
REQREP_ERR("mmap(fd=%d): %s", fd, strerror(errno)); |
|
662
|
0 |
4 |
if (!reqrep_validate_header((ReqRepHeader *)base, map_size, mode)) { |
|
663
|
0 |
0 |
REQREP_ERR("fd %d: invalid or incompatible reqrep", fd); |
|
669
|
0 |
4 |
if (myfd < 0) { |
|
670
|
0 |
0 |
REQREP_ERR("fcntl(F_DUPFD_CLOEXEC): %s", strerror(errno)); |
|
676
|
0 |
4 |
if (!h) { munmap(base, map_size); close(myfd); return NULL; } |
|
681
|
0 |
111 |
if (!h) return; |
|
682
|
8 |
103 |
if (h->notify_fd >= 0) close(h->notify_fd); |
|
683
|
9 |
102 |
if (h->reply_fd >= 0) close(h->reply_fd); |
|
684
|
8 |
103 |
if (h->backing_fd >= 0) close(h->backing_fd); |
|
685
|
111 |
0 |
if (h->hdr) munmap(h->hdr, h->mmap_size); |
|
701
|
0 |
2863 |
if (len > REQREP_STR_LEN_MASK) return -2; |
|
703
|
4 |
2859 |
if (hdr->req_tail - hdr->req_head >= h->req_cap) { |
|
709
|
4 |
2855 |
if (alloc == 0) alloc = 8; |
|
713
|
1 |
2858 |
if ((uint64_t)pos + alloc > h->req_arena_cap) { |
|
718
|
1 |
2858 |
if ((uint64_t)hdr->arena_used + skip > h->req_arena_cap) { |
|
719
|
0 |
1 |
if (hdr->req_tail == hdr->req_head) { |
|
735
|
4 |
2854 |
slot->packed_len = len | (utf8 ? REQREP_UTF8_FLAG : 0); |
|
753
|
1 |
2863 |
if (slot < 0) return -3; |
|
762
|
2858 |
5 |
if (r == 1) { |
|
776
|
1 |
2764 |
if (r == 1 || r == -2) return r; |
|
|
0 |
1 |
if (r == 1 || r == -2) return r; |
|
777
|
0 |
1 |
if (timeout == 0) return r; |
|
782
|
1 |
0 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
785
|
0 |
1 |
uint32_t *futex_word = (r == -3) ? &hdr->slot_futex : &hdr->send_futex; |
|
786
|
0 |
1 |
uint32_t *waiter_cnt = (r == -3) ? &hdr->slot_waiters : &hdr->send_waiters; |
|
790
|
1 |
0 |
if (r == 1 || r == -2) return r; |
|
|
0 |
1 |
if (r == 1 || r == -2) return r; |
|
794
|
1 |
0 |
if (has_deadline) { |
|
795
|
0 |
1 |
if (!reqrep_remaining_time(&deadline, &remaining)) { |
|
805
|
1 |
0 |
if (r == 1 || r == -2) return r; |
|
|
0 |
1 |
if (r == 1 || r == -2) return r; |
|
806
|
1 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return r; |
|
|
1 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return r; |
|
816
|
1154 |
2252 |
if (hdr->req_tail == hdr->req_head) { |
|
828
|
0 |
2252 |
if (!reqrep_ensure_copy_buf(h, len + 1)) |
|
830
|
2248 |
4 |
if (len > 0) |
|
837
|
1123 |
1129 |
if (hdr->arena_used == 0) |
|
851
|
2230 |
1148 |
if (r == 1) reqrep_wake_producers(h->hdr); |
|
860
|
1557 |
597 |
if (r != 0) return r; |
|
861
|
0 |
597 |
if (timeout == 0) return 0; |
|
866
|
597 |
0 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
871
|
61 |
536 |
if (r != 0) return r; |
|
875
|
536 |
0 |
if (has_deadline) { |
|
876
|
0 |
536 |
if (!reqrep_remaining_time(&deadline, &remaining)) { |
|
886
|
531 |
5 |
if (r != 0) return r; |
|
887
|
5 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return 0; |
|
|
5 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return 0; |
|
901
|
0 |
2249 |
if (slot_idx >= h->resp_slots) return -1; |
|
902
|
1 |
2248 |
if (len > h->resp_data_max) return -3; |
|
906
|
194 |
2054 |
if (state != RESP_ACQUIRED) return -2; |
|
907
|
7 |
2047 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != expected_gen) return -2; |
|
910
|
2043 |
4 |
if (len > 0) memcpy(data, str, len); |
|
916
|
0 |
2047 |
if (!__atomic_compare_exchange_n(&slot->state, &expected_state, RESP_READY, |
|
920
|
1920 |
127 |
if (__atomic_load_n(&slot->waiters, __ATOMIC_RELAXED) > 0) |
|
932
|
0 |
5065 |
if (slot_idx >= h->resp_slots) return -1; |
|
936
|
5 |
5060 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != expected_gen) return -4; |
|
937
|
2421 |
2639 |
if (state != RESP_READY) return 0; |
|
942
|
0 |
2639 |
if (!reqrep_ensure_copy_buf(h, len + 1)) return -2; |
|
945
|
2635 |
4 |
if (len > 0) memcpy(h->copy_buf, data, len); |
|
959
|
134 |
2420 |
if (r != 0) return r; |
|
960
|
0 |
2420 |
if (timeout == 0) return 0; |
|
966
|
1800 |
620 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
970
|
1 |
2420 |
if (state == RESP_READY) |
|
976
|
0 |
2420 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != REQREP_ID_GEN(id)) { |
|
982
|
0 |
2420 |
if (state == RESP_READY) { |
|
988
|
1800 |
620 |
if (has_deadline) { |
|
989
|
1 |
1799 |
if (!reqrep_remaining_time(&deadline, &remaining)) { |
|
1000
|
2418 |
1 |
if (r != 0) return r; |
|
1009
|
0 |
218 |
if (slot_idx >= h->resp_slots) return; |
|
1011
|
0 |
218 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != expected_gen) return; |
|
1013
|
207 |
11 |
if (__atomic_compare_exchange_n(&slot->state, &expected_state, RESP_FREE, |
|
1018
|
1 |
206 |
if (__atomic_load_n(&slot->waiters, __ATOMIC_RELAXED) > 0) |
|
1032
|
1801 |
747 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
1035
|
0 |
2548 |
if (r != 1) return r; |
|
1038
|
1801 |
747 |
if (has_deadline) { |
|
1043
|
0 |
1801 |
if (get_timeout <= 0) { |
|
1050
|
1 |
2547 |
if (r != 1) { |
|
1063
|
68 |
10 |
for (uint32_t i = 0; i < h->resp_slots; i++) { |
|
1066
|
61 |
7 |
if ((state == RESP_ACQUIRED || state == RESP_READY) && |
|
|
0 |
61 |
if ((state == RESP_ACQUIRED || state == RESP_READY) && |
|
1067
|
7 |
0 |
__atomic_load_n(&slot->owner_pid, __ATOMIC_RELAXED) == mypid) |
|
1095
|
4 |
1 |
for (uint32_t i = 0; i < h->resp_slots; i++) { |
|
1098
|
2 |
2 |
while (state == RESP_ACQUIRED || state == RESP_READY) { |
|
|
0 |
2 |
while (state == RESP_ACQUIRED || state == RESP_READY) { |
|
1099
|
2 |
0 |
if (__atomic_compare_exchange_n(&slot->state, &state, RESP_FREE, |
|
1103
|
0 |
2 |
if (__atomic_load_n(&slot->waiters, __ATOMIC_RELAXED) > 0) |
|
1129
|
0 |
6 |
if (h->notify_fd >= 0) return h->notify_fd; |
|
1135
|
0 |
2 |
if (h->notify_fd >= 0 && h->notify_fd != fd) |
|
|
0 |
0 |
if (h->notify_fd >= 0 && h->notify_fd != fd) |
|
1141
|
3 |
0 |
if (h->notify_fd >= 0) { |
|
1148
|
2 |
0 |
if (h->notify_fd >= 0) { |
|
1155
|
0 |
8 |
if (h->reply_fd >= 0) return h->reply_fd; |
|
1161
|
0 |
1 |
if (h->reply_fd >= 0 && h->reply_fd != fd) |
|
|
0 |
0 |
if (h->reply_fd >= 0 && h->reply_fd != fd) |
|
1167
|
1 |
0 |
if (h->reply_fd >= 0) { |
|
1174
|
1 |
0 |
if (h->reply_fd >= 0) { |
|
1215
|
202 |
7 |
for (uint32_t i = 0; i < req_cap; i++) |
|
1219
|
51 |
7 |
for (uint32_t i = 0; i < resp_slots_n; i++) { |
|
1229
|
7 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
1231
|
0 |
7 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
|
0 |
0 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
1232
|
0 |
7 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
|
0 |
0 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
1243
|
0 |
7 |
if (anonymous) { |
|
1247
|
0 |
0 |
if (base == MAP_FAILED) { REQREP_ERR("mmap(anonymous): %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { REQREP_ERR("mmap(anonymous): %s", strerror(errno)); return NULL; } |
|
1250
|
0 |
7 |
if (fd < 0) { REQREP_ERR("open(%s): %s", path, strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { REQREP_ERR("open(%s): %s", path, strerror(errno)); return NULL; } |
|
1251
|
0 |
7 |
if (flock(fd, LOCK_EX) < 0) { REQREP_ERR("flock: %s", strerror(errno)); close(fd); return NULL; } |
|
|
0 |
0 |
if (flock(fd, LOCK_EX) < 0) { REQREP_ERR("flock: %s", strerror(errno)); close(fd); return NULL; } |
|
1253
|
0 |
7 |
if (fstat(fd, &st) < 0) { REQREP_ERR("fstat: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
|
0 |
0 |
if (fstat(fd, &st) < 0) { REQREP_ERR("fstat: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
1255
|
1 |
6 |
if (!is_new && (uint64_t)st.st_size < sizeof(ReqRepHeader)) { |
|
|
0 |
1 |
if (!is_new && (uint64_t)st.st_size < sizeof(ReqRepHeader)) { |
|
1256
|
0 |
0 |
REQREP_ERR("%s: file too small", path); flock(fd, LOCK_UN); close(fd); return NULL; |
|
1258
|
6 |
1 |
if (is_new && ftruncate(fd, (off_t)total_size) < 0) { |
|
|
0 |
6 |
if (is_new && ftruncate(fd, (off_t)total_size) < 0) { |
|
1259
|
0 |
0 |
REQREP_ERR("ftruncate: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; |
|
1261
|
1 |
6 |
map_size = is_new ? (size_t)total_size : (size_t)st.st_size; |
|
1263
|
0 |
7 |
if (base == MAP_FAILED) { REQREP_ERR("mmap: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { REQREP_ERR("mmap: %s", strerror(errno)); flock(fd, LOCK_UN); close(fd); return NULL; } |
|
1264
|
1 |
6 |
if (!is_new) { |
|
1265
|
0 |
1 |
if (!reqrep_validate_header((ReqRepHeader *)base, map_size, REQREP_MODE_INT)) { |
|
1266
|
0 |
0 |
REQREP_ERR("%s: invalid or incompatible", path); munmap(base, map_size); flock(fd, LOCK_UN); close(fd); return NULL; |
|
1281
|
1 |
0 |
if (errbuf) errbuf[0] = '\0'; |
|
1283
|
0 |
1 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
|
0 |
0 |
if (req_cap == 0) { REQREP_ERR("invalid req_cap"); return NULL; } |
|
1284
|
0 |
1 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
|
0 |
0 |
if (resp_slots_n == 0) { REQREP_ERR("resp_slots must be > 0"); return NULL; } |
|
1291
|
1 |
0 |
int fd = memfd_create(name ? name : "reqrep_int", MFD_CLOEXEC); |
|
1292
|
0 |
1 |
if (fd < 0) { REQREP_ERR("memfd_create: %s", strerror(errno)); return NULL; } |
|
|
0 |
0 |
if (fd < 0) { REQREP_ERR("memfd_create: %s", strerror(errno)); return NULL; } |
|
1293
|
0 |
1 |
if (ftruncate(fd, (off_t)total_size) < 0) { |
|
1294
|
0 |
0 |
REQREP_ERR("ftruncate: %s", strerror(errno)); close(fd); return NULL; |
|
1297
|
0 |
1 |
if (base == MAP_FAILED) { REQREP_ERR("mmap: %s", strerror(errno)); close(fd); return NULL; } |
|
|
0 |
0 |
if (base == MAP_FAILED) { REQREP_ERR("mmap: %s", strerror(errno)); close(fd); return NULL; } |
|
1308
|
1 |
39 |
if (rslot < 0) return -3; |
|
1322
|
38 |
1 |
if (diff == 0) { |
|
1323
|
38 |
0 |
if (__atomic_compare_exchange_n(&hdr->req_tail, &pos, pos + 1, |
|
1334
|
1 |
0 |
} else if (diff < 0) { |
|
1347
|
8 |
0 |
if (r == 1) return 1; |
|
1348
|
0 |
0 |
if (timeout == 0) return r; |
|
1352
|
0 |
0 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
1355
|
0 |
0 |
uint32_t *futex_word = (r == -3) ? &hdr->slot_futex : &hdr->send_futex; |
|
1356
|
0 |
0 |
uint32_t *waiter_cnt = (r == -3) ? &hdr->slot_waiters : &hdr->send_waiters; |
|
1360
|
0 |
0 |
if (r == 1) return 1; |
|
1364
|
0 |
0 |
if (has_deadline) { |
|
1365
|
0 |
0 |
if (!reqrep_remaining_time(&deadline, &remaining)) { |
|
1374
|
0 |
0 |
if (r == 1) return 1; |
|
1375
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return r; |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return r; |
|
1388
|
36 |
10 |
if (diff == 0) { |
|
1389
|
36 |
0 |
if (__atomic_compare_exchange_n(&hdr->req_head, &pos, pos + 1, |
|
1397
|
10 |
0 |
} else if (diff < 0) { |
|
1408
|
3 |
4 |
if (reqrep_int_try_recv(h, out_value, out_id)) return 1; |
|
1409
|
0 |
4 |
if (timeout == 0) return 0; |
|
1413
|
4 |
0 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
1416
|
0 |
4 |
if (reqrep_int_try_recv(h, out_value, out_id)) return 1; |
|
1419
|
4 |
0 |
if (has_deadline) { |
|
1420
|
0 |
4 |
if (!reqrep_remaining_time(&deadline, &remaining)) { |
|
1428
|
4 |
0 |
if (reqrep_int_try_recv(h, out_value, out_id)) return 1; |
|
1429
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return 0; |
|
|
0 |
0 |
if (rc == -1 && errno == ETIMEDOUT) return 0; |
|
1438
|
0 |
35 |
if (slot_idx >= h->resp_slots) return -1; |
|
1442
|
2 |
33 |
if (state != RESP_ACQUIRED) return -2; |
|
1443
|
1 |
32 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != expected_gen) return -2; |
|
1448
|
0 |
32 |
if (!__atomic_compare_exchange_n(&slot->state, &expected_state, RESP_READY, |
|
1452
|
5 |
27 |
if (__atomic_load_n(&slot->waiters, __ATOMIC_RELAXED) > 0) |
|
1461
|
0 |
40 |
if (slot_idx >= h->resp_slots) return -1; |
|
1465
|
1 |
39 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != expected_gen) return -4; |
|
1466
|
7 |
32 |
if (state != RESP_READY) return 0; |
|
1476
|
2 |
6 |
if (r != 0) return r; |
|
1477
|
0 |
6 |
if (timeout == 0) return 0; |
|
1482
|
1 |
5 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
1485
|
0 |
7 |
if (state == RESP_READY) |
|
1488
|
0 |
7 |
if (__atomic_load_n(&slot->generation, __ATOMIC_ACQUIRE) != REQREP_ID_GEN(id)) { |
|
1493
|
0 |
7 |
if (state == RESP_READY) { |
|
1498
|
2 |
5 |
if (has_deadline) { |
|
1499
|
1 |
1 |
if (!reqrep_remaining_time(&deadline, &remaining)) { |
|
1508
|
5 |
1 |
if (r != 0) return r; |
|
1517
|
1 |
5 |
if (has_deadline) reqrep_make_deadline(timeout, &deadline); |
|
1519
|
0 |
6 |
if (r != 1) return r; |
|
1521
|
1 |
5 |
if (has_deadline) { |
|
1526
|
0 |
1 |
if (get_timeout <= 0) { reqrep_cancel(h, id); return 0; } |
|
1529
|
1 |
5 |
if (r != 1) { |
|
1551
|
16 |
1 |
for (uint32_t i = 0; i < h->req_cap; i++) |
|
1556
|
4 |
1 |
for (uint32_t i = 0; i < h->resp_slots; i++) { |
|
1559
|
2 |
2 |
while (state == RESP_ACQUIRED || state == RESP_READY) { |
|
|
0 |
2 |
while (state == RESP_ACQUIRED || state == RESP_READY) { |
|
1560
|
2 |
0 |
if (__atomic_compare_exchange_n(&slot->state, &state, RESP_FREE, |
|
1564
|
0 |
2 |
if (__atomic_load_n(&slot->waiters, __ATOMIC_RELAXED) > 0) |