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 *
;*****************************************************************************
%include "kernel/corouts/Coroutine.inc"
%include "kernel/threads/Thread.inc"
; EXPORTIERTE FUNKTIONEN
[GLOBAL Coroutine_switch]
[GLOBAL Coroutine_start]
[GLOBAL Thread_switch]
[GLOBAL Thread_start]
; IMPLEMENTIERUNG DER FUNKTIONEN
@ -34,7 +34,7 @@
;; *REGS
;; ESP: RET ADDR
;; == Low address ==
Coroutine_start:
Thread_start:
; *
; * Hier muss Code eingefuegt werden
; *
@ -82,7 +82,7 @@ Coroutine_start:
;; *REGS_NOW
;; SP --> RET ADDR
;; == Low address ==
Coroutine_switch:
Thread_switch:
; *
; * Hier muss Code eingefuegt werden
; *

View File

@ -20,23 +20,25 @@
* 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
// extern "C" deklariert werden, da sie nicht dem Name-Mangeling von C++
// entsprechen.
extern "C" {
void Coroutine_start(struct CoroutineState* regs);
void Coroutine_switch(struct CoroutineState* regs_now, struct CoroutineState* reg_then);
void Thread_start(struct ThreadState* regs);
void Thread_switch(struct ThreadState* regs_now, struct ThreadState* reg_then);
}
unsigned int ThreadCnt = 0;
/*****************************************************************************
* Prozedur: Coroutine_init *
*---------------------------------------------------------------------------*
* Beschreibung: Bereitet den Kontext der Koroutine fuer den ersten *
* 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;
@ -80,7 +82,7 @@ void Coroutine_init(struct CoroutineState* regs, unsigned int* stack, void (*kic
* wuerde ein sinnloser Wert als Ruecksprungadresse *
* interpretiert werden und der Rechner abstuerzen. *
*****************************************************************************/
void kickoff(Coroutine* object) {
void kickoff(Thread* object) {
object->run();
// object->run() kehrt hoffentlich nie hierher zurueck
@ -95,8 +97,8 @@ void kickoff(Coroutine* object) {
* Parameter: *
* stack Stack für die neue Koroutine *
*****************************************************************************/
Coroutine::Coroutine(unsigned int* stack) {
Coroutine_init(&regs, stack, kickoff, this);
Thread::Thread() : stack(new unsigned int[1024]), tid(ThreadCnt++) {
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. *
*****************************************************************************/
void Coroutine::switchToNext() {
void Thread::switchTo(Thread& next) {
/* 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. *
*****************************************************************************/
void Coroutine::start() {
void Thread::start() {
/* hier muss Code eingefügt werden */
Coroutine_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;
Thread_start(&this->regs);
}

View File

@ -25,30 +25,27 @@
#include "lib/Chain.h"
class Thread : public Chain {
private:
Thread(const Thread &copy); // Verhindere Kopieren
Thread(const Thread& copy) = delete; // Verhindere Kopieren
private:
struct ThreadState regs;
unsigned int *stack;
public:
unsigned int tid; // Thread-ID (wird im Konstruktor vergeben)
unsigned int* stack;
public:
unsigned int tid; // Thread-ID (wird im Konstruktor vergeben)
Thread();
Thread () { }
// Thread aktivieren
void start ();
void start();
// Umschalten auf Thread 'next'
void switchTo (Thread& next);
void switchTo(Thread& next);
// Methode des Threads, muss in Sub-Klasse implementiert werden
virtual void run () = 0;
virtual void run() = 0;
~Thread ();
};
~Thread();
};
#endif

View File

@ -28,13 +28,12 @@
#ifndef __CoroutineState_include__
#define __CoroutineState_include__
struct CoroutineState {
void *ebx;
void *esi;
void *edi;
void *ebp;
void *esp;
struct ThreadState {
void* ebx;
void* esi;
void* edi;
void* ebp;
void* esp;
};
#endif