// File: CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::Remove_barrier_for_accessing_lpa(unsigned short, unsigned long)
inline void Address_Mapping_Unit_Page_Level::Remove_barrier_for_accessing_lpa(stream_id_type stream_id, LPA_type lpa)
	{
		auto itr = domains[stream_id]->Locked_LPAs.find(lpa);
		if (itr == domains[stream_id]->Locked_LPAs.end()) {
			PRINT_ERROR("Illegal operation: Unlocking an LPA that has not been locked!");
		}
		domains[stream_id]->Locked_LPAs.erase(itr);

		//If there are read requests waiting behind the barrier, then MQSim assumes they can be serviced with the actual page data that is accessed during GC execution
		auto read_tr = domains[stream_id]->Read_transactions_behind_LPA_barrier.find(lpa);
		while (read_tr != domains[stream_id]->Read_transactions_behind_LPA_barrier.end()) {
			handle_transaction_serviced_signal_from_PHY((*read_tr).second);
			delete (*read_tr).second;
			domains[stream_id]->Read_transactions_behind_LPA_barrier.erase(read_tr);
			read_tr = domains[stream_id]->Read_transactions_behind_LPA_barrier.find(lpa);
		}

		//If there are write requests waiting behind the barrier, then MQSim assumes they can be serviced with the actual page data that is accessed during GC execution. This may not be 100% true for all write requests, but, to avoid more complexity in the simulation, we accept this assumption.
		auto write_tr = domains[stream_id]->Write_transactions_behind_LPA_barrier.find(lpa);
		while (write_tr != domains[stream_id]->Write_transactions_behind_LPA_barrier.end()) {
			handle_transaction_serviced_signal_from_PHY((*write_tr).second);
			delete (*write_tr).second;
			domains[stream_id]->Write_transactions_behind_LPA_barrier.erase(write_tr);
			write_tr = domains[stream_id]->Write_transactions_behind_LPA_barrier.find(lpa);
		}
	}

// Assembly:
subq $0xa8, %rsp
movw %si, %ax
movq %rdi, 0xa0(%rsp)
movw %ax, 0x9e(%rsp)
movq %rdx, 0x90(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0xe8, %rdi
leaq 0x90(%rsp), %rsi
callq 0x5e3d0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x88(%rsp)
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0xe8, %rdi
callq 0x5e430
movq %rax, 0x80(%rsp)
leaq 0x88(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x5ecc0
testb $0x1, %al
jne 0x5b128
jmp 0x5b173
movq 0x7eec1(%rip), %rdi     # 0xd9ff0
leaq 0x4f7b2(%rip), %rsi     # 0xaa8e8
callq 0x8440
movq 0x7eeae(%rip), %rdi     # 0xd9ff0
leaq 0x51cfb(%rip), %rsi     # 0xace44
callq 0x8440
movq %rax, %rdi
movq 0x7ee00(%rip), %rsi     # 0xd9f58
callq 0x8480
movq 0x7ee6c(%rip), %rdi     # 0xd9fd0
callq 0x84f0
movl $0x1, %edi
callq 0x8500
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0xe8, %rdi
movq 0x88(%rsp), %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rsi
callq 0x5ece0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x70(%rsp)
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x148, %rdi            # imm = 0x148
leaq 0x90(%rsp), %rsi
callq 0x5d860
movq %rax, 0x68(%rsp)
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x148, %rdi            # imm = 0x148
callq 0x58e60
movq %rax, 0x60(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x58e40
testb $0x1, %al
jne 0x5b223
jmp 0x5b2d4
leaq 0x68(%rsp), %rdi
callq 0x5d890
movq 0x8(%rax), %rdi
callq 0x58f60
leaq 0x68(%rsp), %rdi
callq 0x5d890
movq 0x8(%rax), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x5b259
movq 0x10(%rsp), %rdi
callq 0x8410
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x148, %rdi            # imm = 0x148
movq 0x68(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rsi
callq 0x58eb0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x50(%rsp)
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x148, %rdi            # imm = 0x148
leaq 0x90(%rsp), %rsi
callq 0x5d860
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x68(%rsp)
jmp 0x5b1e2
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x178, %rdi            # imm = 0x178
leaq 0x90(%rsp), %rsi
callq 0x5d860
movq %rax, 0x40(%rsp)
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x178, %rdi            # imm = 0x178
callq 0x58e60
movq %rax, 0x38(%rsp)
leaq 0x40(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x58e40
testb $0x1, %al
jne 0x5b346
jmp 0x5b3f7
leaq 0x40(%rsp), %rdi
callq 0x5d890
movq 0x8(%rax), %rdi
callq 0x58f60
leaq 0x40(%rsp), %rdi
callq 0x5d890
movq 0x8(%rax), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x5b37c
movq 0x8(%rsp), %rdi
callq 0x8410
movq 0x18(%rsp), %rax
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x178, %rdi            # imm = 0x178
movq 0x40(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rsi
callq 0x58eb0
movq %rax, %rcx
movq 0x18(%rsp), %rax
movq %rcx, 0x28(%rsp)
movq 0xa8(%rax), %rax
movzwl 0x9e(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x178, %rdi            # imm = 0x178
leaq 0x90(%rsp), %rsi
callq 0x5d860
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x40(%rsp)
jmp 0x5b305
addq $0xa8, %rsp
retq
nop