// File: /workspace/github_c_makefile_star2_O2/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 0x1b06(%rip), %r14      # 0x4218
movb (%r14), %cl
pushq $0x1
popq %rax
shll %cl, %eax
movq %rsp, %r12
cltq
addq $0xf, %rax
andq $-0x10, %rax
movq %rsp, %r15
subq %rax, %r15
movq %r15, %rsp
callq 0x2a50
leaq -0x60(%rbp), %rbx
pushq $0x4
popq %rcx
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x11dc
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11fc
movl 0x24(%rbx), %esi
leaq 0x1979(%rip), %rdi      # 0x40da
xorl %eax, %eax
callq 0x1070
cmpl $0xc8, %r14d
je 0x2788
leal 0x1(%r14), %r15d
movq %rbx, %rdi
movl %r14d, %esi
movl %r14d, %edx
callq 0x2982
movl %r15d, %r14d
jmp 0x2768
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x1958(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
movl $0xc8, %r15d
cmpl %r15d, %r14d
je 0x27bf
leal (%r14,%r15), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2982
incl %r14d
jmp 0x27a6
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x1921(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
cmpl $0xc8, %r14d
je 0x27f7
leal 0x190(%r14), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2982
incl %r14d
jmp 0x27d7
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x18e9(%rip), %rdi      # 0x40ee
xorl %r14d, %r14d
xorl %eax, %eax
callq 0x1070
cmpl $0x4f, %r14d
je 0x282c
leal 0x258(%r14), %edx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x2982
incl %r14d
jmp 0x280f
movl -0x3c(%rbp), %esi
leaq 0x18b8(%rip), %rdi      # 0x40ee
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x1070
cmpl $0x1, -0x3c(%rbp)
jne 0x2965
leaq -0x60(%rbp), %r14
movl 0x20(%r14), %edx
movzbl 0x11(%r14), %ecx
leaq 0x18e6(%rip), %rdi      # 0x4143
pushq $0x1
popq %rsi
xorl %eax, %eax
callq 0x1070
movq %r14, %rdi
xorl %esi, %esi
callq 0x11fc
movl 0x20(%r14), %edx
movl 0x24(%r14), %esi
movzbl 0x11(%r14), %ecx
leaq 0x18ef(%rip), %rdi      # 0x4174
xorl %eax, %eax
callq 0x1070
pushq $0x2
popq %r15
subl $0x1, %r15d
jb 0x28ac
movl %ebx, %edx
orl $0x2710, %edx           # imm = 0x2710
movq %r14, %rdi
movl %ebx, %esi
callq 0x2982
incl %ebx
jmp 0x2890
leaq -0x60(%rbp), %rbx
movl 0x24(%rbx), %esi
leaq 0x18e5(%rip), %rdi      # 0x419f
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1812
leaq 0x18fd(%rip), %rdi      # 0x41cf
callq 0x1060
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
leaq 0x185b(%rip), %rdi      # 0x4143
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x29ec
pushq $0x1
popq %r14
movq %rbx, %rdi
movl %r14d, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x29ec
movq %rbx, %rdi
xorl %esi, %esi
callq 0x11fc
movl 0x20(%rbx), %edx
movl 0x24(%rbx), %esi
movzbl 0x11(%rbx), %ecx
leaq 0x1847(%rip), %rdi      # 0x4174
xorl %eax, %eax
callq 0x1070
movq %rbx, %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x29ec
movq %rbx, %rdi
movl %r14d, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x29ec
movq %r12, %rsp
xorl %eax, %eax
leaq -0x20(%rbp), %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x179f(%rip), %rdi      # 0x410b
leaq 0x17ae(%rip), %rsi      # 0x4121
leaq 0x17ba(%rip), %rcx      # 0x4134
pushq $0x4d
popq %rdx
callq 0x1080