// File: /workspace/github_c_makefile_star2_O0/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
subq $0x70, %rsp
movl $0x0, -0x4(%rbp)
leaq 0x1f32(%rip), %rax      # 0x61e8
movb (%rax), %cl
movl $0x1, %eax
shll %cl, %eax
cltq
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rsp, %rcx
movq %rcx, -0x58(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x70(%rbp)
movq %rcx, %rsp
movq %rax, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
callq 0x46c0
movq -0x70(%rbp), %rdx
leaq -0x50(%rbp), %rdi
leaq 0x1ee1(%rip), %rsi      # 0x61e8
movl $0x4, %ecx
callq 0x11c0
leaq -0x50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1210
movl -0x2c(%rbp), %esi
leaq 0x1d8e(%rip), %rdi      # 0x60b6
movb $0x0, %al
callq 0x1050
movl $0x0, -0x68(%rbp)
cmpl $0xc8, -0x68(%rbp)
jge 0x4361
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
movl %edx, %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x4590
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x4336
movl -0x2c(%rbp), %esi
leaq 0x1d5f(%rip), %rdi      # 0x60ca
movb $0x0, %al
callq 0x1050
movl $0x0, -0x68(%rbp)
cmpl $0xc8, -0x68(%rbp)
jge 0x43a4
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
movl %edx, %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x4590
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x4379
movl -0x2c(%rbp), %esi
leaq 0x1d1c(%rip), %rdi      # 0x60ca
movb $0x0, %al
callq 0x1050
movl $0x0, -0x68(%rbp)
cmpl $0xc8, -0x68(%rbp)
jge 0x43e7
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
movl %edx, %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x4590
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x43bc
movl -0x2c(%rbp), %esi
leaq 0x1cd9(%rip), %rdi      # 0x60ca
movb $0x0, %al
callq 0x1050
movl $0x0, -0x68(%rbp)
cmpl $0x4f, -0x68(%rbp)
jge 0x4427
movl -0x68(%rbp), %esi
movl -0x64(%rbp), %edx
movl %edx, %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x4590
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x43ff
movl -0x2c(%rbp), %esi
leaq 0x1c99(%rip), %rdi      # 0x60ca
movb $0x0, %al
callq 0x1050
cmpl $0x1, -0x2c(%rbp)
jne 0x4440
jmp 0x445f
leaq 0x1ca0(%rip), %rdi      # 0x60e7
leaq 0x1caf(%rip), %rsi      # 0x60fd
movl $0x4d, %edx
leaq 0x1cb6(%rip), %rcx      # 0x6110
callq 0x1060
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
movzbl -0x3f(%rbp), %ecx
leaq 0x1caf(%rip), %rdi      # 0x611f
movb $0x0, %al
callq 0x1050
leaq -0x50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1210
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
movzbl -0x3f(%rbp), %ecx
leaq 0x1cbb(%rip), %rdi      # 0x6150
movb $0x0, %al
callq 0x1050
movl $0x0, -0x68(%rbp)
cmpl $0x2, -0x68(%rbp)
jge 0x44c9
movl -0x68(%rbp), %esi
movl -0x68(%rbp), %edx
addl $0x2710, %edx           # imm = 0x2710
leaq -0x50(%rbp), %rdi
callq 0x4590
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x44a3
movl -0x2c(%rbp), %esi
leaq 0x1ca8(%rip), %rdi      # 0x617b
movb $0x0, %al
callq 0x1050
leaq -0x50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1ec0
leaq 0x1caa(%rip), %rdi      # 0x6198
movb $0x0, %al
callq 0x1050
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
movzbl -0x3f(%rbp), %ecx
leaq 0x1c19(%rip), %rdi      # 0x611f
movb $0x0, %al
callq 0x1050
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x4620
leaq -0x50(%rbp), %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x4620
leaq -0x50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1210
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
movzbl -0x3f(%rbp), %ecx
leaq 0x1c02(%rip), %rdi      # 0x6150
movb $0x0, %al
callq 0x1050
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
movl $0x2710, %edx           # imm = 0x2710
callq 0x4620
leaq -0x50(%rbp), %rdi
movl $0x1, %esi
movl $0x2711, %edx           # imm = 0x2711
callq 0x4620
movl $0x0, -0x4(%rbp)
movq -0x58(%rbp), %rax
movq %rax, %rsp
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
nop