// File: CMU-SAFARI[P]MQSim/src/ssd/Data_Cache_Manager_Flash_Advanced.cpp
// Function: SSD_Components::Data_Cache_Manager_Flash_Advanced::Execute_simulator_event(MQSimEngine::Sim_Event*)
void Data_Cache_Manager_Flash_Advanced::Execute_simulator_event(MQSimEngine::Sim_Event* ev)
	{
		Data_Cache_Simulation_Event_Type eventType = (Data_Cache_Simulation_Event_Type)ev->Type;
		Memory_Transfer_Info* transfer_info = (Memory_Transfer_Info*)ev->Parameters;

		switch (eventType)
		{
			case Data_Cache_Simulation_Event_Type::MEMORY_READ_FOR_USERIO_FINISHED://A user read is service from DRAM cache
			case Data_Cache_Simulation_Event_Type::MEMORY_WRITE_FOR_USERIO_FINISHED:
				((User_Request*)(transfer_info)->Related_request)->Sectors_serviced_from_cache -= transfer_info->Size_in_bytes / SECTOR_SIZE_IN_BYTE;
				if (is_user_request_finished((User_Request*)(transfer_info)->Related_request))
					broadcast_user_request_serviced_signal(((User_Request*)(transfer_info)->Related_request));
				break;
			case Data_Cache_Simulation_Event_Type::MEMORY_READ_FOR_CACHE_EVICTION_FINISHED://Reading data from DRAM and writing it back to the flash storage
				static_cast<FTL*>(nvm_firmware)->Address_Mapping_Unit->Translate_lpa_to_ppa_and_dispatch(*((std::list<NVM_Transaction*>*)(transfer_info->Related_request)));
				delete (std::list<NVM_Transaction*>*)transfer_info->Related_request;
				break;
			case Data_Cache_Simulation_Event_Type::MEMORY_WRITE_FOR_CACHE_FINISHED://The recently read data from flash is written back to memory to support future user read requests
				break;
		}
		delete transfer_info;

		memory_channel_is_busy = false;
		if (shared_dram_request_queue)	{
			if (dram_execution_queue[0].size() > 0)	{
				Memory_Transfer_Info* transfer_info = dram_execution_queue[0].front();
				dram_execution_queue[0].pop();
				Simulator->Register_sim_event(Simulator->Time() + estimate_dram_access_time(transfer_info->Size_in_bytes, dram_row_size, dram_busrt_size,
					dram_burst_transfer_time_ddr, dram_tRCD, dram_tCL, dram_tRP),
					this, transfer_info, static_cast<int>(transfer_info->next_event_type));
				memory_channel_is_busy = true;
			}
		} else {
			for (unsigned int i = 0; i < stream_count; i++) {
				dram_execution_list_turn++;
				dram_execution_list_turn %= stream_count;
				if (dram_execution_queue[dram_execution_list_turn].size() > 0) {
					Memory_Transfer_Info* transfer_info = dram_execution_queue[dram_execution_list_turn].front();
					dram_execution_queue[dram_execution_list_turn].pop();
					Simulator->Register_sim_event(Simulator->Time() + estimate_dram_access_time(transfer_info->Size_in_bytes, dram_row_size, dram_busrt_size,
						dram_burst_transfer_time_ddr, dram_tRCD, dram_tCL, dram_tRP),
						this, transfer_info, static_cast<int>(transfer_info->next_event_type));
					memory_channel_is_busy = true;
					break;
				}
			}
		}
	}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x68(%rsp), %rax
