// File: HQarroum[P]thread-pool/examples/one-producer-many-consumers/./../../includes/concurrent_queue.hpp
// Function: unsigned long moodycamel::ConcurrentQueue<std::function<void ()>, moodycamel::ConcurrentQueueDefaultTraits>::ExplicitProducer::dequeue_bulk<std::function<void ()>*>(std::function<void ()>*&, unsigned long)
size_t dequeue_bulk(It& itemFirst, size_t max)
		{
			auto tail = this->tailIndex.load(std::memory_order_relaxed);
			auto overcommit = this->dequeueOvercommit.load(std::memory_order_relaxed);
			auto desiredCount = static_cast<size_t>(tail - (this->dequeueOptimisticCount.load(std::memory_order_relaxed) - overcommit));
			if (details::circular_less_than<size_t>(0, desiredCount)) {
				desiredCount = desiredCount < max ? desiredCount : max;
				std::atomic_thread_fence(std::memory_order_acquire);
				
				auto myDequeueCount = this->dequeueOptimisticCount.fetch_add(desiredCount, std::memory_order_relaxed);
				
				tail = this->tailIndex.load(std::memory_order_acquire);
				auto actualCount = static_cast<size_t>(tail - (myDequeueCount - overcommit));
				if (details::circular_less_than<size_t>(0, actualCount)) {
					actualCount = desiredCount < actualCount ? desiredCount : actualCount;
					if (actualCount < desiredCount) {
						this->dequeueOvercommit.fetch_add(desiredCount - actualCount, std::memory_order_release);
					}
					
					// Get the first index. Note that since there's guaranteed to be at least actualCount elements, this
					// will never exceed tail.
					auto firstIndex = this->headIndex.fetch_add(actualCount, std::memory_order_acq_rel);
					
					// Determine which block the first element is in
					auto localBlockIndex = blockIndex.load(std::memory_order_acquire);
					auto localBlockIndexHead = localBlockIndex->front.load(std::memory_order_acquire);
					
					auto headBase = localBlockIndex->entries[localBlockIndexHead].base;
					auto firstBlockBaseIndex = firstIndex & ~static_cast<index_t>(BLOCK_SIZE - 1);
					auto offset = static_cast<size_t>(static_cast<typename std::make_signed<index_t>::type>(firstBlockBaseIndex - headBase) / BLOCK_SIZE);
					auto indexIndex = (localBlockIndexHead + offset) & (localBlockIndex->size - 1);
					
					// Iterate the blocks and dequeue
					auto index = firstIndex;
					do {
						auto firstIndexInBlock = index;
						index_t endIndex = (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
						endIndex = details::circular_less_than<index_t>(firstIndex + static_cast<index_t>(actualCount), endIndex) ? firstIndex + static_cast<index_t>(actualCount) : endIndex;
						auto block = localBlockIndex->entries[indexIndex].block;
						if (MOODYCAMEL_NOEXCEPT_ASSIGN(T, T&&, details::deref_noexcept(itemFirst) = std::move((*(*block)[index])))) {
							while (index != endIndex) {
								auto& el = *((*block)[index]);
								*itemFirst++ = std::move(el);
								el.~T();
								++index;
							}
						}
						else {
							MOODYCAMEL_TRY {
								while (index != endIndex) {
									auto& el = *((*block)[index]);
									*itemFirst = std::move(el);
									++itemFirst;
									el.~T();
									++index;
								}
							}
							MOODYCAMEL_CATCH (...) {
								// It's too late to revert the dequeue, but we can make sure that all
								// the dequeued objects are properly destroyed and the block index
								// (and empty count) are properly updated before we propagate the exception
								do {
									block = localBlockIndex->entries[indexIndex].block;
									while (index != endIndex) {
										(*block)[index++]->~T();
									}
									block->ConcurrentQueue::Block::template set_many_empty<explicit_context>(firstIndexInBlock, static_cast<size_t>(endIndex - firstIndexInBlock));
									indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1);
									
									firstIndexInBlock = index;
									endIndex = (index & ~static_cast<index_t>(BLOCK_SIZE - 1)) + static_cast<index_t>(BLOCK_SIZE);
									endIndex = details::circular_less_than<index_t>(firstIndex + static_cast<index_t>(actualCount), endIndex) ? firstIndex + static_cast<index_t>(actualCount) : endIndex;
								} while (index != firstIndex + actualCount);
								
								MOODYCAMEL_RETHROW;
							}
						}
						block->ConcurrentQueue::Block::template set_many_empty<explicit_context>(firstIndexInBlock, static_cast<size_t>(endIndex - firstIndexInBlock));
						indexIndex = (indexIndex + 1) & (localBlockIndex->size - 1);
					} while (index != firstIndex + actualCount);
					
					return actualCount;
				}
				else {
					// Wasn't anything to dequeue after all; make the effective dequeue count eventually consistent
					this->dequeueOvercommit.fetch_add(desiredCount, std::memory_order_release);
				}
			}
			
			return 0;
		}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x290, %rsp            # imm = 0x290
