$g++ --std=c++11 main.cpp -lpthread -o sim
running (make sure the simulation input file "input.txt" is places at the location with the current name)
./sim
| 8 // total No. of page frames in main memory | |
| 16 // page size (in bytes) | |
| 4 // No. of page frames per process for FIFO, LIFO, LRU-X, LDF... | |
| 4 // used by LRU-X, OPT-X for lookaheads | |
| 4 // min pool size | |
| 8 // max pool size | |
| 3 // total number of processes | |
| 100 16 // pid1 size1 | |
| 101 16 // pid2 size2 | |
| 102 16 // pid3 size3 | |
| 101 0x0F // processid and address pairs.. | |
| 100 0x1A | |
| 102 0x10 | |
| 102 0xFF | |
| 100 0x20 | |
| 100 0x6F | |
| 102 0x31 | |
| 101 0x11 | |
| 101 0x2A | |
| 101 0x30 | |
| 100 0x71 | |
| 100 0x6A | |
| 100 0x50 | |
| 101 0x4A | |
| 101 0x50 | |
| 100 0x7A | |
| 100 0x70 | |
| 101 0x0A | |
| 100 0xFA | |
| 101 0x10 | |
| 101 0x2A | |
| 102 0xA0 | |
| 102 0x3A | |
| 101 0x30 | |
| 100 0x70 | |
| 100 0x5A | |
| 100 0x70 | |
| 100 0xDA | |
| 100 0x6A | |
| 100 0x10 | |
| 101 0x4A | |
| 101 0x5A | |
| 102 0xAA | |
| 101 0x00 | |
| 101 0x1A | |
| 100 0x2A | |
| 100 0xA0 | |
| 100 0x2A | |
| 100 0xDA | |
| 102 0x10 | |
| 100 0x3A | |
| 100 0x30 | |
| 101 0x20 | |
| 101 0x3A | |
| 101 0x4A | |
| 101 0x5A | |
| 100 0x1A | |
| 102 0x3A | |
| 102 0xF0 | |
| 100 0x20 | |
| 100 -1 // process 100 ends | |
| 101 -1 // process 101 ends | |
| 102 0x3A | |
| 102 0xF0 | |
| 102 0xFA | |
| 102 -1 // process 102 ends |
| #include <stdio.h> | |
| #include <string> | |
| #include <vector> | |
| #include <limits.h> // for INT_MAX | |
| #include <iostream> | |
| #include <fstream> | |
| #include <pthread.h> | |
| pthread_mutex_t memory_mutex = PTHREAD_MUTEX_INITIALIZER; | |
| pthread_mutex_t disk_mutex = PTHREAD_MUTEX_INITIALIZER; | |
| pthread_mutex_t fault_condition_mutex = PTHREAD_MUTEX_INITIALIZER; | |
| pthread_cond_t fault_condition_cond = PTHREAD_COND_INITIALIZER; | |
| pthread_mutex_t disk_condition_mutex = PTHREAD_MUTEX_INITIALIZER; | |
| pthread_cond_t disk_condition_cond = PTHREAD_COND_INITIALIZER; | |
| std::vector<std::string> getStringParts(std::string line) | |
| { | |
| // std::cout << line << '\n'; | |
| std::vector<std::string> list; | |
| if(line.size()==0) return list; | |
| int end = line.find(' '); | |
| if(end != std::string::npos) | |
| { | |
| list.push_back(line.substr(0, end)); | |
| std::vector<std::string> sub_list = getStringParts(line.substr(end+1, line.size())); | |
| if(sub_list.size()!=0) | |
| list.insert(list.end(), sub_list.begin(), sub_list.end()); | |
| } | |
| else | |
| { | |
| end = line.size(); | |
| // if(line.substr(0, end).size()) | |
| list.push_back(line.substr(0, end)); | |
| } | |
| return list; | |
| } | |
| struct Process | |
| { | |
| std::vector<int> frames; | |
| std::string name; | |
| unsigned int page_size; | |
| unsigned int faults; | |
| }; | |
| Process getProcess(std::string name, std::vector<Process> &processes) | |
| { | |
| for(int i= 0; i < processes.size(); i++) | |
| { | |
| if(name == processes[i].name) | |
| { | |
| return processes[i]; | |
| } | |
| } | |
| } | |
| struct Frame | |
| { | |
| std::string process; | |
| int number; | |
| }; | |
| struct Memory | |
| { | |
| std::vector<Frame> *frames; | |
| std::vector<int> *counts; | |
| }; | |
| unsigned int countBits(unsigned int n) | |
| { | |
| unsigned int count = 0; | |
| while (n) | |
| { | |
| count++; | |
| n >>= 1; | |
| } | |
| return count; | |
| } | |
| struct DiskCommand | |
| { | |
| int rw; // 1 for write 0 for read; | |
| Frame *frame; | |
| int slot; | |
| Memory *memory; | |
| }; | |
| struct DiskArgs | |
| { | |
| DiskCommand *command; | |
| }; | |
| struct HandlerArg | |
| { | |
| Memory *memory; | |
| Frame *frame; | |
| DiskCommand *disk_command; | |
| }; | |
| struct ReplacerArgs | |
| { | |
| Memory *memory; | |
| DiskCommand *disk_command; | |
| }; | |
| int getFreeFrame(const Memory *memory) | |
| { | |
| for(int i= 0; i < memory->frames->size(); i++) | |
| { | |
| if(memory->frames->operator[](i).process.length()==0) | |
| { | |
| return i; | |
| } | |
| } | |
| return -1; | |
| } | |
| void* handlerThread(void *vargp) | |
| { | |
| HandlerArg *arg = (HandlerArg *)vargp; | |
| Memory *memory = arg->memory; | |
| Frame *frame = arg->frame; | |
| DiskCommand *disk_command = arg->disk_command; | |
| while (1) | |
| { | |
| pthread_mutex_lock( &fault_condition_mutex ); | |
| pthread_cond_wait( &fault_condition_cond, &fault_condition_mutex ); | |
| pthread_mutex_unlock( &fault_condition_mutex ); | |
| //wait for a free frame in memory | |
| //call the disk process with frame number and memory location and mamory slot | |
| std::cout << "handling fault of process: " << frame->process << " for frame: " << frame->number << '\n'; | |
| int free_frame = getFreeFrame(memory); | |
| while(free_frame == -1) | |
| { | |
| free_frame = getFreeFrame(memory); | |
| std::cout << "no free frames!!\n"; | |
| } | |
| //command and wait for the disk process | |
| pthread_mutex_lock( &disk_mutex ); | |
| disk_command->frame = frame; | |
| disk_command->rw = 0; | |
| disk_command->slot = free_frame; | |
| disk_command->memory = memory; | |
| pthread_mutex_lock( &disk_condition_mutex ); | |
| pthread_cond_signal( &disk_condition_cond ); | |
| pthread_mutex_unlock( &disk_condition_mutex ); | |
| // std::cout << "waiting for disk to bring the frame \n"; | |
| pthread_mutex_lock( &disk_condition_mutex ); | |
| pthread_cond_wait( &disk_condition_cond, &disk_condition_mutex ); | |
| pthread_mutex_unlock( &disk_condition_mutex ); | |
| // std::cout << "disk brought the frame to memeory\n"; | |
| //signal back | |
| pthread_mutex_lock( &fault_condition_mutex ); | |
| pthread_cond_signal( &fault_condition_cond ); | |
| pthread_mutex_unlock( &fault_condition_mutex ); | |
| pthread_mutex_unlock( &disk_mutex ); | |
| // std::cout << "signalled back to the simulator\n"; | |
| } | |
| } | |
| int maxCountSlot(Memory *memory) | |
| { | |
| int max = 0; | |
| int slot = 0; | |
| for(int i= 0; i < memory->counts->size(); i++) | |
| { | |
| if(memory->counts->operator[](i) > max) | |
| { | |
| max = memory->counts->operator[](i); | |
| slot = i; | |
| } | |
| } | |
| return slot; | |
| } | |
| int freeSolts(Memory *memory) | |
| { | |
| int count = 0; | |
| for(int i= 0; i < memory->frames->size(); i++) | |
| { | |
| if(memory->frames->operator[](i).process.length()==0) | |
| { | |
| count++; | |
| } | |
| } | |
| return count; | |
| } | |
| void* replacementThread(void *vargp) | |
| { | |
| ReplacerArgs *arg = (ReplacerArgs *)vargp; | |
| Memory *memory = arg->memory; | |
| DiskCommand *disk_command = arg->disk_command; | |
| int min = 4; | |
| int max = 8; | |
| int free_slots = 0; | |
| Frame frame; | |
| while (1) | |
| { | |
| free_slots = freeSolts(memory); | |
| while(free_slots > 4 ) | |
| { | |
| free_slots = freeSolts(memory); | |
| } | |
| disk_command->frame = &frame; | |
| disk_command->rw = 1; | |
| disk_command->slot = maxCountSlot(memory); | |
| disk_command->memory = memory; | |
| pthread_mutex_lock( &disk_mutex ); | |
| pthread_mutex_lock( &disk_condition_mutex ); | |
| pthread_cond_signal( &disk_condition_cond ); | |
| pthread_mutex_unlock( &disk_condition_mutex ); | |
| // std::cout << "waiting for frame be written to the disk\n"; | |
| pthread_mutex_lock( &disk_condition_mutex ); | |
| pthread_cond_wait( &disk_condition_cond, &disk_condition_mutex ); | |
| pthread_mutex_unlock( &disk_condition_mutex ); | |
| pthread_mutex_unlock( &disk_mutex ); | |
| // std::cout << "disk saved the frame in disk\n"; | |
| } | |
| } | |
| void modifyMemory(Frame *frame, Memory *memory, int slot, int rw) | |
| { | |
| if(rw==0) | |
| { | |
| memory->frames->operator[](slot) = *frame; | |
| } | |
| else | |
| { | |
| memory->frames->operator[](slot).number = -1; | |
| memory->frames->operator[](slot).process = ""; | |
| } | |
| } | |
| void* diskThread(void *vargp) | |
| { | |
| DiskArgs *arg = (DiskArgs *)vargp; | |
| DiskCommand *command = arg->command; | |
| while (1) | |
| { | |
| pthread_mutex_lock( &disk_condition_mutex ); | |
| pthread_cond_wait( &disk_condition_cond, &disk_condition_mutex ); | |
| pthread_mutex_unlock( &disk_condition_mutex ); | |
| // std::cout << "disk started \n"; | |
| modifyMemory(command->frame, command->memory, command->slot, command->rw); | |
| pthread_mutex_lock( &disk_condition_mutex ); | |
| pthread_cond_signal( &disk_condition_cond ); | |
| pthread_mutex_unlock( &disk_condition_mutex ); | |
| } | |
| } | |
| void updateProcesses(Process process, std::vector<Process> &processes) | |
| { | |
| for(int i= 0; i < processes.size(); i++) | |
| { | |
| if(process.name == processes[i].name) | |
| { | |
| processes[i] = process; | |
| return; | |
| } | |
| } | |
| } | |
| int pageInMemory(std::string name, int page, const Memory *memory) | |
| { | |
| for(int i= 0; i < memory->frames->size(); i++) | |
| { | |
| if(name == memory->frames->operator[](i).process && page == memory->frames->operator[](i).number ) | |
| { | |
| return 1; | |
| } | |
| } | |
| return -1; | |
| } | |
| void memorySweepFIFO(Memory *memory) | |
| { | |
| for(int i= 0; i < memory->counts->size(); i++) | |
| { | |
| memory->counts->operator[](i)++; | |
| } | |
| } | |
| int main() | |
| { | |
| std::ifstream file("input.txt"); | |
| std::string line; | |
| std::vector<std::vector<std::string>> sim_data; | |
| while(std::getline(file, line)) | |
| { | |
| std::vector<std::string> list = getStringParts(line); | |
| sim_data.push_back(list); | |
| } | |
| //create the simulator | |
| //initialize memory | |
| int memory_size = std::stoi(sim_data[0][0]); | |
| std::vector<Frame> *frames = new std::vector<Frame>(memory_size); | |
| std::vector<int> *counts = new std::vector<int>(memory_size); | |
| std::cout << "total frames in memeory: " << memory_size << '\n'; | |
| for( int i = 0; i++ ;i<memory_size) | |
| { | |
| Frame frame; | |
| frame.process = ""; | |
| frame.number = -1; | |
| frames->operator[](i)= frame; | |
| counts->operator[](i)= 0; | |
| } | |
| Memory *memory = new Memory; | |
| memory->frames = frames; | |
| memory->counts = counts; | |
| //create the processes | |
| int process_number = std::stoi(sim_data[6][0]); | |
| std::cout << "number of processes: " << process_number << '\n'; | |
| std::vector<Process> processes; | |
| for( int i = 0; i<process_number; i++) | |
| { | |
| Process process; | |
| process.faults = 0; | |
| process.page_size = std::stoi(sim_data[6+1+i][1]); | |
| process.name = sim_data[6+1+i][0]; | |
| processes.push_back(process); | |
| } | |
| //create the disk process | |
| pthread_t driver_id; | |
| DiskArgs *dkarg = new DiskArgs; | |
| DiskCommand *dcmd = new DiskCommand; | |
| dkarg->command = dcmd; | |
| pthread_create(&driver_id, NULL, diskThread, (void*)dkarg); | |
| //create the fault handler process | |
| pthread_t handler_id; | |
| HandlerArg *hndlr = new HandlerArg; | |
| Frame *missing_frame = new Frame; | |
| hndlr->memory = memory; | |
| hndlr->frame = missing_frame; | |
| hndlr->disk_command = dkarg->command; | |
| pthread_create(&handler_id, NULL, handlerThread, (void*)hndlr); | |
| //create the page replacement process | |
| pthread_t rplcmnt_id; | |
| ReplacerArgs *rparg = new ReplacerArgs; | |
| rparg->memory = memory; | |
| rparg->disk_command = dkarg->command; | |
| pthread_create(&rplcmnt_id, NULL, replacementThread, (void*)rparg); | |
| //run simulation | |
| int page_size = std::stoi(sim_data[1][0]); | |
| std::cout << "page size: " << page_size << '\n'; | |
| for( int i = 6+process_number+1; i < sim_data.size(); i++) | |
| { | |
| Process process = getProcess(sim_data[i][0], processes); | |
| if (std::stoi(sim_data[i][1], 0, 16 )==-1) | |
| { | |
| continue; | |
| std::cout << "process died \n"; | |
| } | |
| int page = std::stoi(sim_data[i][1], 0, 16 ) >> (countBits(page_size)-1); | |
| // std::cout << sim_data[i][0] << " " << std::stoi(sim_data[i][1], 0, 16 ) << '\n'; | |
| // std::cout << page << " \n"; | |
| if(-1==pageInMemory(process.name, page, memory)) | |
| { | |
| // signal handler and wait | |
| // std::cout << "fault occured" << "\n"; | |
| missing_frame->number = page; | |
| missing_frame->process = process.name; | |
| pthread_mutex_lock( &fault_condition_mutex ); | |
| pthread_cond_signal( &fault_condition_cond ); | |
| pthread_mutex_unlock( &fault_condition_mutex ); | |
| pthread_mutex_lock( &fault_condition_mutex ); | |
| pthread_cond_wait( &fault_condition_cond, &fault_condition_mutex ); | |
| pthread_mutex_unlock( &fault_condition_mutex ); | |
| process.faults++; | |
| updateProcesses(process, processes); | |
| memorySweepFIFO(memory); | |
| } | |
| }//end of simulation loop | |
| int total = 0; | |
| for(auto process: processes) | |
| { | |
| std::cout << "faults from process " << process.name << " :" << process.faults << " \n"; | |
| total += process.faults; | |
| } | |
| std::cout << "total faults: " << total << " \n"; | |
| return 0; | |
| } |
Can you have a complete version of this code