// File: /workspace/github_cpp_makefile_star2_O1/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
movl $0x1e, %edi
callq 0xc2c0
cmpq $-0x1, %rax
je 0x450fc
movq %rax, %r14
testq %rax, %rax
jle 0x45133
movq %rbx, %rdi
movl $0x2, %esi
movl $0x1c0, %edx            # imm = 0x1C0
callq 0xc780
cmpl $-0x1, %eax
je 0x450fc
movl %eax, %ebx
leaq 0x8(%rsp), %rsi
movl %eax, %edi
callq 0xc760
testl %eax, %eax
jne 0x450f5
cmpq %r14, 0x38(%rsp)
jle 0x450f5
xorl %edi, %edi
callq 0x44ed2
movq %rax, %r15
xorl %edi, %edi
movq %rax, %rsi
movl $0x3, %edx
movl $0x1, %ecx
movl %ebx, %r8d
xorl %r9d, %r9d
callq 0xc830
cmpq $-0x1, %rax
je 0x450f5
movq %rax, %r12
movq %rax, %rdi
callq 0x44ad8
testq %rax, %rax
je 0x45114
movq %rax, %r13
movq %rax, %rdi
callq 0x44ed2
movq %rax, %rbp
movq %r12, %rdi
movq %r15, %rsi
callq 0xc250
testl %eax, %eax
jne 0x450f5
movq %r13, %r12
addq %rbp, %r12
xorl %edi, %edi
movq %r12, %rsi
movl $0x3, %edx
movl $0x1, %ecx
movl %ebx, %r8d
xorl %r9d, %r9d
callq 0xc830
cmpq $-0x1, %rax
je 0x450f5
movq %rax, %r15
addq %rax, %rbp
movq %rbp, %rdi
movq %r13, %rsi
movl $0x3, %edx
movl $0x11, %ecx
movl %ebx, %r8d
movq %r14, %r9
callq 0xc830
cmpq $-0x1, %rax
je 0x450ea
movl %ebx, %edi
callq 0xc8e0
testl %eax, %eax
je 0x450ff
movq %r15, %rdi
movq %r12, %rsi
callq 0xc250
movl %ebx, %edi
callq 0xc8e0
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 0xc250
movl %ebx, %edi
callq 0xc8e0
callq 0xc050
movl $0xb, (%rax)
jmp 0x450fc
leaq 0x4eb6(%rip), %rdi      # 0x49ff0
leaq 0x4ebd(%rip), %rsi      # 0x49ffe
leaq 0x4ed7(%rip), %rcx      # 0x4a01f
movl $0xbe, %edx
callq 0xc2d0