movq %rdi, -0x130(%rbp)
movq %rsi, -0x138(%rbp)
movq %rdx, -0x140(%rbp)
movq -0x130(%rbp), %rax
movq %rax, -0x1e0(%rbp)
addq $0x20, %rax
movq %rax, -0xb0(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x1d8(%rbp)
movl -0xb4(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0xb8(%rbp)
movl -0xb4(%rbp), %eax
movl %eax, -0x1cc(%rbp)
decl %eax
subl $0x2, %eax
jb 0x947c
jmp 0x945c
movl -0x1cc(%rbp), %eax
subl $0x5, %eax
je 0x948f
jmp 0x9469
movq -0x1d8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xc0(%rbp)
jmp 0x94a0
movq -0x1d8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xc0(%rbp)
jmp 0x94a0
movq -0x1d8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xc0(%rbp)
movq -0x1e0(%rbp), %rax
movq -0xc0(%rbp), %rcx
movq %rcx, -0x148(%rbp)
addq $0x38, %rax
movq %rax, -0xc8(%rbp)
movl $0x0, -0xcc(%rbp)
movq -0xc8(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movl -0xcc(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0xd0(%rbp)
movl -0xcc(%rbp), %eax
movl %eax, -0x1e4(%rbp)
decl %eax
subl $0x2, %eax
jb 0x9523
jmp 0x9503
movl -0x1e4(%rbp), %eax
subl $0x5, %eax
je 0x9536
jmp 0x9510
movq -0x1f0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xd8(%rbp)
jmp 0x9547
movq -0x1f0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xd8(%rbp)
jmp 0x9547
movq -0x1f0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xd8(%rbp)
movq -0x1e0(%rbp), %rax
movq -0xd8(%rbp), %rcx
movq %rcx, -0x150(%rbp)
movq -0x148(%rbp), %rcx
movq %rcx, -0x208(%rbp)
addq $0x30, %rax
movq %rax, -0xe0(%rbp)
movl $0x0, -0xe4(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x200(%rbp)
movl -0xe4(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0xe8(%rbp)
movl -0xe4(%rbp), %eax
movl %eax, -0x1f4(%rbp)
decl %eax
subl $0x2, %eax
jb 0x95d8
jmp 0x95b8
movl -0x1f4(%rbp), %eax
subl $0x5, %eax
je 0x95eb
jmp 0x95c5
movq -0x200(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xf0(%rbp)
jmp 0x95fc
movq -0x200(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xf0(%rbp)
jmp 0x95fc
movq -0x200(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xf0(%rbp)
movq -0x208(%rbp), %rax
movq -0xf0(%rbp), %rcx
subq -0x150(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0x3800
testb $0x1, %al
jne 0x9634
jmp 0x9e15
movq -0x158(%rbp), %rax
cmpq -0x140(%rbp), %rax
jae 0x9654
movq -0x158(%rbp), %rax
movq %rax, -0x210(%rbp)
jmp 0x9662
movq -0x140(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x210(%rbp), %rax
movq %rax, -0x158(%rbp)
movl $0x2, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x218(%rbp)
subl $0x4, %eax
ja 0x96b0
movq -0x218(%rbp), %rax
leaq 0xe9fe(%rip), %rcx      # 0x1809c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x96b0
jmp 0x96b0
jmp 0x96b0
mfence
movq -0x1e0(%rbp), %rcx
addq $0x30, %rcx
movq -0x158(%rbp), %rax
movq %rcx, -0x8(%rbp)
movq %rax, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x228(%rbp)
movl -0x14(%rbp), %eax
movq -0x10(%rbp), %rcx
movq %rcx, -0x20(%rbp)
decl %eax
movl %eax, %ecx
movq %rcx, -0x220(%rbp)
subl $0x4, %eax
ja 0x970e
movq -0x220(%rbp), %rax
leaq 0xe9ab(%rip), %rcx      # 0x180b0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x228(%rbp), %rcx
movq -0x20(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x28(%rbp)
jmp 0x977a
movq -0x228(%rbp), %rcx
movq -0x20(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x28(%rbp)
jmp 0x977a
movq -0x228(%rbp), %rcx
movq -0x20(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x28(%rbp)
jmp 0x977a
movq -0x228(%rbp), %rcx
movq -0x20(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x28(%rbp)
jmp 0x977a
movq -0x228(%rbp), %rcx
movq -0x20(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x28(%rbp)
movq -0x1e0(%rbp), %rax
movq -0x28(%rbp), %rcx
movq %rcx, -0x160(%rbp)
addq $0x20, %rax
movq %rax, -0xf8(%rbp)
movl $0x2, -0xfc(%rbp)
movq -0xf8(%rbp), %rax
movq %rax, -0x238(%rbp)
movl -0xfc(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x100(%rbp)
movl -0xfc(%rbp), %eax
movl %eax, -0x22c(%rbp)
decl %eax
subl $0x2, %eax
jb 0x97fa
jmp 0x97da
movl -0x22c(%rbp), %eax
subl $0x5, %eax
je 0x980d
jmp 0x97e7
movq -0x238(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x108(%rbp)
jmp 0x981e
movq -0x238(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x108(%rbp)
jmp 0x981e
movq -0x238(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x148(%rbp), %rax
movq -0x160(%rbp), %rcx
subq -0x150(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x168(%rbp)
movq -0x168(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edi
callq 0x3800
testb $0x1, %al
jne 0x9864
jmp 0x9d1c
movq -0x158(%rbp), %rax
cmpq -0x168(%rbp), %rax
jae 0x9884
movq -0x158(%rbp), %rax
movq %rax, -0x240(%rbp)
jmp 0x9892
movq -0x168(%rbp), %rax
movq %rax, -0x240(%rbp)
movq -0x240(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x168(%rbp), %rax
cmpq -0x158(%rbp), %rax
jae 0x9988
movq -0x1e0(%rbp), %rcx
addq $0x38, %rcx
movq -0x158(%rbp), %rax
movq -0x168(%rbp), %rdx
subq %rdx, %rax
movq %rcx, -0x30(%rbp)
movq %rax, -0x38(%rbp)
movl $0x3, -0x3c(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x250(%rbp)
movl -0x3c(%rbp), %eax
movq -0x38(%rbp), %rcx
movq %rcx, -0x48(%rbp)
decl %eax
movl %eax, %ecx
movq %rcx, -0x248(%rbp)
subl $0x4, %eax
ja 0x991c
movq -0x248(%rbp), %rax
leaq 0xe7c5(%rip), %rcx      # 0x180d8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x250(%rbp), %rcx
movq -0x48(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x50(%rbp)
jmp 0x9988
movq -0x250(%rbp), %rcx
movq -0x48(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x50(%rbp)
jmp 0x9988
movq -0x250(%rbp), %rcx
movq -0x48(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x50(%rbp)
jmp 0x9988
movq -0x250(%rbp), %rcx
movq -0x48(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x50(%rbp)
jmp 0x9988
movq -0x250(%rbp), %rcx
movq -0x48(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x50(%rbp)
movq -0x1e0(%rbp), %rcx
addq $0x28, %rcx
movq -0x168(%rbp), %rax
movq %rcx, -0x58(%rbp)
movq %rax, -0x60(%rbp)
movl $0x4, -0x64(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x260(%rbp)
movl -0x64(%rbp), %eax
movq -0x60(%rbp), %rcx
movq %rcx, -0x70(%rbp)
decl %eax
movl %eax, %ecx
movq %rcx, -0x258(%rbp)
subl $0x4, %eax
ja 0x99e6
movq -0x258(%rbp), %rax
leaq 0xe70f(%rip), %rcx      # 0x180ec
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x260(%rbp), %rcx
movq -0x70(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x78(%rbp)
jmp 0x9a52
movq -0x260(%rbp), %rcx
movq -0x70(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x78(%rbp)
jmp 0x9a52
movq -0x260(%rbp), %rcx
movq -0x70(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x78(%rbp)
jmp 0x9a52
movq -0x260(%rbp), %rcx
movq -0x70(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x78(%rbp)
jmp 0x9a52
movq -0x260(%rbp), %rcx
movq -0x70(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0x78(%rbp)
movq -0x1e0(%rbp), %rdi
movq -0x78(%rbp), %rax
movq %rax, -0x170(%rbp)
addq $0x58, %rdi
movl $0x2, %esi
callq 0xa7b0
movq %rax, -0x178(%rbp)
movq -0x178(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x110(%rbp)
movl $0x2, -0x114(%rbp)
movq -0x110(%rbp), %rax
movq %rax, -0x270(%rbp)
movl -0x114(%rbp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x58d0
movl %eax, -0x118(%rbp)
movl -0x114(%rbp), %eax
movl %eax, -0x264(%rbp)
decl %eax
subl $0x2, %eax
jb 0x9aee
jmp 0x9ace
movl -0x264(%rbp), %eax
subl $0x5, %eax
je 0x9b01
jmp 0x9adb
movq -0x270(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x120(%rbp)
jmp 0x9b12
movq -0x270(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x120(%rbp)
jmp 0x9b12
movq -0x270(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x178(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x180(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movq %rax, -0x188(%rbp)
movq -0x170(%rbp), %rax
andq $-0x20, %rax
movq %rax, -0x190(%rbp)
movq -0x190(%rbp), %rax
subq -0x188(%rbp), %rax
shrq $0x5, %rax
movq %rax, -0x198(%rbp)
movq -0x180(%rbp), %rax
addq -0x198(%rbp), %rax
movq -0x178(%rbp), %rcx
movq (%rcx), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0x1a0(%rbp)
movq -0x170(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x1a8(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movq -0x1a8(%rbp), %rax
andq $-0x20, %rax
addq $0x20, %rax
movq %rax, -0x1b8(%rbp)
movq -0x170(%rbp), %rdi
addq -0x168(%rbp), %rdi
movq -0x1b8(%rbp), %rsi
callq 0x3800
testb $0x1, %al
jne 0x9be6
jmp 0x9bfd
movq -0x170(%rbp), %rax
addq -0x168(%rbp), %rax
movq %rax, -0x278(%rbp)
jmp 0x9c0b
movq -0x1b8(%rbp), %rax
movq %rax, -0x278(%rbp)
movq -0x278(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x178(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x1a0(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq %rax, -0x1c0(%rbp)
movq -0x1a8(%rbp), %rax
cmpq -0x1b8(%rbp), %rax
je 0x9ca7
movq -0x1c0(%rbp), %rdi
movq -0x1a8(%rbp), %rsi
callq 0xa830
movq %rax, -0x1c8(%rbp)
movq -0x1c8(%rbp), %rsi
movq -0x138(%rbp), %rax
movq (%rax), %rdi
movq %rdi, %rcx
addq $0x20, %rcx
movq %rcx, (%rax)
callq 0xa860
movq -0x1c8(%rbp), %rdi
callq 0x6fc0
movq -0x1a8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1a8(%rbp)
jmp 0x9c3d
movq -0x1c0(%rbp), %rdi
movq -0x1b0(%rbp), %rsi
movq -0x1b8(%rbp), %rdx
subq -0x1b0(%rbp), %rdx
callq 0xa8b0
movq -0x1a0(%rbp), %rax
addq $0x1, %rax
movq -0x178(%rbp), %rcx
movq (%rcx), %rcx
subq $0x1, %rcx
andq %rcx, %rax
movq %rax, -0x1a0(%rbp)
movq -0x1a8(%rbp), %rax
movq -0x170(%rbp), %rcx
addq -0x168(%rbp), %rcx
cmpq %rcx, %rax
jne 0x9ba2
movq -0x168(%rbp), %rax
movq %rax, -0x128(%rbp)
jmp 0x9e20
movq -0x1e0(%rbp), %rcx
addq $0x38, %rcx
movq -0x158(%rbp), %rax
movq %rcx, -0x80(%rbp)
movq %rax, -0x88(%rbp)
movl $0x3, -0x8c(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x288(%rbp)
movl -0x8c(%rbp), %eax
movq -0x88(%rbp), %rcx
movq %rcx, -0x98(%rbp)
decl %eax
movl %eax, %ecx
movq %rcx, -0x280(%rbp)
subl $0x4, %eax
ja 0x9d89
movq -0x280(%rbp), %rax
leaq 0xe344(%rip), %rcx      # 0x180c4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x288(%rbp), %rcx
movq -0x98(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0xa0(%rbp)
jmp 0x9e13
movq -0x288(%rbp), %rcx
movq -0x98(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0xa0(%rbp)
jmp 0x9e13
movq -0x288(%rbp), %rcx
movq -0x98(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0xa0(%rbp)
jmp 0x9e13
movq -0x288(%rbp), %rcx
movq -0x98(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0xa0(%rbp)
jmp 0x9e13
movq -0x288(%rbp), %rcx
movq -0x98(%rbp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, -0xa0(%rbp)
jmp 0x9e15
movq $0x0, -0x128(%rbp)
movq -0x128(%rbp), %rax
addq $0x290, %rsp            # imm = 0x290
popq %rbp
retq