// File: /workspace/github_cpp_makefile_star2_O2/iPapatsoris[P]Paging-Simulator/Simulator.cpp
// Function: Simulator::runWorkingSet(Address*, bool&)
void Simulator::runWorkingSet(Address *address, bool& processSwitch) {
	WorkingSet *workingSet = workingSetManager->getWorkingSetByProcess(address->getProcessId());
	if (processSwitch) {
		cout << "Restoring process " << address->getProcessId() << " working set:" << endl;
		processSwitch = false;
		bool change = false;
		this->restoreWorkingSetMemory(workingSet->getWorkingSet(), change);
		if (! change) {
			cout << "\tWorking set is already in memory" << endl;
		}
	}
	Address *victimAddress = NULL;
	workingSet->update(*address, &victimAddress);
	Address **mappingFrame = invertedPageTable.getFrameByAddress(*address);
	if (mappingFrame != NULL) {
		/* Page already in memory */
		this->checkWrite(address, *mappingFrame);
		delete address;
	}
	else {
		/* Page not in memory */
		statistics.pageFaults++;
		Address **freeFrame = invertedPageTable.getFreeFrame();
		if (freeFrame != NULL) {
			invertedPageTable.occupyFrame(freeFrame, address);
			printPageFault(NULL, address);
		}
		else {
			/* Remove a page not in working set.
			 * Prioritize the one just removed from working set (if any) */
			Address **victimFrame;
			if (victimAddress != NULL) {
				victimFrame = invertedPageTable.getFrameByAddress(*victimAddress);
			}
			else {
				victimFrame = invertedPageTable.getVictimFrameNotInSet(workingSet->getWorkingSet());
			}
			Address *toDelete = *victimFrame;
			*victimFrame = address;
			printPageFault(toDelete, address);
			if (toDelete->getDirty()) {
				cout << " Saving victim to disk.";
				statistics.diskWrites++;
			}
			delete toDelete;
		}
		cout << endl;
	}
	if (victimAddress != NULL) {
		delete victimAddress;
	}
	//workingSet->print();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r12
movq %rsi, %rbx
movq %rdi, %r14
movq 0x50(%rdi), %rdi
movl (%rsi), %eax
leaq -0x3c(%rbp), %rsi
movl %eax, (%rsi)
callq 0x3b50
movq %rax, %r15
cmpb $0x1, (%r12)
jne 0x2ea9
movq 0x51a2(%rip), %rdi      # 0x7fd8
leaq 0x22ed(%rip), %rsi      # 0x512a
callq 0x2180
movl (%rbx), %esi
movq %rax, %rdi
callq 0x2240
leaq 0x22ea(%rip), %rsi      # 0x513d
movq %rax, %rdi
callq 0x2180
movq %rax, %rdi
callq 0x20e0
xorl %r13d, %r13d
movb %r13b, (%r12)
leaq -0x29(%rbp), %r12
movb %r13b, (%r12)
movq %r15, %rdi
callq 0x3c24
movq %r14, %rdi
movq %rax, %rsi
movq %r12, %rdx
callq 0x30b2
cmpb %r13b, (%r12)
jne 0x2ea9
movq 0x5143(%rip), %rdi      # 0x7fd8
leaq 0x22af(%rip), %rsi      # 0x514b
callq 0x2180
movq %rax, %rdi
callq 0x20e0
leaq -0x38(%rbp), %rdx
andq $0x0, (%rdx)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3b62
leaq 0x38(%r14), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3708
testq %rax, %rax
je 0x2ee8
movq (%rax), %rdx
movq %rbx, %rsi
callq 0x2f9a
movq %rbx, %rdi
callq 0x2170
jmp 0x2f7c
incl 0x5c(%r14)
movq %r12, %rdi
callq 0x3766
testq %rax, %rax
je 0x2f13
movq %r12, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x3796
xorl %edi, %edi
movq %rbx, %rsi
callq 0x3008
jmp 0x2f70
movq -0x38(%rbp), %rsi
testq %rsi, %rsi
je 0x2f26
movq %r12, %rdi
callq 0x3708
jmp 0x2f39
movq %r15, %rdi
callq 0x3c24
movq %r12, %rdi
movq %rax, %rsi
callq 0x37a0
movq (%rax), %r15
movq %rbx, (%rax)
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3008
cmpb $0x1, 0x8(%r15)
jne 0x2f68
movq 0x5080(%rip), %rdi      # 0x7fd8
leaq 0x21b3(%rip), %rsi      # 0x5112
callq 0x2180
incl 0x60(%r14)
movq %r15, %rdi
callq 0x2170
movq 0x5061(%rip), %rdi      # 0x7fd8
callq 0x20e0
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x2f8a
callq 0x2170
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop