// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::Remove_barrier_for_accessing_mvpn(unsigned short, unsigned int)
inline void Address_Mapping_Unit_Page_Level::Remove_barrier_for_accessing_mvpn(stream_id_type stream_id, MVPN_type mvpn)
	{
		auto itr = domains[stream_id]->Locked_MVPNs.find(mvpn);
		if (itr == domains[stream_id]->Locked_MVPNs.end()) {
			PRINT_ERROR("Illegal operation: Unlocking an MVPN that has not been locked!");
		}
		domains[stream_id]->Locked_MVPNs.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
		if (domains[stream_id]->MVPN_read_transactions_waiting_behind_barrier.find(mvpn) != domains[stream_id]->MVPN_read_transactions_waiting_behind_barrier.end()) {
			domains[stream_id]->MVPN_read_transactions_waiting_behind_barrier.erase(mvpn);
			PPA_type ppn = domains[stream_id]->GlobalTranslationDirectory[mvpn].MPPN;
			if (ppn == NO_MPPN) {
				PRINT_ERROR("Reading an invalid physical flash page address in function generate_flash_read_request_for_mapping_data!")
			}

			NVM_Transaction_Flash_RD* readTR = new NVM_Transaction_Flash_RD(Transaction_Source_Type::MAPPING, stream_id,
					SECTOR_SIZE_IN_BYTE, NO_LPA, NO_PPA, NULL, mvpn, ((page_status_type)0x1) << sector_no_per_page, CurrentTimeStamp);
			Convert_ppa_to_address(ppn, readTR->Address);
			readTR->PPA = ppn;
			Stats::Total_flash_reads_for_mapping++;
			Stats::Total_flash_reads_for_mapping_per_stream[stream_id]++;

			handle_transaction_serviced_signal_from_PHY(readTR);
			
			delete readTR;
		}

		//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.
		if (domains[stream_id]->MVPN_write_transaction_waiting_behind_barrier.find(mvpn) != domains[stream_id]->MVPN_write_transaction_waiting_behind_barrier.end()) {
			domains[stream_id]->MVPN_write_transaction_waiting_behind_barrier.erase(mvpn);
			//Writing back all dirty CMT entries that fall into the same translation virtual page (MVPN)
			unsigned int read_size = 0;
			page_status_type readSectorsBitmap = 0;
			LPA_type start_lpn = get_start_LPN_in_MVP(mvpn);
			LPA_type end_lpn = get_end_LPN_in_MVP(mvpn);
			for (LPA_type lpn_itr = start_lpn; lpn_itr <= end_lpn; lpn_itr++) {
				if (domains[stream_id]->CMT->Exists(stream_id, lpn_itr)) {
					if (domains[stream_id]->CMT->Is_dirty(stream_id, lpn_itr)) {
						domains[stream_id]->CMT->Make_clean(stream_id, lpn_itr);
					} else {
						page_status_type bitlocation = (((page_status_type)0x1) << (((lpn_itr - start_lpn) * GTD_entry_size) / SECTOR_SIZE_IN_BYTE));
						if ((readSectorsBitmap & bitlocation) == 0) {
							readSectorsBitmap |= bitlocation;
							read_size += SECTOR_SIZE_IN_BYTE;
						}
					}
				}
			}

			//Read the unchaged mapping entries from flash to merge them with updated parts of MVPN
			MPPN_type mppn = domains[stream_id]->GlobalTranslationDirectory[mvpn].MPPN;
			NVM_Transaction_Flash_WR* writeTR = new NVM_Transaction_Flash_WR(Transaction_Source_Type::MAPPING, stream_id, SECTOR_SIZE_IN_BYTE * sector_no_per_page,
				mvpn, mppn, NULL, mvpn, NULL, (((page_status_type)0x1) << sector_no_per_page) - 1, CurrentTimeStamp);

			Stats::Total_flash_reads_for_mapping++;
			Stats::Total_flash_writes_for_mapping++;
			Stats::Total_flash_reads_for_mapping_per_stream[stream_id]++;
			Stats::Total_flash_writes_for_mapping_per_stream[stream_id]++;

			handle_transaction_serviced_signal_from_PHY(writeTR);

			delete writeTR;
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %edx, 0x4(%rsp)
movq 0xa8(%rdi), %rax
movl %esi, %r12d
movq (%rax,%r12,8), %rax
movq 0x128(%rax), %rcx
testq %rcx, %rcx
je 0x30304
movl %edx, %ebp
movl %esi, %r13d
movq %rdi, %r14
leaq 0x118(%rax), %rdi
addq $0x120, %rax            # imm = 0x120
movq %rax, %rsi
xorl %edx, %edx
cmpl %ebp, 0x20(%rcx)
setb %dl
cmovaeq %rcx, %rsi
movq 0x10(%rcx,%rdx,8), %rcx
testq %rcx, %rcx
jne 0x2ffa6
cmpq %rax, %rsi
je 0x30304
cmpl %ebp, 0x20(%rsi)
ja 0x30304
callq 0x30878
movq 0xa8(%r14), %rax
movq (%rax,%r12,8), %rax
movq 0x1b8(%rax), %rcx
testq %rcx, %rcx
je 0x3011a
leaq 0x1a8(%rax), %r15
leaq 0x1b0(%rax), %rsi
movq %rsi, %rdx
xorl %edi, %edi
cmpl %ebp, 0x20(%rcx)
setb %dil
cmovaeq %rcx, %rdx
movq 0x10(%rcx,%rdi,8), %rcx
testq %rcx, %rcx
jne 0x2ffff
cmpq %rsi, %rdx
je 0x3011a
cmpl %ebp, 0x20(%rdx)
ja 0x3011a
movl %r13d, (%rsp)
leaq 0x4(%rsp), %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x305dc
movq %r15, %rdi
movq %rax, %rsi
callq 0x3065a
movq 0xa8(%r14), %rax
movq (%rax,%r12,8), %rax
movq (%rax), %rax
movl (%rbx), %r13d
movq %r13, %rcx
shlq $0x4, %rcx
movl (%rax,%rcx), %ebx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq %rax, %rbx
je 0x30347
movl $0xa0, %edi
callq 0x73a0
movq %rax, %r15
movb 0x7c(%r14), %cl
movl $0x1, %ebp
shlq %cl, %rbp
callq 0x28018
movq %rax, %rdi
callq 0x2841a
movzwl (%rsp), %edx
movq %r15, %rdi
movl $0x3, %esi
movl $0x200, %ecx            # imm = 0x200
movq $-0x1, %r8
movq $-0x1, %r9
pushq %rax
pushq %rbp
pushq %r13
pushq $0x0
callq 0x48114
addq $0x20, %rsp
movq %r15, %rdx
addq $0x38, %rdx
movq (%r14), %rax
movq %r14, %rdi
movq %rbx, %rsi
callq *0x88(%rax)
movq %rbx, 0x60(%r15)
leaq 0x3f63b(%rip), %rax     # 0x6f720
incq (%rax)
leal (,%r12,8), %ebx
leaq 0x3f639(%rip), %rax     # 0x6f730
incq (%rax,%rbx)
movq %r15, %rdi
callq 0x2f234
movq %r15, %rdi
callq 0x7370
movq 0xa8(%r14), %rax
movq (%rax,%rbx), %rax
movl (%rsp), %r13d
movq 0x1e8(%rax), %rcx
testq %rcx, %rcx
je 0x302f5
leaq 0x1d8(%rax), %r15
addq $0x1e0, %rax            # imm = 0x1E0
movl 0x4(%rsp), %edx
movq %rax, %rsi
xorl %edi, %edi
cmpl %edx, 0x20(%rcx)
setb %dil
cmovaeq %rcx, %rsi
movq 0x10(%rcx,%rdi,8), %rcx
testq %rcx, %rcx
jne 0x3013e
cmpq %rax, %rsi
je 0x302f5
cmpl 0x20(%rsi), %edx
jb 0x302f5
leaq 0x4(%rsp), %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x305dc
movq %r15, %rdi
movq %rax, %rsi
callq 0x3065a
movl (%rbx), %eax
movl 0xc0(%r14), %edx
leal 0x1(%rax), %ecx
imull %edx, %ecx
imull %eax, %edx
decl %ecx
cmpl %ecx, %edx
ja 0x3023a
movl %ecx, %ebx
movl %edx, %r15d
movl %r13d, %eax
movq %r12, %r13
shlq $0x38, %r13
incq %rbx
leaq 0x10(%rsp), %rbp
movl %eax, (%rsp)
movzwl %ax, %eax
movl %eax, 0x8(%rsp)
movq 0xa8(%r14), %rax
movq (%rax,%r12,8), %rax
movq 0x10(%rax), %rdi
movq %r15, %rax
orq %r13, %rax
movq %rax, 0x10(%rsp)
movq %rbp, %rsi
callq 0x30a0c
testq %rax, %rax
je 0x3022a
movq 0x10(%rax), %rax
cmpl $0x2, 0x14(%rax)
jne 0x3022a
movq 0xa8(%r14), %rax
movq (%rax,%r12,8), %rax
movq 0x10(%rax), %rdi
movl 0x8(%rsp), %esi
movq %r15, %rdx
callq 0x297c8
testb %al, %al
je 0x3022a
movq 0xa8(%r14), %rax
movq (%rax,%r12,8), %rax
movq 0x10(%rax), %rdi
movl 0x8(%rsp), %esi
movq %r15, %rdx
callq 0x2983a
incq %r15
cmpq %r15, %rbx
jne 0x301bf
movl 0x4(%rsp), %eax
movl (%rsp), %r13d
movq 0xa8(%r14), %rcx
movq (%rcx,%r12,8), %rcx
movq (%rcx), %rcx
movl %eax, %ebx
movq %rbx, %rax
shlq $0x4, %rax
movl (%rcx,%rax), %eax
movq %rax, 0x8(%rsp)
movl $0xb0, %edi
callq 0x73a0
movq %rax, %r15
movl 0x7c(%r14), %ebp
movq $-0x1, %r14
movl %ebp, %ecx
shlq %cl, %r14
callq 0x28018
movq %rax, %rdi
callq 0x2841a
shll $0x9, %ebp
notq %r14
subq $0x8, %rsp
xorl %r10d, %r10d
movzwl %r13w, %edx
movq %r15, %rdi
movl $0x3, %esi
movl %ebp, %ecx
movq %rbx, %r8
movq 0x10(%rsp), %r9
pushq %rax
pushq %r14
pushq %r10
pushq %rbx
pushq %r10
callq 0x481c8
addq $0x30, %rsp
leaq 0x3f462(%rip), %rax     # 0x6f720
incq (%rax)
leaq 0x3f460(%rip), %rax     # 0x6f728
incq (%rax)
shll $0x3, %r12d
leaq 0x3f45a(%rip), %rax     # 0x6f730
incq (%rax,%r12)
leaq 0x3fc4f(%rip), %rax     # 0x6ff30
incq (%rax,%r12)
movq %r15, %rdi
callq 0x2f234
movq %r15, %rdi
callq 0x7370
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x3ece5(%rip), %rbx     # 0x6eff0
leaq 0x26296(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x28af1(%rip), %rsi     # 0x58e12
movq %rbx, %rdi
callq 0x7390
movq %rax, %rdi
callq 0x71c0
movq 0x3ec98(%rip), %rdi     # 0x6efd0
callq 0x7430
movl $0x1, %edi
callq 0x7440
movq 0x3eca2(%rip), %rbx     # 0x6eff0
leaq 0x26253(%rip), %rsi     # 0x565a8
movq %rbx, %rdi
callq 0x7390
leaq 0x288b7(%rip), %rsi     # 0x58c1b
jmp 0x30321
jmp 0x30368
movq %rax, %rbx
movq %r15, %rdi
callq 0x7370
movq %rbx, %rdi
callq 0x7620
nop