reformat
This commit is contained in:
@ -15,13 +15,12 @@
|
||||
#include "kernel/threads/Thread.h"
|
||||
|
||||
class IdleThread : public Thread {
|
||||
private:
|
||||
public:
|
||||
IdleThread(const Thread& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
public:
|
||||
IdleThread() : Thread("IdleThread") {}
|
||||
|
||||
void run() override {
|
||||
/*[[noreturn]]*/ void run() override {
|
||||
// Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert
|
||||
log.info() << "IdleThread enabled preemption" << endl;
|
||||
scheduler.enable_preemption(this->tid);
|
||||
|
||||
@ -19,8 +19,6 @@
|
||||
|
||||
class Scheduler {
|
||||
private:
|
||||
Scheduler(const Scheduler& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
NamedLogger log;
|
||||
|
||||
bse::vector<bse::unique_ptr<Thread>> ready_queue;
|
||||
@ -35,8 +33,8 @@ private:
|
||||
unsigned int idle_tid = 0U;
|
||||
|
||||
// Roughly the old dispatcher functionality
|
||||
void start(bse::vector<bse::unique_ptr<Thread>>::iterator next); // Start next without prev
|
||||
void switch_to(Thread* prev_raw, bse::vector<bse::unique_ptr<Thread>>::iterator next); // Switch from prev to next
|
||||
/*[[noreturn]]*/ void start(bse::vector<bse::unique_ptr<Thread>>::iterator next); // Start next without prev
|
||||
/*[[noreturn]]*/ void switch_to(Thread* prev_raw, bse::vector<bse::unique_ptr<Thread>>::iterator next); // Switch from prev to next
|
||||
|
||||
// Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird)
|
||||
void enable_preemption(unsigned int tid) { idle_tid = tid; }
|
||||
@ -45,6 +43,8 @@ private:
|
||||
void ready(bse::unique_ptr<Thread>&& thread);
|
||||
|
||||
public:
|
||||
Scheduler(const Scheduler& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
Scheduler() : log("SCHED"), ready_queue(true), block_queue(true) {} // lazy queues, wait for allocator
|
||||
|
||||
// The scheduler has to init the queues explicitly after the allocator is available
|
||||
@ -63,7 +63,7 @@ public:
|
||||
bool preemption_enabled() const { return idle_tid != 0U; }
|
||||
|
||||
// Scheduler starten
|
||||
void schedule();
|
||||
/*[[noreturn]]*/ void schedule();
|
||||
|
||||
// Helper that directly constructs the thread, then readys it
|
||||
template<typename T, typename... Args>
|
||||
@ -80,13 +80,13 @@ public:
|
||||
// NOTE: When a thread exits itself it will disappear...
|
||||
// Maybe put exited threads in an exited queue?
|
||||
// Then they would have to be acquired from there to exit...
|
||||
void exit();
|
||||
/* [[noreturn]] */ void exit(); // Returns on error because we don't have exceptions
|
||||
|
||||
// Thread mit 'Gewalt' terminieren
|
||||
void kill(unsigned int tid, bse::unique_ptr<Thread>* ptr);
|
||||
void kill(unsigned int tid) { kill(tid, nullptr); }
|
||||
|
||||
// Ask thread to exit
|
||||
// Asks thread to exit
|
||||
// NOTE: I had many problems with killing threads that were stuck in some semaphore
|
||||
// or were involved in any locking mechanisms, so with this a thread can make sure
|
||||
// to "set things right" before exiting itself (but could also be ignored)
|
||||
@ -94,13 +94,13 @@ public:
|
||||
void nice_kill(unsigned int tid) { nice_kill(tid, nullptr); }
|
||||
|
||||
// CPU freiwillig abgeben und Auswahl des naechsten Threads
|
||||
void yield();
|
||||
/* [[noreturn]] */ void yield(); // Returns when only the idle thread runs
|
||||
|
||||
// Thread umschalten; wird aus der ISR des PITs gerufen
|
||||
void preempt();
|
||||
/* [[noreturn]] */ void preempt(); // Returns when only the idle thread runs
|
||||
|
||||
// Blocks current thread (move to block_queue)
|
||||
void block();
|
||||
/* [[noreturn]] */ void block(); // Returns on error because we don't have exceptions
|
||||
|
||||
// Deblock by tid (move to ready_queue)
|
||||
void deblock(unsigned int tid);
|
||||
|
||||
@ -55,51 +55,10 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread*
|
||||
// Funktion muss daher dafuer sorgen, dass diese Adresse nie benoetigt
|
||||
// wird, sie darf also nicht terminieren, sonst kracht's.
|
||||
|
||||
// *(--sp) = (unsigned int*)object; // Parameter
|
||||
// I thought this syntax was a bit clearer than decrementing a pointer
|
||||
stack[-1] = (unsigned int)object;
|
||||
|
||||
// *(--sp) = (unsigned int*)0x131155; // Ruecksprungadresse (Dummy)
|
||||
stack[-2] = 0x131155U;
|
||||
|
||||
// Nun legen wir noch die Adresse der Funktion "kickoff" ganz oben auf
|
||||
// den Stack. Wenn dann bei der ersten Aktivierung dieser Koroutine der
|
||||
// Stackpointer so initialisiert wird, dass er auf diesen Eintrag
|
||||
// verweist, genuegt ein ret, um die Funktion kickoff zu starten.
|
||||
// Genauso sollen auch alle spaeteren Threadwechsel ablaufen.
|
||||
|
||||
// *(--sp) = (unsigned int*)kickoff; // Adresse
|
||||
stack[-3] = (unsigned int)kickoff;
|
||||
|
||||
// Initialisierung der Struktur ThreadState mit den Werten, die die
|
||||
// nicht-fluechtigen Register beim ersten Starten haben sollen.
|
||||
// Wichtig ist dabei nur der Stackpointer.
|
||||
|
||||
// NOTE: Old code before I used pusha/popa
|
||||
// regs->ebx = 0;
|
||||
// regs->esi = 0;
|
||||
// regs->edi = 0;
|
||||
// regs->ebp = 0;
|
||||
// regs->esp = sp; // esp now points to the location of the address of kickoff
|
||||
|
||||
// nachfolgend die fluechtige Register
|
||||
// wichtig fuer preemptives Multitasking
|
||||
// regs->eax = 0;
|
||||
// regs->ecx = 0;
|
||||
// regs->edx = 0;
|
||||
|
||||
// flags initialisieren
|
||||
// regs->efl = (void*)0x200; // Interrupt-Enable
|
||||
|
||||
// NOTE: New code with pusha/popa
|
||||
// unsigned int* temp = (unsigned int*)sp;
|
||||
// *(--sp) = 0; // EAX
|
||||
// *(--sp) = 0; // ECX
|
||||
// *(--sp) = 0; // EDX
|
||||
// *(--sp) = 0; // EBX
|
||||
// *(--sp) = (unsigned int*)temp; // ESP
|
||||
// *(--sp) = 0; // EBP
|
||||
// *(--sp) = 0; // ESI
|
||||
// *(--sp) = 0; // EDI
|
||||
stack[-4] = 0; // EAX
|
||||
stack[-5] = 0; // ECX
|
||||
stack[-6] = 0; // EDX
|
||||
@ -108,12 +67,8 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread*
|
||||
stack[-9] = 0; // EBP
|
||||
stack[-10] = 0; // ESI
|
||||
stack[-11] = 0; // EDI
|
||||
|
||||
// popf
|
||||
// *(--sp) = (unsigned int*)0x200; // Interrupt-Enable
|
||||
stack[-12] = 0x200U;
|
||||
|
||||
// *esp = (unsigned int)sp;
|
||||
*esp = (unsigned int)&stack[-12];
|
||||
}
|
||||
|
||||
@ -127,10 +82,10 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread*
|
||||
* wuerde ein sinnloser Wert als Ruecksprungadresse *
|
||||
* interpretiert werden und der Rechner abstuerzen. *
|
||||
*****************************************************************************/
|
||||
void kickoff(Thread* object) {
|
||||
[[noreturn]] void kickoff(Thread* object) {
|
||||
object->run();
|
||||
|
||||
// object->run() kehrt hoffentlich nie hierher zurueck
|
||||
// object->run() kehrt (hoffentlich) nie hierher zurueck
|
||||
while (true) {}
|
||||
}
|
||||
|
||||
|
||||
@ -32,8 +32,6 @@
|
||||
|
||||
class Thread {
|
||||
private:
|
||||
Thread(const Thread& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
unsigned int* stack;
|
||||
unsigned int esp;
|
||||
|
||||
@ -48,22 +46,24 @@ protected:
|
||||
friend class Scheduler; // Scheduler can access tid
|
||||
|
||||
public:
|
||||
Thread(const Thread& copy) = delete; // Verhindere Kopieren
|
||||
|
||||
virtual ~Thread() {
|
||||
log.info() << "Uninitialized thread, ID: " << dec << this->tid << " (" << name << ")" << endl;
|
||||
delete[] this->stack;
|
||||
}
|
||||
|
||||
// Thread aktivieren
|
||||
void start() const;
|
||||
/*[[noreturn]]*/ void start() const;
|
||||
|
||||
// Umschalten auf Thread 'next'
|
||||
void switchTo(Thread& next);
|
||||
/*[[noreturn]]*/ void switchTo(Thread& next);
|
||||
|
||||
// Ask thread to terminate itself
|
||||
void suicide() { running = false; }
|
||||
|
||||
// Methode des Threads, muss in Sub-Klasse implementiert werden
|
||||
virtual void run() = 0;
|
||||
[[noreturn]] virtual void run() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user