// File: /workspace/github_c_makefile_star2_O1/dlbeer[P]dhara/tests/epoch_roll.c
// Function: main
int main(void)
{
	const size_t page_size = 1 << sim_nand.log2_page_size;
	struct dhara_map map;
	uint8_t page_buf[page_size];
	int write_seed = 0;
	int i;

	sim_reset();
	dhara_map_init(&map, &sim_nand, page_buf, GC_RATIO);
	dhara_map_resume(&map, NULL);
	printf("resumed, head = %d\n", map.journal.head);

	/* Write pages until we have just barely wrapped around, but not
	 * yet hit a checkpoint.
	 */
	for (i = 0; i < 200; i++)
		mt_write(&map, i, write_seed++);
	printf("written a little, head = %d\n", map.journal.head);

	for (i = 0; i < 200; i++)
		mt_write(&map, i, write_seed++);
	printf("written a little, head = %d\n", map.journal.head);
	for (i = 0; i < 200; i++)
		mt_write(&map, i, write_seed++);
	printf("written a little, head = %d\n", map.journal.head);
	for (i = 0; i < 79; i++)
		mt_write(&map, i, write_seed++);
	printf("written a little, head = %d\n", map.journal.head);
	assert(map.journal.head == 1); /* Required for this test */

	/* Now, see what happens on resume if we don't sync.
	 *
	 * Here's where a bug occured: the new epoch counter was not
	 * incremented when finding the next free user page, if that
	 * procedure required wrapping around the end of the chip from
	 * the last checkblock. From this point on, new pages written
	 * are potentially lost, because they will be wrongly identified
	 * as older than the pages coming physically later in the chip.
	 */
	printf("before resume: head = %d, tail = %d, epoch = %d\n",
		map.journal.head, map.journal.tail, map.journal.epoch);
	dhara_map_resume(&map, NULL);
	printf("resumed, head = %d, tail = %d, epoch = %d\n",
		map.journal.head, map.journal.tail, map.journal.epoch);

	for (i = 0; i < 2; i++)
		mt_write(&map, i, i + 10000);
	printf("written new data, head = %d\n", map.journal.head);
	dhara_map_sync(&map, NULL);

	/* Try another resume */
	printf("--------------------------------------------------------\n");
	printf("before resume: head = %d, tail = %d, epoch = %d\n",
		map.journal.head, map.journal.tail, map.journal.epoch);
	mt_assert(&map, 0, 10000);
	mt_assert(&map, 1, 10001);
	dhara_map_resume(&map, NULL);
	printf("resumed, head = %d, tail = %d, epoch = %d\n",
		map.journal.head, map.journal.tail, map.journal.epoch);
	mt_assert(&map, 0, 10000);
	mt_assert(&map, 1, 10001);

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
leaq 0x1720(%rip), %r14      # 0x4218
movb (%r14), %cl
movl $0x1, %eax
shll %cl, %eax
movq %rsp, %r12
cltq
addq $0xf, %rax
andq $-0x10, %rax
movq %rsp, %r15
subq %rax, %r15
movq %r15, %rsp
callq 0x2e38
leaq -0x68(%rbp), %rbx
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
movl $0x4, %ecx
callq 0x12ec
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x130c
movl 0x24(%rbx), %esi
leaq 0x158f(%rip), %rdi      # 0x40da
xorl %eax, %eax
callq 0x1070
leal 0x1(%r14), %r15d
movq %rbx, %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2d68
movl %r15d, %r14d
cmpl $0xc8, %r15d
jne 0x2b52
leaq -0x68(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x1570(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
movl $0xc8, %r15d
leal (%r14,%r15), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2d68
incl %r14d
cmpl %r15d, %r14d
jne 0x2b8e
leaq -0x68(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x153b(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
leal 0x190(%r14), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2d68
incl %r14d
cmpl $0xc8, %r14d
jne 0x2bbd
leaq -0x68(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x1505(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
leal 0x258(%r14), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2d68
incl %r14d
cmpl $0x4f, %r14d
jne 0x2bf3
movl -0x44(%rbp), %esi
leaq 0x14d6(%rip), %rdi      # 0x40ee
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x1070
cmpl $0x1, -0x44(%rbp)
jne 0x2d49
leaq -0x68(%rbp), %r14
movl 0x20(%r14), %edx
movzbl 0x11(%r14), %ecx
leaq 0x1504(%rip), %rdi      # 0x4143
movl $0x1, %esi
xorl %eax, %eax
callq 0x1070
movq %r14, %rdi
xorl %esi, %esi
callq 0x130c
movl 0x20(%r14), %edx
movl 0x24(%r14), %esi
movzbl 0x11(%r14), %ecx
leaq 0x150b(%rip), %rdi      # 0x4174
xorl %eax, %eax
callq 0x1070
movl $0x2710, %r13d          # imm = 0x2710
leal (%rbx,%r13), %r15d
movq %r14, %rdi
movl %ebx, %esi
movl %r15d, %edx
callq 0x2d68
incl %ebx
cmpl %r13d, %r15d
je 0x2c76
leaq -0x68(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x1503(%rip), %rdi      # 0x419f
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1a31
leaq 0x151b(%rip), %rdi      # 0x41cf
callq 0x1060
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
leaq 0x1479(%rip), %rdi      # 0x4143
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x2dd4
movq %rbx, %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x2dd4
movq %rbx, %rdi
xorl %esi, %esi
callq 0x130c
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
leaq 0x1467(%rip), %rdi      # 0x4174
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x2dd4
movq %rbx, %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x2dd4
movq %r12, %rsp
xorl %eax, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x13bb(%rip), %rdi      # 0x410b
leaq 0x13ca(%rip), %rsi      # 0x4121
leaq 0x13d6(%rip), %rcx      # 0x4134
movl $0x4d, %edx
callq 0x1080