// File: /workspace/github_cpp_makefile_star2_O3/HQarroum[P]thread-pool/examples/one-producer-many-consumers/./../../includes/concurrent_queue.hpp
// Function: moodycamel::ConcurrentQueue<std::function<void ()>, moodycamel::ConcurrentQueueDefaultTraits>::ImplicitProducer::~ImplicitProducer()
~ImplicitProducer()
		{
			// Note that since we're in the destructor we can assume that all enqueue/dequeue operations
			// completed already; this means that all undequeued elements are placed contiguously across
			// contiguous blocks, and that only the first and last remaining blocks can be only partially
			// empty (all other remaining blocks must be completely full).
			
#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
			// Unregister ourselves for thread termination notification
			if (!this->inactive.load(std::memory_order_relaxed)) {
				details::ThreadExitNotifier::unsubscribe(&threadExitListener);
			}
#endif
			
			// Destroy all remaining elements!
			auto tail = this->tailIndex.load(std::memory_order_relaxed);
			auto index = this->headIndex.load(std::memory_order_relaxed);
			Block* block = nullptr;
			assert(index == tail || details::circular_less_than(index, tail));
			bool forceFreeLastBlock = index != tail;		// If we enter the loop, then the last (tail) block will not be freed
			while (index != tail) {
				if ((index & static_cast<index_t>(BLOCK_SIZE - 1)) == 0 || block == nullptr) {
					if (block != nullptr) {
						// Free the old block
						this->parent->add_block_to_free_list(block);
					}
					
					block = get_block_index_entry_for_index(index)->value.load(std::memory_order_relaxed);
				}
				
				((*block)[index])->~T();
				++index;
			}
			// Even if the queue is empty, there's still one block that's not on the free list
			// (unless the head index reached the end of it, in which case the tail will be poised
			// to create a new block).
			if (this->tailBlock != nullptr && (forceFreeLastBlock || (tail & static_cast<index_t>(BLOCK_SIZE - 1)) != 0)) {
				this->parent->add_block_to_free_list(this->tailBlock);
			}
			
			// Destroy block index
			auto localBlockIndex = blockIndex.load(std::memory_order_relaxed);
			if (localBlockIndex != nullptr) {
				for (size_t i = 0; i != localBlockIndex->capacity; ++i) {
					localBlockIndex->index[i]->~BlockIndexEntry();
				}
				do {
					auto prev = localBlockIndex->prev;
					localBlockIndex->~BlockIndexHeader();
					(Traits::free)(localBlockIndex);
					localBlockIndex = prev;
				} while (localBlockIndex != nullptr);
			}
		}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
leaq 0x53f2(%rip), %rax      # 0xbd28
movq %rax, (%rdi)
movq 0x20(%rdi), %r14
movq 0x28(%rdi), %r15
movq %r15, %rax
subq %r14, %rax
setne %cl
movabsq $-0x7fffffffffffffff, %rdx # imm = 0x8000000000000001
cmpq %rdx, %rax
setb %al
testb %al, %cl
jne 0x6b14
movq %rdi, %rbx
cmpq %r14, %r15
je 0x6a59
xorl %r13d, %r13d
movq %r15, %r12
movq %r12, %rdi
andq $0x1f, %rdi
setne %al
testq %r13, %r13
setne %cl
testb %al, %cl
jne 0x6a33
testq %r13, %r13
je 0x69d8
movq 0x50(%rbx), %rcx
movl $0x80000000, %eax       # imm = 0x80000000
lock
xaddl %eax, 0x430(%r13)
testl %eax, %eax
jne 0x69d8
movq 0x28(%rcx), %rax
movq %rax, 0x438(%r13)
movl $0x1, 0x430(%r13)
lock
cmpxchgq %r13, 0x28(%rcx)
je 0x69d8
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
lock
xaddl %edx, 0x430(%r13)
cmpl $0x1, %edx
je 0x69ab
movq 0x60(%rbx), %rcx
movq 0x8(%rcx), %rdx
movq 0x18(%rcx), %rax
movq (%rax,%rdx,8), %rsi
movq (%rsi), %rsi
cmpq $0x1, %rsi
je 0x6af5
movq %r12, %r8
andq $-0x20, %r8
movq %r8, %r9
subq %rsi, %r9
shrq $0x5, %r9
addq %rdx, %r9
movq (%rcx), %rcx
decq %rcx
andq %r9, %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rcx
cmpq %r8, %rcx
jne 0x6ad6
movq 0x8(%rax), %rcx
testq %rcx, %rcx
je 0x6ad6
movq 0x8(%rax), %r13
shll $0x5, %edi
movq 0x10(%r13,%rdi), %rax
testq %rax, %rax
je 0x6a4d
addq %r13, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
incq %r12
cmpq %r14, %r12
jne 0x6974
movq 0x40(%rbx), %rcx
testq %rcx, %rcx
je 0x6ab2
xorq %r14, %r15
andl $0x1f, %r14d
orq %r15, %r14
je 0x6ab2
movq 0x50(%rbx), %rdx
movl $0x80000000, %eax       # imm = 0x80000000
lock
xaddl %eax, 0x430(%rcx)
testl %eax, %eax
jne 0x6ab2
movq 0x28(%rdx), %rax
movq %rax, 0x438(%rcx)
movl $0x1, 0x430(%rcx)
lock
cmpxchgq %rcx, 0x28(%rdx)
je 0x6ab2
movl $0x7fffffff, %esi       # imm = 0x7FFFFFFF
lock
xaddl %esi, 0x430(%rcx)
cmpl $0x1, %esi
je 0x6a87
movq 0x60(%rbx), %rdi
testq %rdi, %rdi
je 0x6acc
movq 0x20(%rdi), %rbx
callq 0x32a0
movq %rbx, %rdi
testq %rbx, %rbx
jne 0x6abb
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0xb21(%rip), %rdi       # 0x75fe
leaq 0x5fa(%rip), %rsi       # 0x70de
leaq 0xa31(%rip), %rcx       # 0x751c
movl $0xb81, %edx            # imm = 0xB81
callq 0x3150
leaq 0xa01(%rip), %rdi       # 0x74fd
leaq 0x5db(%rip), %rsi       # 0x70de
leaq 0xa12(%rip), %rcx       # 0x751c
movl $0xb7c, %edx            # imm = 0xB7C
callq 0x3150
leaq 0xf8e(%rip), %rdi       # 0x7aa9
leaq 0x5bc(%rip), %rsi       # 0x70de
leaq 0xfba(%rip), %rcx       # 0x7ae3
movl $0x982, %edx            # imm = 0x982
callq 0x3150
movq %rax, %rdi
callq 0x3ae9
nop