| 96 | |
| 97 | template <bool Atomic> |
| 98 | bool Ring_Buffer_Ex<Atomic>::getbytes_ex_(void *data, size_t len, bool advp) |
| 99 | { |
| 100 | if (len == 0) |
| 101 | return true; |
| 102 | |
| 103 | const size_t rp = atomic_load_maybe(rp_, std::memory_order_relaxed); |
| 104 | const size_t wp = atomic_load_maybe(wp_, data ? std::memory_order_acquire : std::memory_order_relaxed); |
| 105 | const size_t cap = cap_; |
| 106 | |
| 107 | // same as `size_used()` except `wp` memory order to synchronize data |
| 108 | size_t used = wp + ((wp < rp) ? cap : 0) - rp; |
| 109 | |
| 110 | if (used < len) |
| 111 | return false; |
| 112 | |
| 113 | const uint8_t *src = rbdata_.get(); |
| 114 | uint8_t *dst = (uint8_t *)data; |
| 115 | |
| 116 | if (data) { |
| 117 | const size_t taillen = std::min(len, cap - rp); |
| 118 | std::copy_n(&src[rp], taillen, dst); |
| 119 | std::copy_n(src, len - taillen, dst + taillen); |
| 120 | } |
| 121 | |
| 122 | if (advp) |
| 123 | atomic_store_maybe(rp_, (rp + len < cap) ? (rp + len) : (rp + len - cap), std::memory_order_relaxed); |
| 124 | return true; |
| 125 | } |
| 126 | |
| 127 | template <bool Atomic> |
| 128 | bool Ring_Buffer_Ex<Atomic>::putbytes_(const void *data, size_t len) |
no test coverage detected