// File: /workspace/github_cpp_makefile_star2_O3/jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_env_write_meta
static int
mdb_env_write_meta(MDB_txn *txn)
{
	MDB_env *env;
	MDB_meta	meta, metab, *mp;
	unsigned flags;
	size_t mapsize;
	off_t off;
	int rc, len, toggle;
	char *ptr;
	HANDLE mfd;
#ifdef _WIN32
	OVERLAPPED ov;
#else
	int r2;
#endif

	toggle = txn->mt_txnid & 1;
	DPRINTF(("writing meta page %d for root page %"Z"u",
		toggle, txn->mt_dbs[MAIN_DBI].md_root));

	env = txn->mt_env;
	flags = txn->mt_flags & env->me_flags;
	mp = env->me_metas[toggle];
	mapsize = env->me_metas[toggle ^ 1]->mm_mapsize;
	/* Persist any increases of mapsize config */
	if (mapsize < env->me_mapsize)
		mapsize = env->me_mapsize;

	if (flags & MDB_WRITEMAP) {
		mp->mm_mapsize = mapsize;
		mp->mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI];
		mp->mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI];
		mp->mm_last_pg = txn->mt_next_pgno - 1;
#if (__GNUC__ * 100 + __GNUC_MINOR__ >= 404) && /* TODO: portability */	\
	!(defined(__i386__) || defined(__x86_64__))
		/* LY: issue a memory barrier, if not x86. ITS#7969 */
		__sync_synchronize();
