| 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