// File: /workspace/github_cpp_makefile_star2_O2/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 %r12
pushq %rbx
pushq %rax
movq 0x18(%rsi), %r15
testq %r15, %r15
je 0x5578
movq %rsi, %r12
movq %rdi, %rbx
movzbl (%r15), %eax
movq 0x60(%rdi), %rcx
movq 0x18(%rcx,%rax,8), %rdi
movq %r15, %rsi
callq 0x5db4
movslq 0x4(%r15), %rax
movq 0x60(%rbx), %rcx
movq 0x10(%rcx), %rcx
movq (%rcx), %rcx
shlq $0x4, %rax
andq $0x0, 0x8(%rcx,%rax)
movq 0x58(%r12), %r14
movq 0x10(%r15), %rsi
cmpb $0x1, 0x8(%r15)
jne 0x54c8
cmpq %r12, %rsi
je 0x54ad
movq %r14, 0x58(%rsi)
movq (%rbx), %rcx
addq $0x3e8, %r14            # imm = 0x3E8
pushq $0x1
popq %rdx
pushq $0x9
popq %r8
movq %rbx, %rdi
movq %r14, %r9
callq 0x637a
movq 0x10(%r15), %rsi
andq $0x0, 0x18(%rsi)
pushq $0x28
popq %rsi
movq %r15, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2170
testq %rsi, %rsi
je 0x54e8
movq 0x8afc(%rip), %rdi      # 0xdfd0
leaq 0x411c(%rip), %rsi      # 0x95f7
callq 0x2140
movq %rax, %rdi
callq 0x20b0
movzbl (%r15), %eax
movq 0x60(%rbx), %rcx
movq 0x18(%rcx,%rax,8), %rdi
callq 0x5ea0
movq %rax, %r12
pushq $0x28
popq %rsi
movq %r15, %rdi
callq 0x2170
testq %r12, %r12
je 0x5578
movq 0x10(%r12), %r15
testq %r15, %r15
jne 0x5532
movq 0x8ab2(%rip), %rdi      # 0xdfd0
leaq 0x40eb(%rip), %rsi      # 0x9610
callq 0x2140
movq %rax, %rdi
callq 0x20b0
andq $0x0, 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
pushq $0x1
popq %rdx
pushq $0x9
popq %r8
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %r9
callq 0x637a
andq $0x0, 0x18(%r15)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq