// File: /workspace/github_c_makefile_star2_O3/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 %r12
pushq %rbx
subq $0x40, %rsp
leaq 0x17c6(%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 0x2d88
leaq -0x60(%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 0x1635(%rip), %rdi      # 0x40da
xorl %eax, %eax
callq 0x1070
leal 0x1(%r14), %r15d
movq %rbx, %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2cb6
movl %r15d, %r14d
cmpl $0xc8, %r15d
jne 0x2aac
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x1616(%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 0x2cb6
incl %r14d
cmpl %r15d, %r14d
jne 0x2ae8
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x15e1(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
leal 0x190(%r14), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2cb6
incl %r14d
cmpl $0xc8, %r14d
jne 0x2b17
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x15ab(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
leal 0x258(%r14), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2cb6
incl %r14d
cmpl $0x4f, %r14d
jne 0x2b4d
movl -0x3c(%rbp), %esi
leaq 0x157c(%rip), %rdi      # 0x40ee
xorl %eax, %eax
callq 0x1070
cmpl $0x1, -0x3c(%rbp)
jne 0x2c97
leaq -0x60(%rbp), %rbx
movl 0x20(%rbx), %edx
movzbl 0x11(%rbx), %ecx
leaq 0x15ae(%rip), %r15      # 0x4143
movq %r15, %rdi
movl $0x1, %esi
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
callq 0x130c
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
leaq 0x15b5(%rip), %r14      # 0x4174
movq %r14, %rdi
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x2cb6
movq %rbx, %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x2cb6
movl 0x24(%rbx), %esi
leaq 0x15ab(%rip), %rdi      # 0x419f
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
callq 0x19ae
leaq 0x15c3(%rip), %rdi      # 0x41cf
callq 0x1060
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
movq %r15, %rdi
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x2d22
movq %rbx, %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x2d22
movq %rbx, %rdi
xorl %esi, %esi
callq 0x130c
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
movq %r14, %rdi
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x2d22
movq %rbx, %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x2d22
movq %r12, %rsp
xorl %eax, %eax
leaq -0x20(%rbp), %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x146d(%rip), %rdi      # 0x410b
leaq 0x147c(%rip), %rsi      # 0x4121
leaq 0x1488(%rip), %rcx      # 0x4134
movl $0x4d, %edx
callq 0x1080