// File: /workspace/github_cpp_makefile_star2_O2/dadocolussi[P]gdc-circular_queue/src/gdc_circular_queue_factory.c
// Function: gdc_circular_queue_map_shared
gdc_circular_queue*
gdc_circular_queue_map_shared(const char *name)
{
	// Ignore size. The true size is defined in the mapped memory.
	long page_size = sysconf(_SC_PAGESIZE);
	if (page_size == -1)
	{
		return NULL;
	}
	assert(page_size > 0);
	
	int fd = shm_open(name, O_RDWR, S_IRWXU);
	if (fd == -1)
	{
		return NULL;
	}
	
	struct stat st;
	int status = fstat(fd, &st);
	if (status != 0 || st.st_size <= page_size)
	{
		// Not fully initialized yet.
		close(fd);
		return NULL;
	}
	
	size_t init_size = gdc_circular_queue_footprint(0);
	void *p = mmap(
		NULL,
		init_size,
		PROT_READ | PROT_WRITE,
		MAP_SHARED,
		fd,
		0);
	if (p == MAP_FAILED)
	{
		close(fd);
		return NULL;
	}
	
	gdc_circular_queue *q = p;
	atomic_thread_fence(memory_order_acquire);
	size_t capacity = gdc_circular_queue_capacity(q);
	
	if (capacity == 0)
	{
		munmap(p, init_size);
		close(fd);
		errno = EAGAIN;
		return NULL;
	}
	
	size_t footprint = gdc_circular_queue_footprint(capacity);
	
	if (munmap(p, init_size) != 0)
	{
		close(fd);
		return NULL;
	}
	
	p = mmap(
		NULL,
		footprint + capacity,
		PROT_READ | PROT_WRITE,
		MAP_SHARED,
		fd,
		0);
	if (p == MAP_FAILED)
	{
		close(fd);
		return NULL;
	}
	
	q = p;
	void *pp = (char*)p + footprint;
	void *p2 = mmap(
		pp,
		capacity,
		PROT_READ | PROT_WRITE, 
		MAP_SHARED | MAP_FIXED,
		fd,
		page_size);
	if (p2 == MAP_FAILED)
	{
		munmap(p, footprint + capacity);
		close(fd);
		return NULL;
	}
	
	if (close(fd) != 0)
	{
		munmap(p, footprint + capacity);
		close(fd);
		return NULL;
	}
	
	return q;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %rbx
pushq $0x1e
popq %rdi
callq 0xc300
cmpq $-0x1, %rax
je 0x34eca
movq %rax, %r14
testq %rax, %rax
jle 0x34f01
pushq $0x2
popq %rsi
movq %rbx, %rdi
movl $0x1c0, %edx            # imm = 0x1C0
callq 0xc7c0
cmpl $-0x1, %eax
je 0x34eca
movl %eax, %ebx
leaq 0x8(%rsp), %rsi
movl %eax, %edi
callq 0xc7a0
testl %eax, %eax
jne 0x34ec3
cmpq %r14, 0x38(%rsp)
jle 0x34ec3
xorl %edi, %edi
callq 0x34cb6
movq %rax, %r15
pushq $0x3
popq %rdx
pushq $0x1
popq %rcx
xorl %edi, %edi
movq %rax, %rsi
movl %ebx, %r8d
xorl %r9d, %r9d
callq 0xc850
cmpq $-0x1, %rax
je 0x34ec3
movq %rax, %r12
movq %rax, %rdi
callq 0x34937
testq %rax, %rax
je 0x34ee2
movq %rax, %r13
movq %rax, %rdi
callq 0x34cb6
movq %rax, %rbp
movq %r12, %rdi
movq %r15, %rsi
callq 0xc280
testl %eax, %eax
jne 0x34ec3
movq %r13, %r12
addq %rbp, %r12
pushq $0x3
popq %rdx
pushq $0x1
popq %rcx
xorl %edi, %edi
movq %r12, %rsi
movl %ebx, %r8d
xorl %r9d, %r9d
callq 0xc850
cmpq $-0x1, %rax
je 0x34ec3
movq %rax, %r15
addq %rax, %rbp
pushq $0x3
popq %rdx
pushq $0x11
popq %rcx
movq %rbp, %rdi
movq %r13, %rsi
movl %ebx, %r8d
movq %r14, %r9
callq 0xc850
cmpq $-0x1, %rax
je 0x34eb8
movl %ebx, %edi
callq 0xc910
testl %eax, %eax
je 0x34ecd
movq %r15, %rdi
movq %r12, %rsi
callq 0xc280
movl %ebx, %edi
callq 0xc910
xorl %r15d, %r15d
movq %r15, %rax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r12, %rdi
movq %r15, %rsi
callq 0xc280
movl %ebx, %edi
callq 0xc910
callq 0xc040
movl $0xb, (%rax)
jmp 0x34eca
leaq 0x40f8(%rip), %rdi      # 0x39000
leaq 0x40ff(%rip), %rsi      # 0x3900e
leaq 0x4119(%rip), %rcx      # 0x3902f
movl $0xbe, %edx
callq 0xc310