// File: /workspace/github_cpp_makefile_star2_O2/jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_txn_begin
int
mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
{
	MDB_txn *txn;
	MDB_ntxn *ntxn;
	int rc, size, tsize;

	flags &= MDB_TXN_BEGIN_FLAGS;
	flags |= env->me_flags & MDB_WRITEMAP;

	if (env->me_flags & MDB_RDONLY & ~flags) /* write txn in RDONLY env */
		return EACCES;

	if (parent) {
		/* Nested transactions: Max 1 child, write txns only, no writemap */
		flags |= parent->mt_flags;
		if (flags & (MDB_RDONLY|MDB_WRITEMAP|MDB_TXN_BLOCKED)) {
			return (parent->mt_flags & MDB_TXN_RDONLY) ? EINVAL : MDB_BAD_TXN;
		}
		/* Child txns save MDB_pgstate and use own copy of cursors */
		size = env->me_maxdbs * (sizeof(MDB_db)+sizeof(MDB_cursor *)+1);
		size += tsize = sizeof(MDB_ntxn);
	} else if (flags & MDB_RDONLY) {
		size = env->me_maxdbs * (sizeof(MDB_db)+1);
		size += tsize = sizeof(MDB_txn);
	} else {
		/* Reuse preallocated write txn. However, do not touch it until
		 * mdb_txn_renew0() succeeds, since it currently may be active.
		 */
		txn = env->me_txn0;
		goto renew;
	}
	if ((txn = calloc(1, size)) == NULL) {
		DPRINTF(("calloc: %s", strerror(errno)));
		return ENOMEM;
	}
	txn->mt_dbxs = env->me_dbxs;	/* static */
	txn->mt_dbs = (MDB_db *) ((char *)txn + tsize);
	txn->mt_dbflags = (unsigned char *)txn + size - env->me_maxdbs;
	txn->mt_flags = flags;
	txn->mt_env = env;

	if (parent) {
		unsigned int i;
		txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs);
		txn->mt_dbiseqs = parent->mt_dbiseqs;
		txn->mt_u.dirty_list = malloc(sizeof(MDB_ID2)*MDB_IDL_UM_SIZE);
		if (!txn->mt_u.dirty_list ||
			!(txn->mt_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)))
		{
			free(txn->mt_u.dirty_list);
			free(txn);
			return ENOMEM;
		}
		txn->mt_txnid = parent->mt_txnid;
		txn->mt_dirty_room = parent->mt_dirty_room;
		txn->mt_u.dirty_list[0].mid = 0;
		txn->mt_spill_pgs = NULL;
		txn->mt_next_pgno = parent->mt_next_pgno;
		parent->mt_flags |= MDB_TXN_HAS_CHILD;
		parent->mt_child = txn;
		txn->mt_parent = parent;
		txn->mt_numdbs = parent->mt_numdbs;
		memcpy(txn->mt_dbs, parent->mt_dbs, txn->mt_numdbs * sizeof(MDB_db));
		/* Copy parent's mt_dbflags, but clear DB_NEW */
		for (i=0; i<txn->mt_numdbs; i++)
			txn->mt_dbflags[i] = parent->mt_dbflags[i] & ~DB_NEW;
		rc = 0;
		ntxn = (MDB_ntxn *)txn;
		ntxn->mnt_pgstate = env->me_pgstate; /* save parent me_pghead & co */
		if (env->me_pghead) {
			size = MDB_IDL_SIZEOF(env->me_pghead);
			env->me_pghead = mdb_midl_alloc(env->me_pghead[0]);
			if (env->me_pghead)
				memcpy(env->me_pghead, ntxn->mnt_pgstate.mf_pghead, size);
			else
				rc = ENOMEM;
		}
		if (!rc)
			rc = mdb_cursor_shadow(parent, txn);
		if (rc)
			mdb_txn_end(txn, MDB_END_FAIL_BEGINCHILD);
	} else { /* MDB_RDONLY */
		txn->mt_dbiseqs = env->me_dbiseqs;
renew:
		rc = mdb_txn_renew0(txn);
	}
	if (rc) {
		if (txn != env->me_txn0)
			free(txn);
	} else {
		txn->mt_flags |= flags;	/* could not change txn=me_txn0 earlier */
		*ret = txn;
		DPRINTF(("begin txn %"Z"u%c %p on mdbenv %p, root page %"Z"u",
			txn->mt_txnid, (flags & MDB_RDONLY) ? 'r' : 'w',
			(void *) txn, (void *) env, txn->mt_dbs[MAIN_DBI].md_root));
	}

	return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl 0xc(%rdi), %ebx
movl %edx, %eax
notl %eax
andl %ebx, %eax
btl $0x11, %eax
jae 0x31d8
pushq $0xd
popq %rbp
movl %ebp, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rcx, %r12
movq %rdi, %r14
movl %edx, %eax
andl $0x70000, %eax          # imm = 0x70000
andl $0x80000, %ebx          # imm = 0x80000
orl %eax, %ebx
testq %rsi, %rsi
je 0x3210
movl 0x7c(%rsi), %eax
orl %eax, %ebx
testl $0xa0013, %ebx          # imm = 0xA0013
je 0x321f
btl $0x11, %eax
movl $0xffff87c2, %eax       # imm = 0xFFFF87C2
pushq $0x16
popq %rbp
cmovael %eax, %ebp
jmp 0x31c7
btl $0x11, %edx
jb 0x323c
movq 0x68(%r14), %r15
jmp 0x338a
movq %rsi, 0x8(%rsp)
movq %r12, 0x18(%rsp)
movl $0x98, %eax
movq %rax, 0x10(%rsp)
movl $0x98, %eax
pushq $0x39
jmp 0x3257
movq %rsi, 0x8(%rsp)
movq %r12, 0x18(%rsp)
movl $0x88, %eax
movq %rax, 0x10(%rsp)
movl $0x88, %eax
pushq $0x31
popq %rcx
movq %r14, %r12
movl 0x24(%r14), %r13d
imull %r13d, %ecx
addl %eax, %ecx
movslq %ecx, %r14
pushq $0x1
popq %rdi
movq %r14, %rsi
callq 0x2200
pushq $0xc
popq %rbp
testq %rax, %rax
je 0x31c7
movq %rax, %r15
movq 0x10(%rsp), %rcx
addq %rax, %rcx
addq %rax, %r14
subq %r13, %r14
movq 0x88(%r12), %rax
movq %rax, 0x50(%r15)
movq %rcx, 0x58(%r15)
movq %r14, 0x70(%r15)
movl %ebx, 0x7c(%r15)
movq %r12, 0x20(%r15)
movq 0x8(%rsp), %r14
testq %r14, %r14
je 0x3376
movq %r12, 0x28(%rsp)
imulq $0x30, %r13, %rax
addq %rax, %rcx
movq %rcx, 0x68(%r15)
movq 0x60(%r14), %rax
movq %rax, 0x60(%r15)
movl $0x200000, %edi         # imm = 0x200000
callq 0x2270
movq %rax, 0x48(%r15)
testq %rax, %rax
je 0x34db
movl $0x1ffff, %edi          # imm = 0x1FFFF
callq 0xb17a
movq %rax, 0x28(%r15)
movq 0x48(%r15), %rdi
testq %rax, %rax
je 0x34dd
movq 0x18(%r14), %rax
movq %rax, 0x18(%r15)
movl 0x80(%r14), %eax
movl %eax, 0x80(%r15)
andq $0x0, (%rdi)
andq $0x0, 0x40(%r15)
movq 0x10(%r14), %rax
movq %rax, 0x10(%r15)
orb $0x10, 0x7c(%r14)
movq %r15, 0x8(%r14)
movq %r14, (%r15)
movl 0x78(%r14), %eax
movl %eax, 0x78(%r15)
movq 0x58(%r15), %rdi
movq 0x58(%r14), %rsi
imulq $0x30, %rax, %rdx
callq 0x2240
xorl %eax, %eax
movq 0x28(%rsp), %rsi
movl 0x78(%r15), %ecx
cmpq %rcx, %rax
jae 0x33ab
movq 0x70(%r14), %rcx
movb (%rcx,%rax), %cl
andb $-0x5, %cl
movq 0x70(%r15), %rdx
movb %cl, (%rdx,%rax)
incq %rax
jmp 0x3357
movq 0x98(%r12), %rax
movq %rax, 0x60(%r15)
movq %r12, %r14
movq 0x18(%rsp), %r12
movq %r15, %rdi
callq 0x2e42
movl %eax, %ebp
testl %eax, %eax
jne 0x34f7
orl %ebx, 0x7c(%r15)
movq %r15, (%r12)
xorl %ebp, %ebp
jmp 0x31c7
movl %ebx, 0x24(%rsp)
movups 0xb0(%rsi), %xmm0
movups %xmm0, 0x88(%r15)
movq 0xb0(%rsi), %rax
testq %rax, %rax
je 0x340f
movq %r14, %r13
leaq 0xb0(%rsi), %r12
movl (%rax), %r14d
movl %r14d, %edi
callq 0xb17a
movq %rax, (%r12)
testq %rax, %rax
je 0x34e4
movq %r15, %rcx
addq $0x88, %rcx
leal 0x8(,%r14,8), %edx
movq (%rcx), %rsi
movslq %edx, %rdx
movq %rax, %rdi
callq 0x2240
movq %r13, %r14
movq %r14, 0x8(%rsp)
movl 0x78(%r14), %ebx
movq %rbx, %r12
testl %r12d, %r12d
jle 0x350e
leaq -0x1(%r12), %rbx
movq 0x8(%rsp), %rax
movq 0x68(%rax), %rax
movq -0x8(%rax,%r12,8), %r13
testq %r13, %r13
je 0x3418
cmpq $0x0, 0x10(%r13)
movl $0x378, %ecx            # imm = 0x378
movl $0x188, %eax            # imm = 0x188
cmoveq %rax, %rcx
movq %rcx, 0x10(%rsp)
imulq $0x30, %rbx, %rax
movq %rax, 0x30(%rsp)
testq %r13, %r13
je 0x3418
movq 0x10(%rsp), %rdi
callq 0x2270
testq %rax, %rax
je 0x34e4
movq %rax, %r14
movl $0x188, %edx            # imm = 0x188
movq %rax, %rdi
movq %r13, %rsi
callq 0x2240
movq %r14, 0x8(%r13)
movq 0x58(%r15), %rax
addq 0x30(%rsp), %rax
movq %rax, 0x28(%r13)
andq $0x0, 0x18(%r13)
andq $0x0, 0x38(%r13)
movq 0x10(%r13), %rbp
testq %rbp, %rbp
je 0x34c4
movq %r14, %rdi
addq $0x188, %rdi            # imm = 0x188
movl $0x1f0, %edx            # imm = 0x1F0
movq %rbp, %rsi
callq 0x2240
andq $0x0, 0x18(%rbp)
movq 0x68(%r15), %rax
movq -0x8(%rax,%r12,8), %rcx
movq %rcx, (%r13)
movq %r13, -0x8(%rax,%r12,8)
movq (%r14), %r13
jmp 0x345d
xorl %edi, %edi
callq 0x2030
jmp 0x3501
pushq $0x6
popq %rsi
movq %r15, %rdi
callq 0x351c
pushq $0xc
popq %rbp
movq 0x28(%rsp), %r14
cmpq 0x68(%r14), %r15
je 0x31c7
movq %r15, %rdi
callq 0x2030
jmp 0x31c7
movq 0x18(%rsp), %r12
movl 0x24(%rsp), %ebx
jmp 0x339c