// File: BenLangmead[P]bowtie/./shmem.h
// Function: bool allocSharedMem<unsigned char>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, unsigned long, unsigned char**, char const*, bool)
bool allocSharedMem(std::string fname,
                    size_t len,
                    T ** dst,
                    const char *memName,
                    bool verbose)
{
	using namespace std;
	int shmid = -1;
	// Calculate key given string
	key_t key = (key_t)hash_string(fname);
	shmid_ds ds;
	int ret;
	// Reserve 4 bytes at the end for silly synchronization
	size_t shmemLen = len + 4;
	if(verbose) {
		cerr << "Reading " << len << "+4 bytes into shared memory for " << memName << endl;
	}
	T *ptr = NULL;
	while(true) {
		// Create the shrared-memory block
		if((shmid = shmget(key, shmemLen, IPC_CREAT | 0666)) < 0) {
			if(errno == ENOMEM) {
				cerr << "Out of memory allocating shared area " << memName << endl;
			} else if(errno == EACCES) {
				cerr << "EACCES" << endl;
			} else if(errno == EEXIST) {
				cerr << "EEXIST" << endl;
			} else if(errno == EINVAL) {
				cerr << "Warning: shared-memory chunk's segment size doesn't match expected size (" << (shmemLen) << ")" << endl
					 << "Deleting old shared memory block and trying again." << endl;
				shmid = shmget(key, 0, 0);
				if((ret = shmctl(shmid, IPC_RMID, &ds)) < 0) {
					cerr << "shmctl returned " << ret
						 << " for IPC_RMID, errno is " << errno
						 << ", shmid is " << shmid << endl;
					throw 1;
				} else {
					cerr << "Deleted shared mem chunk with shmid " << shmid << endl;
				}
				continue;
			} else if(errno == ENOENT) {
				cerr << "ENOENT" << endl;
			} else if(errno == ENOSPC) {
				cerr << "ENOSPC" << endl;
			} else {
				cerr << "shmget returned " << shmid << " for and errno is " << errno << endl;
			}
			throw 1;
		}
		ptr = (T*)shmat(shmid, 0, 0);
		if(ptr == (void*)-1) {
			cerr << "Failed to attach " << memName << " to shared memory with shmat()." << endl;
			throw 1;
		}
		if(ptr == NULL) {
			cerr << memName << " pointer returned by shmat() was NULL." << endl;
			throw 1;
		}
		// Did I create it, or did I just attach to one created by
		// another process?
		if((ret = shmctl(shmid, IPC_STAT, &ds)) < 0) {
			cerr << "shmctl returned " << ret << " for IPC_STAT and errno is " << errno << endl;
			throw 1;
		}
		if((size_t)ds.shm_segsz != shmemLen) {
			cerr << "Warning: shared-memory chunk's segment size (" << ds.shm_segsz
				 << ") doesn't match expected size (" << shmemLen << ")" << endl
				 << "Deleting old shared memory block and trying again." << endl;
			if((ret = shmctl(shmid, IPC_RMID, &ds)) < 0) {
				cerr << "shmctl returned " << ret << " for IPC_RMID and errno is " << errno << endl;
				throw 1;
			}
		} else {
			break;
		}
	} // while(true)
	*dst = ptr;
	bool initid = (((volatile uint32_t*)((char*)ptr + len))[0] == SHMEM_INIT);
	if(ds.shm_cpid == getpid() && !initid) {
		if(verbose) {
			cerr << "  I (pid = " << getpid() << ") created the "
			     << "shared memory for " << memName << endl;
		}
		// Set this value just off the end of the chunk to
		// indicate that the data hasn't been read yet.
		((volatile uint32_t*)((char*)ptr + len))[0] = SHMEM_UNINIT;
		return true;
	} else {
		if(verbose) {
			cerr << "  I (pid = " << getpid()
			     << ") did not create the shared memory for "
			     << memName << ".  Pid " << ds.shm_cpid << " did." << endl;
		}
		return false;
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movb %r8b, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
andb $0x1, %al
movb %al, -0x29(%rbp)
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
callq 0x17930
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0xb8(%rbp)
testb $0x1, -0x29(%rbp)
je 0x1a1f0
movq 0x2fe42(%rip), %rdi     # 0x49ff0
leaq 0x28c81(%rip), %rsi     # 0x42e36
callq 0x5360
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x50c0
movq %rax, %rdi
leaq 0x28c6f(%rip), %rsi     # 0x42e3f
callq 0x5360
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x5360
movq %rax, %rdi
movq 0x2fd95(%rip), %rsi     # 0x49f80
callq 0x53c0
movq $0x0, -0xc0(%rbp)
movl -0x34(%rbp), %edi
movq -0xb8(%rbp), %rsi
movl $0x3b6, %edx            # imm = 0x3B6
callq 0x51c0
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
jge 0x1a501
callq 0x5050
cmpl $0xc, (%rax)
jne 0x1a258
movq 0x2fdc4(%rip), %rdi     # 0x49ff0
leaq 0x28c2d(%rip), %rsi     # 0x42e60
callq 0x5360
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x5360
movq %rax, %rdi
movq 0x2fd32(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a4de
callq 0x5050
cmpl $0xd, (%rax)
jne 0x1a289
movq 0x2fd87(%rip), %rdi     # 0x49ff0
leaq 0x28c16(%rip), %rsi     # 0x42e86
callq 0x5360
movq %rax, %rdi
movq 0x2fd01(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a4dc
callq 0x5050
cmpl $0x11, (%rax)
jne 0x1a2ba
movq 0x2fd56(%rip), %rdi     # 0x49ff0
leaq 0x28bec(%rip), %rsi     # 0x42e8d
callq 0x5360
movq %rax, %rdi
movq 0x2fcd0(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a4da
callq 0x5050
cmpl $0x16, (%rax)
jne 0x1a41f
movq 0x2fd21(%rip), %rdi     # 0x49ff0
leaq 0x28bbe(%rip), %rsi     # 0x42e94
callq 0x5360
movq %rax, %rdi
movq -0xb8(%rbp), %rsi
callq 0x50c0
movq %rax, %rdi
leaq 0x272c4(%rip), %rsi     # 0x415b8
callq 0x5360
movq %rax, %rdi
movq 0x2fc7d(%rip), %rsi     # 0x49f80
callq 0x53c0
movq %rax, %rdi
leaq 0x28bcc(%rip), %rsi     # 0x42ede
callq 0x5360
movq %rax, %rdi
movq 0x2fc5f(%rip), %rsi     # 0x49f80
callq 0x53c0
movl -0x34(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x51c0
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %edi
xorl %esi, %esi
leaq -0xa8(%rbp), %rdx
callq 0x52a0
movl %eax, -0xac(%rbp)
cmpl $0x0, %eax
jge 0x1a3ed
movq 0x2fc92(%rip), %rdi     # 0x49ff0
leaq 0x28bac(%rip), %rsi     # 0x42f11
callq 0x5360
movq %rax, %rdi
movl -0xac(%rbp), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x28ba0(%rip), %rsi     # 0x42f22
callq 0x5360
movq %rax, -0xd0(%rbp)
callq 0x5050
movq -0xd0(%rbp), %rdi
movl (%rax), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x28b90(%rip), %rsi     # 0x42f3b
callq 0x5360
movq %rax, %rdi
movl -0x30(%rbp), %esi
callq 0x5750
movq %rax, %rdi
movq 0x2fbbb(%rip), %rsi     # 0x49f80
callq 0x53c0
movl $0x4, %edi
callq 0x5180
movq %rax, %rdi
movl $0x1, (%rdi)
movq 0x2fb8c(%rip), %rsi     # 0x49f70
xorl %eax, %eax
movl %eax, %edx
callq 0x5720
movq 0x2fbfc(%rip), %rdi     # 0x49ff0
leaq 0x28b4c(%rip), %rsi     # 0x42f47
callq 0x5360
movq %rax, %rdi
movl -0x30(%rbp), %esi
callq 0x5750
movq %rax, %rdi
movq 0x2fb6b(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a1fb
callq 0x5050
cmpl $0x2, (%rax)
jne 0x1a450
movq 0x2fbc0(%rip), %rdi     # 0x49ff0
leaq 0x28b35(%rip), %rsi     # 0x42f6c
callq 0x5360
movq %rax, %rdi
movq 0x2fb3a(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a4d6
callq 0x5050
cmpl $0x1c, (%rax)
jne 0x1a47e
movq 0x2fb8f(%rip), %rdi     # 0x49ff0
leaq 0x28b0b(%rip), %rsi     # 0x42f73
callq 0x5360
movq %rax, %rdi
movq 0x2fb09(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a4d4
movq 0x2fb6b(%rip), %rdi     # 0x49ff0
leaq 0x28aee(%rip), %rsi     # 0x42f7a
callq 0x5360
movq %rax, %rdi
movl -0x30(%rbp), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x28ae5(%rip), %rsi     # 0x42f8b
callq 0x5360
movq %rax, -0xd8(%rbp)
callq 0x5050
movq -0xd8(%rbp), %rdi
movl (%rax), %esi
callq 0x5750
movq %rax, %rdi
movq 0x2fab1(%rip), %rsi     # 0x49f80
callq 0x53c0
jmp 0x1a4d6
jmp 0x1a4d8
jmp 0x1a4da
jmp 0x1a4dc
jmp 0x1a4de
movl $0x4, %edi
callq 0x5180
movq %rax, %rdi
movl $0x1, (%rdi)
movq 0x2fa78(%rip), %rsi     # 0x49f70
xorl %eax, %eax
movl %eax, %edx
callq 0x5720
movl -0x30(%rbp), %edi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x5590
movq %rax, -0xc0(%rbp)
movq $-0x1, %rax
cmpq %rax, -0xc0(%rbp)
jne 0x1a586
movq 0x2fac3(%rip), %rdi     # 0x49ff0
leaq 0x28a6a(%rip), %rsi     # 0x42f9e
callq 0x5360
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x5360
movq %rax, %rdi
leaq 0x28a61(%rip), %rsi     # 0x42fb0
callq 0x5360
movq %rax, %rdi
movq 0x2fa22(%rip), %rsi     # 0x49f80
callq 0x53c0
movl $0x4, %edi
callq 0x5180
movq %rax, %rdi
movl $0x1, (%rdi)
movq 0x2f9f3(%rip), %rsi     # 0x49f70
xorl %eax, %eax
movl %eax, %edx
callq 0x5720
cmpq $0x0, -0xc0(%rbp)
jne 0x1a5e1
movq -0x28(%rbp), %rsi
movq 0x2fa55(%rip), %rdi     # 0x49ff0
callq 0x5360
movq %rax, %rdi
leaq 0x28a26(%rip), %rsi     # 0x42fd0
callq 0x5360
movq %rax, %rdi
movq 0x2f9c7(%rip), %rsi     # 0x49f80
callq 0x53c0
movl $0x4, %edi
callq 0x5180
movq %rax, %rdi
movl $0x1, (%rdi)
movq 0x2f998(%rip), %rsi     # 0x49f70
xorl %eax, %eax
movl %eax, %edx
callq 0x5720
movl -0x30(%rbp), %edi
movl $0x2, %esi
leaq -0xa8(%rbp), %rdx
callq 0x52a0
movl %eax, -0xac(%rbp)
cmpl $0x0, %eax
jge 0x1a67c
movq 0x2f9e9(%rip), %rdi     # 0x49ff0
leaq 0x28903(%rip), %rsi     # 0x42f11
callq 0x5360
movq %rax, %rdi
movl -0xac(%rbp), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x289cc(%rip), %rsi     # 0x42ff7
callq 0x5360
movq %rax, -0xe0(%rbp)
callq 0x5050
movq -0xe0(%rbp), %rdi
movl (%rax), %esi
callq 0x5750
movq %rax, %rdi
movq 0x2f92c(%rip), %rsi     # 0x49f80
callq 0x53c0
movl $0x4, %edi
callq 0x5180
movq %rax, %rdi
movl $0x1, (%rdi)
movq 0x2f8fd(%rip), %rsi     # 0x49f70
xorl %eax, %eax
movl %eax, %edx
callq 0x5720
movq -0x78(%rbp), %rax
cmpq -0xb8(%rbp), %rax
je 0x1a7a0
movq 0x2f95c(%rip), %rdi     # 0x49ff0
leaq 0x28978(%rip), %rsi     # 0x43013
callq 0x5360
movq %rax, %rdi
movq -0x78(%rbp), %rsi
callq 0x50c0
movq %rax, %rdi
leaq 0x2898b(%rip), %rsi     # 0x43041
callq 0x5360
movq %rax, %rdi
movq -0xb8(%rbp), %rsi
callq 0x50c0
movq %rax, %rdi
leaq 0x26ee4(%rip), %rsi     # 0x415b8
callq 0x5360
movq %rax, %rdi
movq 0x2f89d(%rip), %rsi     # 0x49f80
callq 0x53c0
movq %rax, %rdi
leaq 0x287ec(%rip), %rsi     # 0x42ede
callq 0x5360
movq %rax, %rdi
movq 0x2f87f(%rip), %rsi     # 0x49f80
callq 0x53c0
movl -0x30(%rbp), %edi
xorl %esi, %esi
leaq -0xa8(%rbp), %rdx
callq 0x52a0
movl %eax, -0xac(%rbp)
cmpl $0x0, %eax
jge 0x1a79e
movq 0x2f8c7(%rip), %rdi     # 0x49ff0
leaq 0x287e1(%rip), %rsi     # 0x42f11
callq 0x5360
movq %rax, %rdi
movl -0xac(%rbp), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x28914(%rip), %rsi     # 0x43061
callq 0x5360
movq %rax, -0xe8(%rbp)
callq 0x5050
movq -0xe8(%rbp), %rdi
movl (%rax), %esi
callq 0x5750
movq %rax, %rdi
movq 0x2f80a(%rip), %rsi     # 0x49f80
callq 0x53c0
movl $0x4, %edi
callq 0x5180
movq %rax, %rdi
movl $0x1, (%rdi)
movq 0x2f7db(%rip), %rsi     # 0x49f70
xorl %eax, %eax
movl %eax, %edx
callq 0x5720
jmp 0x1a7a2
jmp 0x1a7a7
jmp 0x1a1fb
movq -0xc0(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0xc0(%rbp), %rax
movq -0x18(%rbp), %rcx
movl (%rax,%rcx), %eax
cmpl $0xffaa6161, %eax       # imm = 0xFFAA6161
sete %al
andb $0x1, %al
movb %al, -0xc1(%rbp)
movl -0x58(%rbp), %eax
movl %eax, -0xec(%rbp)
callq 0x55e0
movl %eax, %ecx
movl -0xec(%rbp), %eax
cmpl %ecx, %eax
jne 0x1a885
testb $0x1, -0xc1(%rbp)
jne 0x1a885
testb $0x1, -0x29(%rbp)
je 0x1a86a
movq 0x2f7e5(%rip), %rdi     # 0x49ff0
leaq 0x2886b(%rip), %rsi     # 0x4307d
callq 0x5360
movq %rax, -0xf8(%rbp)
callq 0x55e0
movq -0xf8(%rbp), %rdi
movl %eax, %esi
callq 0x5750
movq %rax, %rdi
leaq 0x2884e(%rip), %rsi     # 0x43089
callq 0x5360
movq %rax, %rdi
leaq 0x28863(%rip), %rsi     # 0x430ad
callq 0x5360
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x5360
movq %rax, %rdi
movq 0x2f71b(%rip), %rsi     # 0x49f80
callq 0x53c0
movq -0xc0(%rbp), %rax
movq -0x18(%rbp), %rcx
movl $0xafba4242, (%rax,%rcx) # imm = 0xAFBA4242
movb $0x1, -0x1(%rbp)
jmp 0x1a913
testb $0x1, -0x29(%rbp)
je 0x1a90f
movq 0x2f75a(%rip), %rdi     # 0x49ff0
leaq 0x287e0(%rip), %rsi     # 0x4307d
callq 0x5360
movq %rax, -0x100(%rbp)
callq 0x55e0
movq -0x100(%rbp), %rdi
movl %eax, %esi
callq 0x5750
movq %rax, %rdi
leaq 0x287d2(%rip), %rsi     # 0x43098
callq 0x5360
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x5360
movq %rax, %rdi
leaq 0x287df(%rip), %rsi     # 0x430c0
callq 0x5360
movq %rax, %rdi
movl -0x58(%rbp), %esi
callq 0x5750
movq %rax, %rdi
leaq 0x287cd(%rip), %rsi     # 0x430c8
callq 0x5360
movq %rax, %rdi
movq 0x2f676(%rip), %rsi     # 0x49f80
callq 0x53c0
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)