// File: /workspace/github_cpp_makefile_star2_O3/narges64[P]SIMBA/ftl.cpp
// Function: write_cleanup(ssd_info*, sub_request*)
void write_cleanup(ssd_info * ssd, sub_request * sub){
	// remove the entry from the buffer since the request is done
	buffer_entry * buf_ent = sub->buf_entry;
	if (buf_ent == NULL) return;

	if (buf_ent->gc)
		ssd->dram->gc_buffer->remove_entry(buf_ent);
	else
		ssd->dram->buffer->remove_entry(buf_ent);

	int lpn = buf_ent->lpn;
	ssd->dram->map->map_entry[lpn].buf_ent = NULL;

	int64_t complete_time = sub->complete_time;

	if (buf_ent->outlier){
		if (buf_ent->sub != sub) {
			buf_ent->sub->complete_time = complete_time;

			change_subrequest_state (ssd, buf_ent->sub,
				SR_MODE_ST_S, ssd->current_time,
				SR_MODE_COMPLETE, complete_time + 1000);
		}
		buf_ent->sub->buf_entry = NULL;

		delete buf_ent;
	}else {
		if (buf_ent->sub != NULL)
			cout << "there is a problem here " << endl;

		// By removing one subrequest from buffer, we might put another sub request in the buffer
		buffer_entry * outlier_entry = NULL;
		if (buf_ent->gc)
			outlier_entry = ssd->dram->gc_buffer->move_outlier();
		else
			outlier_entry = ssd->dram->buffer->move_outlier();

		delete buf_ent;

		if (outlier_entry != NULL) {
			sub_request * outlier_sub = outlier_entry->sub;
			if (outlier_sub == NULL)
				cout << "outlier sub cannot be null" << endl;
			outlier_entry->sub = NULL;
			ssd->dram->map->map_entry[outlier_sub->lpn].buf_ent = outlier_entry;

			outlier_sub->complete_time = complete_time + 1000;

			change_subrequest_state(ssd, outlier_sub,
				SR_MODE_ST_S, ssd->current_time,
				SR_MODE_COMPLETE, complete_time+1000);
			outlier_sub->buf_entry = NULL;

		}
	}
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq 0x18(%rsi), %r15
testq %r15, %r15
je 0x5cd7
movq %rsi, %r12
movq %rdi, %rbx
movzbl (%r15), %eax
movq 0x60(%rdi), %rcx
movq 0x18(%rcx,%rax,8), %rdi
movq %r15, %rsi
callq 0x6624
movslq 0x4(%r15), %rax
movq 0x60(%rbx), %rcx
movq 0x10(%rcx), %rcx
movq (%rcx), %rcx
shlq $0x4, %rax
movq $0x0, 0x8(%rcx,%rax)
movq 0x58(%r12), %r14
movq 0x10(%r15), %rsi
cmpb $0x1, 0x8(%r15)
jne 0x5bcc
cmpq %r12, %rsi
je 0x5bae
movq %r14, 0x58(%rsi)
movq (%rbx), %rcx
addq $0x3e8, %r14            # imm = 0x3E8
movq %rbx, %rdi
movl $0x1, %edx
movl $0x9, %r8d
movq %r14, %r9
callq 0x6d7e
movq 0x10(%r15), %rsi
movq $0x0, 0x18(%rsi)
movl $0x28, %esi
movq %r15, %rdi
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x21a0
testq %rsi, %rsi
je 0x5c14
movq 0x83f8(%rip), %r12      # 0xdfd0
leaq 0x4aeb(%rip), %rsi      # 0xa6ca
movl $0x18, %edx
movq %r12, %rdi
callq 0x21e0
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r12, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20f0
movzbl (%r15), %eax
movq 0x60(%rbx), %rcx
movq 0x18(%rcx,%rax,8), %rdi
callq 0x6758
movq %rax, %r12
movl $0x28, %esi
movq %r15, %rdi
callq 0x21a0
testq %r12, %r12
je 0x5cd7
movq 0x10(%r12), %r15
testq %r15, %r15
jne 0x5c8c
movq 0x8380(%rip), %r13      # 0xdfd0
leaq 0x4a8c(%rip), %rsi      # 0xa6e3
movl $0x1a, %edx
movq %r13, %rdi
callq 0x21e0
movq (%r13), %rax
movq -0x18(%rax), %rdi
addq %r13, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r13, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20f0
xorl %r13d, %r13d
movq %r13, 0x10(%r12)
movq 0x60(%rbx), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
movl 0xc(%r15), %ecx
shlq $0x4, %rcx
movq %r12, 0x8(%rax,%rcx)
addq $0x3e8, %r14            # imm = 0x3E8
movq %r14, 0x58(%r15)
movq (%rbx), %rcx
movq %rbx, %rdi
movq %r15, %rsi
movl $0x1, %edx
movl $0x9, %r8d
movq %r14, %r9
callq 0x6d7e
movq %r13, 0x18(%r15)
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq