spz3/main.cpp

94 lines
3.7 KiB
C++

#include <iostream>
#include <random>
#include "Kernel.h"
#include "MMU.h"
static int MAX_PROC = 10;
static int PAGE_N = 100;
static int PROC_CREATION_INTERVAL = 100;
static int WORKING_SET_SIZE = 15;
int main() {
std::random_device rd;
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 = 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 < 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) {
Process *current_process = kernel.RunQ.get_head();
std::uniform_int_distribution<unsigned int> index_distribution;
for (int j = 0; j < 30; ++j) {
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, current_process->page_table.size() - 1);
const unsigned int table_index = index_distribution(gen);
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);
}
}
++current_process->elapsed_time;
++new_proc_time;
kernel.stat_update();
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;
const unsigned int cached_len = kernel.busy_pages.get_num();
for (curr = kernel.busy_pages.get_head(), j = 0;
curr && j < cached_len;
curr = cached_next, ++j) {
cached_next = curr->next;
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);
kernel.free_pages.insert_tail(curr);
}
}
kernel.RunQ.set_head(current_process->next);
kernel.RunQ.remove(current_process);
if (new_proc_time >= PROC_CREATION_INTERVAL) {
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;
}
}
{
unsigned int busy_stat = kernel.busy_pages.get_num(), free_stat = kernel.free_pages.get_num();
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.is_empty()) {
std::cout << "[main:scheduling] No processes left to execute!" << std::endl;
break;
}
}
std::cout << "[main:scheduling] Simulation finished." << std::endl;
return 0;
}