movl 0x18(%rax), %eax
movl %eax, 0x64(%rsp)
movq 0x68(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x58(%rsp)
movl 0x64(%rsp), %eax
movl %eax, 0x3c(%rsp)
testl %eax, %eax
je 0x6bcca
jmp 0x6bc60
movl 0x3c(%rsp), %eax
subl $0x1, %eax
je 0x6bd10
jmp 0x6bc6f
movl 0x3c(%rsp), %eax
addl $-0x2, %eax
subl $0x1, %eax
ja 0x6bd12
jmp 0x6bc81
movq 0x30(%rsp), %rdi
movq 0x58(%rsp), %rax
movl (%rax), %edx
shrl $0x9, %edx
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rax
movl 0x58(%rax), %ecx
subl %edx, %ecx
movl %ecx, 0x58(%rax)
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x6c3c0
testb $0x1, %al
jne 0x6bcb5
jmp 0x6bcc8
movq 0x30(%rsp), %rdi
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
callq 0x67bf0
jmp 0x6bd12
movq 0x30(%rsp), %rax
movq 0x38(%rax), %rax
movq 0x38(%rax), %rdi
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rsi
movq (%rdi), %rax
callq *0x60(%rax)
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0x6bd0e
movq 0x28(%rsp), %rdi
callq 0x6c2b0
movq 0x28(%rsp), %rdi
callq 0x8410
jmp 0x6bd12
jmp 0x6bd12
movq 0x58(%rsp), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x6bd2c
movq 0x20(%rsp), %rdi
callq 0x8410
movq 0x30(%rsp), %rax
movb $0x0, 0xc8(%rax)
testb $0x1, 0xe0(%rax)
je 0x6be0a
movq 0x30(%rsp), %rax
movq 0xd0(%rax), %rdi
callq 0x6bfa0
cmpq $0x0, %rax
jbe 0x6be05
movq 0x30(%rsp), %rax
movq 0xd0(%rax), %rdi
callq 0x6bfb0
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq (%rcx), %rcx
movq %rcx, 0x50(%rsp)
movq 0xd0(%rax), %rdi
callq 0x6bfc0
callq 0x46500
movq %rax, 0x18(%rsp)
callq 0x46500
movq %rax, %rdi
callq 0x46c50
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x10(%rsp)
movq 0x50(%rsp), %rcx
movl (%rcx), %edi
movl 0x40(%rax), %esi
movl 0x48(%rax), %edx
movsd 0x50(%rax), %xmm0
movq 0x58(%rax), %rcx
movq 0x60(%rax), %r8
movq 0x68(%rax), %r9
callq 0x6c4e0
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdi
movq 0x30(%rsp), %rdx
addq %rax, %rsi
movq 0x50(%rsp), %rcx
movq 0x50(%rsp), %rax
movl 0x10(%rax), %r8d
callq 0x46c60
movq 0x30(%rsp), %rax
movb $0x1, 0xc8(%rax)
jmp 0x6bf49
movl $0x0, 0x4c(%rsp)
movq 0x30(%rsp), %rcx
movl 0x4c(%rsp), %eax
cmpl 0x74(%rcx), %eax
jae 0x6bf47
movq 0x30(%rsp), %rax
movl 0xe4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xe4(%rax)
movl 0x74(%rax), %ecx
movl 0xe4(%rax), %eax
xorl %edx, %edx
divl %ecx
movq 0x30(%rsp), %rax
movl %edx, 0xe4(%rax)
movq 0xd0(%rax), %rdi
movslq 0xe4(%rax), %rax
imulq $0x50, %rax, %rax
addq %rax, %rdi
callq 0x6bfa0
cmpq $0x0, %rax
jbe 0x6bf35
movq 0x30(%rsp), %rax
movq 0xd0(%rax), %rdi
movslq 0xe4(%rax), %rax
imulq $0x50, %rax, %rax
addq %rax, %rdi
callq 0x6bfb0
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq (%rcx), %rcx
movq %rcx, 0x40(%rsp)
movq 0xd0(%rax), %rdi
movslq 0xe4(%rax), %rax
imulq $0x50, %rax, %rax
addq %rax, %rdi
callq 0x6bfc0
callq 0x46500
movq %rax, 0x8(%rsp)
callq 0x46500
movq %rax, %rdi
callq 0x46c50
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, (%rsp)
movq 0x40(%rsp), %rcx
movl (%rcx), %edi
movl 0x40(%rax), %esi
movl 0x48(%rax), %edx
movsd 0x50(%rax), %xmm0
movq 0x58(%rax), %rcx
movq 0x60(%rax), %r8
movq 0x68(%rax), %r9
callq 0x6c4e0
movq (%rsp), %rsi
movq 0x8(%rsp), %rdi
movq 0x30(%rsp), %rdx
addq %rax, %rsi
movq 0x40(%rsp), %rcx
movq 0x40(%rsp), %rax
movl 0x10(%rax), %r8d
callq 0x46c60
movq 0x30(%rsp), %rax
movb $0x1, 0xc8(%rax)
jmp 0x6bf47
jmp 0x6bf37
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x6be12
jmp 0x6bf49
addq $0x78, %rsp
retq
nop