1

implement new list interface (optional)

This commit is contained in:
2022-07-19 23:36:57 +02:00
parent 241699a9bf
commit 18c659c4cc
6 changed files with 83 additions and 47 deletions

View File

@ -23,6 +23,7 @@
#include "kernel/threads/Scheduler.h" #include "kernel/threads/Scheduler.h"
#include "kernel/threads/IdleThread.h" #include "kernel/threads/IdleThread.h"
#include <optional>
/***************************************************************************** /*****************************************************************************
* Methode: Dispatcher::start * * Methode: Dispatcher::start *
@ -108,12 +109,18 @@ void Scheduler::exit() {
cpu.enable_int(); cpu.enable_int();
return; return;
} }
Thread& next = *(Thread*)this->ready_queue.remove_first();
log << DEBUG << "Exiting thread, ID: " << dec << this->active->tid << " => " << next.tid << endl; Thread* next = this->ready_queue.remove_first().value_or(nullptr);
if (next == nullptr) {
log << ERROR << "(Exit) Couldn't remove thread from ready_queue" << endl;
cpu.enable_int();
return;
}
log << DEBUG << "Exiting thread, ID: " << dec << this->active->tid << " => " << next->tid << endl;
delete this->active; delete this->active;
this->dispatch(next); this->dispatch(*next);
// Interrupts werden in Thread_switch in Thread.asm wieder zugelassen // Interrupts werden in Thread_switch in Thread.asm wieder zugelassen
// dispatch kehr nicht zurueck // dispatch kehr nicht zurueck
@ -203,12 +210,18 @@ void Scheduler::yield() {
return; return;
} }
Thread& next = *(Thread*)this->ready_queue.remove_first(); Thread* next = this->ready_queue.remove_first().value_or(nullptr);
if (next == nullptr) {
log << ERROR << "(Yield) Couldn't remove thread from ready_queue" << endl;
cpu.enable_int();
return;
}
this->ready_queue.insert_last(this->active); this->ready_queue.insert_last(this->active);
// log << TRACE << "Yielding, ID: " << dec << this->active->tid << " => " << next.tid << endl; // log << TRACE << "Yielding, ID: " << dec << this->active->tid << " => " << next.tid << endl;
this->dispatch(next); this->dispatch(*next);
} }
/***************************************************************************** /*****************************************************************************
@ -251,10 +264,17 @@ void Scheduler::block() {
this->block_queue.insert_last(this->active); // Thread that will be blocked waits in block_queue, so the scheduler can also this->block_queue.insert_last(this->active); // Thread that will be blocked waits in block_queue, so the scheduler can also
// kill blocked threads (for example keyboard demo needs this) // kill blocked threads (for example keyboard demo needs this)
Thread& next = *(Thread*)this->ready_queue.remove_first();
log << TRACE << "Blocking thread, ID: " << dec << this->active->tid << " => " << next.tid << endl;
this->dispatch(next); Thread* next = this->ready_queue.remove_first().value_or(nullptr);
if (next == nullptr) {
log << ERROR << "(Block) Couldn't remove thread from ready_queue" << endl;
cpu.enable_int();
return;
}
log << TRACE << "Blocking thread, ID: " << dec << this->active->tid << " => " << next->tid << endl;
this->dispatch(*next);
} }
/***************************************************************************** /*****************************************************************************

View File

@ -22,7 +22,13 @@ void Semaphore::v() {
if (!this->waitQueue.empty()) { if (!this->waitQueue.empty()) {
// Semaphore stays busy and unblocks next thread to work in critical section // Semaphore stays busy and unblocks next thread to work in critical section
Thread* next = (Thread*)this->waitQueue.remove_first(); Thread* next = this->waitQueue.remove_first().value_or(nullptr);
if (next == nullptr) {
// TODO: Log this once the logger is static
this->lock.release();
return;
}
this->lock.release(); this->lock.release();
scheduler.deblock(next); scheduler.deblock(next);
} else { } else {

View File

@ -70,9 +70,9 @@ void ArrayListDemo::run() {
kout << "Starting..." << endl; kout << "Starting..." << endl;
for (unsigned int n = 0; n < 10000; ++n) { for (unsigned int n = 0; n < 10000; ++n) {
this->list.insert_last(active); this->list.insert_last(active);
active = list.remove_first(); active = list.remove_first().value_or(-1);
if (this->list.size() != 3) { if (this->list.size() != 3 || active == -1) {
kout << "ERROR: Thread went missing" << endl; kout << "ERROR: Thread went missing" << endl;
break; break;
} }

View File

@ -70,9 +70,9 @@ void LinkedListDemo::run() {
kout << "Starting..." << endl; kout << "Starting..." << endl;
for (unsigned int n = 0; n < 10000; ++n) { for (unsigned int n = 0; n < 10000; ++n) {
this->list.insert_last(active); this->list.insert_last(active);
active = list.remove_first(); active = list.remove_first().value_or(-1);
if (this->list.size() != 3) { if (this->list.size() != 3 || active == -1) {
kout << "ERROR: Thread went missing" << endl; kout << "ERROR: Thread went missing" << endl;
break; break;
} }

View File

@ -143,7 +143,7 @@ public:
if (i == size()) { if (i == size()) {
// Insert at end // Insert at end
return insert_last(e); return insert_last(std::forward<Type>(e));
} }
copy_right(i); // Changes pos copy_right(i); // Changes pos
@ -153,7 +153,7 @@ public:
} }
std::size_t insert_first(Type e) override { std::size_t insert_first(Type e) override {
return insert_at(e, 0); return insert_at(std::forward<Type>(e), 0);
} }
std::size_t insert_last(Type e) override { std::size_t insert_last(Type e) override {
@ -173,7 +173,7 @@ public:
Type e = std::move(buf[i]); Type e = std::move(buf[i]);
copy_left(i); copy_left(i);
return std::make_optional(e); return e;
} }
std::optional<Type> remove_first() override { std::optional<Type> remove_first() override {
@ -204,7 +204,7 @@ public:
return std::nullopt; return std::nullopt;
} }
return std::make_optional(buf[i]); return buf[i];
} }
std::optional<Type> first() const override { std::optional<Type> first() const override {
@ -233,7 +233,7 @@ public:
out << "Print List (" << dec << size() << " elements): "; out << "Print List (" << dec << size() << " elements): ";
for (std::size_t i = 0; i < size(); ++i) { for (std::size_t i = 0; i < size(); ++i) {
out << dec << get(i) << " "; out << dec << buf[i] << " ";
} }
out << endl; out << endl;
} }

View File

@ -43,19 +43,19 @@ public:
// Type is T // Type is T
using Type = typename List<T, LinkedListIterator<Wrapper<T>>>::Type; // T is different from the List type (Wrapper<T>) using Type = typename List<T, LinkedListIterator<Wrapper<T>>>::Type; // T is different from the List type (Wrapper<T>)
using Iterator = typename List<T, LinkedListIterator<Wrapper<T>>>::Iterator; using Iterator = typename List<T, LinkedListIterator<Wrapper<T>>>::Iterator;
using Wrapper = typename Iterator::Type; using WrapperType = typename Iterator::Type;
private: private:
unsigned int num_elements = 0; unsigned int num_elements = 0;
Wrapper* head = nullptr; WrapperType* head = nullptr;
Wrapper* tail = nullptr; WrapperType* tail = nullptr;
std::optional<Wrapper*> get_wrapper(unsigned int i) { std::optional<WrapperType*> get_wrapper(unsigned int i) {
Wrapper* current = head; WrapperType* current = head;
unsigned int pos = 0; unsigned int pos = 0;
while (current != nullptr) { while (current != nullptr) {
if (pos == i) { if (pos == i) {
return std::make_optional(current); return current;
} }
current = current->next; current = current->next;
@ -67,8 +67,8 @@ private:
public: public:
~LinkedList() { ~LinkedList() {
Wrapper* current = head; WrapperType* current = head;
Wrapper* next; WrapperType* next;
while (current != nullptr) { while (current != nullptr) {
next = current->next; next = current->next;
@ -91,15 +91,19 @@ public:
} }
if (i == 0) { if (i == 0) {
return insert_first(e); return insert_first(std::forward<Type>(e));
} }
if (i == size()) { if (i == size()) {
return insert_last(e); return insert_last(std::forward<Type>(e));
} }
Wrapper* old_e = get_wrapper(i); WrapperType* old_e = get_wrapper(i).value_or(nullptr);
Wrapper* new_e = new Wrapper(e); if (old_e == nullptr) {
return -1;
}
WrapperType* new_e = new WrapperType(e);
new_e->prev = old_e->prev; new_e->prev = old_e->prev;
new_e->next = old_e; new_e->next = old_e;
@ -111,8 +115,8 @@ public:
} }
unsigned int insert_first(Type e) override { unsigned int insert_first(Type e) override {
Wrapper* old_head = head; WrapperType* old_head = head;
head = new Wrapper(e); head = new WrapperType(e);
head->prev = nullptr; head->prev = nullptr;
head->next = old_head; head->next = old_head;
@ -129,8 +133,8 @@ public:
} }
unsigned int insert_last(Type e) override { unsigned int insert_last(Type e) override {
Wrapper* old_tail = tail; WrapperType* old_tail = tail;
tail = new Wrapper(e); tail = new WrapperType(e);
tail->next = nullptr; tail->next = nullptr;
tail->prev = old_tail; tail->prev = old_tail;
@ -159,7 +163,11 @@ public:
return remove_last(); return remove_last();
} }
Wrapper* e = get_wrapper(i); WrapperType* e = get_wrapper(i).value_or(nullptr);
if (e == nullptr) {
return std::nullopt;
}
Type ret = *e; Type ret = *e;
e->next->prev = e->prev; e->next->prev = e->prev;
@ -168,7 +176,7 @@ public:
delete e; delete e;
num_elements = num_elements - 1; num_elements = num_elements - 1;
return std::make_optional(ret); return ret;
} }
std::optional<Type> remove_first() override { std::optional<Type> remove_first() override {
@ -177,7 +185,7 @@ public:
} }
Type e = *head; Type e = *head;
Wrapper* old_head = head; WrapperType* old_head = head;
head = head->next; head = head->next;
if (head != nullptr) { if (head != nullptr) {
@ -189,7 +197,7 @@ public:
delete old_head; delete old_head;
num_elements = num_elements - 1; num_elements = num_elements - 1;
return std::make_optional(e); return e;
} }
std::optional<Type> remove_last() override { std::optional<Type> remove_last() override {
@ -198,32 +206,34 @@ public:
} }
Type e = *tail; Type e = *tail;
Wrapper* old_tail = tail; WrapperType* old_tail = tail;
tail = tail->prev; tail = tail->prev;
if (tail != nullptr) { if (tail != nullptr) {
tail->next = nullptr; tail->next = nullptr;
} else { } else {
head == nullptr; head = nullptr;
} }
delete old_tail; delete old_tail;
num_elements = num_elements - 1; num_elements = num_elements - 1;
return std::make_optional(e); return e;
} }
bool remove(Type e) override { bool remove(Type e) override {
unsigned int pos = 0; unsigned int pos = 0;
Wrapper* wrapper = head; WrapperType* wrapper = head;
while (wrapper != nullptr) { while (wrapper != nullptr) {
if (*wrapper == e) { if (*wrapper == e) {
return remove_at(pos); return remove_at(pos).has_value();
} }
wrapper = wrapper->next; wrapper = wrapper->next;
pos++; pos++;
} }
return false;
} }
std::optional<Type> get(unsigned int i) const override { std::optional<Type> get(unsigned int i) const override {
@ -238,11 +248,11 @@ public:
return last(); return last();
} }
Wrapper* wrapper = head; WrapperType* wrapper = head;
for (unsigned int pos = 0; pos < i; ++pos) { for (unsigned int pos = 0; pos < i; ++pos) {
wrapper = wrapper->next; wrapper = wrapper->next;
} }
return std::make_optional(*wrapper); return *wrapper;
} }
std::optional<Type> first() const override { std::optional<Type> first() const override {
@ -250,7 +260,7 @@ public:
return std::nullopt; return std::nullopt;
} }
return std::make_optional(*head); return *head;
} }
std::optional<Type> last() const override { std::optional<Type> last() const override {
@ -258,7 +268,7 @@ public:
return std::nullopt; return std::nullopt;
} }
return std::make_optional(*tail); return *tail;
} }
bool empty() const override { bool empty() const override {