// File: /workspace/github_cpp_makefile_star2_O3/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 $0x18, %rsp
movl 0xc(%rdi), %r14d
movl %edx, %eax
notl %eax
andl %r14d, %eax
movl $0xd, %ebp
btl $0x11, %eax
jae 0x3491
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rsi, %r12
movq %rdi, %rbx
movl %edx, %eax
andl $0x70000, %eax          # imm = 0x70000
andl $0x80000, %r14d         # imm = 0x80000
orl %eax, %r14d
testq %rsi, %rsi
je 0x34d1
movl 0x7c(%r12), %eax
orl %eax, %r14d
testl $0xa0013, %r14d         # imm = 0xA0013
je 0x34e5
btl $0x11, %eax
movl $0xffff87c2, %eax       # imm = 0xFFFF87C2
movl $0x16, %ebp
cmovael %eax, %ebp
jmp 0x3480
movq %rcx, 0x8(%rsp)
btl $0x11, %edx
jb 0x34ff
movq 0x68(%rbx), %r15
jmp 0x36b2
movq %rcx, 0x8(%rsp)
movl $0x98, %eax
movq %rax, (%rsp)
movl $0x98, %eax
movl $0x39, %ecx
jmp 0x3512
movl $0x88, %eax
movq %rax, (%rsp)
movl $0x88, %eax
movl $0x31, %ecx
movl 0x24(%rbx), %edx
movq %rdx, 0x10(%rsp)
imull %edx, %ecx
addl %eax, %ecx
movslq %ecx, %r13
movl $0x1, %edi
movq %r13, %rsi
callq 0x2200
movl $0xc, %ebp
testq %rax, %rax
je 0x3480
movq %rax, %r15
movq (%rsp), %rcx
addq %rax, %rcx
addq %rax, %r13
movq 0x10(%rsp), %rdx
subq %rdx, %r13
movq 0x88(%rbx), %rax
movq %rax, 0x50(%r15)
movq %rcx, 0x58(%r15)
movq %r13, 0x70(%r15)
movl %r14d, 0x7c(%r15)
movq %rbx, 0x20(%r15)
testq %r12, %r12
je 0x36a7
leaq (%rdx,%rdx,2), %rax
shlq $0x4, %rax
addq %rax, %rcx
movq %rcx, 0x68(%r15)
movq 0x60(%r12), %rax
movq %rax, 0x60(%r15)
movl $0x200000, %edi         # imm = 0x200000
callq 0x2270
movq %rax, 0x48(%r15)
testq %rax, %rax
je 0x36d3
movl $0x1ffff, %edi          # imm = 0x1FFFF
callq 0xb9fb
movq %rax, 0x28(%r15)
movq 0x48(%r15), %rdi
testq %rax, %rax
je 0x36d5
movq 0x18(%r12), %rax
movq %rax, 0x18(%r15)
movl 0x80(%r12), %eax
movl %eax, 0x80(%r15)
xorl %eax, %eax
movq %rax, (%rdi)
movq %rax, 0x40(%r15)
movq 0x10(%r12), %rax
movq %rax, 0x10(%r15)
orb $0x10, 0x7c(%r12)
movq %r15, 0x8(%r12)
movq %r12, (%r15)
movl 0x78(%r12), %eax
movl %eax, 0x78(%r15)
movq 0x58(%r15), %rdi
movq 0x58(%r12), %rsi
shlq $0x4, %rax
leaq (%rax,%rax,2), %rdx
callq 0x2240
cmpl $0x0, 0x78(%r15)
je 0x363e
xorl %eax, %eax
movq 0x70(%r12), %rcx
movb (%rcx,%rax), %cl
andb $-0x5, %cl
movq 0x70(%r15), %rdx
movb %cl, (%rdx,%rax)
incq %rax
movl 0x78(%r15), %ecx
cmpq %rcx, %rax
jb 0x3620
movups 0xb0(%rbx), %xmm0
movups %xmm0, 0x88(%r15)
movq 0xb0(%rbx), %rax
testq %rax, %rax
je 0x3694
leaq 0xb0(%rbx), %rbp
movl (%rax), %r13d
movl %r13d, %edi
callq 0xb9fb
movq %rax, (%rbp)
testq %rax, %rax
je 0x36dc
movq %r15, %rcx
addq $0x88, %rcx
leal 0x8(,%r13,8), %edx
movq (%rcx), %rsi
movslq %edx, %rdx
movq %rax, %rdi
callq 0x2240
movq %r12, %rdi
movq %r15, %rsi
callq 0x3705
movl %eax, %ebp
testl %eax, %eax
jne 0x36e1
jmp 0x36c0
movq 0x98(%rbx), %rax
movq %rax, 0x60(%r15)
movq %r15, %rdi
callq 0x30ea
movl %eax, %ebp
testl %eax, %eax
jne 0x36ee
orl %r14d, 0x7c(%r15)
movq 0x8(%rsp), %rax
movq %r15, (%rax)
xorl %ebp, %ebp
jmp 0x3480
xorl %edi, %edi
callq 0x2030
jmp 0x36f8
movl $0xc, %ebp
movq %r15, %rdi
movl $0x6, %esi
callq 0x380d
cmpq 0x68(%rbx), %r15
je 0x3480
movq %r15, %rdi
callq 0x2030
jmp 0x3480