add vorgabe09
This commit is contained in:
@ -22,6 +22,9 @@ public:
|
||||
IdleThread() {}
|
||||
|
||||
void run() override {
|
||||
// Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert
|
||||
scheduler.setInitialized();
|
||||
|
||||
while (true) {
|
||||
scheduler.yield();
|
||||
// kout << "Idle!" << endl;
|
||||
|
||||
@ -22,7 +22,8 @@ void Scheduler::schedule() {
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
Thread* idle = new IdleThread();
|
||||
this->readyQueue.enqueue(idle);
|
||||
// this->readyQueue.enqueue(idle);
|
||||
this->ready(idle);
|
||||
|
||||
/* Bevor diese Methode anufgerufen wird, muss zumindest der Idle-Thread
|
||||
* in der Queue eingefuegt worden sein.
|
||||
@ -44,7 +45,13 @@ void Scheduler::ready(Thread* that) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
// Thread-Wechsel durch PIT verhindern
|
||||
cpu.disable_int ();
|
||||
|
||||
this->readyQueue.enqueue(that);
|
||||
|
||||
// Thread-Wechsel durch PIT jetzt wieder erlauben
|
||||
cpu.enable_int ();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -59,8 +66,14 @@ void Scheduler::exit() {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
// Thread-Wechsel durch PIT verhindern
|
||||
cpu.disable_int ();
|
||||
|
||||
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
||||
this->dispatch(next);
|
||||
|
||||
// Interrupts werden in Thread_switch in Thread.asm wieder zugelassen
|
||||
// dispatch kehr nicht zurueck
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -78,7 +91,13 @@ void Scheduler::kill(Thread* that) {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
// Thread-Wechsel durch PIT verhindern
|
||||
cpu.disable_int ();
|
||||
|
||||
this->readyQueue.remove(that);
|
||||
|
||||
// Thread-Wechsel durch PIT jetzt wieder erlauben
|
||||
cpu.enable_int ();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -96,6 +115,9 @@ void Scheduler::yield() {
|
||||
|
||||
/* hier muss Code eingefuegt werden */
|
||||
|
||||
// Thread-Wechsel durch PIT verhindern
|
||||
cpu.disable_int ();
|
||||
|
||||
// When only one thread exists (IdleThread) it can't yield as the readyqueue becomes empty
|
||||
// and this is not handled anywhere else
|
||||
if (this->readyQueue.isEmpty()) {
|
||||
@ -106,4 +128,20 @@ void Scheduler::yield() {
|
||||
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
||||
this->readyQueue.enqueue(this->get_active());
|
||||
this->dispatch(next);
|
||||
|
||||
// Thread-Wechsel durch PIT jetzt wieder erlauben
|
||||
cpu.enable_int ();
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Methode: Scheduler::preempt *
|
||||
*---------------------------------------------------------------------------*
|
||||
* Beschreibung: Diese Funktion wird aus der ISR des PITs aufgerufen und *
|
||||
* schaltet auf den naechsten Thread um, sofern einer vor- *
|
||||
* handen ist. *
|
||||
*****************************************************************************/
|
||||
void Scheduler::preempt () {
|
||||
|
||||
/* Hier muss Code eingefuegt werden */
|
||||
|
||||
}
|
||||
|
||||
@ -22,8 +22,20 @@ private:
|
||||
|
||||
Queue readyQueue; // auf die CPU wartende Threads
|
||||
|
||||
// Scheduler wird evt. von einer Unterbrechung vom Zeitgeber gerufen,
|
||||
// bevor er initialisiert wurde
|
||||
bool initialized;
|
||||
|
||||
public:
|
||||
Scheduler() {}
|
||||
Scheduler() : initialized(false) {}
|
||||
|
||||
// Scheduler initialisiert?
|
||||
// Zeitgeber-Unterbrechung kommt evt. bevor der Scheduler fertig
|
||||
// intiialisiert wurde!
|
||||
bool isInitialized() { return initialized; }
|
||||
|
||||
// ruft nur der Idle-Thread (erster Thread der vom Scheduler gestartet wird)
|
||||
void setInitialized() { initialized = true; }
|
||||
|
||||
// Scheduler starten
|
||||
void schedule();
|
||||
@ -39,6 +51,10 @@ public:
|
||||
|
||||
// CPU freiwillig abgeben und Auswahl des naechsten Threads
|
||||
void yield();
|
||||
|
||||
|
||||
// Thread umschalten; wird aus der ISR des PITs gerufen
|
||||
void preempt ();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -70,6 +70,15 @@ void Thread_init(struct ThreadState* regs, unsigned int* stack, void (*kickoff)(
|
||||
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
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
||||
@ -15,6 +15,13 @@
|
||||
* ThreadState, in dem die Werte der nicht-fluechtigen *
|
||||
* Register gesichert werden koennen. *
|
||||
* *
|
||||
* Zusaetzlich zum vorhandenen freiwilligen Umschalten der *
|
||||
* CPU mit 'Thread_switch' gibt es nun ein forciertes Um- *
|
||||
* durch den Zeitgeber-Interrupt ausgeloest wird und in *
|
||||
* Assembler in startup.asm implementiert ist. Fuer das *
|
||||
* Zusammenspiel mit dem Scheduler ist die Methode *
|
||||
* 'prepare_preemption' in Scheduler.cc wichtig. *
|
||||
* *
|
||||
* Autor: Michael, Schoettner, HHU, 16.12.2016 *
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
@ -24,3 +24,7 @@ esi_offset: resd 1
|
||||
edi_offset: resd 1
|
||||
ebp_offset: resd 1
|
||||
esp_offset: resd 1
|
||||
eax_offset: resd 1
|
||||
ecx_offset: resd 1
|
||||
edx_offset: resd 1
|
||||
efl_offset: resd 1
|
||||
|
||||
@ -34,6 +34,12 @@ struct ThreadState {
|
||||
void* edi;
|
||||
void* ebp;
|
||||
void* esp;
|
||||
// nachfolgend die fluechtige Register
|
||||
// wichtig fuer preemptives Multitasking
|
||||
void *eax;
|
||||
void *ecx;
|
||||
void *edx;
|
||||
void *efl;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user