Compare commits

..

1 Commits

Author SHA1 Message Date
rhinemann daf81a2de7 Finalised the lab work. 2025-04-01 22:06:25 +03:00
5 changed files with 44 additions and 53 deletions

View File

@ -4,10 +4,8 @@
using std::next;
Kernel::Kernel(const unsigned int RunQ_max_length, const List<PhysicalPage> &free_pages,
const List<PhysicalPage> &busy_pages) : free_pages(free_pages), busy_pages(busy_pages) {
RunQ.reserve(RunQ_max_length);
}
Kernel::Kernel(const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages)
: free_pages(free_pages), busy_pages(busy_pages) {}
void Kernel::page_fault(std::vector<PTE> *page_table, const unsigned int idx) {
std::cout << std::format("[kernel:page_fault] Handling {} started", idx) << std::endl;
@ -18,24 +16,20 @@ void Kernel::page_fault(std::vector<PTE> *page_table, const unsigned int idx) {
free_pages.remove(page);
busy_pages.insert_tail(page);
std::cout << std::format("[kernel:page_fault:free] Found free page #{}, using it",
page->PPN) << std::endl;
std::cout << std::format("[kernel:page_fault:free] Found free page #{}, using it", page->PPN) << std::endl;
} else {
std::cout << "[kernel:page_fault] No free pages available, trying to swap..." << std::endl;
for (PhysicalPage *curr = busy_pages.get_head();; curr = curr->next) {
if ((*curr->PT)[curr->idx].R)
(*curr->PT)[curr->idx].R = false;
else {
std::cout << std::format("[kernel:page_fault:random] Selected physical page #{} for replacement",
curr->PPN) << std::endl;
std::cout << std::format("[kernel:page_fault:random] Selected physical page #{} for replacement", curr->PPN) << std::endl;
// curr->PT->erase(next(curr->PT->begin(), curr->idx));
(*curr->PT)[curr->idx].P = false;
curr->PT->erase(next(curr->PT->begin(), curr->idx));
page = curr;
busy_pages.set_head(curr->next);
std::cout << std::format("[kernel:page_fault:random] Auto-advanced the list of busy pages to ppn {}",
busy_pages.get_head()->PPN) << std::endl;
std::cout << std::format("[kernel:page_fault:random] Auto-advanced the list of busy pages to ppn {}", busy_pages.get_head()->PPN) << std::endl;
break;
}
}
@ -58,5 +52,4 @@ void Kernel::stat_update() {
std::cout << std::format("[kernel:update_job] Updating ppn {} status", curr->PPN) << std::endl;
}
}
busy_pages.set_head(curr);
}

View File

