Agora
1.2.0
Agora project
|
Go to the documentation of this file.
38 #pragma GCC diagnostic push
39 #pragma GCC diagnostic ignored "-Wconversion"
41 #ifdef MCDBGQ_USE_RELACY
42 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
46 #if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
50 #pragma warning(disable: 4127) // conditional expression is constant
53 #if defined(__APPLE__)
54 #include "TargetConditionals.h"
57 #ifdef MCDBGQ_USE_RELACY
58 #include "relacy/relacy_std.hpp"
59 #include "relacy_shims.h"
73 #include <type_traits>
89 #if defined(MCDBGQ_USE_RELACY)
96 #elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
99 extern "C" __declspec(dllimport)
unsigned long __stdcall GetCurrentThreadId(
void);
101 static_assert(
sizeof(
unsigned long) ==
sizeof(std::uint32_t),
"Expected size of unsigned long to be 32 bits on Windows");
107 #elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE)
119 template<std::
size_t>
struct thread_id_size { };
120 template<>
struct thread_id_size<4> {
typedef std::uint32_t numeric_t; };
121 template<>
struct thread_id_size<8> {
typedef std::uint64_t numeric_t; };
123 template<>
struct thread_id_converter<
thread_id_t> {
134 return std::hash<std::thread::id>()(
x);
145 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
146 #define MOODYCAMEL_THREADLOCAL __thread
147 #elif defined(_MSC_VER)
148 #define MOODYCAMEL_THREADLOCAL __declspec(thread)
151 #define MOODYCAMEL_THREADLOCAL thread_local
162 #ifndef MOODYCAMEL_CONSTEXPR_IF
163 #if (defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17) || __cplusplus > 201402L
164 #define MOODYCAMEL_CONSTEXPR_IF if constexpr
165 #define MOODYCAMEL_MAYBE_UNUSED [[maybe_unused]]
167 #define MOODYCAMEL_CONSTEXPR_IF if
168 #define MOODYCAMEL_MAYBE_UNUSED
173 #ifndef MOODYCAMEL_EXCEPTIONS_ENABLED
174 #if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__))
175 #define MOODYCAMEL_EXCEPTIONS_ENABLED
178 #ifdef MOODYCAMEL_EXCEPTIONS_ENABLED
179 #define MOODYCAMEL_TRY try
180 #define MOODYCAMEL_CATCH(...) catch(__VA_ARGS__)
181 #define MOODYCAMEL_RETHROW throw
182 #define MOODYCAMEL_THROW(expr) throw (expr)
184 #define MOODYCAMEL_TRY MOODYCAMEL_CONSTEXPR_IF (true)
185 #define MOODYCAMEL_CATCH(...) else MOODYCAMEL_CONSTEXPR_IF (false)
186 #define MOODYCAMEL_RETHROW
187 #define MOODYCAMEL_THROW(expr)
190 #ifndef MOODYCAMEL_NOEXCEPT
191 #if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED)
192 #define MOODYCAMEL_NOEXCEPT
193 #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true
194 #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true
195 #elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800
198 #define MOODYCAMEL_NOEXCEPT _NOEXCEPT
199 #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference<valueType>::value && std::is_move_constructible<type>::value ? std::is_trivially_move_constructible<type>::value : std::is_trivially_copy_constructible<type>::value)
200 #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference<valueType>::value && std::is_move_assignable<type>::value ? std::is_trivially_move_assignable<type>::value || std::is_nothrow_move_assignable<type>::value : std::is_trivially_copy_assignable<type>::value || std::is_nothrow_copy_assignable<type>::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr))
201 #elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900
202 #define MOODYCAMEL_NOEXCEPT _NOEXCEPT
203 #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference<valueType>::value && std::is_move_constructible<type>::value ? std::is_trivially_move_constructible<type>::value || std::is_nothrow_move_constructible<type>::value : std::is_trivially_copy_constructible<type>::value || std::is_nothrow_copy_constructible<type>::value)
204 #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference<valueType>::value && std::is_move_assignable<type>::value ? std::is_trivially_move_assignable<type>::value || std::is_nothrow_move_assignable<type>::value : std::is_trivially_copy_assignable<type>::value || std::is_nothrow_copy_assignable<type>::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr))
206 #define MOODYCAMEL_NOEXCEPT noexcept
207 #define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr)
208 #define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr)
212 #ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
213 #ifdef MCDBGQ_USE_RELACY
214 #define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
219 #if (!defined(_MSC_VER) || _MSC_VER >= 1900) && (!defined(__MINGW32__) && !defined(__MINGW64__) || !defined(__WINPTHREADS_VERSION)) && (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
228 #ifndef MOODYCAMEL_DELETE_FUNCTION
229 #if defined(_MSC_VER) && _MSC_VER < 1800
230 #define MOODYCAMEL_DELETE_FUNCTION
232 #define MOODYCAMEL_DELETE_FUNCTION = delete
237 #ifndef MOODYCAMEL_ALIGNAS
239 #if defined(_MSC_VER) && _MSC_VER <= 1800
240 #define MOODYCAMEL_ALIGNAS(alignment) __declspec(align(alignment))
241 #define MOODYCAMEL_ALIGNOF(obj) __alignof(obj)
242 #define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) typename details::Vs2013Aligned<std::alignment_of<obj>::value, T>::type
243 template<
int Align,
typename T>
struct Vs2013Aligned { };
244 template<
typename T>
struct Vs2013Aligned<1,
T> {
typedef __declspec(align(1))
T type; };
245 template<
typename T>
struct Vs2013Aligned<2,
T> {
typedef __declspec(align(2))
T type; };
246 template<
typename T>
struct Vs2013Aligned<4,
T> {
typedef __declspec(align(4))
T type; };
247 template<
typename T>
struct Vs2013Aligned<8,
T> {
typedef __declspec(align(8))
T type; };
248 template<
typename T>
struct Vs2013Aligned<16,
T> {
typedef __declspec(align(16))
T type; };
249 template<
typename T>
struct Vs2013Aligned<32,
T> {
typedef __declspec(align(32))
T type; };
250 template<
typename T>
struct Vs2013Aligned<64,
T> {
typedef __declspec(align(64))
T type; };
251 template<
typename T>
struct Vs2013Aligned<128,
T> {
typedef __declspec(align(128))
T type; };
252 template<
typename T>
struct Vs2013Aligned<256,
T> {
typedef __declspec(align(256))
T type; };
255 #define MOODYCAMEL_ALIGNAS(alignment) alignas(alignment)
256 #define MOODYCAMEL_ALIGNOF(obj) alignof(obj)
257 #define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) alignas(alignof(obj)) typename details::identity<T>::type
266 #define MOODYCAMEL_NO_TSAN
267 #if defined(__has_feature)
268 #if __has_feature(thread_sanitizer)
269 #undef MOODYCAMEL_NO_TSAN
270 #define MOODYCAMEL_NO_TSAN __attribute__((no_sanitize("thread")))
276 #if defined(__GNUC__)
277 static inline bool (
likely)(
bool x) {
return __builtin_expect((
x),
true); }
278 static inline bool (
unlikely)(
bool x) {
return __builtin_expect((
x),
false); }
285 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
286 #include "internal/concurrentqueue_internal_debug.h"
295 ? (
static_cast<T>(1) << (
sizeof(
T) * CHAR_BIT - 1)) -
static_cast<T>(1)
296 :
static_cast<T>(-1);
299 #if defined(__GLIBCXX__)
383 #ifndef MCDBGQ_USE_RELACY
386 #if defined(malloc) || defined(free)
389 static inline void* WORKAROUND_malloc(
size_t size) {
return malloc(
size); }
390 static inline void WORKAROUND_free(
void*
ptr) {
return free(
ptr); }
391 static inline void* (
malloc)(
size_t size) {
return WORKAROUND_malloc(
size); }
392 static inline void (
free)(
void*
ptr) {
return WORKAROUND_free(
ptr); }
395 static inline void free(
void*
ptr) {
return std::free(
ptr); }
400 static inline void*
malloc(
size_t size) {
return rl::rl_malloc(
size, $); }
401 static inline void free(
void*
ptr) {
return rl::rl_free(
ptr, $); }
413 struct ProducerToken;
414 struct ConsumerToken;
418 class ConcurrentQueueTests;
436 static inline std::uint32_t
hash(std::uint32_t h)
446 return h ^ (h >> 16);
450 static inline std::uint64_t
hash(std::uint64_t h)
453 h *= 0xff51afd7ed558ccd;
455 h *= 0xc4ceb9fe1a85ec53;
456 return h ^ (h >> 33);
463 static_assert(
sizeof(
thread_id_t) <= 8,
"Expected a platform where thread IDs are at most 64-bit values");
472 #pragma warning(push)
473 #pragma warning(disable: 4554)
476 return static_cast<T>(a - b) >
static_cast<T>(
static_cast<T>(1) <<
static_cast<T>(
sizeof(
T) * CHAR_BIT - 1));
499 for (std::size_t
i = 1;
i <
sizeof(
T);
i <<= 1) {
509 T temp = std::move(
left.load(std::memory_order_relaxed));
510 left.store(std::move(
right.load(std::memory_order_relaxed)), std::memory_order_relaxed);
511 right.store(std::move(
temp), std::memory_order_relaxed);
520 template<
bool Enable>
535 -> decltype(std::forward<U>(
x))
537 return std::forward<U>(
x);
541 template<
typename It>
547 #if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
553 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
554 #ifdef MCDBGQ_USE_RELACY
555 typedef RelacyThreadExitListener ThreadExitListener;
556 typedef RelacyThreadExitNotifier ThreadExitNotifier;
558 struct ThreadExitListener
560 typedef void (*callback_t)(
void*);
564 ThreadExitListener* next;
568 class ThreadExitNotifier
571 static void subscribe(ThreadExitListener* listener)
573 auto& tlsInst = instance();
574 listener->next = tlsInst.tail;
575 tlsInst.tail = listener;
578 static void unsubscribe(ThreadExitListener* listener)
580 auto& tlsInst = instance();
581 ThreadExitListener** prev = &tlsInst.tail;
582 for (
auto ptr = tlsInst.tail;
ptr !=
nullptr;
ptr =
ptr->next) {
583 if (
ptr == listener) {
592 ThreadExitNotifier() : tail(nullptr) { }
596 ~ThreadExitNotifier()
599 assert(
this == &instance() &&
"If this assert fails, you likely have a buggy compiler! Change the preprocessor conditions such that MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined.");
600 for (
auto ptr = tail;
ptr !=
nullptr;
ptr =
ptr->next) {
601 ptr->callback(
ptr->userData);
606 static inline ThreadExitNotifier& instance()
608 static thread_local ThreadExitNotifier notifier;
613 ThreadExitListener* tail;
632 template<
typename T,
typename Traits>
635 template<
typename T,
typename Traits>
641 other.producer =
nullptr;
659 if (other.producer !=
nullptr) {
697 template<
typename T,
typename Traits>
700 template<
typename T,
typename Traits>
741 template<
typename T,
typename Traits>
745 template<
typename T,
typename Traits = ConcurrentQueueDefaultTraits>
755 static const size_t BLOCK_SIZE =
static_cast<size_t>(Traits::BLOCK_SIZE);
762 #pragma warning(push)
763 #pragma warning(disable: 4307) // + integral constant overflow (that's what the ternary expression is for!)
764 #pragma warning(disable: 4309) // static_cast: Truncation of constant value
773 static_assert(
sizeof(
index_t) >=
sizeof(
size_t),
"Traits::index_t must be at least as wide as Traits::size_t");
803 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
808 explicitProducers.store(
nullptr, std::memory_order_relaxed);
809 implicitProducers.store(
nullptr, std::memory_order_relaxed);
816 ConcurrentQueue(
size_t minCapacity,
size_t maxExplicitProducers,
size_t maxImplicitProducers)
825 size_t blocks = (((minCapacity +
BLOCK_SIZE - 1) /
BLOCK_SIZE) - 1) * (maxExplicitProducers + 1) + 2 * (maxExplicitProducers + maxImplicitProducers);
828 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
829 explicitProducers.store(
nullptr, std::memory_order_relaxed);
830 implicitProducers.store(
nullptr, std::memory_order_relaxed);
841 while (
ptr !=
nullptr) {
842 auto next =
ptr->next_prod();
843 if (
ptr->token !=
nullptr) {
844 ptr->token->producer =
nullptr;
853 while (
hash !=
nullptr) {
854 auto prev =
hash->prev;
855 if (prev !=
nullptr) {
856 for (
size_t i = 0;
i !=
hash->capacity; ++
i) {
857 hash->entries[
i].~ImplicitProducerKVP();
859 hash->~ImplicitProducerHash();
860 (Traits::free)(
hash);
867 auto block =
freeList.head_unsafe();
868 while (block !=
nullptr) {
869 auto next = block->freeListNext.load(std::memory_order_relaxed);
870 if (block->dynamicallyAllocated) {
892 producerCount(other.producerCount.load(std::memory_order_relaxed)),
896 freeList(std::move(other.freeList)),
905 other.producerListTail.store(
nullptr, std::memory_order_relaxed);
906 other.producerCount.store(0, std::memory_order_relaxed);
907 other.nextExplicitConsumerId.store(0, std::memory_order_relaxed);
908 other.globalExplicitConsumerOffset.store(0, std::memory_order_relaxed);
910 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
911 explicitProducers.store(other.explicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed);
912 other.explicitProducers.store(
nullptr, std::memory_order_relaxed);
913 implicitProducers.store(other.implicitProducers.load(std::memory_order_relaxed), std::memory_order_relaxed);
914 other.implicitProducers.store(
nullptr, std::memory_order_relaxed);
917 other.initialBlockPoolIndex.store(0, std::memory_order_relaxed);
918 other.initialBlockPoolSize = 0;
919 other.initialBlockPool =
nullptr;
942 if (
this == &other) {
960 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
977 else return inner_enqueue<CanAlloc>(item);
988 else return inner_enqueue<CanAlloc>(std::move(item));
997 return inner_enqueue<CanAlloc>(token, item);
1006 return inner_enqueue<CanAlloc>(token, std::move(item));
1015 template<
typename It>
1019 else return inner_enqueue_bulk<CanAlloc>(itemFirst,
count);
1028 template<
typename It>
1031 return inner_enqueue_bulk<CanAlloc>(token, itemFirst,
count);
1042 else return inner_enqueue<CannotAlloc>(item);
1053 else return inner_enqueue<CannotAlloc>(std::move(item));
1061 return inner_enqueue<CannotAlloc>(token, item);
1069 return inner_enqueue<CannotAlloc>(token, std::move(item));
1079 template<
typename It>
1083 else return inner_enqueue_bulk<CannotAlloc>(itemFirst,
count);
1091 template<
typename It>
1094 return inner_enqueue_bulk<CannotAlloc>(token, itemFirst,
count);
1103 template<
typename U>
1108 size_t nonEmptyCount = 0;
1109 ProducerBase* best =
nullptr;
1110 size_t bestSize = 0;
1111 for (
auto ptr =
producerListTail.load(std::memory_order_acquire); nonEmptyCount < 3 && ptr != nullptr; ptr = ptr->next_prod()) {
1112 auto size =
ptr->size_approx();
1114 if (
size > bestSize) {
1124 if (nonEmptyCount > 0) {
1129 if (
ptr != best &&
ptr->dequeue(item)) {
1146 template<
typename U>
1150 if (
ptr->dequeue(item)) {
1161 template<
typename U>
1178 if (
static_cast<ProducerBase*
>(token.
currentProducer)->dequeue(item)) {
1187 if (
ptr ==
nullptr) {
1191 if (
ptr->dequeue(item)) {
1197 if (
ptr ==
nullptr) {
1209 template<
typename It>
1227 template<
typename It>
1248 if (
ptr ==
nullptr) {
1252 auto dequeued =
ptr->dequeue_bulk(itemFirst,
max);
1254 if (dequeued != 0) {
1258 if (dequeued ==
max) {
1263 if (
ptr ==
nullptr) {
1278 template<
typename U>
1291 template<
typename It>
1345 template<AllocationMode canAlloc,
typename U>
1348 return static_cast<ExplicitProducer*
>(token.
producer)->ConcurrentQueue::ExplicitProducer::template enqueue<canAlloc>(std::forward<U>(element));
1351 template<AllocationMode canAlloc,
typename U>
1355 return producer ==
nullptr ? false : producer->ConcurrentQueue::ImplicitProducer::template enqueue<canAlloc>(std::forward<U>(element));
1358 template<AllocationMode canAlloc,
typename It>
1361 return static_cast<ExplicitProducer*
>(token.
producer)->ConcurrentQueue::ExplicitProducer::template enqueue_bulk<canAlloc>(itemFirst,
count);
1364 template<AllocationMode canAlloc,
typename It>
1368 return producer ==
nullptr ? false : producer->ConcurrentQueue::ImplicitProducer::template enqueue_bulk<canAlloc>(itemFirst,
count);
1378 auto prodCount =
producerCount.load(std::memory_order_relaxed);
1384 std::uint32_t offset = prodCount - 1 - (token.
initialOffset % prodCount);
1386 for (std::uint32_t
i = 0;
i != offset; ++
i) {
1395 if (delta >= prodCount) {
1396 delta = delta % prodCount;
1398 for (std::uint32_t
i = 0;
i != delta; ++
i) {
1416 template <
typename N>
1428 template<
typename N>
1440 #ifdef MCDBGQ_NOLOCKFREE_FREELIST
1441 debug::DebugLock lock(mutex);
1454 #ifdef MCDBGQ_NOLOCKFREE_FREELIST
1455 debug::DebugLock lock(mutex);
1457 auto head =
freeListHead.load(std::memory_order_acquire);
1458 while (head !=
nullptr) {
1459 auto prevHead = head;
1460 auto refs = head->freeListRefs.load(std::memory_order_relaxed);
1461 if ((refs &
REFS_MASK) == 0 || !head->freeListRefs.compare_exchange_strong(refs, refs + 1, std::memory_order_acquire, std::memory_order_relaxed)) {
1468 auto next = head->freeListNext.load(std::memory_order_relaxed);
1469 if (
freeListHead.compare_exchange_strong(head, next, std::memory_order_acquire, std::memory_order_relaxed)) {
1475 head->freeListRefs.fetch_sub(2, std::memory_order_release);
1482 refs = prevHead->freeListRefs.fetch_sub(1, std::memory_order_acq_rel);
1505 auto head =
freeListHead.load(std::memory_order_relaxed);
1507 node->freeListNext.store(head, std::memory_order_relaxed);
1508 node->freeListRefs.store(1, std::memory_order_release);
1509 if (!
freeListHead.compare_exchange_strong(head, node, std::memory_order_release, std::memory_order_relaxed)) {
1526 #ifdef MCDBGQ_NOLOCKFREE_FREELIST
1527 debug::DebugMutex mutex;
1543 #ifdef MCDBGQ_TRACKMEM
1548 template<InnerQueueContext context>
1560 std::atomic_thread_fence(std::memory_order_acquire);
1566 std::atomic_thread_fence(std::memory_order_acquire);
1575 template<InnerQueueContext context>
1594 template<InnerQueueContext context>
1599 std::atomic_thread_fence(std::memory_order_release);
1601 for (
size_t j = 0; j !=
count; ++j) {
1603 emptyFlags[
i + j].store(
true, std::memory_order_relaxed);
1615 template<InnerQueueContext context>
1621 emptyFlags[
i].store(
true, std::memory_order_relaxed);
1630 template<InnerQueueContext context>
1636 emptyFlags[
i].store(
false, std::memory_order_relaxed);
1661 #ifdef MCDBGQ_TRACKMEM
1668 #ifdef MCDBGQ_TRACKMEM
1693 template<
typename U>
1704 template<
typename It>
1719 auto tail =
tailIndex.load(std::memory_order_relaxed);
1720 auto head =
headIndex.load(std::memory_order_relaxed);
1739 #ifdef MCDBGQ_TRACKMEM
1740 friend struct MemStats;
1775 Block* halfDequeuedBlock =
nullptr;
1790 block = block->next;
1791 if (block->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
1796 if (block == halfDequeuedBlock) {
1803 (*block)[
i++]->~T();
1812 auto nextBlock = block->next;
1813 if (block->dynamicallyAllocated) {
1825 while (header !=
nullptr) {
1827 header->~BlockIndexHeader();
1828 (Traits::free)(header);
1833 template<AllocationMode allocMode,
typename U>
1836 index_t currentTailIndex = this->
tailIndex.load(std::memory_order_relaxed);
1837 index_t newTailIndex = 1 + currentTailIndex;
1842 if (this->
tailBlock !=
nullptr && this->
tailBlock->
next->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
1845 this->
tailBlock->ConcurrentQueue::Block::template reset_empty<explicit_context>();
1857 auto head = this->
headIndex.load(std::memory_order_relaxed);
1858 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
1859 if (!details::circular_less_than<index_t>(head, currentTailIndex +
BLOCK_SIZE)
1881 auto newBlock = this->
parent->ConcurrentQueue::template requisition_block<allocMode>();
1882 if (newBlock ==
nullptr) {
1885 #ifdef MCDBGQ_TRACKMEM
1886 newBlock->owner =
this;
1888 newBlock->ConcurrentQueue::Block::template reset_empty<explicit_context>();
1890 newBlock->next = newBlock;
1904 new ((*this->
tailBlock)[currentTailIndex])
T(std::forward<U>(element));
1916 (
void)originalBlockIndexSlotsUsed;
1921 entry.base = currentTailIndex;
1927 this->
tailIndex.store(newTailIndex, std::memory_order_release);
1933 new ((*this->
tailBlock)[currentTailIndex])
T(std::forward<U>(element));
1935 this->
tailIndex.store(newTailIndex, std::memory_order_release);
1939 template<
typename U>
1942 auto tail = this->
tailIndex.load(std::memory_order_relaxed);
1944 if (details::circular_less_than<index_t>(this->
dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) {
1961 std::atomic_thread_fence(std::memory_order_acquire);
1976 tail = this->
tailIndex.load(std::memory_order_acquire);
1977 if ((
details::likely)(details::circular_less_than<index_t>(myDequeueCount - overcommit, tail))) {
1988 auto index = this->
headIndex.fetch_add(1, std::memory_order_acq_rel);
1993 auto localBlockIndex =
blockIndex.load(std::memory_order_acquire);
1994 auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire);
1999 auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
2002 auto block = localBlockIndex->entries[(localBlockIndexHead + offset) & (localBlockIndex->size - 1)].block;
2005 auto& el = *((*block)[
index]);
2015 (*block)[
index]->~T();
2016 block->ConcurrentQueue::Block::template set_empty<explicit_context>(
index);
2018 } guard = { block,
index };
2020 element = std::move(el);
2023 element = std::move(el);
2025 block->ConcurrentQueue::Block::template set_empty<explicit_context>(
index);
2039 template<AllocationMode allocMode,
typename It>
2050 Block* firstAllocatedBlock =
nullptr;
2053 size_t blockBaseDiff = ((startTailIndex +
count - 1) & ~
static_cast<index_t>(
BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast<index_t>(
BLOCK_SIZE - 1));
2055 if (blockBaseDiff > 0) {
2057 while (blockBaseDiff > 0 && this->
tailBlock !=
nullptr && this->
tailBlock->
next != firstAllocatedBlock && this->tailBlock->
next->ConcurrentQueue::Block::template is_empty<explicit_context>()) {
2062 firstAllocatedBlock = firstAllocatedBlock ==
nullptr ? this->
tailBlock : firstAllocatedBlock;
2065 entry.base = currentTailIndex;
2071 while (blockBaseDiff > 0) {
2075 auto head = this->
headIndex.load(std::memory_order_relaxed);
2076 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
2083 this->
tailBlock = startBlock ==
nullptr ? firstAllocatedBlock : startBlock;
2090 this->
tailBlock = startBlock ==
nullptr ? firstAllocatedBlock : startBlock;
2097 originalBlockIndexFront = originalBlockIndexSlotsUsed;
2101 auto newBlock = this->
parent->ConcurrentQueue::template requisition_block<allocMode>();
2102 if (newBlock ==
nullptr) {
2105 this->
tailBlock = startBlock ==
nullptr ? firstAllocatedBlock : startBlock;
2109 #ifdef MCDBGQ_TRACKMEM
2110 newBlock->owner =
this;
2112 newBlock->ConcurrentQueue::Block::template set_all_empty<explicit_context>();
2114 newBlock->next = newBlock;
2121 firstAllocatedBlock = firstAllocatedBlock ==
nullptr ? this->
tailBlock : firstAllocatedBlock;
2126 entry.base = currentTailIndex;
2133 auto block = firstAllocatedBlock;
2135 block->ConcurrentQueue::Block::template reset_empty<explicit_context>();
2139 block = block->next;
2149 currentTailIndex = startTailIndex;
2152 assert((startTailIndex &
static_cast<index_t>(
BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock !=
nullptr ||
count == 0);
2153 if ((startTailIndex &
static_cast<index_t>(
BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock !=
nullptr) {
2158 if (details::circular_less_than<index_t>(newTailIndex, stopIndex)) {
2159 stopIndex = newTailIndex;
2162 while (currentTailIndex != stopIndex) {
2163 new ((*this->
tailBlock)[currentTailIndex++])
T(*itemFirst++);
2168 while (currentTailIndex != stopIndex) {
2185 auto constructedStopIndex = currentTailIndex;
2186 auto lastBlockEnqueued = this->
tailBlock;
2190 this->
tailBlock = startBlock ==
nullptr ? firstAllocatedBlock : startBlock;
2193 auto block = startBlock;
2195 block = firstAllocatedBlock;
2197 currentTailIndex = startTailIndex;
2200 if (details::circular_less_than<index_t>(constructedStopIndex, stopIndex)) {
2201 stopIndex = constructedStopIndex;
2203 while (currentTailIndex != stopIndex) {
2204 (*block)[currentTailIndex++]->~T();
2206 if (block == lastBlockEnqueued) {
2209 block = block->next;
2217 assert(currentTailIndex == newTailIndex);
2224 if (firstAllocatedBlock !=
nullptr)
2228 this->
tailIndex.store(newTailIndex, std::memory_order_release);
2232 template<
typename It>
2235 auto tail = this->
tailIndex.load(std::memory_order_relaxed);
2237 auto desiredCount =
static_cast<size_t>(tail - (this->
dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit));
2238 if (details::circular_less_than<size_t>(0, desiredCount)) {
2239 desiredCount = desiredCount <
max ? desiredCount :
max;
2240 std::atomic_thread_fence(std::memory_order_acquire);
2244 tail = this->
tailIndex.load(std::memory_order_acquire);
2245 auto actualCount =
static_cast<size_t>(tail - (myDequeueCount - overcommit));
2246 if (details::circular_less_than<size_t>(0, actualCount)) {
2247 actualCount = desiredCount < actualCount ? desiredCount : actualCount;
2248 if (actualCount < desiredCount) {
2249 this->
dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release);
2254 auto firstIndex = this->
headIndex.fetch_add(actualCount, std::memory_order_acq_rel);
2257 auto localBlockIndex =
blockIndex.load(std::memory_order_acquire);
2258 auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire);
2260 auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
2261 auto firstBlockBaseIndex = firstIndex & ~static_cast<index_t>(
BLOCK_SIZE - 1);
2263 auto indexIndex = (localBlockIndexHead + offset) & (localBlockIndex->size - 1);
2266 auto index = firstIndex;
2268 auto firstIndexInBlock =
index;
2270 endIndex = details::circular_less_than<index_t>(firstIndex +
static_cast<index_t>(actualCount), endIndex) ? firstIndex +
static_cast<index_t>(actualCount) : endIndex;
2271 auto block = localBlockIndex->entries[indexIndex].block;
2273 while (
index != endIndex) {
2274 auto& el = *((*block)[
index]);
2275 *itemFirst++ = std::move(el);
2282 while (
index != endIndex) {
2283 auto& el = *((*block)[
index]);
2284 *itemFirst = std::move(el);
2295 block = localBlockIndex->entries[indexIndex].block;
2296 while (
index != endIndex) {
2297 (*block)[
index++]->~T();
2299 block->ConcurrentQueue::Block::template set_many_empty<explicit_context>(firstIndexInBlock,
static_cast<size_t>(endIndex - firstIndexInBlock));
2300 indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1);
2302 firstIndexInBlock =
index;
2304 endIndex = details::circular_less_than<index_t>(firstIndex +
static_cast<index_t>(actualCount), endIndex) ? firstIndex +
static_cast<index_t>(actualCount) : endIndex;
2305 }
while (
index != firstIndex + actualCount);
2310 block->ConcurrentQueue::Block::template set_many_empty<explicit_context>(firstIndexInBlock,
static_cast<size_t>(endIndex - firstIndexInBlock));
2311 indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1);
2312 }
while (
index != firstIndex + actualCount);
2348 if (newRawPtr ==
nullptr) {
2361 i = (
i + 1) & prevBlockSizeMask;
2368 header->front.store(numberOfFilledSlotsToExpose - 1, std::memory_order_relaxed);
2369 header->entries = newBlockIndexEntries;
2375 blockIndex.store(header, std::memory_order_release);
2390 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
2396 #ifdef MCDBGQ_TRACKMEM
2397 friend struct MemStats;
2423 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
2425 if (!this->
inactive.load(std::memory_order_relaxed)) {
2426 details::ThreadExitNotifier::unsubscribe(&threadExitListener);
2431 auto tail = this->
tailIndex.load(std::memory_order_relaxed);
2433 Block* block =
nullptr;
2435 bool forceFreeLastBlock =
index != tail;
2436 while (
index != tail) {
2438 if (block !=
nullptr) {
2457 auto localBlockIndex =
blockIndex.load(std::memory_order_relaxed);
2458 if (localBlockIndex !=
nullptr) {
2459 for (
size_t i = 0;
i != localBlockIndex->capacity; ++
i) {
2460 localBlockIndex->index[
i]->~BlockIndexEntry();
2463 auto prev = localBlockIndex->prev;
2464 localBlockIndex->~BlockIndexHeader();
2465 (Traits::free)(localBlockIndex);
2466 localBlockIndex = prev;
2467 }
while (localBlockIndex !=
nullptr);
2471 template<AllocationMode allocMode,
typename U>
2474 index_t currentTailIndex = this->
tailIndex.load(std::memory_order_relaxed);
2475 index_t newTailIndex = 1 + currentTailIndex;
2478 auto head = this->
headIndex.load(std::memory_order_relaxed);
2479 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
2483 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2484 debug::DebugLock lock(mutex);
2488 if (!insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) {
2493 auto newBlock = this->
parent->ConcurrentQueue::template requisition_block<allocMode>();
2494 if (newBlock ==
nullptr) {
2496 idxEntry->
value.store(
nullptr, std::memory_order_relaxed);
2499 #ifdef MCDBGQ_TRACKMEM
2500 newBlock->owner =
this;
2502 newBlock->ConcurrentQueue::Block::template reset_empty<implicit_context>();
2507 new ((*newBlock)[currentTailIndex])
T(std::forward<U>(element));
2511 idxEntry->
value.store(
nullptr, std::memory_order_relaxed);
2518 idxEntry->
value.store(newBlock, std::memory_order_relaxed);
2523 this->
tailIndex.store(newTailIndex, std::memory_order_release);
2529 new ((*this->
tailBlock)[currentTailIndex])
T(std::forward<U>(element));
2531 this->
tailIndex.store(newTailIndex, std::memory_order_release);
2535 template<
typename U>
2541 if (details::circular_less_than<index_t>(this->
dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit, tail)) {
2542 std::atomic_thread_fence(std::memory_order_acquire);
2545 tail = this->
tailIndex.load(std::memory_order_acquire);
2546 if ((
details::likely)(details::circular_less_than<index_t>(myDequeueCount - overcommit, tail))) {
2553 auto block = entry->value.load(std::memory_order_relaxed);
2554 auto& el = *((*block)[
index]);
2557 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2560 debug::DebugLock lock(producer->mutex);
2570 (*block)[
index]->~T();
2571 if (block->ConcurrentQueue::Block::template set_empty<implicit_context>(
index)) {
2572 entry->
value.store(
nullptr, std::memory_order_relaxed);
2578 element = std::move(el);
2581 element = std::move(el);
2584 if (block->ConcurrentQueue::Block::template set_empty<implicit_context>(
index)) {
2586 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2587 debug::DebugLock lock(mutex);
2590 entry->value.store(
nullptr, std::memory_order_relaxed);
2607 #pragma warning(push)
2608 #pragma warning(disable: 4706) // assignment within conditional expression
2610 template<AllocationMode allocMode,
typename It>
2624 Block* firstAllocatedBlock =
nullptr;
2628 size_t blockBaseDiff = ((startTailIndex +
count - 1) & ~
static_cast<index_t>(
BLOCK_SIZE - 1)) - ((startTailIndex - 1) & ~static_cast<index_t>(
BLOCK_SIZE - 1));
2630 if (blockBaseDiff > 0) {
2631 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2632 debug::DebugLock lock(mutex);
2641 bool indexInserted =
false;
2642 auto head = this->
headIndex.load(std::memory_order_relaxed);
2643 assert(!details::circular_less_than<index_t>(currentTailIndex, head));
2646 if (full || !(indexInserted = insert_block_index_entry<allocMode>(idxEntry, currentTailIndex)) || (newBlock = this->
parent->ConcurrentQueue::template requisition_block<allocMode>()) ==
nullptr) {
2649 if (indexInserted) {
2651 idxEntry->
value.store(
nullptr, std::memory_order_relaxed);
2653 currentTailIndex = (startTailIndex - 1) & ~
static_cast<index_t>(
BLOCK_SIZE - 1);
2654 for (
auto block = firstAllocatedBlock; block !=
nullptr; block = block->next) {
2657 idxEntry->
value.store(
nullptr, std::memory_order_relaxed);
2666 #ifdef MCDBGQ_TRACKMEM
2667 newBlock->owner =
this;
2669 newBlock->ConcurrentQueue::Block::template reset_empty<implicit_context>();
2670 newBlock->
next =
nullptr;
2673 idxEntry->
value.store(newBlock, std::memory_order_relaxed);
2677 if ((startTailIndex &
static_cast<index_t>(
BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock !=
nullptr) {
2682 endBlock = newBlock;
2683 firstAllocatedBlock = firstAllocatedBlock ==
nullptr ? newBlock : firstAllocatedBlock;
2684 }
while (blockBaseDiff > 0);
2689 currentTailIndex = startTailIndex;
2691 assert((startTailIndex &
static_cast<index_t>(
BLOCK_SIZE - 1)) != 0 || firstAllocatedBlock !=
nullptr ||
count == 0);
2692 if ((startTailIndex &
static_cast<index_t>(
BLOCK_SIZE - 1)) == 0 && firstAllocatedBlock !=
nullptr) {
2697 if (details::circular_less_than<index_t>(newTailIndex, stopIndex)) {
2698 stopIndex = newTailIndex;
2701 while (currentTailIndex != stopIndex) {
2702 new ((*this->
tailBlock)[currentTailIndex++])
T(*itemFirst++);
2707 while (currentTailIndex != stopIndex) {
2714 auto constructedStopIndex = currentTailIndex;
2715 auto lastBlockEnqueued = this->
tailBlock;
2718 auto block = startBlock;
2720 block = firstAllocatedBlock;
2722 currentTailIndex = startTailIndex;
2725 if (details::circular_less_than<index_t>(constructedStopIndex, stopIndex)) {
2726 stopIndex = constructedStopIndex;
2728 while (currentTailIndex != stopIndex) {
2729 (*block)[currentTailIndex++]->~T();
2731 if (block == lastBlockEnqueued) {
2734 block = block->next;
2738 currentTailIndex = (startTailIndex - 1) & ~
static_cast<index_t>(
BLOCK_SIZE - 1);
2739 for (
auto block = firstAllocatedBlock; block !=
nullptr; block = block->next) {
2742 idxEntry->value.store(
nullptr, std::memory_order_relaxed);
2752 assert(currentTailIndex == newTailIndex);
2757 this->
tailIndex.store(newTailIndex, std::memory_order_release);
2761 #pragma warning(pop)
2764 template<
typename It>
2767 auto tail = this->
tailIndex.load(std::memory_order_relaxed);
2769 auto desiredCount =
static_cast<size_t>(tail - (this->
dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit));
2770 if (details::circular_less_than<size_t>(0, desiredCount)) {
2771 desiredCount = desiredCount <
max ? desiredCount :
max;
2772 std::atomic_thread_fence(std::memory_order_acquire);
2776 tail = this->
tailIndex.load(std::memory_order_acquire);
2777 auto actualCount =
static_cast<size_t>(tail - (myDequeueCount - overcommit));
2778 if (details::circular_less_than<size_t>(0, actualCount)) {
2779 actualCount = desiredCount < actualCount ? desiredCount : actualCount;
2780 if (actualCount < desiredCount) {
2781 this->
dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release);
2786 auto firstIndex = this->
headIndex.fetch_add(actualCount, std::memory_order_acq_rel);
2789 auto index = firstIndex;
2793 auto blockStartIndex =
index;
2795 endIndex = details::circular_less_than<index_t>(firstIndex +
static_cast<index_t>(actualCount), endIndex) ? firstIndex +
static_cast<index_t>(actualCount) : endIndex;
2797 auto entry = localBlockIndex->
index[indexIndex];
2798 auto block = entry->value.load(std::memory_order_relaxed);
2800 while (
index != endIndex) {
2801 auto& el = *((*block)[
index]);
2802 *itemFirst++ = std::move(el);
2809 while (
index != endIndex) {
2810 auto& el = *((*block)[
index]);
2811 *itemFirst = std::move(el);
2819 entry = localBlockIndex->
index[indexIndex];
2820 block = entry->value.load(std::memory_order_relaxed);
2821 while (
index != endIndex) {
2822 (*block)[
index++]->~T();
2825 if (block->ConcurrentQueue::Block::template set_many_empty<implicit_context>(blockStartIndex,
static_cast<size_t>(endIndex - blockStartIndex))) {
2826 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2827 debug::DebugLock lock(mutex);
2829 entry->value.store(
nullptr, std::memory_order_relaxed);
2832 indexIndex = (indexIndex + 1) & (localBlockIndex->
capacity - 1);
2834 blockStartIndex =
index;
2836 endIndex = details::circular_less_than<index_t>(firstIndex +
static_cast<index_t>(actualCount), endIndex) ? firstIndex +
static_cast<index_t>(actualCount) : endIndex;
2837 }
while (
index != firstIndex + actualCount);
2842 if (block->ConcurrentQueue::Block::template set_many_empty<implicit_context>(blockStartIndex,
static_cast<size_t>(endIndex - blockStartIndex))) {
2844 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2845 debug::DebugLock lock(mutex);
2849 entry->value.store(
nullptr, std::memory_order_relaxed);
2853 indexIndex = (indexIndex + 1) & (localBlockIndex->
capacity - 1);
2854 }
while (
index != firstIndex + actualCount);
2885 template<AllocationMode allocMode>
2888 auto localBlockIndex =
blockIndex.load(std::memory_order_relaxed);
2889 if (localBlockIndex ==
nullptr) {
2892 size_t newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1);
2893 idxEntry = localBlockIndex->index[newTail];
2895 idxEntry->
value.load(std::memory_order_relaxed) ==
nullptr) {
2897 idxEntry->
key.store(blockStartIndex, std::memory_order_relaxed);
2898 localBlockIndex->tail.store(newTail, std::memory_order_release);
2909 localBlockIndex =
blockIndex.load(std::memory_order_relaxed);
2910 newTail = (localBlockIndex->tail.load(std::memory_order_relaxed) + 1) & (localBlockIndex->capacity - 1);
2911 idxEntry = localBlockIndex->index[newTail];
2913 idxEntry->
key.store(blockStartIndex, std::memory_order_relaxed);
2914 localBlockIndex->tail.store(newTail, std::memory_order_release);
2920 auto localBlockIndex =
blockIndex.load(std::memory_order_relaxed);
2921 localBlockIndex->tail.store((localBlockIndex->tail.load(std::memory_order_relaxed) - 1) & (localBlockIndex->capacity - 1), std::memory_order_relaxed);
2928 return localBlockIndex->
index[idx];
2933 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
2934 debug::DebugLock lock(mutex);
2937 localBlockIndex =
blockIndex.load(std::memory_order_acquire);
2938 auto tail = localBlockIndex->
tail.load(std::memory_order_acquire);
2939 auto tailBase = localBlockIndex->
index[tail]->
key.load(std::memory_order_relaxed);
2944 size_t idx = (tail + offset) & (localBlockIndex->
capacity - 1);
2945 assert(localBlockIndex->
index[idx]->
key.load(std::memory_order_relaxed) ==
index && localBlockIndex->
index[idx]->
value.load(std::memory_order_relaxed) !=
nullptr);
2951 auto prev =
blockIndex.load(std::memory_order_relaxed);
2952 size_t prevCapacity = prev ==
nullptr ? 0 : prev->capacity;
2954 auto raw =
static_cast<char*
>((Traits::malloc)(
2958 if (raw ==
nullptr) {
2965 if (prev !=
nullptr) {
2966 auto prevTail = prev->tail.load(std::memory_order_relaxed);
2967 auto prevPos = prevTail;
2970 prevPos = (prevPos + 1) & (prev->capacity - 1);
2971 index[
i++] = prev->index[prevPos];
2972 }
while (prevPos != prevTail);
2973 assert(
i == prevCapacity);
2975 for (
size_t i = 0;
i != entryCount; ++
i) {
2978 index[prevCapacity +
i] = entries +
i;
2980 header->prev = prev;
2981 header->entries = entries;
2982 header->index =
index;
2986 blockIndex.store(header, std::memory_order_release);
2997 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
2999 details::ThreadExitListener threadExitListener;
3003 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
3009 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODBLOCKINDEX
3010 mutable debug::DebugMutex mutex;
3012 #ifdef MCDBGQ_TRACKMEM
3013 friend struct MemStats;
3052 #ifdef MCDBGQ_TRACKMEM
3053 block->owner =
nullptr;
3060 while (block !=
nullptr) {
3061 auto next = block->next;
3073 template<AllocationMode canAlloc>
3077 if (block !=
nullptr) {
3082 if (block !=
nullptr) {
3087 return create<Block>();
3095 #ifdef MCDBGQ_TRACKMEM
3098 size_t allocatedBlocks;
3101 size_t ownedBlocksExplicit;
3102 size_t ownedBlocksImplicit;
3103 size_t implicitProducers;
3104 size_t explicitProducers;
3105 size_t elementsEnqueued;
3106 size_t blockClassBytes;
3107 size_t queueClassBytes;
3108 size_t implicitBlockIndexBytes;
3109 size_t explicitBlockIndexBytes;
3116 MemStats stats = { 0 };
3120 auto block = q->
freeList.head_unsafe();
3121 while (block !=
nullptr) {
3122 ++stats.allocatedBlocks;
3124 block = block->freeListNext.load(std::memory_order_relaxed);
3129 stats.implicitProducers += implicit ? 1 : 0;
3130 stats.explicitProducers += implicit ? 0 : 1;
3135 auto head = prod->headIndex.load(std::memory_order_relaxed);
3136 auto tail = prod->tailIndex.load(std::memory_order_relaxed);
3137 auto hash = prod->blockIndex.load(std::memory_order_relaxed);
3138 if (
hash !=
nullptr) {
3139 for (
size_t i = 0;
i !=
hash->capacity; ++
i) {
3141 ++stats.allocatedBlocks;
3142 ++stats.ownedBlocksImplicit;
3145 stats.implicitBlockIndexBytes +=
hash->capacity *
sizeof(
typename ImplicitProducer::BlockIndexEntry);
3147 stats.implicitBlockIndexBytes +=
sizeof(
typename ImplicitProducer::BlockIndexHeader) +
hash->capacity *
sizeof(
typename ImplicitProducer::BlockIndexEntry*);
3150 for (; details::circular_less_than<index_t>(head, tail); head +=
BLOCK_SIZE) {
3158 auto tailBlock = prod->tailBlock;
3159 bool wasNonEmpty =
false;
3160 if (tailBlock !=
nullptr) {
3161 auto block = tailBlock;
3163 ++stats.allocatedBlocks;
3164 if (!
block->ConcurrentQueue::Block::template is_empty<explicit_context>() || wasNonEmpty) {
3166 wasNonEmpty = wasNonEmpty ||
block != tailBlock;
3168 ++stats.ownedBlocksExplicit;
3170 }
while (block != tailBlock);
3172 auto index = prod->blockIndex.load(std::memory_order_relaxed);
3173 while (
index !=
nullptr) {
3174 stats.explicitBlockIndexBytes +=
sizeof(
typename ExplicitProducer::BlockIndexHeader) +
index->size *
sizeof(
typename ExplicitProducer::BlockIndexEntry);
3175 index =
static_cast<typename ExplicitProducer::BlockIndexHeader*
>(
index->prev);
3181 stats.allocatedBlocks += freeOnInitialPool;
3182 stats.freeBlocks += freeOnInitialPool;
3184 stats.blockClassBytes =
sizeof(Block) * stats.allocatedBlocks;
3192 MemStats getMemStats()
3194 return MemStats::getFor(
this);
3197 friend struct MemStats;
3213 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
3214 debug::DebugLock lock(implicitProdMutex);
3218 if (
ptr->inactive.load(std::memory_order_relaxed) &&
ptr->isExplicit == isExplicit) {
3219 bool expected =
true;
3220 if (
ptr->inactive.compare_exchange_strong(expected,
false, std::memory_order_acquire, std::memory_order_relaxed)) {
3229 return add_producer(isExplicit ?
static_cast<ProducerBase*
>(create<ExplicitProducer>(
this)) : create<ImplicitProducer>(
this));
3235 if (producer ==
nullptr) {
3244 producer->next = prevTail;
3245 }
while (!
producerListTail.compare_exchange_weak(prevTail, producer, std::memory_order_release, std::memory_order_relaxed));
3247 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
3248 if (producer->isExplicit) {
3249 auto prevTailExplicit = explicitProducers.load(std::memory_order_relaxed);
3251 static_cast<ExplicitProducer*
>(producer)->nextExplicitProducer = prevTailExplicit;
3252 }
while (!explicitProducers.compare_exchange_weak(prevTailExplicit,
static_cast<ExplicitProducer*
>(producer), std::memory_order_release, std::memory_order_relaxed));
3255 auto prevTailImplicit = implicitProducers.load(std::memory_order_relaxed);
3257 static_cast<ImplicitProducer*
>(producer)->nextImplicitProducer = prevTailImplicit;
3258 }
while (!implicitProducers.compare_exchange_weak(prevTailImplicit,
static_cast<ImplicitProducer*
>(producer), std::memory_order_release, std::memory_order_relaxed));
3282 std::atomic<details::thread_id_t>
key;
3289 key.store(other.key.load(std::memory_order_relaxed), std::memory_order_relaxed);
3290 value = other.value;
3301 if (
this != &other) {
3308 template<
typename XT,
typename XTraits>
3331 hash->prev =
nullptr;
3354 ImplicitProducerHash*
hash;
3364 ImplicitProducerHash*
hash;
3386 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
3387 debug::DebugLock lock(implicitProdMutex);
3394 assert(mainHash !=
nullptr);
3397 auto index = hashedId;
3401 auto probedKey =
hash->entries[
index].key.load(std::memory_order_relaxed);
3402 if (probedKey ==
id) {
3408 auto value =
hash->entries[
index].value;
3409 if (
hash != mainHash) {
3412 index &= mainHash->capacity - 1;
3413 probedKey = mainHash->entries[
index].key.load(std::memory_order_relaxed);
3415 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
3417 if ((probedKey == empty && mainHash->entries[
index].key.compare_exchange_strong(empty,
id, std::memory_order_relaxed, std::memory_order_relaxed)) ||
3418 (probedKey == reusable && mainHash->entries[
index].key.compare_exchange_strong(reusable,
id, std::memory_order_acquire, std::memory_order_acquire))) {
3420 if ((probedKey == empty && mainHash->entries[
index].key.compare_exchange_strong(empty,
id, std::memory_order_relaxed, std::memory_order_relaxed))) {
3422 mainHash->entries[
index].value = value;
3448 if (newCount >= (mainHash->capacity >> 1)) {
3449 auto newCapacity = mainHash->capacity << 1;
3450 while (newCount >= (newCapacity >> 1)) {
3454 if (raw ==
nullptr) {
3461 auto newHash =
new (raw) ImplicitProducerHash;
3462 newHash->capacity =
static_cast<size_t>(newCapacity);
3463 newHash->entries =
reinterpret_cast<ImplicitProducerKVP*
>(details::align_for<ImplicitProducerKVP>(raw +
sizeof(ImplicitProducerHash)));
3464 for (
size_t i = 0;
i != newCapacity; ++
i) {
3465 new (newHash->entries +
i) ImplicitProducerKVP;
3468 newHash->prev = mainHash;
3481 if (newCount < (mainHash->capacity >> 1) + (mainHash->capacity >> 2)) {
3484 if (producer ==
nullptr) {
3492 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
3493 producer->threadExitListener.callback = &ConcurrentQueue::implicit_producer_thread_exited_callback;
3494 producer->threadExitListener.userData = producer;
3495 details::ThreadExitNotifier::subscribe(&producer->threadExitListener);
3498 auto index = hashedId;
3500 index &= mainHash->capacity - 1;
3501 auto probedKey = mainHash->entries[
index].key.load(std::memory_order_relaxed);
3504 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
3506 if ((probedKey == empty && mainHash->entries[
index].key.compare_exchange_strong(empty,
id, std::memory_order_relaxed, std::memory_order_relaxed)) ||
3507 (probedKey == reusable && mainHash->entries[
index].key.compare_exchange_strong(reusable,
id, std::memory_order_acquire, std::memory_order_acquire))) {
3509 if ((probedKey == empty && mainHash->entries[
index].key.compare_exchange_strong(empty,
id, std::memory_order_relaxed, std::memory_order_relaxed))) {
3511 mainHash->entries[
index].value = producer;
3526 #ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
3530 details::ThreadExitNotifier::unsubscribe(&producer->threadExitListener);
3533 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
3534 debug::DebugLock lock(implicitProdMutex);
3537 assert(
hash !=
nullptr);
3545 auto index = hashedId;
3548 probedKey =
hash->entries[
index].key.load(std::memory_order_relaxed);
3549 if (probedKey ==
id) {
3558 producer->inactive.store(
true, std::memory_order_release);
3561 static void implicit_producer_thread_exited_callback(
void* userData)
3564 auto queue = producer->parent;
3565 queue->implicit_producer_thread_exited(producer);
3573 template<
typename TAlign>
3577 return (Traits::malloc)(
size);
3580 void* raw = (Traits::malloc)(
size + alignment - 1 +
sizeof(
void*));
3583 char*
ptr = details::align_for<TAlign>(
reinterpret_cast<char*
>(raw) +
sizeof(
void*));
3584 *(
reinterpret_cast<void**
>(
ptr) - 1) = raw;
3589 template<
typename TAlign>
3593 return (Traits::free)(
ptr);
3595 (Traits::free)(
ptr ? *(
reinterpret_cast<void**
>(
ptr) - 1) :
nullptr);
3598 template<
typename U>
3602 U*
p =
static_cast<U*
>(aligned_malloc<U>(
sizeof(U) *
count));
3606 for (
size_t i = 0;
i !=
count; ++
i)
3611 template<
typename U>
3616 for (
size_t i =
count;
i != 0; )
3622 template<
typename U>
3625 void*
p = aligned_malloc<U>(
sizeof(U));
3626 return p !=
nullptr ?
new (
p) U :
nullptr;
3629 template<
typename U,
typename A1>
3632 void*
p = aligned_malloc<U>(
sizeof(U));
3633 return p !=
nullptr ?
new (
p) U(std::forward<A1>(a1)) :
nullptr;
3636 template<
typename U>
3652 #ifndef MCDBGQ_USEDEBUGFREELIST
3655 debug::DebugFreeList<Block>
freeList;
3667 #ifdef MCDBGQ_NOLOCKFREE_IMPLICITPRODHASH
3668 debug::DebugMutex implicitProdMutex;
3671 #ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
3672 std::atomic<ExplicitProducer*> explicitProducers;
3673 std::atomic<ImplicitProducer*> implicitProducers;
3678 template<
typename T,
typename Traits>
3687 template<
typename T,
typename Traits>
3689 : producer(reinterpret_cast<
ConcurrentQueue<
T, Traits>*>(&queue)->recycle_or_create_producer(true))
3696 template<
typename T,
typename Traits>
3698 : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr)
3704 template<
typename T,
typename Traits>
3706 : itemsConsumedFromCurrent(0), currentProducer(nullptr), desiredProducer(nullptr)
3712 template<
typename T,
typename Traits>
3728 template<
typename T,
typename Traits>
3736 #if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
3737 #pragma warning(pop)
3740 #if defined(__GNUC__)
3741 #pragma GCC diagnostic pop
static double get_time()
Definition: test_modulation.cc:24
arma::cx_float COMPLEX
Definition: test_transpose.cc:27
bool insert_block_index_entry(BlockIndexEntry *&idxEntry, index_t blockStartIndex)
Definition: concurrentqueue.h:2886
DEFINE_string(profile, "random", "The profile of the input user bytes (e.g., 'random', '123')")
int stick_this_thread_to_core(int core_id)
Definition: cpu_attach.cc:10
bool enqueue(U &&element)
Definition: concurrentqueue.h:1834
static double bench_multiply_dim2(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:89
Definition: phy_stats.h:15
void Demod64qamHardSse(float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:732
Definitions for Agora's AVX2-based LDPC encoder.
static bool is_lock_free()
Definition: concurrentqueue.h:1317
static size_t LdpcEncodingInputBufSize(size_t base_graph, size_t zc)
Definition: utils_ldpc.h:167
bool try_enqueue_bulk(producer_token_t const &token, It itemFirst, size_t count)
Definition: concurrentqueue.h:1092
static void aligned_free(void *ptr)
Definition: concurrentqueue.h:3590
bool dequeue(U &element)
Definition: concurrentqueue.h:2536
void Demod256qamHardLoop(const float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:1269
static void run_benchmark_ZF(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:131
Declaration file for the UDPComm class. This class is used to send messages and receive messages from...
double freq_ghz
Definition: bench.cc:10
static void run_benchmark_precode(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:189
static constexpr size_t kNumCodeBlocks
Definition: test_ldpc.cc:22
static double bench_ZF_warmup(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:29
Definition: concurrentqueue.h:2406
static const size_t IMPLICIT_INITIAL_INDEX_SIZE
Definition: concurrentqueue.h:357
Definition: concurrentqueue.h:630
Definition: concurrentqueue.h:435
static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
Definition: concurrentqueue.h:759
thread_id_t thread_id()
Definition: concurrentqueue.h:157
void flushCache()
Definition: test_matrix.cc:18
void populate_initial_block_list(size_t blockCount)
Definition: concurrentqueue.h:3022
static void run_benchmark_multiply(int dim, unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:160
std::atomic< BlockIndexHeader * > blockIndex
Definition: concurrentqueue.h:2995
std::atomic< std::uint32_t > freeListRefs
Definition: concurrentqueue.h:1656
void reset_empty()
Definition: concurrentqueue.h:1631
void Calloc(size_t dim1, size_t dim2, Agora_memory::Alignment_t alignment)
Definition: memory_manage.h:45
Definition: test_transpose.cc:22
ProducerToken & operator=(ProducerToken &&other) noexcept
Definition: concurrentqueue.h:647
ConcurrentQueue & operator=(ConcurrentQueue &&other) noexcept
Definition: concurrentqueue.h:924
void PinToCoreWithOffset(ThreadType thread_type, size_t core_offset, size_t thread_id, bool allow_reuse, bool verbose)
Definition: utils.cc:157
w
Definition: mm_gui.py:119
int16_t MaxDecoderIter() const
Definition: ldpc_config.h:48
static void run_benchmark_256qam(unsigned iterations, unsigned mode)
Definition: test_modulation.cc:449
static void AdaptBitsFromMod(const uint8_t *vec_in, uint8_t *vec_out, int len, int mod_type)
Definition: utils_ldpc.h:86
std::atomic< details::thread_id_t > key
Definition: concurrentqueue.h:3282
Definition: concurrentqueue.h:1749
Insert the data and pilot values
Definition: generate_data.m:83
void swap(ConcurrentQueue &other) noexcept
Definition: concurrentqueue.h:934
end IFFT Reshape the symbol vector into two different spatial streams size
Definition: generate_data.m:73
auto printf(const S &fmt, const T &... args) -> int
Definition: printf.h:631
void GenRawData(Direction dir, std::vector< int8_t > &information, size_t ue_id)
Generate one raw information bit sequence.
Definition: data_generator.h:65
Definition: concurrentqueue.h:3311
Definition: udp_comm.h:18
static void destroy(U *p)
Definition: concurrentqueue.h:3637
bool EarlyTermination() const
Definition: ldpc_config.h:49
static void LdpcEncodeHelper(size_t base_graph, size_t zc, size_t nRows, int8_t *encoded_buffer, int8_t *parity_buffer, const int8_t *input_buffer)
Definition: utils_ldpc.h:195
static void ConvertShortToFloat(const short *in_buf, float *out_buf, size_t n_elems)
Produces outputs -1->+0.999.
Definition: datatype_conversion.h:41
size_t CoreOffset() const
Definition: config.h:180
friend struct ExplicitProducer
Definition: concurrentqueue.h:1332
@ value
Definition: concurrentqueue.h:618
static void run_benchmark_data_type(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:401
uint16_t src_port
Definition: eth_common.h:60
std::uintptr_t thread_id_t
Definition: concurrentqueue.h:154
static const size_t MAX_SUBQUEUE_SIZE
Definition: concurrentqueue.h:766
size_t dequeue_bulk(It &itemFirst, size_t max)
Definition: concurrentqueue.h:2233
static double bench_mod_256qam(unsigned iterations, unsigned mode)
Definition: test_modulation.cc:271
ssize_t Connect(const std::string &remote_address, const std::string &remote_port)
The remote_address | remote_port is the only address to which datagrams are received....
Definition: udp_server.h:39
#define MOODYCAMEL_THREADLOCAL
Definition: concurrentqueue.h:151
size_t try_dequeue_bulk_from_producer(producer_token_t const &producer, It itemFirst, size_t max)
Definition: concurrentqueue.h:1292
std::array< ImplicitProducerKVP, INITIAL_IMPLICIT_PRODUCER_HASH_SIZE > initialImplicitProducerHashEntries
Definition: concurrentqueue.h:3661
void swap(ImplicitProducerKVP &other) noexcept
Definition: concurrentqueue.h:3299
static double CyclesToNs(size_t cycles, double freq_ghz)
Definition: gettime.h:103
static void run_benchmark_64qam(unsigned iterations, unsigned mode)
Definition: test_modulation.cc:444
size_t try_dequeue_bulk(It itemFirst, size_t max)
Definition: concurrentqueue.h:1210
Direction
Definition: symbols.h:39
Definition: concurrentqueue.h:83
void Demod64qamHardAvx2(float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:921
#define LOOP_NUM
Definition: test_transpose.cc:20
size_t size_approx() const
Definition: concurrentqueue.h:1304
std::uint32_t initialOffset
Definition: concurrentqueue.h:732
void WorkerToMasterMaster(moodycamel::ConcurrentQueue< ItemT > *queue)
Definition: test_concurrent_queue.cc:65
Definition: concurrentqueue.h:254
static const size_t BLOCK_SIZE
Definition: concurrentqueue.h:342
static constexpr size_t kSIMDTestNum
Definition: test_datatype_conversion.cc:13
void Demod64qamSoftLoop(const float *vec_in, int8_t *llr, int num)
Definition: modulation_srslte.cc:117
static void SimdConvertFloat16ToFloat32(float *out_buf, const float *in_buf, size_t n_elems)
Definition: datatype_conversion.h:547
@ error
Definition: format-inl.h:643
int main(int argc, char *argv[])
Definition: test_modulation.cc:455
int hammingdist(uint8_t x, uint8_t y)
Definition: test_modulation.cc:249
FreeList()
Definition: concurrentqueue.h:1431
InnerQueueContext
Definition: concurrentqueue.h:1536
static constexpr size_t kCol2s
Definition: test_ptr_grid.cc:7
static size_t LdpcNumEncodedBits(size_t base_graph, size_t zc, size_t nRows)
Definition: utils_ldpc.h:159
GeneratorWrapper< T > value(T &&value)
Definition: catch.hpp:3999
void add_blocks_to_free_list(Block *block)
Definition: concurrentqueue.h:3058
static void destroy_array(U *p, size_t count)
Definition: concurrentqueue.h:3612
@ left
Definition: core.h:2021
static constexpr size_t kFrameWnd
Definition: symbols.h:18
static constexpr double kCodeRate[kModTestNum]
Definition: test_demul_threaded.cc:18
fallback_uintptr uintptr_t
Definition: format.h:332
#define unused(x)
Definition: utils.h:14
details::ConcurrentQueueProducerTypelessBase * desiredProducer
Definition: concurrentqueue.h:736
static gen_tag_t FrmSymSc(size_t frame_id, size_t symbol_id, size_t sc_id)
Definition: message.h:95
static constexpr size_t kBaseGraph
Definition: test_ldpc.cc:23
void swap(ConsumerToken &other) noexcept
Definition: concurrentqueue.h:714
TEST(TestConcurrentQueue, MasterToWorkerStatic)
Definition: test_concurrent_queue.cc:41
static U * create_array(size_t count)
Definition: concurrentqueue.h:3599
Definition: test_concurrent_queue.cc:10
void * PaddedAlignedAlloc(Alignment_t alignment, size_t size)
Definition: memory_manage.cc:15
static double GetTimeUs()
Definition: gettime.h:14
static const std::uint32_t REFS_MASK
Definition: concurrentqueue.h:1523
ProducerBase * add_producer(ProducerBase *producer)
Definition: concurrentqueue.h:3232
string mode
Definition: mm_gui.py:105
std::atomic< index_t > tailIndex
Definition: concurrentqueue.h:1726
void Demod256qamSoftSse(const float *vec_in, int8_t *llr, int num)
Definition: modulation.cc:2201
static double bench_multiply_transpose(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:111
size_t NumRows() const
Definition: ldpc_config.h:52
ImplicitProducerKVP * entries
Definition: concurrentqueue.h:3314
for p
Definition: process_rx_frame.m:36
int flushCache()
Definition: test_mufft.cc:16
int main(int argc, char *argv[])
Definition: test_matrix.cc:228
AllocationMode
Definition: concurrentqueue.h:1338
static void swap_relaxed(std::atomic< T > &left, std::atomic< T > &right)
Definition: concurrentqueue.h:507
std::atomic< bool > inactive
Definition: concurrentqueue.h:426
static constexpr size_t kNumFillerBits
Definition: test_ldpc.cc:25
void Demod256qamHardSse(float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:1329
static double bench_ZF(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:47
~ImplicitProducer()
Definition: concurrentqueue.h:2416
::moodycamel::ConsumerToken consumer_token_t
Definition: concurrentqueue.h:750
void set_all_empty()
Definition: concurrentqueue.h:1616
std::atomic< std::uint32_t > freeListRefs
Definition: concurrentqueue.h:1421
static void * aligned_malloc(size_t size)
Definition: concurrentqueue.h:3574
static const size_t BLOCK_SIZE
Definition: concurrentqueue.h:755
@ right
Definition: core.h:2021
static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE
Definition: concurrentqueue.h:368
void * z
Definition: concurrentqueue.h:310
size_t BsAntNum() const
Definition: config.h:35
static U * create()
Definition: concurrentqueue.h:3623
static const std::string kIpv6Address
Definition: test_udp_client_server.cc:20
static size_t BitsToBytes(size_t n_bits)
Definition: utils_ldpc.h:124
std::atomic< Block * > freeListNext
Definition: concurrentqueue.h:1657
Basic UDP server class based on OS sockets that supports receiving messages.
Definition: udp_server.h:13
#define K
Definition: test_transpose.cc:19
void MasterToWorkerDynamicWorker(Config *cfg, size_t worker_id, moodycamel::ConcurrentQueue< EventData > &event_queue, moodycamel::ConcurrentQueue< EventData > &complete_task_queue, moodycamel::ProducerToken *ptok, Table< complex_float > &data_buffer, PtrGrid< kFrameWnd, kMaxDataSCs, complex_float > &ul_beam_matrices, Table< complex_float > &ue_spec_pilot_buffer, Table< complex_float > &equal_buffer, PtrCube< kFrameWnd, kMaxSymbols, kMaxUEs, int8_t > &demod_buffers_, PhyStats *phy_stats, Stats *stats)
Definition: test_demul_threaded.cc:64
#define MOODYCAMEL_DELETE_FUNCTION
Definition: concurrentqueue.h:232
Provides the UDPServer functions from the UDPComm class. Receiver only support.
TEST(TestPtrGrid, Basic)
Definition: test_ptr_grid.cc:10
std::atomic< std::uint32_t > globalExplicitConsumerOffset
Definition: concurrentqueue.h:3665
static const std::uint32_t SHOULD_BE_ON_FREELIST
Definition: concurrentqueue.h:1524
static void free(void *ptr)
Definition: concurrentqueue.h:395
bool try_enqueue(producer_token_t const &token, T &&item)
Definition: concurrentqueue.h:1067
bool isExplicit
Definition: concurrentqueue.h:1735
static void * malloc(size_t size)
Definition: concurrentqueue.h:394
static constexpr bool kPrintUplinkInformationBytes
Definition: test_ldpc_mod.cc:29
void Demod16qamHardLoop(const float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:322
void UDPSend(const std::string &local_address, uint16_t local_port, const std::string &remote_address, uint16_t remote_port)
Test the connection use case.
Definition: test_udp_client_server.cc:61
void Demod64qamHardLoop(const float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:699
static void demod_16qam_loop2(float *vec_in, uint8_t *vec_out, int ue_num)
Definition: test_fft_mkl.cc:261
TEST(TestZF, Perf)
Measure performance of zeroforcing.
Definition: test_zf.cc:10
Pilot RX by socket threads(=reference time)
std::array< size_t, kMaxTags > tags_
Definition: message.h:146
@ implicit_context
Definition: concurrentqueue.h:1536
void swap(nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > &j1, nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24114
SPDLOG_INLINE spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT
Definition: os-inl.h:71
int main(int argc, char **argv)
Definition: test_zf_threaded.cc:169
static const size_t EXPLICIT_INITIAL_INDEX_SIZE
Definition: concurrentqueue.h:757
std::size_t index_t
Definition: concurrentqueue.h:335
int main()
Definition: test_ldpc.cc:30
@ CannotAlloc
Definition: concurrentqueue.h:1338
std::atomic< ImplicitProducerHash * > implicitProducerHash
Definition: concurrentqueue.h:3658
#define TOSTRING(x)
Definition: symbols.h:14
int flushCacheRuntime(long *p, long long p_size)
Definition: test_fft_mkl.cc:33
bool enqueue_bulk(producer_token_t const &token, It itemFirst, size_t count)
Definition: concurrentqueue.h:1029
friend struct ImplicitProducer
Definition: concurrentqueue.h:1334
ProducerBase * recycle_or_create_producer(bool isExplicit)
Definition: concurrentqueue.h:3205
details::ConcurrentQueueProducerTypelessBase * producer
Definition: concurrentqueue.h:691
bool inner_enqueue_bulk(producer_token_t const &token, It itemFirst, size_t count)
Definition: concurrentqueue.h:1359
std::vector< std::complex< float >, boost::alignment::aligned_allocator< std::complex< float >, kSimdAlignment > > SimdAlignCxFltVector
Definition: simd_types.h:30
static double test_get_time(void)
Definition: test_matrix.cc:12
size_t pr_blockIndexFront
Definition: concurrentqueue.h:2386
static double bench_fft_1d_0(unsigned N, unsigned iterations, int direction)
Definition: test_mufft.cc:55
#define MOODYCAMEL_NOEXCEPT
Definition: concurrentqueue.h:206
ItemT(size_t value)
Definition: test_concurrent_queue.cc:16
Definition: concurrentqueue.h:307
const FrameStats & Frame() const
Definition: config.h:340
int main(int argc, char **argv)
Definition: test_zf.cc:72
count
Definition: inspect_agora_results.m:96
static const thread_id_t invalid_thread_id
Definition: concurrentqueue.h:155
static constexpr bool kVerbose
Definition: test_ldpc_baseband.cc:26
bool try_enqueue(T &&item)
Definition: concurrentqueue.h:1050
index_t getTail() const
Definition: concurrentqueue.h:1724
Block * next
Definition: concurrentqueue.h:1652
Block * block
Definition: concurrentqueue.h:2329
temp
Definition: parse_dl_file.m:5
static constexpr size_t kNumWorkers
Definition: test_concurrent_queue.cc:7
static constexpr size_t kAntTestNum
Definition: test_zf_threaded.cc:14
size_t dequeue_bulk(It &itemFirst, size_t max)
Definition: concurrentqueue.h:1705
static double CyclesToUs(size_t cycles, double freq_ghz)
Definition: gettime.h:97
static constexpr bool kEnableEarlyTermination
Definition: test_ldpc.cc:24
void Demod64qamSoftSse(float *vec_in, int8_t *llr, int num)
Definition: modulation_srslte.cc:131
std::atomic< Block * > value
Definition: concurrentqueue.h:2873
Block * initialBlockPool
Definition: concurrentqueue.h:3649
@ explicit_context
Definition: concurrentqueue.h:1536
bool valid() const
Definition: concurrentqueue.h:672
void GenCodeblock(Direction dir, const int8_t *input_ptr, std::vector< int8_t > &encoded_codeword)
Generate the encoded bit sequence for one code block for the active LDPC configuration from the input...
Definition: data_generator.h:87
thread_id_t thread_id_hash_t
Definition: concurrentqueue.h:85
static size_t LdpcEncodingEncodedBufSize(size_t base_graph, size_t zc)
Definition: utils_ldpc.h:181
ConcurrentQueue * parent
Definition: concurrentqueue.h:1736
std::vector< complex_float > BinForIfft(const std::vector< complex_float > &modulated_codeword) const
An array with OfdmDataNum() elements with the OfdmDataNum() modulated elements binned at the center.
Definition: data_generator.h:169
size_t try_dequeue_bulk(consumer_token_t &token, It itemFirst, size_t max)
Definition: concurrentqueue.h:1228
bool update_current_producer_after_rotation(consumer_token_t &token)
Definition: concurrentqueue.h:1371
static void AllocBuffer1d(T **buffer, U dim, Agora_memory::Alignment_t alignment, int init_zero)
Definition: memory_manage.h:105
void Demod16qamHardSse(float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:345
#define MOODYCAMEL_CONSTEXPR_IF
Definition: concurrentqueue.h:167
FreeList & operator=(FreeList const &)=delete
#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj)
Definition: concurrentqueue.h:257
void swap_implicit_producer_hashes(ConcurrentQueue &other)
Definition: concurrentqueue.h:3336
Declaration file for cpu attachment helper functions.
int main(int argc, char *argv[])
Definition: test_mufft.cc:123
index
Definition: parse_all_dl.m:11
int main(int argc, char **argv)
Definition: test_ptr_grid.cc:48
void WorkerToMasterWorkerWithToken(size_t worker_id, moodycamel::ConcurrentQueue< ItemT > *queue, moodycamel::ProducerToken *ptok)
Definition: test_concurrent_queue.cc:75
bool inner_enqueue(producer_token_t const &token, U &&element)
Definition: concurrentqueue.h:1346
TEST(TestDemul, VaryingConfig)
Definition: test_demul_threaded.cc:117
int main(int argc, char **argv)
Definition: test_armadillo.cc:80
std::atomic< index_t > dequeueOvercommit
Definition: concurrentqueue.h:1730
ssize_t Connect(const std::string &remote_address, uint16_t remote_port)
The remote_address | remote_port is the address to which datagrams are sent. 1:1 association me->remo...
Definition: udp_client.h:34
static void run_benchmark_1d(unsigned N, unsigned iterations)
Definition: test_mufft.cc:90
snr
Definition: inspect_agora_results.m:118
std::atomic< bool > emptyFlags[BLOCK_SIZE<=EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD ? BLOCK_SIZE :1]
Definition: concurrentqueue.h:1654
void InitModulationTable(Table< complex_float > &mod_table, size_t mod_order)
Definition: modulation.cc:42
Definition: concurrentqueue.h:1678
filename
Definition: parse_all_dl.m:14
std::atomic< BlockIndexHeader * > blockIndex
Definition: concurrentqueue.h:2381
constexpr std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: chrono.h:1488
bool try_enqueue(producer_token_t const &token, T const &item)
Definition: concurrentqueue.h:1059
friend class ConcurrentQueueTests
Definition: concurrentqueue.h:729
#define MOODYCAMEL_NO_TSAN
Definition: concurrentqueue.h:266
const nlohmann::json & MCSParams(Direction dir) const
Definition: config.h:288
size_t OfdmDataNum() const
Definition: config.h:47
static void TryEnqueueFallback(moodycamel::ConcurrentQueue< EventData > *mc_queue, moodycamel::ProducerToken *producer_token, const EventData &event)
Definition: concurrent_queue_wrapper.h:18
auto runtime(const S &s) -> basic_runtime< char_t< S >>
Definition: core.h:3098
int main(int argc, char *argv[])
Definition: test_fft_mkl.cc:467
size_t value_
Definition: test_concurrent_queue.cc:11
ProducerBase * next_prod() const
Definition: concurrentqueue.h:1715
void Demod64qamSoftAvx2(float *vec_in, int8_t *llr, int num)
Definition: modulation.cc:1103
void flushCache()
Definition: test_modulation.cc:14
Definition: concurrentqueue.h:618
static constexpr size_t kSendPort
Definition: test_udp_client_server.cc:13
static void SimdConvertShortToFloat(const short *in_buf, float *out_buf, size_t n_elems)
Definition: datatype_conversion.h:126
FreeList< Block > freeList
Definition: concurrentqueue.h:3653
static constexpr size_t kNumPackets
Definition: test_udp_client_server.cc:16
float RandFloat(float min, float max)
Definition: test_ldpc_mod.cc:42
static double bench_demod(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:279
void Demod256qamHardAvx2(float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:1569
Implementation file for the Data generator class to generate binary files as inputs to Agora,...
Definition: message.h:142
void MasterToWorkerStaticMaster(moodycamel::ConcurrentQueue< ItemT > *queue, moodycamel::ProducerToken **ptoks)
Definition: test_concurrent_queue.cc:21
constexpr auto num_bits() -> int
Definition: format.h:343
void populate_initial_implicit_producer_hash()
Definition: concurrentqueue.h:3318
Definition: concurrentqueue.h:320
static constexpr size_t kMaxDecoderIters
Definition: test_ldpc.cc:26
#define BS_ANT
Definition: test_transpose.cc:18
Definition: concurrentqueue.h:624
void Demod16qamSoftSse(float *vec_in, int8_t *llr, int num)
Definition: modulation_srslte.cc:36
int main(int argc, char **argv)
Definition: test_avx512_complex_mul.cc:107
static void run_benchmark_1d(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:345
list row
Definition: plot_csv.py:11
void Demod16qamSoftLoop(const float *vec_in, int8_t *llr, int num)
Definition: modulation_srslte.cc:24
Definition: concurrentqueue.h:82
ConcurrentQueue & operator=(ConcurrentQueue const &)=delete
static double bench_data_type_convert(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:142
Aligned types for SIMD compatibility.
size_t padding_[7]
Definition: test_concurrent_queue.cc:12
auto ptr(T p) -> const void *
Definition: format.h:2680
Definition: concurrentqueue.h:292
Self defined functions for message storage and passing.
bool inner_enqueue(U &&element)
Definition: concurrentqueue.h:1352
static thread_id_hash_t prehash(thread_id_t const &x)
Definition: concurrentqueue.h:86
void Free()
Definition: memory_manage.h:84
size_t dequeue_bulk(It &itemFirst, size_t max)
Definition: concurrentqueue.h:2765
Definition: concurrentqueue.h:2326
T const * operator[](index_t idx) const noexcept
Definition: concurrentqueue.h:1646
bool set_empty(index_t i)
Definition: concurrentqueue.h:1576
std::max_align_t std_max_align_t
Definition: concurrentqueue.h:302
static size_t hash_thread_id(thread_id_t id)
Definition: concurrentqueue.h:461
static constexpr size_t kReceivePort
Definition: test_udp_client_server.cc:14
static size_t LdpcGetMinZc()
Definition: utils_ldpc.h:187
static constexpr bool kVerbose
Definition: test_ldpc_mod.cc:28
static const int MAX_SEMA_SPINS
Definition: concurrentqueue.h:380
bool try_dequeue_from_producer(producer_token_t const &producer, U &item)
Definition: concurrentqueue.h:1279
std::atomic< index_t > key
Definition: concurrentqueue.h:2872
uint16_t len
Definition: eth_common.h:62
Declaration file for the DoDemul class.
Scramble Class and helper functions.
for i
Definition: generate_data.m:107
TEST(TestDemod256QAM, SoftLoop)
Definition: test_256qam_demod.cc:148
j template void())
Definition: json.hpp:4744
ConcurrentQueue & swap_internal(ConcurrentQueue &other)
Definition: concurrentqueue.h:940
bool enqueue(T const &item)
Definition: concurrentqueue.h:974
~ProducerToken()
Definition: concurrentqueue.h:674
Building blocks for generating end-to-end or unit test workloads for Agora.
Definition: data_generator.h:21
static void NanoSleep(size_t ns, double freq_ghz)
Sleep for some nanoseconds.
Definition: gettime.h:39
static constexpr float kNoiseLevels[15]
Definition: test_ldpc_baseband.cc:28
void Demod16qamHardAvx2(float *vec_in, uint8_t *vec_out, int num)
Definition: modulation.cc:472
static auto eval(U &&x) -> decltype(std::forward< U >(x))
Definition: concurrentqueue.h:534
Definition: concurrentqueue.h:2870
Definition: concurrentqueue.h:3280
bool enqueue_bulk(It itemFirst, size_t count)
Definition: concurrentqueue.h:2040
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5867
std::atomic< N * > freeListHead
Definition: concurrentqueue.h:1521
Plot Rx waveform for u
Definition: inspect_single_frame.m:108
std::atomic< std::uint32_t > nextExplicitConsumerId
Definition: concurrentqueue.h:3664
static size_t Rdtsc()
Return the TSC.
Definition: gettime.h:25
ConsumerToken(ConcurrentQueue< T, Traits > &q)
Definition: concurrentqueue.h:3697
bool dequeue(U &element)
Definition: concurrentqueue.h:1694
Communications Library: a) Generate pilot/preamble sequences b) OFDM modulation.
complex_float ModSingle(int x, Table< complex_float > &mod_table)
Definition: modulation.cc:209
#define MOODYCAMEL_TRY
Definition: concurrentqueue.h:179
size_t get_block_index_index_for_index(index_t index, BlockIndexHeader *&localBlockIndex) const
Definition: concurrentqueue.h:2931
static U * create(A1 &&a1)
Definition: concurrentqueue.h:3630
ConcurrentQueue(ConcurrentQueue &&other) noexcept
Definition: concurrentqueue.h:890
void UDPRecv(const std::string &local_address, uint16_t local_port, const std::string &remote_address, uint16_t remote_port)
Test the connection use case.
Definition: test_udp_client_server.cc:157
auto fprintf(std::FILE *f, const S &fmt, const T &... args) -> int
Definition: printf.h:607
ConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers)
Definition: concurrentqueue.h:816
void rewind_block_index_tail()
Definition: concurrentqueue.h:2918
friend class ConcurrentQueueTests
Definition: concurrentqueue.h:688
static void CheckArmaMemoryState(arma::uhword state, bool dynamic)
Definition: test_armadillo.cc:13
size_t nextBlockIndexCapacity
Definition: concurrentqueue.h:2994
#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr)
Definition: concurrentqueue.h:207
ssize_t Recv(std::byte *buf, size_t len) const
Try to receive up to len bytes in buf by default this will not block.
Definition: udp_comm.cc:372
static constexpr size_t kFrameOffsets[kAntTestNum]
Definition: test_zf_threaded.cc:16
bool inner_enqueue_bulk(It itemFirst, size_t count)
Definition: concurrentqueue.h:1365
ssize_t Connect(const std::string &remote_address, uint16_t remote_port) const
The remote_address | remote_port is the address to which datagrams are sent. 1:1 association me<->rem...
Definition: udp_comm.cc:250
std::atomic< std::uint32_t > producerCount
Definition: concurrentqueue.h:3646
void Demod16qamSoftAvx2(float *vec_in, int8_t *llr, int num)
Definition: modulation.cc:601
static void SimdConvertFloat32ToFloat16(float *out_buf, const float *in_buf, size_t n_elems)
Definition: datatype_conversion.h:576
size_t tag_
Definition: message.h:43
int main(int argc, char **argv)
Definition: test_datatype_conversion.cc:324
void MasterToWorkerDynamicMaster(Config *cfg, moodycamel::ConcurrentQueue< EventData > &event_queue, moodycamel::ConcurrentQueue< EventData > &complete_task_queue)
Definition: test_demul_threaded.cc:23
bool new_block_index(size_t numberOfFilledSlotsToExpose)
Definition: concurrentqueue.h:2341
static T ceil_to_pow_2(T x)
Definition: concurrentqueue.h:490
Definition: concurrentqueue.h:1429
Block()
Definition: concurrentqueue.h:1540
uint16_t check
Definition: eth_common.h:69
#define MOODYCAMEL_CATCH(...)
Definition: concurrentqueue.h:180
static constexpr size_t kMaxItrNum
Definition: test_demul_threaded.cc:15
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD
Definition: concurrentqueue.h:756
complex_float ModSingleUint8(uint8_t x, Table< complex_float > &mod_table)
Definition: modulation.cc:213
static constexpr float kSnrLevels[15]
Definition: test_ldpc_mod.cc:33
virtual ~ProducerBase()
Definition: concurrentqueue.h:1691
static double mufft_get_time(void)
Definition: test_mufft.cc:10
static constexpr size_t kFrameOffsets[kModTestNum]
Definition: test_demul_threaded.cc:19
void Send(const std::string &rem_hostname, uint16_t rem_port, const std::byte *msg, size_t len)
Send one UDP packet to a remote server. The client caches the the remote server's addrinfo after reso...
Definition: udp_client.h:50
thread_id_t thread_id_numeric_size_t
Definition: concurrentqueue.h:84
friend class ConcurrentQueueTests
Definition: concurrentqueue.h:1336
std::atomic< size_t > num_workers_ready_atomic
Definition: test_zf_threaded.cc:18
a class to store JSON values
Definition: json.hpp:3367
size_t DemulEventsPerSymbol() const
Definition: config.h:197
#define NUM_SYMBOLS
Definition: test_256qam_demod.cc:10
ImplicitProducerHash * prev
Definition: concurrentqueue.h:3315
Definition: ldpc_config.h:14
static double bench_mod_64qam(unsigned iterations, unsigned mode)
Definition: test_modulation.cc:136
#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr)
Definition: concurrentqueue.h:208
bool enqueue(T &&item)
Definition: concurrentqueue.h:985
static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
Definition: concurrentqueue.h:363
bool enqueue_bulk(It itemFirst, size_t count)
Definition: concurrentqueue.h:1016
ImplicitProducer * get_or_add_implicit_producer()
Definition: concurrentqueue.h:3374
static double bench_fft_1d(unsigned N, unsigned iterations, int direction)
Definition: test_mufft.cc:26
ImplicitProducerKVP()
Definition: concurrentqueue.h:3285
static const T value
Definition: concurrentqueue.h:294
bool try_enqueue_bulk(It itemFirst, size_t count)
Definition: concurrentqueue.h:1080
int main(int argc, char **argv)
Definition: test_concurrent_queue.cc:135
void saveData(char *filename, complex_float *ptr, int row, int col)
Definition: test_transpose.cc:39
static gen_tag_t FrmSc(size_t frame_id, size_t sc_id)
Definition: message.h:117
static size_t LdpcGetMaxZc()
Definition: utils_ldpc.h:190
static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE
Definition: concurrentqueue.h:760
std::atomic< size_t > initialBlockPoolIndex
Definition: concurrentqueue.h:3648
for ue_num
Definition: parse_all_dl.m:84
uint32_t NextU32()
Definition: utils.h:189
long long y
Definition: concurrentqueue.h:309
static constexpr size_t kMaxDataSCs
Definition: symbols.h:283
bool dynamicallyAllocated
Definition: concurrentqueue.h:1659
static constexpr size_t kNumRows
Definition: test_ldpc.cc:28
static void Run256QamSoftDemod(void(*demod_func)(const float *, int8_t *, int), const char *func_desc)
Definition: test_256qam_demod.cc:51
#define MOODYCAMEL_MAYBE_UNUSED
Definition: concurrentqueue.h:168
static constexpr size_t kModTestNum
Definition: test_demul_threaded.cc:16
double FreqGhz() const
Definition: config.h:56
FreeList(FreeList &&other)
Definition: concurrentqueue.h:1432
std::array< std::array< T *, COLS >, ROWS > mat_
Definition: memory_manage.h:192
static const size_t IMPLICIT_INITIAL_INDEX_SIZE
Definition: concurrentqueue.h:758
void MasterToWorkerDynamicMaster(Config *cfg, moodycamel::ConcurrentQueue< EventData > &event_queue, moodycamel::ConcurrentQueue< EventData > &complete_task_queue)
Definition: test_zf_threaded.cc:20
int main(int argc, char **argv)
Definition: test_256qam_demod.cc:215
bool dequeue(U &element)
Definition: concurrentqueue.h:1940
static std::string MapModToStr(size_t mod_order)
Definition: modulation.h:39
ImplicitProducerKVP & operator=(ImplicitProducerKVP &&other) noexcept
Definition: concurrentqueue.h:3293
std::atomic< index_t > dequeueOptimisticCount
Definition: concurrentqueue.h:1729
BlockIndexEntry * pr_blockIndexEntries
Definition: concurrentqueue.h:2387
~ExplicitProducer()
Definition: concurrentqueue.h:1768
int main(int argc, char *argv[])
Definition: test_ldpc_mod.cc:56
Profile
Definition: data_generator.h:24
Definition: concurrentqueue.h:416
static constexpr size_t kMaxModType
Definition: symbols.h:297
bool enqueue(U &&element)
Definition: concurrentqueue.h:2472
bool set_many_empty(index_t i, size_t count)
Definition: concurrentqueue.h:1595
bool try_dequeue(consumer_token_t &token, U &item)
Definition: concurrentqueue.h:1162
bool new_block_index()
Definition: concurrentqueue.h:2949
int main(int argc, char **argv)
Definition: test_scrambler.cc:162
static std::atomic< bool > server_ready
Definition: test_udp_client_server.cc:17
#define MOODYCAMEL_RETHROW
Definition: concurrentqueue.h:181
ImplicitProducer * value
Definition: concurrentqueue.h:3283
size_t capacity
Definition: concurrentqueue.h:3313
N * head_unsafe() const
Definition: concurrentqueue.h:1492
static bool circular_less_than(T a, T b)
Definition: concurrentqueue.h:469
static std::atomic< size_t > num_workers_ready_atomic
Definition: test_demul_threaded.cc:21
std::atomic< size_t > elementsCompletelyDequeued
Definition: concurrentqueue.h:1653
void Demod256qamSoftLoop(const float *vec_in, int8_t *llr, int num)
Definition: modulation.cc:2157
static double bench_fft_1d_mkl(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:40
details::identity< char[sizeof(T) *BLOCK_SIZE] >::type elements
Definition: concurrentqueue.h:1649
static double MeasureRdtscFreq()
Definition: gettime.h:51
void ServerConnect(const std::string &src_address, const uint16_t src_port, const std::string &dest_address, const uint16_t dest_port)
Definition: test_udp_client_server.cc:117
void swap(FreeList &other)
Definition: concurrentqueue.h:1433
size_t BeamEventsPerSymbol() const
Definition: config.h:202
ProducerToken * token
Definition: concurrentqueue.h:427
const size_t kNEntries
Definition: test_ptr_grid.cc:8
ProducerBase(ConcurrentQueue *parent_, bool isExplicit_)
Definition: concurrentqueue.h:1680
static double GetTime()
Definition: gettime.h:22
size_t NumULSyms() const
Definition: framestats.cc:85
static size_t WorkerRdtsc()
Definition: gettime.h:34
Definition: concurrentqueue.h:423
float real
Definition: test_transpose.cc:23
static constexpr size_t kNumWorkers
Definition: test_zf_threaded.cc:11
static constexpr size_t kMaxTestNum
Definition: test_demul_threaded.cc:14
uint16_t ExpansionFactor() const
Definition: ldpc_config.h:47
static double CyclesToMs(size_t cycles, double freq_ghz)
Definition: gettime.h:91
int main(int argc, char *argv[])
Definition: test_ldpc_baseband.cc:40
void * pr_blockIndexRaw
Definition: concurrentqueue.h:2388
static double bench_fft_1d_mkl_out(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:107
void ClientConnect(const std::string &src_address, uint16_t src_port, const std::string &dest_address, uint16_t dest_port)
Test the connection use case.
Definition: test_udp_client_server.cc:42
static auto deref_noexcept(It &it) noexcept -> decltype(*it)
Definition: concurrentqueue.h:542
TEST(WLAN_Scrambler, fixed_input_scramble_int8_t)
Construct a new TEST object.
Definition: test_scrambler.cc:22
std::atomic_flag implicitProducerHashResizeInProgress
Definition: concurrentqueue.h:3662
Definition: concurrentqueue.h:548
void UpdateUlMCS(const nlohmann::json &mcs)
Definition: config.cc:747
void ClientSendTo(const std::string &src_address, uint16_t src_port, const std::string &dest_address, uint16_t dest_port)
Test the non-connection use case (SendTo)
Definition: test_udp_client_server.cc:23
static void run_benchmark_16qam(unsigned iterations, unsigned mode)
Definition: test_modulation.cc:439
std::atomic< bool > shouldBeOnFreeList
Definition: concurrentqueue.h:1658
static double bench_mod_16qam(unsigned iterations, unsigned mode)
Definition: test_modulation.cc:26
Definition: json.hpp:5213
static size_t LdpcNumInputBits(size_t base_graph, size_t zc)
Definition: utils_ldpc.h:139
ConsumerToken(ConsumerToken &&other) noexcept
Definition: concurrentqueue.h:703
void add_block_to_free_list(Block *block)
Definition: concurrentqueue.h:3050
ImplicitProducer(ConcurrentQueue *parent_)
Definition: concurrentqueue.h:2408
bool enqueue(producer_token_t const &token, T &&item)
Definition: concurrentqueue.h:1004
bool try_dequeue_non_interleaved(U &item)
Definition: concurrentqueue.h:1147
static T const & nomove(T const &x)
Definition: concurrentqueue.h:515
N * try_get()
Definition: concurrentqueue.h:1452
ExplicitProducer(ConcurrentQueue *parent_)
Definition: concurrentqueue.h:1751
ProducerToken(ProducerToken &&other) noexcept
Definition: concurrentqueue.h:638
ImplicitProducerKVP(ImplicitProducerKVP &&other) noexcept
Definition: concurrentqueue.h:3287
Declaration file for the DoBeamWeights class. Zero forcing for one subcarrier.
TEST(UDPClientServer, PerfIpv4)
Definition: test_udp_client_server.cc:197
T type
Definition: concurrentqueue.h:254
static double fft_get_time(void)
Definition: test_fft_mkl.cc:16
std::atomic< index_t > headIndex
Definition: concurrentqueue.h:1727
void Demod256qamSoftAvx2(const float *vec_in, int8_t *llr, int num)
Definition: modulation.cc:2365
static constexpr size_t kK5GnrNumPunctured
Definition: test_ldpc.cc:27
bool enqueue_bulk(It itemFirst, size_t count)
Definition: concurrentqueue.h:2611
static constexpr float kSnrLevels[15]
Definition: test_ldpc_baseband.cc:31
OutputIterator copy(const RangeT &range, OutputIterator out)
Definition: ranges.h:26
Traits::size_t size_t
Definition: concurrentqueue.h:753
uint32_t NumCbLen() const
Definition: ldpc_config.h:50
std::atomic< N * > freeListNext
Definition: concurrentqueue.h:1422
noise
Definition: generate_data_dl.m:131
static constexpr size_t kMaxTestNum
Definition: test_zf_threaded.cc:12
@ CanAlloc
Definition: concurrentqueue.h:1338
static constexpr size_t kCols
Definition: test_ptr_grid.cc:6
static void run_benchmark_demod(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:439
Definition: concurrentqueue.h:417
ImplicitProducerHash initialImplicitProducerHash
Definition: concurrentqueue.h:3660
std::string to_string() const
Definition: eth_common.h:64
static void SimdConvertFloatToShort(const float *in_buf, short *out_buf, size_t n_elems, size_t n_prefix=0, float scale_down_factor=1.0f)
Definition: datatype_conversion.h:266
int main(int argc, char **argv)
Definition: test_transpose.cc:51
uint16_t BaseGraph() const
Definition: ldpc_config.h:46
ConcurrentQueueProducerTypelessBase()
Definition: concurrentqueue.h:429
size_t BeamBlockSize() const
Definition: config.h:200
Definition: concurrentqueue.h:459
static bool() likely(bool x)
Definition: concurrentqueue.h:280
std::uint32_t lastKnownGlobalOffset
Definition: concurrentqueue.h:733
uint16_t id
Definition: eth_common.h:65
Declaration file for the configuration class which importants json configuration values into class va...
void MasterToWorkerStaticWorker(size_t worker_id, moodycamel::ConcurrentQueue< ItemT > *queue, moodycamel::ProducerToken *ptok)
Definition: test_concurrent_queue.cc:28
static constexpr size_t kRows
Definition: test_ptr_grid.cc:5
#define NUM_ITERATIONS
Definition: test_256qam_demod.cc:11
end load("results.mat") colors
static constexpr size_t kNumWorkers
Definition: test_demul_threaded.cc:13
static constexpr size_t kMaxItrNum
Definition: test_zf_threaded.cc:13
std::uint32_t itemsConsumedFromCurrent
Definition: concurrentqueue.h:734
float RandFloatFromShort(float min, float max)
Definition: test_ldpc_mod.cc:46
bool try_dequeue(U &item)
Definition: concurrentqueue.h:1104
Definition: concurrentqueue.h:695
static __m256 M256ComplexCf32Mult(__m256 data1, __m256 data2, bool conj)
Definition: comms-lib-avx.cc:196
details::ConcurrentQueueProducerTypelessBase * currentProducer
Definition: concurrentqueue.h:735
int main(int argc, char **argv)
Definition: test_demul_threaded.cc:189
ConsumerToken & operator=(ConsumerToken &&other) noexcept
Definition: concurrentqueue.h:708
Block * try_get_block_from_initial_pool()
Definition: concurrentqueue.h:3039
bool try_enqueue(T const &item)
Definition: concurrentqueue.h:1039
static constexpr size_t kNumInputBytes
Definition: test_scrambler.cc:14
bool is_empty() const
Definition: concurrentqueue.h:1549
void reown_producers()
Definition: concurrentqueue.h:3265
static constexpr size_t kMaxUEs
Definition: symbols.h:289
Definition: udp_client.h:13
T * operator[](index_t idx) noexcept
Definition: concurrentqueue.h:1645
static constexpr size_t kModBitsNums[kModTestNum]
Definition: test_demul_threaded.cc:17
static double bench_ifft_1d_mkl(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:74
static void ApplyAwgn(complex_float *signal, complex_float *output, int len, float snr)
Definition: test_256qam_demod.cc:20
static double bench_multiply_dim1(unsigned Nx, unsigned Ny, unsigned iterations)
Definition: test_matrix.cc:67
void MasterToWorkerDynamicWorker(Config *cfg, size_t worker_id, moodycamel::ConcurrentQueue< EventData > &event_queue, moodycamel::ConcurrentQueue< EventData > &complete_task_queue, moodycamel::ProducerToken *ptok, PtrGrid< kFrameWnd, kMaxUEs, complex_float > &csi_buffers, Table< complex_float > &calib_dl_msum_buffer, Table< complex_float > &calib_ul_msum_buffer, Table< complex_float > &calib_dl_buffer, Table< complex_float > &calib_ul_buffer, PtrGrid< kFrameWnd, kMaxDataSCs, complex_float > &ul_beam_matrices, PtrGrid< kFrameWnd, kMaxDataSCs, complex_float > &dl_beam_matrices, PhyStats *phy_stats, Stats *stats)
Definition: test_zf_threaded.cc:52
static const thread_id_t invalid_thread_id2
Definition: concurrentqueue.h:156
std::size_t size_t
Definition: concurrentqueue.h:323
std::vector< complex_float > GetCommonPilotTimeDomain() const
Return the time-domain pilot symbol with OfdmCaNum complex floats.
Definition: data_generator.h:179
ConcurrentQueueProducerTypelessBase * next
Definition: concurrentqueue.h:425
std::atomic< size_t > implicitProducerHashCount
Definition: concurrentqueue.h:3659
static void demod_16qam_loop(float *vec_in, uint8_t *vec_out, int ue_num)
Definition: test_fft_mkl.cc:243
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
Definition: format.h:883
Declaration file for the PhyStats class.
static constexpr float kShrtFltConvFactor
Definition: datatype_conversion.h:18
Definition: concurrentqueue.h:1538
Definition: concurrentqueue.h:1417
void add(N *node)
Definition: concurrentqueue.h:1438
::moodycamel::ProducerToken producer_token_t
Definition: concurrentqueue.h:749
std::atomic< ProducerBase * > producerListTail
Definition: concurrentqueue.h:3645
void ServerRecvFrom(const std::string &src_address, uint16_t src_port, const std::string &dest_address, uint16_t dest_port)
Definition: test_udp_client_server.cc:79
static const size_t MAX_SUBQUEUE_SIZE
Definition: concurrentqueue.h:374
ssize_t Recv(std::byte *buf, size_t len) const
Try to receive up to len bytes in buf by default this will not block.
Definition: udp_server.h:55
static std::uint32_t hash(std::uint32_t h)
Definition: concurrentqueue.h:436
static const size_t EXPLICIT_INITIAL_INDEX_SIZE
Definition: concurrentqueue.h:353
FreeListNode()
Definition: concurrentqueue.h:1419
static constexpr bool kPrintUplinkInformationBytes
Definition: test_ldpc_baseband.cc:27
uint32_t frame_id_
Definition: message.h:32
static std::uint64_t hash(std::uint64_t h)
Definition: concurrentqueue.h:450
static constexpr size_t kMaxAntennas
Definition: symbols.h:286
std_max_align_t x
Definition: concurrentqueue.h:308
static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD
Definition: concurrentqueue.h:349
void printbits(uint8_t x)
Definition: test_modulation.cc:260
Block * try_get_block_from_free_list()
Definition: concurrentqueue.h:3067
size_t pr_blockIndexSize
Definition: concurrentqueue.h:2385
Block * tailBlock
Definition: concurrentqueue.h:1732
BlockIndexEntry * get_block_index_entry_for_index(index_t index) const
Definition: concurrentqueue.h:2924
static constexpr float kNoiseLevels[15]
Definition: test_ldpc_mod.cc:30
ConcurrentQueue(size_t capacity=6 *BLOCK_SIZE)
Definition: concurrentqueue.h:792
static size_t LdpcEncodingParityBufSize(size_t base_graph, size_t zc)
Definition: utils_ldpc.h:174
static T const & eval(T const &x)
Definition: concurrentqueue.h:524
static const std::string kIpv4Address
Definition: test_udp_client_server.cc:19
size_t ModOrderBits(Direction dir) const
Definition: config.h:247
#define OFDM
Definition: test_transpose.cc:17
uint32_t NumCbCodewLen() const
Definition: ldpc_config.h:51
index_t base
Definition: concurrentqueue.h:2328
size_t GetULSymbol(size_t location) const
Definition: framestats.cc:114
size_t pr_blockIndexSlotsUsed
Definition: concurrentqueue.h:2384
TEST(TestZF, VaryingConfig)
Definition: test_zf_threaded.cc:108
static void ConvertFloatToShort(const float *in_buf, short *out_buf, size_t n_elems, size_t n_prefix=0, float scale_down_factor=1.0f)
Definition: datatype_conversion.h:237
static constexpr size_t kBsAntNums[kAntTestNum]
Definition: test_zf_threaded.cc:15
bool enqueue(producer_token_t const &token, T const &item)
Definition: concurrentqueue.h:995
static constexpr size_t kMaxTestNum
Definition: test_concurrent_queue.cc:8
void Send(const std::string &rem_hostname, uint16_t rem_port, const std::byte *msg, size_t len)
Send one UDP packet to a remote server. The client caches the the remote server's addrinfo after reso...
Definition: udp_comm.cc:270
size_t size_approx() const
Definition: concurrentqueue.h:1717
int flushCache()
Definition: test_transpose.cc:29
size_t initialBlockPoolSize
Definition: concurrentqueue.h:3650
static void AdaptBitsForMod(const uint8_t *bit_seq_in, uint8_t *bytes_out, size_t len, size_t mod_type)
Fill-in the bytes of bytes_out with mod_type bits per byte, taken from the bit sequence bit_seq_in.
Definition: utils_ldpc.h:60
std::vector< complex_float > GetModulation(const std::vector< int8_t > &encoded_codeword)
Return the output of modulating the encoded codeword.
Definition: data_generator.h:108
static char * align_for(char *ptr)
Definition: concurrentqueue.h:483
void swap(ProducerToken &other) noexcept
Definition: concurrentqueue.h:653
int flushCache()
Definition: test_fft_mkl.cc:22
void add_knowing_refcount_is_zero(N *node)
Definition: concurrentqueue.h:1495
static bool() unlikely(bool x)
Definition: concurrentqueue.h:281
void WorkerToMasterWorkerWithoutToken(size_t worker_id, moodycamel::ConcurrentQueue< ItemT > *queue)
Definition: test_concurrent_queue.cc:87
Traits::index_t index_t
Definition: concurrentqueue.h:752
TEST(Modulation, adapt_bits_for_mod_one)
Definition: test_datatype_conversion.cc:15
Block * requisition_block()
Definition: concurrentqueue.h:3074
void swap(typename ConcurrentQueue< T, Traits >::ImplicitProducerKVP &a, typename ConcurrentQueue< T, Traits >::ImplicitProducerKVP &b) noexcept
Definition: concurrentqueue.h:3729
Definition: concurrentqueue.h:521
result
Definition: format-inl.h:640
void RandAllocCxFloat(size_t dim1, size_t dim2, Agora_memory::Alignment_t alignment)
Definition: memory_manage.h:69
ProducerBase * recycle_or_create_producer(bool isExplicit, bool &recycled)
Definition: concurrentqueue.h:3211
std::array< std::array< std::array< T *, DIM3 >, DIM2 >, DIM1 > cube_
The pointer cells.
Definition: memory_manage.h:265
DEFINE_string(profile, "random", "The profile of the input user bytes (e.g., 'random', '123')")
type
Definition: core.h:1131
int mod_order
Definition: ofdmtxrx.py:397
int main(int argc, char **argv)
Definition: test_udp_client_server.cc:252
float imag
Definition: test_transpose.cc:24
static void run_benchmark_1d_ifft(unsigned N, unsigned iterations)
Definition: test_fft_mkl.cc:373
TEST(TestArmadillo, CorrectnessStackMemoryState0)
Definition: test_armadillo.cc:61
static constexpr size_t kMessageSize
Definition: test_udp_client_server.cc:15
void RandAllocCxFloat(size_t n_entries)
Definition: memory_manage.h:166
ProducerToken(ConcurrentQueue< T, Traits > &queue)
Definition: concurrentqueue.h:3679
static const index_t INVALID_BLOCK_BASE
Definition: concurrentqueue.h:2868
~ConcurrentQueue()
Definition: concurrentqueue.h:837