implement new list interface (optional)
This commit is contained in:
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user