Finished all methods. Main function and debug printing pending.
This commit is contained in:
parent
359ffa755c
commit
5de65255e1
29
Kernel.cpp
29
Kernel.cpp
|
@ -1,19 +1,29 @@
|
||||||
#include "Kernel.h"
|
#include "Kernel.h"
|
||||||
|
|
||||||
Kernel::Kernel(const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages)
|
using std::next;
|
||||||
: free_pages(free_pages), busy_pages(busy_pages) {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Kernel::Kernel(const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages)
|
||||||
|
: free_pages(free_pages), busy_pages(busy_pages), swapped_page(nullptr) {}
|
||||||
|
|
||||||
void Kernel::page_fault(PageTable page_table, const int idx) {
|
void Kernel::page_fault(PageTable page_table, const int idx) {
|
||||||
PhysicalPage *page;
|
PhysicalPage *page = nullptr;
|
||||||
if (!this->free_pages.is_empty()) {
|
if (!this->free_pages.is_empty()) {
|
||||||
page = free_pages.last();
|
page = free_pages.get_head()->prev;
|
||||||
free_pages.remove(page);
|
free_pages.remove(page);
|
||||||
busy_pages.insert_tail(page);
|
busy_pages.insert_tail(page);
|
||||||
} else {
|
} else {
|
||||||
page = nullptr; // TODO: page replacement algorithm
|
for (PhysicalPage *curr = busy_pages.get_head();; curr = curr->next) {
|
||||||
|
if ((*curr->PT)[curr->idx].R)
|
||||||
|
(*curr->PT)[curr->idx].R = false;
|
||||||
|
else {
|
||||||
|
curr->PT->entries.erase(next(curr->PT->entries.begin(), curr->idx));
|
||||||
|
page = curr;
|
||||||
|
busy_pages.set_head(curr->next);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
page_table[idx].PPN = page->PPN;
|
page_table[idx].PPN = page->PPN;
|
||||||
page_table[idx].P = true;
|
page_table[idx].P = true;
|
||||||
|
@ -23,7 +33,10 @@ void Kernel::page_fault(PageTable page_table, const int idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Kernel::stat_update() {
|
void Kernel::stat_update() {
|
||||||
for (int i = 0; i < 10; ++i) {
|
int i;
|
||||||
// TODO: update busy page stats
|
PhysicalPage *curr;
|
||||||
|
for (i = 0, curr = busy_pages.get_head(); i < 10; ++i, curr = curr->next) {
|
||||||
|
if ((*curr->PT)[curr->idx].R)
|
||||||
|
(*curr->PT)[curr->idx].R = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
2
Kernel.h
2
Kernel.h
|
@ -11,7 +11,7 @@
|
||||||
class Kernel {
|
class Kernel {
|
||||||
public:
|
public:
|
||||||
List<PhysicalPage> free_pages, busy_pages;
|
List<PhysicalPage> free_pages, busy_pages;
|
||||||
// TODO: RunQ
|
PhysicalPage *swapped_page;
|
||||||
std::vector<Process> RunQ;
|
std::vector<Process> RunQ;
|
||||||
Kernel(const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages);
|
Kernel(const List<PhysicalPage> &free_pages, const List<PhysicalPage> &busy_pages);
|
||||||
void page_fault(PageTable page_table, int idx);
|
void page_fault(PageTable page_table, int idx);
|
||||||
|
|
104
List.h
104
List.h
|
@ -3,96 +3,84 @@
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class List {
|
class List {
|
||||||
T *head, *tail;
|
T *head;
|
||||||
unsigned int num;
|
unsigned int num;
|
||||||
const unsigned int idx;
|
public:
|
||||||
public:
|
explicit List();
|
||||||
explicit List(unsigned int idx);
|
[[nodiscard]] T *get_head();
|
||||||
T *first();
|
void set_head(T *head);
|
||||||
T *last();
|
void insert_head(T *elem);
|
||||||
void insert_head(T *elem);
|
void insert_tail(T *elem);
|
||||||
void insert_tail(T *elem);
|
void insert_before(T *elem, T *reference_point);
|
||||||
void insert_before(T *elem1, T *elem2);
|
void remove(T *elem);
|
||||||
void remove(T *elem);
|
bool is_empty();
|
||||||
bool is_empty();
|
[[nodiscard]] unsigned int get_num() const;
|
||||||
[[nodiscard]] unsigned int get_num() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define for_each_in_list(elem, list) \
|
|
||||||
for ( \
|
|
||||||
(elem) = (list)->first(); \
|
|
||||||
(elem) != nullptr; \
|
|
||||||
(elem) = (list)->next(elem) \
|
|
||||||
)
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
List<T>::List(const unsigned int idx) : head{nullptr}, tail{nullptr}, num{0}, idx{idx} {
|
List<T>::List() : head{nullptr}, num{0} {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T * List<T>::first() {
|
T *List<T>::get_head() {
|
||||||
return this->head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T * List<T>::last() {
|
void List<T>::set_head(T *head) {
|
||||||
return this->tail;
|
this->head = head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void List<T>::insert_head(T *elem) {
|
void List<T>::insert_head(T *elem) {
|
||||||
const unsigned int idx{this->idx};
|
if (!head)
|
||||||
|
elem->next = elem->prev = elem;
|
||||||
|
|
||||||
|
else {
|
||||||
|
elem->next = head;
|
||||||
|
elem->prev = head->prev;
|
||||||
|
head->prev->next = elem;
|
||||||
|
head->prev = elem;
|
||||||
|
}
|
||||||
|
|
||||||
elem->next[idx] = this->head;
|
|
||||||
elem->prev[idx] = nullptr;
|
|
||||||
if (this->head != nullptr)
|
|
||||||
this->head->prev[idx] = elem;
|
|
||||||
if (this->tail == nullptr)
|
|
||||||
this->tail = elem;
|
|
||||||
this->head = elem;
|
this->head = elem;
|
||||||
++this->num;
|
++this->num;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void List<T>::insert_tail(T *elem) {
|
void List<T>::insert_tail(T *elem) {
|
||||||
const unsigned int idx{this->idx};
|
if (!head)
|
||||||
|
elem->next = elem->prev = elem;
|
||||||
elem->next[idx] = nullptr;
|
else {
|
||||||
elem->prev[idx] = this->tail;
|
elem->next = head;
|
||||||
if (this->tail != nullptr)
|
elem->prev = head->prev;
|
||||||
this->tail->next[idx] = elem;
|
head->prev->next = elem;
|
||||||
if (this->head == nullptr)
|
head->prev = elem;
|
||||||
this->head = elem;
|
}
|
||||||
this->tail = elem;
|
|
||||||
++this->num;
|
++this->num;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void List<T>::insert_before(T *elem1, T *elem2) {
|
void List<T>::insert_before(T *elem, T *reference_point) {
|
||||||
const unsigned int idx{this->idx};
|
elem->next = reference_point;
|
||||||
|
elem->prev = reference_point->prev;
|
||||||
elem1->next[idx] = elem2;
|
reference_point->prev = elem;
|
||||||
elem1->prev[idx] = elem2->prev[idx];
|
if (elem->prev == nullptr)
|
||||||
elem2->prev[idx] = elem1;
|
this->head = elem;
|
||||||
if (elem1->prev[idx] == nullptr)
|
|
||||||
this->head = elem1;
|
|
||||||
else
|
else
|
||||||
elem1->prev[idx]->next[idx] = elem1;
|
elem->prev->next = elem;
|
||||||
++this->num;
|
++this->num;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void List<T>::remove(T *elem) {
|
void List<T>::remove(T *elem) {
|
||||||
const unsigned int idx{this->idx};
|
if (elem->next)
|
||||||
|
elem->next->prev = elem->prev;
|
||||||
if (elem->next[idx] != nullptr)
|
if (elem->prev)
|
||||||
elem->next[idx]->prev[idx] = elem->prev[idx];
|
elem->prev->next = elem->next;
|
||||||
if (elem->prev[idx] != nullptr)
|
|
||||||
elem->prev[idx]->next[idx] = elem->next[idx];
|
|
||||||
if (this->head == elem)
|
if (this->head == elem)
|
||||||
this->head = elem->next[idx];
|
this->head = elem->next;
|
||||||
if (this->tail == elem)
|
|
||||||
this->tail = elem->prev[idx];
|
|
||||||
--this->num;
|
--this->num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
MMU.h
1
MMU.h
|
@ -12,7 +12,6 @@ enum AccessType {
|
||||||
class MMU {
|
class MMU {
|
||||||
public:
|
public:
|
||||||
static void access(Kernel kernel, PageTable table, int index, AccessType type);
|
static void access(Kernel kernel, PageTable table, int index, AccessType type);
|
||||||
// TODO type of access
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "PageTable.h"
|
#include "PageTable.h"
|
||||||
|
|
||||||
PTE & PageTable::operator[](const int index) {
|
PTE &PageTable::operator[](const unsigned int index) {
|
||||||
return this->entries.at(index);
|
return this->entries.at(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
//
|
|
||||||
// Created by rhinemann on 10.03.25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef PAGETABLE_H
|
#ifndef PAGETABLE_H
|
||||||
#define PAGETABLE_H
|
#define PAGETABLE_H
|
||||||
|
|
||||||
|
@ -12,7 +8,7 @@
|
||||||
class PageTable {
|
class PageTable {
|
||||||
public:
|
public:
|
||||||
std::vector<PTE> entries;
|
std::vector<PTE> entries;
|
||||||
PTE &operator[](int index);
|
PTE &operator[](unsigned int index);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //PAGETABLE_H
|
#endif //PAGETABLE_H
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "PhysicalPage.h"
|
#include "PhysicalPage.h"
|
||||||
|
|
||||||
PhysicalPage::PhysicalPage(const unsigned int PPN): PPN(PPN) {
|
PhysicalPage::PhysicalPage(const unsigned int PPN)
|
||||||
|
: PPN(PPN), idx(0), PT{nullptr}, next{nullptr}, prev(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicalPage::take_up(PageTable *PT, const unsigned int idx) {
|
void PhysicalPage::take_up(PageTable *PT, const unsigned int idx) {
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
//
|
|
||||||
// Created by rhinemann on 10.03.25.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef PHYSICALPAGE_H
|
#ifndef PHYSICALPAGE_H
|
||||||
#define PHYSICALPAGE_H
|
#define PHYSICALPAGE_H
|
||||||
|
|
||||||
|
@ -11,7 +7,7 @@ class PhysicalPage {
|
||||||
public:
|
public:
|
||||||
unsigned int PPN, idx;
|
unsigned int PPN, idx;
|
||||||
PageTable *PT;
|
PageTable *PT;
|
||||||
PhysicalPage *next[2], *prev[2];
|
PhysicalPage *next, *prev;
|
||||||
|
|
||||||
explicit PhysicalPage(unsigned int PPN);
|
explicit PhysicalPage(unsigned int PPN);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,6 @@ Process::Process(PageTable *pageTable, const unsigned int executionTime)
|
||||||
: pageTable(pageTable), executionTime(executionTime), elapsedTime(0) {
|
: pageTable(pageTable), executionTime(executionTime), elapsedTime(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process::is_finished() {
|
bool Process::is_finished() const {
|
||||||
return elapsedTime >= executionTime;
|
return elapsedTime >= executionTime;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Process {
|
||||||
PageTable *pageTable;
|
PageTable *pageTable;
|
||||||
unsigned int executionTime, elapsedTime;
|
unsigned int executionTime, elapsedTime;
|
||||||
Process(PageTable *pageTable, unsigned int executionTime);
|
Process(PageTable *pageTable, unsigned int executionTime);
|
||||||
bool is_finished();
|
[[nodiscard]] bool is_finished() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
8
main.cpp
8
main.cpp
|
@ -11,7 +11,7 @@ int main() {
|
||||||
std::mt19937 gen(rd());
|
std::mt19937 gen(rd());
|
||||||
std::uniform_int_distribution<unsigned int> distribution(0, 10);
|
std::uniform_int_distribution<unsigned int> distribution(0, 10);
|
||||||
|
|
||||||
List<PhysicalPage> free_pages(0), busy_pages(0);
|
List<PhysicalPage> free_pages, busy_pages;
|
||||||
Kernel kernel(free_pages, busy_pages);
|
Kernel kernel(free_pages, busy_pages);
|
||||||
|
|
||||||
for (int i = 0; i < PAGE_N; ++i) {
|
for (int i = 0; i < PAGE_N; ++i) {
|
||||||
|
@ -22,10 +22,14 @@ int main() {
|
||||||
kernel.RunQ.emplace_back(nullptr, distribution(gen));
|
kernel.RunQ.emplace_back(nullptr, distribution(gen));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (!kernel.RunQ.empty()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto process : kernel.RunQ)
|
for (const auto process : kernel.RunQ)
|
||||||
std::cout << process.executionTime << std::endl;
|
std::cout << process.executionTime << std::endl;
|
||||||
|
|
||||||
// std::cout << MAX_PROC << std::endl;
|
std::cout << MAX_PROC << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue