// File: dadocolussi[P]gdc-circular_queue/src/gdc_circular_queue_factory.c
// Function: gdc_circular_queue_create_shared
int
gdc_circular_queue_create_shared(
	const char* name,
	size_t capacity,
	int sync,
	int (*mdinit)(gdc_circular_queue*, void*),
	void* md_context)
{
	// Unlink any old shared memory object with the same name.
	int status = shm_unlink(name);
	if (status == -1 && errno != ENOENT)
	{
		return -1;
	}
	
	// Create a new shared memory object.
	int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, S_IRWXU);
	if (fd == -1)
	{
		shm_unlink(name);
		return -1;
	}
	
	size_t len = gdc_circular_queue_footprint(capacity) + capacity;
	status = ftruncate(fd, len);
	if (status != 0)
	{
		close(fd);
		shm_unlink(name);
		return -1;
	}
	
	void *p = mmap(
		NULL,
		len,
		PROT_READ | PROT_WRITE,
		MAP_SHARED,
		fd,
		0);
	if (p == MAP_FAILED)
	{
		shm_unlink(name);
		close(fd);
		return -1;
	}
	
	gdc_circular_queue* q = p;
	status = gdc_circular_queue_init(q, capacity, sync, mdinit, md_context);
	
	if (status == -1)
	{
		shm_unlink(name);
		close(fd);
		return status;
	}
	
	if (munmap(p, len) != 0)
	{
		shm_unlink(name);
		close(fd);
		return -1;
	}
	
	if (close(fd) != 0)
	{
		shm_unlink(name);
		return -1;
	}
	
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq -0x10(%rbp), %rdi
callq 0xebf0
movl %eax, -0x34(%rbp)
cmpl $-0x1, -0x34(%rbp)
jne 0x7c113
callq 0xe070
cmpl $0x2, (%rax)
je 0x7c113
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7c268
movq -0x10(%rbp), %rdi
movl $0xc2, %esi
movl $0x1c0, %edx            # imm = 0x1C0
callq 0xeac0
movl %eax, -0x38(%rbp)
cmpl $-0x1, -0x38(%rbp)
jne 0x7c144
movq -0x10(%rbp), %rdi
callq 0xebf0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7c268
movq -0x18(%rbp), %rdi
callq 0x7c280
addq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movl -0x38(%rbp), %edi
movq -0x40(%rbp), %rsi
callq 0xe8f0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0x7c187
movl -0x38(%rbp), %edi
callq 0xec60
movq -0x10(%rbp), %rdi
callq 0xebf0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7c268
movq -0x40(%rbp), %rsi
movl -0x38(%rbp), %r8d
xorl %eax, %eax
movl %eax, %r9d
movl $0x3, %edx
movl $0x1, %ecx
movq %r9, %rdi
callq 0xeb80
movq %rax, -0x48(%rbp)
movq $-0x1, %rax
cmpq %rax, -0x48(%rbp)
jne 0x7c1d4
movq -0x10(%rbp), %rdi
callq 0xebf0
movl -0x38(%rbp), %edi
callq 0xec60
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7c268
movq -0x48(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %edx
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %r8
callq 0x7b9a0
movl %eax, -0x34(%rbp)
cmpl $-0x1, -0x34(%rbp)
jne 0x7c216
movq -0x10(%rbp), %rdi
callq 0xebf0
movl -0x38(%rbp), %edi
callq 0xec60
movl -0x34(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x7c268
movq -0x48(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0xe360
cmpl $0x0, %eax
je 0x7c242
movq -0x10(%rbp), %rdi
callq 0xebf0
movl -0x38(%rbp), %edi
callq 0xec60
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7c268
movl -0x38(%rbp), %edi
callq 0xec60
cmpl $0x0, %eax
je 0x7c261
movq -0x10(%rbp), %rdi
callq 0xebf0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7c268
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)