migrate coroutines to threads
This commit is contained in:
@ -1,52 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* *
|
|
||||||
* C O R O U T I N E *
|
|
||||||
* *
|
|
||||||
*---------------------------------------------------------------------------*
|
|
||||||
* Beschreibung: Implementierung eines Koroutinen-Konzepts. *
|
|
||||||
* Die Koroutinen sind miteinander verkettet, weswegen die *
|
|
||||||
* Klasse Coroutine ein Subtyp von 'Chain' ist. *
|
|
||||||
* *
|
|
||||||
* Im Konstruktor wird der initialie Kontext der Koroutine *
|
|
||||||
* eingerichtet. Mit 'start' wird ein Koroutine aktiviert. *
|
|
||||||
* Das Umschalten auf die naechste Koroutine erfolgt durch *
|
|
||||||
* Aufruf von 'switchToNext'. *
|
|
||||||
* *
|
|
||||||
* Um bei einem Koroutinenwechsel den Kontext sichern zu *
|
|
||||||
* koennen, enthaelt jedes Koroutinenobjekt eine Struktur *
|
|
||||||
* CoroutineState, in dem die Werte der nicht-fluechtigen *
|
|
||||||
* Register gesichert werden koennen. *
|
|
||||||
* *
|
|
||||||
* Autor: Michael, Schoettner, HHU, 13.08.2020 *
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef __Coroutine_include__
|
|
||||||
#define __Coroutine_include__
|
|
||||||
|
|
||||||
#include "kernel/corouts/CoroutineState.h"
|
|
||||||
#include "lib/Chain.h"
|
|
||||||
|
|
||||||
class Coroutine : public Chain {
|
|
||||||
|
|
||||||
private:
|
|
||||||
Coroutine(const Coroutine& copy) = delete; // Verhindere Kopieren
|
|
||||||
|
|
||||||
struct CoroutineState regs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Coroutine(unsigned int* stack);
|
|
||||||
|
|
||||||
// Coroutine aktivieren
|
|
||||||
void start();
|
|
||||||
|
|
||||||
// Auf die naechste Coroutine umschalten
|
|
||||||
void switchToNext();
|
|
||||||
|
|
||||||
// Methode der Coroutine, muss in Sub-Klasse implementiert werden
|
|
||||||
virtual void run() = 0;
|
|
||||||
|
|
||||||
// Verweis auf nächste Coroutine setzen
|
|
||||||
void setNext(Chain* next);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@ -12,12 +12,12 @@
|
|||||||
;* Autor: Olaf Spinczyk, TU Dortmund *
|
;* Autor: Olaf Spinczyk, TU Dortmund *
|
||||||
;*****************************************************************************
|
;*****************************************************************************
|
||||||
|
|
||||||
%include "kernel/corouts/Coroutine.inc"
|
%include "kernel/threads/Thread.inc"
|
||||||
|
|
||||||
; EXPORTIERTE FUNKTIONEN
|
; EXPORTIERTE FUNKTIONEN
|
||||||
|
|
||||||
[GLOBAL Coroutine_switch]
|
[GLOBAL Thread_switch]
|
||||||
[GLOBAL Coroutine_start]
|
[GLOBAL Thread_start]
|
||||||
|
|
||||||
; IMPLEMENTIERUNG DER FUNKTIONEN
|
; IMPLEMENTIERUNG DER FUNKTIONEN
|
||||||
|
|
||||||
@ -34,7 +34,7 @@
|
|||||||
;; *REGS
|
;; *REGS
|
||||||
;; ESP: RET ADDR
|
;; ESP: RET ADDR
|
||||||
;; == Low address ==
|
;; == Low address ==
|
||||||
Coroutine_start:
|
Thread_start:
|
||||||
; *
|
; *
|
||||||
; * Hier muss Code eingefuegt werden
|
; * Hier muss Code eingefuegt werden
|
||||||
; *
|
; *
|
||||||
@ -82,7 +82,7 @@ Coroutine_start:
|
|||||||
;; *REGS_NOW
|
;; *REGS_NOW
|
||||||
;; SP --> RET ADDR
|
;; SP --> RET ADDR
|
||||||
;; == Low address ==
|
;; == Low address ==
|
||||||
Coroutine_switch:
|
Thread_switch:
|
||||||
; *
|
; *
|
||||||
; * Hier muss Code eingefuegt werden
|
; * Hier muss Code eingefuegt werden
|
||||||
; *
|
; *
|
||||||
@ -20,23 +20,25 @@
|
|||||||
* Autor: Michael, Schoettner, HHU, 13.08.2020 *
|
* Autor: Michael, Schoettner, HHU, 13.08.2020 *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "kernel/corouts/Coroutine.h"
|
#include "kernel/threads/Thread.h"
|
||||||
|
|
||||||
// Funktionen, die auf der Assembler-Ebene implementiert werden, muessen als
|
// Funktionen, die auf der Assembler-Ebene implementiert werden, muessen als
|
||||||
// extern "C" deklariert werden, da sie nicht dem Name-Mangeling von C++
|
// extern "C" deklariert werden, da sie nicht dem Name-Mangeling von C++
|
||||||
// entsprechen.
|
// entsprechen.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
void Coroutine_start(struct CoroutineState* regs);
|
void Thread_start(struct ThreadState* regs);
|
||||||
void Coroutine_switch(struct CoroutineState* regs_now, struct CoroutineState* reg_then);
|
void Thread_switch(struct ThreadState* regs_now, struct ThreadState* reg_then);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ThreadCnt = 0;
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Prozedur: Coroutine_init *
|
* Prozedur: Coroutine_init *
|
||||||
*---------------------------------------------------------------------------*
|
*---------------------------------------------------------------------------*
|
||||||
* Beschreibung: Bereitet den Kontext der Koroutine fuer den ersten *
|
* Beschreibung: Bereitet den Kontext der Koroutine fuer den ersten *
|
||||||
* Aufruf vor. *
|
* Aufruf vor. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void Coroutine_init(struct CoroutineState* regs, unsigned int* stack, void (*kickoff)(Coroutine*), void* object) {
|
void Thread_init(struct ThreadState* regs, unsigned int* stack, void (*kickoff)(Thread*), void* object) {
|
||||||
|
|
||||||
register unsigned int** sp = (unsigned int**)stack;
|
register unsigned int** sp = (unsigned int**)stack;
|
||||||
|
|
||||||
@ -80,7 +82,7 @@ void Coroutine_init(struct CoroutineState* regs, unsigned int* stack, void (*kic
|
|||||||
* wuerde ein sinnloser Wert als Ruecksprungadresse *
|
* wuerde ein sinnloser Wert als Ruecksprungadresse *
|
||||||
* interpretiert werden und der Rechner abstuerzen. *
|
* interpretiert werden und der Rechner abstuerzen. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void kickoff(Coroutine* object) {
|
void kickoff(Thread* object) {
|
||||||
object->run();
|
object->run();
|
||||||
|
|
||||||
// object->run() kehrt hoffentlich nie hierher zurueck
|
// object->run() kehrt hoffentlich nie hierher zurueck
|
||||||
@ -95,8 +97,8 @@ void kickoff(Coroutine* object) {
|
|||||||
* Parameter: *
|
* Parameter: *
|
||||||
* stack Stack für die neue Koroutine *
|
* stack Stack für die neue Koroutine *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Coroutine::Coroutine(unsigned int* stack) {
|
Thread::Thread() : stack(new unsigned int[1024]), tid(ThreadCnt++) {
|
||||||
Coroutine_init(®s, stack, kickoff, this);
|
Thread_init(®s, stack + 1024, kickoff, this); // Stack grows from top to bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -104,11 +106,11 @@ Coroutine::Coroutine(unsigned int* stack) {
|
|||||||
*---------------------------------------------------------------------------*
|
*---------------------------------------------------------------------------*
|
||||||
* Beschreibung: Auf die nächste Koroutine umschalten. *
|
* Beschreibung: Auf die nächste Koroutine umschalten. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void Coroutine::switchToNext() {
|
void Thread::switchTo(Thread& next) {
|
||||||
|
|
||||||
/* hier muss Code eingefügt werden */
|
/* hier muss Code eingefügt werden */
|
||||||
|
|
||||||
Coroutine_switch(&this->regs, &((Coroutine*)this->next)->regs);
|
Thread_switch(&this->regs, &next.regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -116,21 +118,9 @@ void Coroutine::switchToNext() {
|
|||||||
*---------------------------------------------------------------------------*
|
*---------------------------------------------------------------------------*
|
||||||
* Beschreibung: Aktivierung der Koroutine. *
|
* Beschreibung: Aktivierung der Koroutine. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void Coroutine::start() {
|
void Thread::start() {
|
||||||
|
|
||||||
/* hier muss Code eingefügt werden */
|
/* hier muss Code eingefügt werden */
|
||||||
|
|
||||||
Coroutine_start(&this->regs);
|
Thread_start(&this->regs);
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* Methode: Coroutine::start *
|
|
||||||
*---------------------------------------------------------------------------*
|
|
||||||
* Beschreibung: Verweis auf nächste Koroutine setzen. *
|
|
||||||
*****************************************************************************/
|
|
||||||
void Coroutine::setNext(Chain* next) {
|
|
||||||
|
|
||||||
/* hier muss Code eingefügt werden */
|
|
||||||
|
|
||||||
this->next = next;
|
|
||||||
}
|
}
|
||||||
@ -25,30 +25,27 @@
|
|||||||
#include "lib/Chain.h"
|
#include "lib/Chain.h"
|
||||||
|
|
||||||
class Thread : public Chain {
|
class Thread : public Chain {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(const Thread ©); // Verhindere Kopieren
|
Thread(const Thread& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
private:
|
|
||||||
struct ThreadState regs;
|
struct ThreadState regs;
|
||||||
unsigned int *stack;
|
unsigned int* stack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int tid; // Thread-ID (wird im Konstruktor vergeben)
|
unsigned int tid; // Thread-ID (wird im Konstruktor vergeben)
|
||||||
|
|
||||||
|
Thread();
|
||||||
|
|
||||||
Thread () { }
|
|
||||||
|
|
||||||
// Thread aktivieren
|
// Thread aktivieren
|
||||||
void start ();
|
void start();
|
||||||
|
|
||||||
// Umschalten auf Thread 'next'
|
// Umschalten auf Thread 'next'
|
||||||
void switchTo (Thread& next);
|
void switchTo(Thread& next);
|
||||||
|
|
||||||
// Methode des Threads, muss in Sub-Klasse implementiert werden
|
// Methode des Threads, muss in Sub-Klasse implementiert werden
|
||||||
virtual void run () = 0;
|
virtual void run() = 0;
|
||||||
|
|
||||||
~Thread ();
|
~Thread();
|
||||||
|
};
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -28,13 +28,12 @@
|
|||||||
#ifndef __CoroutineState_include__
|
#ifndef __CoroutineState_include__
|
||||||
#define __CoroutineState_include__
|
#define __CoroutineState_include__
|
||||||
|
|
||||||
struct CoroutineState {
|
struct ThreadState {
|
||||||
void *ebx;
|
void* ebx;
|
||||||
void *esi;
|
void* esi;
|
||||||
void *edi;
|
void* edi;
|
||||||
void *ebp;
|
void* ebp;
|
||||||
void *esp;
|
void* esp;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Reference in New Issue
Block a user