1

Implement SchedulerService

This commit is contained in:
2022-12-08 17:13:34 +01:00
parent a781e094ec
commit 312b844916
30 changed files with 142 additions and 75 deletions

View File

@ -12,6 +12,7 @@
#include "kernel/system/Globals.h"
#include "kernel/system/System.h"
#include "kernel/service/InterruptService.h"
#include "kernel/service/SchedulerService.h"
namespace Device {
@ -72,11 +73,7 @@ void PIT::trigger() {
// log << TRACE << "Incrementing systime" << endl;
// alle 10ms, Systemzeit weitersetzen
Kernel::systime++;
// Bei jedem Tick einen Threadwechsel ausloesen.
// Aber nur wenn der Scheduler bereits fertig intialisiert wurde
// und ein weiterer Thread rechnen moechte
Kernel::systime++; // TODO: Timeservice
/* hier muss Code eingefuegt werden */
@ -88,12 +85,9 @@ void PIT::trigger() {
last_indicator_refresh = Kernel::systime;
}
// TODO: Use schedulerservice
// Preemption
if (Kernel::scheduler.preemption_enabled()) {
// log << TRACE << "Preemption" << endl;
Kernel::scheduler.preempt();
}
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.yield();
}
}

View File

@ -1,5 +1,7 @@
#include "kernel/event/KeyEventListener.h"
#include "kernel/system/Globals.h"
#include "kernel/service/SchedulerService.h"
#include "kernel/system/System.h"
namespace Kernel {
@ -9,7 +11,8 @@ void KeyEventListener::trigger(char c) {
char KeyEventListener::waitForKeyEvent() const {
Logger::instance() << DEBUG << "KEvLis:: Thread with id: " << tid << " waiting for key event" << endl;
scheduler.block();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.block();
return lastChar; // This is only executed after thread is woken up by manager
}

View File

@ -1,5 +1,7 @@
#include "KeyEventManager.h"
#include "kernel/system/Globals.h"
#include "kernel/service/SchedulerService.h"
#include "kernel/system/System.h"
namespace Kernel {
@ -20,10 +22,11 @@ void KeyEventManager::unsubscribe(KeyEventListener &unsub) {
void KeyEventManager::broadcast(char c) {
log.trace() << "Beginning Broadcast" << endl;
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
for (KeyEventListener *listener: listeners) {
log.trace() << "Broadcasting " << c << " to Thread ID: " << dec << listener->tid << endl;
listener->trigger(c);
scheduler.deblock(listener->tid);
schedulerService.deblock(listener->tid);
}
}

View File

@ -19,7 +19,7 @@ private:
public:
KeyEventManager(const KeyEventManager &copy) = delete;
KeyEventManager() : log("KEvMan"), listeners(true) {}
KeyEventManager() : log("KEvMan") {}
void init() {
listeners.reserve();

View File

@ -1,5 +1,7 @@
#include "Semaphore.h"
#include "kernel/system/Globals.h"
#include "kernel/service/SchedulerService.h"
#include "kernel/system/System.h"
namespace Async {
@ -16,11 +18,12 @@ void Semaphore::p() {
if (!wait_queue.initialized()) { // TODO: I will replace this suboptimal datastructure in the future
wait_queue.reserve();
}
wait_queue.push_back(Kernel::scheduler.get_active());
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
wait_queue.push_back(schedulerService.active());
Device::CPU::disable_int(); // Make sure the block() comes through after releasing the lock
lock.release();
Kernel::scheduler.block(); // Moves to next thread, enables int
schedulerService.block(); // Moves to next thread, enables int
}
}
@ -34,7 +37,9 @@ void Semaphore::v() {
Device::CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock
lock.release();
Kernel::scheduler.deblock(tid); // Enables int
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.deblock(tid); // Enables int
} else {
// No more threads want to work so free semaphore
counter = counter + 1;

View File

@ -29,7 +29,7 @@ public:
Semaphore(const Semaphore &copy) = delete; // Verhindere Kopieren
// Konstruktor: Initialisieren des Semaphorzaehlers
Semaphore(int c) : wait_queue(true), counter(c) {}
explicit Semaphore(int c) : counter(c) {}
// 'Passieren': Warten auf das Freiwerden eines kritischen Abschnitts.
void p();

View File

@ -1,5 +1,7 @@
#include "ArrayDemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
void ArrayDemo::run() {
Container::Array<int, 10> arr1{};
@ -37,5 +39,6 @@ void ArrayDemo::run() {
// arr1.swap(arr3); // Not possible as type/size has to match
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -6,9 +6,9 @@
class ArrayDemo : public Kernel::Thread {
public:
ArrayDemo(const ArrayDemo& copy) = delete;
ArrayDemo(const ArrayDemo &copy) = delete;
ArrayDemo() : Thread("ArrayDemo") {}
ArrayDemo() = default;
void run() override;
};

View File

@ -10,6 +10,8 @@
#include "HeapDemo.h"
#include "lib/util/System.h"
#include "kernel/service/SchedulerService.h"
#include "kernel/system/System.h"
void HeapDemo::run() {
Util::System::out.lock();
@ -75,5 +77,7 @@ void HeapDemo::run() {
Util::System::out << "HEAP_DEMO END ===============================================================" << endl;
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -16,15 +16,16 @@
class MyObj {
public:
constexpr MyObj() : value(5) {};
constexpr MyObj(const unsigned int val) : value(val) {};
const unsigned int value;
};
class HeapDemo : public Kernel::Thread {
public:
HeapDemo(const HeapDemo& copy) = delete;
HeapDemo(const HeapDemo &copy) = delete;
HeapDemo() : Thread("HeapDemo") {}
HeapDemo() = default;
void run() override;
};

View File

@ -9,6 +9,8 @@
*****************************************************************************/
#include "KeyboardDemo.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
void KeyboardDemo::run() {
@ -30,5 +32,6 @@ void KeyboardDemo::run() {
}
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -23,7 +23,7 @@ private:
public:
KeyboardDemo(const KeyboardDemo &copy) = delete;
KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) {
KeyboardDemo() : listener(tid) {
Kernel::kevman.subscribe(listener);
}

View File

@ -10,6 +10,8 @@
#include "TextDemo.h"
#include "VBEdemo.h"
#include "VectorDemo.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
void print_demo_menu() {
Util::System::out.lock();
@ -36,55 +38,56 @@ void MainMenu::run() {
char input = '\0';
unsigned int running_demo = 0;
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
while (running) {
input = listener.waitForKeyEvent();
if ((input >= '0' && input <= '9') || input == '!') {
switch (input) {
case '1':
running_demo = Kernel::scheduler.ready<TextDemo>();
running_demo = schedulerService.ready<TextDemo>();
break;
case '2':
running_demo = Kernel::scheduler.ready<PCSPKdemo>(&Device::PCSPK::aerodynamic);
running_demo = schedulerService.ready<PCSPKdemo>(&Device::PCSPK::aerodynamic);
break;
case '3':
running_demo = Kernel::scheduler.ready<KeyboardDemo>();
running_demo = schedulerService.ready<KeyboardDemo>();
break;
case '4':
running_demo = Kernel::scheduler.ready<HeapDemo>();
running_demo = schedulerService.ready<HeapDemo>();
break;
case '5':
running_demo = Kernel::scheduler.ready<VBEdemo>();
running_demo = schedulerService.ready<VBEdemo>();
break;
case '6':
running_demo = Kernel::scheduler.ready<PagingDemo>();
running_demo = schedulerService.ready<PagingDemo>();
break;
case '7':
running_demo = Kernel::scheduler.ready<PreemptiveThreadDemo>(3);
running_demo = schedulerService.ready<PreemptiveThreadDemo>(3);
break;
case '8':
running_demo = Kernel::scheduler.ready<VectorDemo>();
running_demo = schedulerService.ready<VectorDemo>();
break;
case '9':
running_demo = Kernel::scheduler.ready<ArrayDemo>();
running_demo = schedulerService.ready<ArrayDemo>();
break;
case '0':
running_demo = Kernel::scheduler.ready<SmartPointerDemo>();
running_demo = schedulerService.ready<SmartPointerDemo>();
break;
case '!':
running_demo = Kernel::scheduler.ready<StringDemo>();
running_demo = schedulerService.ready<StringDemo>();
break;
}
} else if (input == 'k') {
Kernel::scheduler.nice_kill(running_demo); // NOTE: If thread exits itself this will throw error
schedulerService.suicide(running_demo); // NOTE: If thread exits itself this will throw error
print_demo_menu();
} else if (input == 'K') {
Kernel::scheduler.kill(running_demo);
schedulerService.kill(running_demo);
print_demo_menu();
}
}
Kernel::scheduler.exit();
schedulerService.exit();
// This thread won't be deleted...
}

View File

@ -10,9 +10,9 @@ private:
Kernel::KeyEventListener listener;
public:
MainMenu(const MainMenu& copy) = delete;
MainMenu(const MainMenu &copy) = delete;
MainMenu() : Thread("MainMenu"), listener(tid) {
MainMenu() : listener(tid) {
Kernel::kevman.subscribe(listener);
}

View File

@ -1,5 +1,7 @@
#include "PCSPKdemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
void PCSPKdemo::run() {
Util::System::out.lock();
@ -13,5 +15,6 @@ void PCSPKdemo::run() {
Util::System::out << "Finished" << endl;
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -9,9 +9,9 @@ private:
void (*melody)(); // Allow to pass a melody to play when initializing the demo
public:
PCSPKdemo(const PCSPKdemo& copy) = delete;
PCSPKdemo(const PCSPKdemo &copy) = delete;
PCSPKdemo(void (*melody)()) : Thread("PCSPKdemo"), melody(melody) {}
PCSPKdemo(void (*melody)()) : melody(melody) {}
~PCSPKdemo() override {
Device::PCSPK::off();

View File

@ -1,5 +1,9 @@
#include "PagingDemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
NamedLogger PagingDemo::log = NamedLogger("PagingDemo");
void PagingDemo::writeprotect_page() {
Util::System::out << "Accessing a writeprotected page triggers bluescreen,\nif you can read this it didn't work"
@ -48,5 +52,6 @@ void PagingDemo::run() {
break;
}
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -5,18 +5,22 @@
#include "kernel/process/Thread.h"
#include "kernel/event/KeyEventListener.h"
class PagingDemo: public Kernel::Thread {
class PagingDemo : public Kernel::Thread {
private:
void writeprotect_page();
void free_page();
void notpresent_page();
Kernel::KeyEventListener listener;
public:
PagingDemo(const PagingDemo& copy) = delete;
static NamedLogger log;
PagingDemo(): Thread("PagingDemo"), listener(tid) {
public:
PagingDemo(const PagingDemo &copy) = delete;
PagingDemo() : listener(tid) {
Kernel::kevman.subscribe(listener);
}

View File

@ -1,5 +1,7 @@
#include "PreemptiveThreadDemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
void PreemptiveLoopThread::run() {
int cnt = 0;
@ -15,7 +17,8 @@ void PreemptiveLoopThread::run() {
Util::System::out.unlock();
}
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}
void PreemptiveThreadDemo::run() {
@ -25,11 +28,12 @@ void PreemptiveThreadDemo::run() {
Util::System::out << "Preemptive Thread Demo:" << endl;
Util::System::out << "Readying LoopThreads" << endl;
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
for (unsigned int i = 0; i < number_of_threads; ++i) {
Kernel::scheduler.ready<PreemptiveLoopThread>(i);
schedulerService.ready<PreemptiveLoopThread>(i);
}
Util::System::out << "Exiting main thread" << endl;
Util::System::out.unlock();
Kernel::scheduler.exit();
schedulerService.exit();
}

View File

@ -10,10 +10,10 @@ private:
int id;
public:
PreemptiveLoopThread(const PreemptiveLoopThread& copy) = delete; // Verhindere Kopieren
PreemptiveLoopThread(const PreemptiveLoopThread &copy) = delete; // Verhindere Kopieren
// Gibt der Loop einen Stack und eine Id.
PreemptiveLoopThread(int i) : Thread("LoopThread"), id(i) {}
PreemptiveLoopThread(int i) : id(i) {}
// Zaehlt einen Zaehler hoch und gibt ihn auf dem Bildschirm aus.
void run() override;
@ -24,9 +24,9 @@ private:
unsigned int number_of_threads;
public:
PreemptiveThreadDemo(const PreemptiveThreadDemo& copy) = delete; // Verhindere Kopieren
PreemptiveThreadDemo(const PreemptiveThreadDemo &copy) = delete; // Verhindere Kopieren
PreemptiveThreadDemo(unsigned int n) : Thread("PreemptiveThreadDemo"), number_of_threads(n) {}
PreemptiveThreadDemo(unsigned int n) : number_of_threads(n) {}
// Thread-Startmethode
void run() override;

View File

@ -2,6 +2,8 @@
#include "kernel/process/IdleThread.h"
#include "lib/util/System.h"
NamedLogger SmartPointerDemo::log = NamedLogger("SmartPointerDemo");
void SmartPointerDemo::run() {
Util::System::out.lock();
Util::System::out.clear();
@ -119,5 +121,6 @@ void SmartPointerDemo::run() {
log.info() << "Should be deleted by now..." << endl;
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -5,11 +5,14 @@
class SmartPointerDemo : public Kernel::Thread {
public:
SmartPointerDemo(const SmartPointerDemo& copy) = delete;
SmartPointerDemo(const SmartPointerDemo &copy) = delete;
SmartPointerDemo() : Thread("SmartPointerDemo") {}
SmartPointerDemo() = default;
void run() override;
private:
static NamedLogger log;
};
#endif

View File

@ -1,5 +1,9 @@
#include "StringDemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
NamedLogger StringDemo::log = NamedLogger("StringDemo");
void StringDemo::run() {
Util::System::out.lock();
@ -55,5 +59,6 @@ void StringDemo::run() {
<< static_cast<int>(String::string(arr) == str2) << endl;
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -4,10 +4,13 @@
#include "kernel/system/Globals.h"
class StringDemo : public Kernel::Thread {
public:
StringDemo(const StringDemo& copy) = delete;
private:
static NamedLogger log;
StringDemo() : Thread("StringDemo") {}
public:
StringDemo(const StringDemo &copy) = delete;
StringDemo() = default;
void run() override;
};

View File

@ -10,6 +10,8 @@
#include "TextDemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
void TextDemo::run() {
@ -40,5 +42,6 @@ void TextDemo::run() {
Util::System::out << endl;
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -16,9 +16,9 @@
class TextDemo : public Kernel::Thread {
public:
TextDemo(const TextDemo& copy) = delete;
TextDemo(const TextDemo &copy) = delete;
TextDemo() : Thread("TextDemo") {}
TextDemo() = default;
void run() override;
};

View File

@ -10,6 +10,8 @@
#include "VBEdemo.h"
#include "bmp_hhu.cc"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
/*****************************************************************************
* Methode: VBEdemo::linInterPol1D *
@ -17,7 +19,9 @@
* Beschreibung: Farbwert in einer Dimension interpoliert berechnen. *
*****************************************************************************/
int VBEdemo::linInterPol1D(int x, int xr, int l, int r) {
return ((((l >> 16) * (xr - x) + (r >> 16) * x) / xr) << 16) | (((((l >> 8) & 0xFF) * (xr - x) + ((r >> 8) & 0xFF) * x) / xr) << 8) | (((l & 0xFF) * (xr - x) + (r & 0xFF) * x) / xr);
return ((((l >> 16) * (xr - x) + (r >> 16) * x) / xr) << 16) |
(((((l >> 8) & 0xFF) * (xr - x) + ((r >> 8) & 0xFF) * x) / xr) << 8) |
(((l & 0xFF) * (xr - x) + (r & 0xFF) * x) / xr);
}
/*****************************************************************************
@ -56,7 +60,7 @@ void VBEdemo::drawBitmap() {
unsigned int sprite_width = hhu.width;
unsigned int sprite_height = hhu.height;
unsigned int sprite_bpp = hhu.bytes_per_pixel;
const uint8_t* sprite_pixel = reinterpret_cast<const uint8_t*>(hhu.pixel_data);
const uint8_t *sprite_pixel = reinterpret_cast<const uint8_t *>(hhu.pixel_data);
/* Hier muss Code eingefuegt werden */
@ -98,5 +102,6 @@ void VBEdemo::run() {
while (running) {}
// selbst terminieren
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -17,16 +17,18 @@ class VBEdemo : public Kernel::Thread {
private:
// Hilfsfunktionen fuer drawColors()
static int linInterPol1D(int x, int xr, int l, int r);
static int linInterPol2D(int x, int y, int lt, int rt, int lb, int rb);
public:
VBEdemo(const VBEdemo& copy) = delete; // Verhindere Kopieren
VBEdemo(const VBEdemo &copy) = delete; // Verhindere Kopieren
// Gib dem Anwendungsthread einen Stack.
VBEdemo() : Thread("VBEdemo") {}
VBEdemo() = default;
~VBEdemo() override {
Kernel::allocator.free(reinterpret_cast<void*>(Kernel::vesa.hfb)); // Memory is allocated after every start and never deleted, so add that
Kernel::allocator.free(
reinterpret_cast<void *>(Kernel::vesa.hfb)); // Memory is allocated after every start and never deleted, so add that
Device::VESA::initTextMode();
}

View File

@ -1,5 +1,9 @@
#include "VectorDemo.h"
#include "lib/util/System.h"
#include "kernel/system/System.h"
#include "kernel/service/SchedulerService.h"
NamedLogger VectorDemo::log = NamedLogger("VectorDemo");
void print(OutStream &os, const Container::Vector<int> &list) {
os << "Printing List: ";
@ -107,5 +111,6 @@ void VectorDemo::run() {
}
Util::System::out.unlock();
Kernel::scheduler.exit();
auto &schedulerService = Kernel::System::getService<Kernel::SchedulerService>();
schedulerService.exit();
}

View File

@ -7,11 +7,14 @@
class VectorDemo : public Kernel::Thread {
public:
VectorDemo(const VectorDemo& copy) = delete;
VectorDemo(const VectorDemo &copy) = delete;
VectorDemo() : Thread("VectorDemo") {}
VectorDemo() = default;
void run() override;
private:
static NamedLogger log;
};
#endif