@ -11,8 +11,8 @@
class Kernel {
public:
List<PhysicalPage> free_pages, busy_pages;
std::vector<Process> RunQ;
Kernel(unsigned int RunQ_max_length, const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages);
List<Process> RunQ;
Kernel(const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages);
void page_fault(std::vector<PTE> *page_table, unsigned int idx);
void stat_update();

View File

@ -1,21 +1,19 @@
#include "Process.h"
#include <iostream>
#include <ostream>
#include <random>
#include <utility>
Process::Process(const unsigned int id, std::vector<PTE> page_table, const unsigned int execution_time, const unsigned int working_set_size)
: page_table(std::move(page_table)), execution_time(execution_time), id(id) {
Process::Process(const unsigned int id, std::vector<PTE> page_table, const unsigned int working_set_size,
const unsigned int execution_time) : page_table(std::move(page_table)), execution_time(execution_time), elapsed_time(0),
id(id), next(nullptr), prev(nullptr) {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned int> working_set_distribution(0, this->page_table.size() - 1);
std::cout << page_table.size() - 1 << std::endl;
std::uniform_int_distribution<unsigned int> page_table_distribution(0, this->page_table.size() - 1);
for (int i = 0; i < working_set_size; ++i) {
working_set.push_back(working_set_distribution(gen));
working_set.push_back(page_table_distribution(gen));
}
}
bool Process::is_finished(const unsigned int elapsed_time) const {
bool Process::is_finished() const {
return elapsed_time >= execution_time;
}

View File

@ -7,9 +7,13 @@ class Process {
public:
std::vector<PTE> page_table;
std::vector<unsigned int> working_set;
unsigned int execution_time, id;
Process(unsigned int id, std::vector<PTE> page_table, unsigned int execution_time, unsigned int working_set_size);
[[nodiscard]] bool is_finished(unsigned int elapsed_time) const;
unsigned int execution_time, elapsed_time, id;
Process *next, *prev;
Process(unsigned int id, std::vector<PTE> page_table, unsigned int working_set_size, unsigned int execution_time);
[[nodiscard]] bool is_finished() const;
};
#endif //PROCESS_H

View File

@ -14,48 +14,42 @@ int main() {
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned int> page_table_distribution(500, 1000), lifetime_distribution(50, 500), access_type_distr(1, 10);
Kernel kernel(MAX_PROC, List<PhysicalPage>(), List<PhysicalPage>());
Kernel kernel = Kernel(List<PhysicalPage>(), List<PhysicalPage>());
unsigned int elapsed_time = 0, new_proc_time = 0, new_ppn;
for (new_ppn = 1; new_ppn <= PAGE_N; ++new_ppn) {
kernel.free_pages.insert_head(new PhysicalPage(new_ppn));
}
for (int i = 0; i < kernel.RunQ.capacity(); ++i) {
kernel.RunQ.emplace_back(i, std::vector(page_table_distribution(gen), PTE()), lifetime_distribution(gen),
WORKING_SET_SIZE);
for (int i = 0; i < MAX_PROC; ++i) {
kernel.RunQ.insert_head(new Process(i, std::vector(page_table_distribution(gen), PTE()), WORKING_SET_SIZE, lifetime_distribution(gen)));
}
for (int i = 0; i < 10'000; ++i) {
const int process_index = i % kernel.RunQ.size();
if (kernel.RunQ.empty()) {
break;
}
Process *current_process = kernel.RunQ.get_head();
std::uniform_int_distribution<unsigned int> index_distribution;
for (int j = 0; j < 30; ++j) {
const AccessType access_type = access_type_distr(gen) == 1 ? WRITE : READ;
const AccessType type = access_type_distr(gen) == 1 ? WRITE : READ;
if (access_type_distr(gen) == 1) {
index_distribution = std::uniform_int_distribution<unsigned int>(0, kernel.RunQ.at(process_index).page_table.size() - 1);
index_distribution = std::uniform_int_distribution<unsigned int>(0, current_process->page_table.size() - 1);
const unsigned int table_index = index_distribution(gen);
MMU::access(kernel, &kernel.RunQ.at(process_index).page_table, table_index, access_type);
}
else {
index_distribution = std::uniform_int_distribution<unsigned int>(0, kernel.RunQ.at(process_index).working_set.size() - 1);
const unsigned int table_index = kernel.RunQ.at(process_index).working_set[index_distribution(gen)];
MMU::access(kernel, &kernel.RunQ.at(process_index).page_table, table_index, access_type);
MMU::access(kernel, &current_process->page_table, table_index, type);
} else {
index_distribution = std::uniform_int_distribution<unsigned int>(0, current_process->working_set.size() - 1);
const unsigned int table_index = index_distribution(gen);
MMU::access(kernel, &current_process->page_table, current_process->working_set[table_index], type);
}
}
++elapsed_time;
++current_process->elapsed_time;
++new_proc_time;
kernel.stat_update();
if (kernel.RunQ.at(process_index).is_finished(elapsed_time)) {
std::cout << std::format("[kernel:remove_current_process] Cleaning up process id {}", kernel.RunQ.at(process_index).id) << std::endl;
if (current_process->is_finished()) {
std::cout << std::format("[kernel:remove_current_process] Cleaning up process id {}", current_process->id) << std::endl;
PhysicalPage *curr, *cached_next;
unsigned int j;
@ -64,20 +58,19 @@ int main() {
curr && j < cached_len;
curr = cached_next, ++j) {
cached_next = curr->next;
if (curr->PT == &kernel.RunQ.at(process_index).page_table) {
if (curr->PT == &current_process->page_table) {
std::cout << std::format("[kernel:remove_current_process] Found ppn #{}, freeing it", curr->PPN) << std::endl;
kernel.busy_pages.remove(curr);
curr->PT = nullptr;
kernel.free_pages.insert_tail(curr);
}
}
kernel.RunQ.erase(kernel.RunQ.begin());
kernel.RunQ.set_head(current_process->next);
kernel.RunQ.remove(current_process);
if (new_proc_time >= PROC_CREATION_INTERVAL) {
kernel.RunQ.emplace_back(new_ppn, std::vector(page_table_distribution(gen), PTE()), lifetime_distribution(gen), WORKING_SET_SIZE);
kernel.RunQ.insert_tail(new Process(new_ppn, std::vector(page_table_distribution(gen), PTE()), WORKING_SET_SIZE, lifetime_distribution(gen)));
++new_ppn;
new_proc_time = 0;
}
@ -88,10 +81,13 @@ int main() {
std::cout << std::format("[main:metrics] Memory usage stats: busy {}, free {}, total {}", busy_stat, free_stat, free_stat + busy_stat) << std::endl;
}
if (kernel.RunQ.empty()) {
if (kernel.RunQ.is_empty()) {
std::cout << "[main:scheduling] No processes left to execute!" << std::endl;
break;
}
}
std::cout << "[main:scheduling] Simulation finished." << std::endl;
return 0;
}