#endif
		mp->mm_txnid = txn->mt_txnid;
		if (!(flags & (MDB_NOMETASYNC|MDB_NOSYNC))) {
			unsigned meta_size = env->me_psize;
			rc = (env->me_flags & MDB_MAPASYNC) ? MS_ASYNC : MS_SYNC;
			ptr = (char *)mp - PAGEHDRSZ;
#ifndef _WIN32	/* POSIX msync() requires ptr = start of OS page */
			r2 = (ptr - env->me_map) & (env->me_os_psize - 1);
			ptr -= r2;
			meta_size += r2;
#endif
			if (MDB_MSYNC(ptr, meta_size, rc)) {
				rc = ErrCode();
				goto fail;
			}
		}
		goto done;
	}
	metab.mm_txnid = mp->mm_txnid;
	metab.mm_last_pg = mp->mm_last_pg;

	meta.mm_mapsize = mapsize;
	meta.mm_dbs[FREE_DBI] = txn->mt_dbs[FREE_DBI];
	meta.mm_dbs[MAIN_DBI] = txn->mt_dbs[MAIN_DBI];
	meta.mm_last_pg = txn->mt_next_pgno - 1;
	meta.mm_txnid = txn->mt_txnid;

	off = offsetof(MDB_meta, mm_mapsize);
	ptr = (char *)&meta + off;
	len = sizeof(MDB_meta) - off;
	off += (char *)mp - env->me_map;

	/* Write to the SYNC fd */
	mfd = (flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ? env->me_fd : env->me_mfd;
#ifdef _WIN32
	{
		memset(&ov, 0, sizeof(ov));
		ov.Offset = off;
		if (!WriteFile(mfd, ptr, len, (DWORD *)&rc, &ov))
			rc = -1;
	}
#else
retry_write:
	rc = pwrite(mfd, ptr, len, off);
#endif
	if (rc != len) {
		rc = rc < 0 ? ErrCode() : EIO;
#ifndef _WIN32
		if (rc == EINTR)
			goto retry_write;
#endif
		DPUTS("write failed, disk error?");
		/* On a failure, the pagecache still contains the new data.
		 * Write some old data back, to prevent it from being used.
		 * Use the non-SYNC fd; we know it will fail anyway.
		 */
		meta.mm_last_pg = metab.mm_last_pg;
		meta.mm_txnid = metab.mm_txnid;
#ifdef _WIN32
		memset(&ov, 0, sizeof(ov));
		ov.Offset = off;
		WriteFile(env->me_fd, ptr, len, NULL, &ov);
#else
		r2 = pwrite(env->me_fd, ptr, len, off);
		(void)r2;	/* Silence warnings. We don't care about pwrite's return value */
#endif
fail:
		env->me_flags |= MDB_FATAL_ERROR;
		return rc;
	}
	/* MIPS has cache coherency issues, this is a no-op everywhere else */
	CACHEFLUSH(env->me_map + off, len, DCACHE);
done:
	/* Memory ordering issues are irrelevant; since the entire writer
	 * is wrapped by wmutex, all of these changes will become visible
	 * after the wmutex is unlocked. Since the DB is multi-version,
	 * readers will get consistent data regardless of how fresh or
	 * how stale their view of these values is.
	 */
	if (env->me_txns)
		env->me_txns->mti_txnid = txn->mt_txnid;

	return MDB_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %rbx
movq 0x18(%rdi), %rcx
movq 0x20(%rdi), %r13
movl %ecx, %edx
andl $0x1, %edx
movl 0xc(%r13), %eax
andl 0x7c(%rdi), %eax
movq 0x48(%r13,%rdx,8), %rdi
xorl $0x1, %edx
movq 0x48(%r13,%rdx,8), %rdx
movq 0x10(%rdx), %rsi
movq 0x70(%r13), %rdx
cmpq %rdx, %rsi
cmovaq %rsi, %rdx
btl $0x13, %eax
jb 0x5934
movq 0x80(%rdi), %rsi
movq %rsi, 0x8(%rsp)
movq 0x78(%rdi), %rsi
movq %rsi, (%rsp)
leaq 0x20(%rsp), %r14
movq %rdx, (%r14)
movq 0x58(%rbx), %rdx
movups (%rdx), %xmm0
movups 0x10(%rdx), %xmm1
movups 0x20(%rdx), %xmm2
movups %xmm2, 0x28(%r14)
movups %xmm1, 0x18(%r14)
movups %xmm0, 0x8(%r14)
movups 0x30(%rdx), %xmm0
movups 0x40(%rdx), %xmm1
movups 0x50(%rdx), %xmm2
movups %xmm0, 0x38(%r14)
movups %xmm1, 0x48(%r14)
movups %xmm2, 0x58(%r14)
movq 0x10(%rbx), %rdx
decq %rdx
movq %rdx, 0x68(%r14)
movq %rcx, 0x70(%r14)
movq 0x38(%r13), %rcx
negq %rcx
leaq (%rdi,%rcx), %r15
addq $0x10, %r15
xorl %ecx, %ecx
testl $0x50000, %eax          # imm = 0x50000
sete %cl
movl (%r13,%rcx,8), %r12d
movl $0x78, %edx
movl %r12d, %edi
movq %r14, %rsi
movq %r15, %rcx
callq 0x22a0
cmpl $0x78, %eax
je 0x598c
testl %eax, %eax
jns 0x59e5
callq 0x2050
movl (%rax), %ebp
cmpl $0x4, %ebp
je 0x5903
jmp 0x59ea
movq %rdx, 0x10(%rdi)
movq 0x58(%rbx), %rcx
movups (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movups 0x20(%rcx), %xmm2
movups %xmm2, 0x38(%rdi)
movups %xmm1, 0x28(%rdi)
movups %xmm0, 0x18(%rdi)
movq 0x58(%rbx), %rcx
movups 0x30(%rcx), %xmm0
movups 0x40(%rcx), %xmm1
movups 0x50(%rcx), %xmm2
movups %xmm1, 0x58(%rdi)
movups %xmm2, 0x68(%rdi)
movups %xmm0, 0x48(%rdi)
movq 0x10(%rbx), %rcx
decq %rcx
movq %rcx, 0x78(%rdi)
movq 0x18(%rbx), %rcx
movq %rcx, 0x80(%rdi)
testl $0x50000, %eax          # imm = 0x50000
je 0x59a5
movq 0x40(%r13), %rax
xorl %ebp, %ebp
testq %rax, %rax
je 0x5a1c
movq 0x18(%rbx), %rcx
movq %rcx, 0x30(%rax)
jmp 0x5a1c
xorl %eax, %eax
btl $0x14, 0xc(%r13)
setae %al
leal (%rax,%rax,2), %edx
incl %edx
addq $-0x10, %rdi
movl 0x38(%r13), %eax
movl %edi, %ecx
subl %eax, %ecx
movl 0x14(%r13), %eax
decl %eax
andl %ecx, %eax
movslq %eax, %rsi
subq %rsi, %rdi
addl 0x10(%r13), %esi
callq 0x2100
testl %eax, %eax
je 0x598c
callq 0x2050
movl (%rax), %ebp
jmp 0x5a17
movl $0x5, %ebp
movq (%rsp), %rax
movq %rax, 0x88(%rsp)
movq 0x8(%rsp), %rax
movq %rax, 0x90(%rsp)
movl (%r13), %edi
movl $0x78, %edx
movq %r14, %rsi
movq %r15, %rcx
callq 0x22a0
orb $-0x80, 0xf(%r13)
movl %ebp, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq