// File: dadocolussi[P]gdc-circular_queue/tests/pingpong.cpp
// Function: run()
void
run()
{
	long page_size = ::sysconf(_SC_PAGESIZE);
	assert(page_size > 0);
	std::string ping_name("/gdcq.ping");
	std::string pong_name("/gdcq.pong");

#if USE_C_API
	F rqf(ping_name, 10 * page_size);
	F wqf(pong_name);
	bool seed = false;
#else
	F wqf(ping_name);
	F rqf(pong_name, 10 * page_size);
	bool seed = true;
#endif

	std::cout << "Trying to resolve write queue" << std::endl;
	Q& rq = rqf.get();
	for (int i = 0; i < 10; ++i)
	{
		if (wqf.can_get())
		{
			break;
		}

		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
	
	if (!wqf.can_get())
	{
		throw std::runtime_error("Failed to resolve write queue");
	}
	
	Q& wq = wqf.get();
	std::cout << "Did resolve write queue" << std::endl;

	std::size_t seq = 0;
	std::size_t n = 1000000;

	if (seed)
	{
		wq.push(&seq, sizeof seq);
		++seq;
	}

	while (seq < n)
	{
		auto i = rq.peek();

		if (i == nullptr)
		{
			continue;
		}

		if (seq == 0)
		{
			// Initialize sequence.
			seq = *i;
		}

		assert(*i == seq);
		rq.pop(sizeof seq);
		assert(rq.empty());

		if (++seq < n)
		{
			wq.push(&seq, sizeof seq);
			++seq;
		}
	}

	std::cout << "Did send and receive " << n << " messages" << std::endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x200, %rsp            # imm = 0x200
movl $0x1e, %edi
callq 0x2150
movq %rax, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
jle 0x2512
jmp 0x2531
leaq 0x4b23(%rip), %rdi      # 0x703c
leaq 0x4b2a(%rip), %rsi      # 0x704a
movl $0x34, %edx
leaq 0x4b31(%rip), %rcx      # 0x705d
callq 0x2160
leaq -0x29(%rbp), %rdi
movq %rdi, -0x198(%rbp)
callq 0x2320
movq -0x198(%rbp), %rdx
leaq 0x4b19(%rip), %rsi      # 0x7068
leaq -0x28(%rbp), %rdi
callq 0x2b00
jmp 0x255a
leaq -0x29(%rbp), %rdi
callq 0x2210
leaq -0x61(%rbp), %rdi
movq %rdi, -0x1a0(%rbp)
callq 0x2320
movq -0x1a0(%rbp), %rdx
leaq 0x4af2(%rip), %rsi      # 0x7073
leaq -0x60(%rbp), %rdi
callq 0x2b00
jmp 0x258c
leaq -0x61(%rbp), %rdi
callq 0x2210
leaq -0xc8(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x2bb0
jmp 0x25a7
movq -0x8(%rbp), %rax
addq %rax, %rax
leaq (%rax,%rax,4), %rax
movq %rax, -0x1b0(%rbp)
leaq -0x148(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
leaq -0x149(%rbp), %rsi
callq 0x2c50
movq -0x1b0(%rbp), %rdx
movq -0x1a8(%rbp), %r8
leaq -0x128(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x1, %ecx
callq 0x2ce0
jmp 0x25f8
leaq -0x148(%rbp), %rdi
callq 0x2de0
movb $0x1, -0x14a(%rbp)
movq 0x89b6(%rip), %rdi      # 0xafc8
leaq 0x4a65(%rip), %rsi      # 0x707e
callq 0x21d0
movq %rax, -0x1b8(%rbp)
jmp 0x2627
movq -0x1b8(%rbp), %rdi
movq 0x897b(%rip), %rsi      # 0xafb0
callq 0x21f0
jmp 0x263c
leaq -0x128(%rbp), %rdi
callq 0x2e00
movq %rax, -0x1c0(%rbp)
jmp 0x2651
movq -0x1c0(%rbp), %rax
movq %rax, -0x158(%rbp)
movl $0x0, -0x15c(%rbp)
cmpl $0xa, -0x15c(%rbp)
jge 0x2751
leaq -0xc8(%rbp), %rdi
callq 0x2e30
movb %al, -0x1c1(%rbp)
jmp 0x268a
movb -0x1c1(%rbp), %al
testb $0x1, %al
jne 0x2696
jmp 0x270e
jmp 0x2751
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x29(%rbp), %rdi
callq 0x2210
jmp 0x2a47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x61(%rbp), %rdi
callq 0x2210
jmp 0x2a3e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x2a35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x2de0
jmp 0x2a29
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x2a1d
movl $0x1, -0x16c(%rbp)
leaq -0x168(%rbp), %rdi
leaq -0x16c(%rbp), %rsi
callq 0x2f60
jmp 0x272d
leaq -0x168(%rbp), %rdi
callq 0x2eb0
jmp 0x273b
jmp 0x273d
movl -0x15c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x15c(%rbp)
jmp 0x2669
leaq -0xc8(%rbp), %rdi
callq 0x2e30
movb %al, -0x1c2(%rbp)
jmp 0x2765
movb -0x1c2(%rbp), %al
testb $0x1, %al
jne 0x27d2
jmp 0x2771
movl $0x10, %edi
callq 0x2100
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x1d0(%rbp)
leaq 0x490d(%rip), %rsi      # 0x709c
callq 0x20b0
jmp 0x2796
movq -0x1d0(%rbp), %rdi
movq 0x884c(%rip), %rsi      # 0xaff0
movq 0x8815(%rip), %rdx      # 0xafc0
callq 0x2300
jmp 0x2a50
movq -0x1d0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
callq 0x2190
jmp 0x2a1d
leaq -0xc8(%rbp), %rdi
callq 0x2e00
movq %rax, -0x1d8(%rbp)
jmp 0x27e7
movq -0x1d8(%rbp), %rax
movq %rax, -0x178(%rbp)
movq 0x87cc(%rip), %rdi      # 0xafc8
leaq 0x48b7(%rip), %rsi      # 0x70ba
callq 0x21d0
movq %rax, -0x1e0(%rbp)
jmp 0x2811
movq -0x1e0(%rbp), %rdi
movq 0x8791(%rip), %rsi      # 0xafb0
callq 0x21f0
jmp 0x2826
movq $0x0, -0x180(%rbp)
movq $0xf4240, -0x188(%rbp) # imm = 0xF4240
testb $0x1, -0x14a(%rbp)
je 0x286f
movq -0x178(%rbp), %rdi
leaq -0x180(%rbp), %rsi
movl $0x8, %edx
callq 0x2f80
movq -0x180(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x180(%rbp)
jmp 0x2871
movq -0x180(%rbp), %rax
cmpq -0x188(%rbp), %rax
jae 0x2981
movq -0x158(%rbp), %rdi
callq 0x2ff0
movq %rax, -0x190(%rbp)
cmpq $0x0, -0x190(%rbp)
jne 0x28a4
jmp 0x2871
cmpq $0x0, -0x180(%rbp)
jne 0x28bf
movq -0x190(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x180(%rbp)
movq -0x190(%rbp), %rax
movq (%rax), %rax
cmpq -0x180(%rbp), %rax
jne 0x28d4
jmp 0x28f3
leaq 0x47f7(%rip), %rdi      # 0x70d2
leaq 0x4768(%rip), %rsi      # 0x704a
movl $0x6e, %edx
leaq 0x476f(%rip), %rcx      # 0x705d
callq 0x2160
movq -0x158(%rbp), %rdi
movl $0x8, %esi
callq 0x3180
movq -0x158(%rbp), %rdi
callq 0x32c0
testb $0x1, %al
jne 0x2916
jmp 0x2918
jmp 0x2937
leaq 0x47bd(%rip), %rdi      # 0x70dc
leaq 0x4724(%rip), %rsi      # 0x704a
movl $0x70, %edx
leaq 0x472b(%rip), %rcx      # 0x705d
callq 0x2160
movq -0x180(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x180(%rbp)
cmpq -0x188(%rbp), %rax
jae 0x297c
movq -0x178(%rbp), %rdi
leaq -0x180(%rbp), %rsi
movl $0x8, %edx
callq 0x2f80
movq -0x180(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x180(%rbp)
jmp 0x2871
movq 0x8640(%rip), %rdi      # 0xafc8
leaq 0x4758(%rip), %rsi      # 0x70e7
callq 0x21d0
movq %rax, -0x1e8(%rbp)
jmp 0x299d
movq -0x1e8(%rbp), %rdi
movq -0x188(%rbp), %rsi
callq 0x2060
movq %rax, -0x1f0(%rbp)
jmp 0x29b9
movq -0x1f0(%rbp), %rdi
leaq 0x4736(%rip), %rsi      # 0x70fd
callq 0x21d0
movq %rax, -0x1f8(%rbp)
jmp 0x29d5
movq -0x1f8(%rbp), %rdi
movq 0x85cd(%rip), %rsi      # 0xafb0
callq 0x21f0
jmp 0x29ea
leaq -0x128(%rbp), %rdi
callq 0x33d0
leaq -0xc8(%rbp), %rdi
callq 0x33d0
leaq -0x60(%rbp), %rdi
callq 0x2130
leaq -0x28(%rbp), %rdi
callq 0x2130
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
leaq -0x128(%rbp), %rdi
callq 0x33d0
leaq -0xc8(%rbp), %rdi
callq 0x33d0
leaq -0x60(%rbp), %rdi
callq 0x2130
leaq -0x28(%rbp), %rdi
callq 0x2130
movq -0x38(%rbp), %rdi
callq 0x2310