1

migrate coroutines to threads

This commit is contained in:
churl
2022-06-05 15:52:23 +02:00
parent 4840c91707
commit 717872c2d9
6 changed files with 36 additions and 102 deletions

View File

@ -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

View File

@ -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
; * ; *

View File

@ -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(&regs, stack, kickoff, this); Thread_init(&regs, 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;
} }

View File

@ -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 &copy); // 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

View File

@ -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