changed a lot of small clang-tidy warnings
This commit is contained in:
@ -4,29 +4,29 @@
|
|||||||
// Can't initialize in constructor as memory management already needs working CGA for output
|
// Can't initialize in constructor as memory management already needs working CGA for output
|
||||||
// NOTE: This has to be called when memorymanagement is active
|
// NOTE: This has to be called when memorymanagement is active
|
||||||
void BufferedCGA::init(unsigned int pages) {
|
void BufferedCGA::init(unsigned int pages) {
|
||||||
this->scrollback_buffer = new ScrollbackBuffer(ROWS, pages); // No delete since it's only off when shutting the os down
|
this->scrollback_buffer = std::make_unique<ScrollbackBuffer>(ROWS, pages); // No delete since it's only off when shutting the os down
|
||||||
this->screen_buffer = new CGA::cga_page_t;
|
this->screen_buffer = std::make_unique<CGA::cga_page_t>();
|
||||||
|
|
||||||
if (this->scrollback_buffer == NULL || this->screen_buffer == NULL) {
|
if (this->scrollback_buffer == NULL || this->screen_buffer == NULL) {
|
||||||
if constexpr (DEBUG) kout << "Error initializing scrollback buffer" << endl;
|
if constexpr (DEBUG) { kout << "Error initializing scrollback buffer" << endl; }
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->initialized = true;
|
this->initialized = true;
|
||||||
if constexpr (DEBUG) kout << "Initialized scrollback buffer" << endl;
|
if constexpr (DEBUG) { kout << "Initialized scrollback buffer" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferedCGA::display_scrollback() {
|
void BufferedCGA::display_scrollback() {
|
||||||
if (this->initialized) {
|
if (this->initialized) {
|
||||||
if (this->scrollback == 0) {
|
if (this->scrollback == 0) {
|
||||||
// Use pagebuffer
|
// Use pagebuffer
|
||||||
mmem::memcpy<CGA::cga_page_t>((CGA::cga_page_t*)CGA_START, this->screen_buffer);
|
mmem::memcpy<CGA::cga_page_t>((CGA::cga_page_t*)CGA_START, this->screen_buffer.get());
|
||||||
} else {
|
} else {
|
||||||
// Use scrollback
|
// Use scrollback
|
||||||
this->scrollback_buffer->get((cga_line_t*)CGA_START, this->scrollback - 1);
|
this->scrollback_buffer->get((CGA::cga_line_t*)CGA_START, this->scrollback - 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if constexpr (DEBUG) kout << "ScrollbackBuffer not initialized" << endl;
|
if constexpr (DEBUG) { kout << "ScrollbackBuffer not initialized" << endl; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,9 +43,9 @@ void BufferedCGA::print(char* string, int n, unsigned char attrib) {
|
|||||||
|
|
||||||
void BufferedCGA::scrollup() {
|
void BufferedCGA::scrollup() {
|
||||||
if (this->initialized) {
|
if (this->initialized) {
|
||||||
this->scrollback_buffer->put((cga_line_t*)CGA_START);
|
this->scrollback_buffer->put((CGA::cga_line_t*)CGA_START);
|
||||||
} else {
|
} else {
|
||||||
if constexpr (DEBUG) kout << "ScrollbackBuffer not initialized" << endl;
|
if constexpr (DEBUG) { kout << "ScrollbackBuffer not initialized" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
CGA::scrollup();
|
CGA::scrollup();
|
||||||
@ -57,9 +57,9 @@ void BufferedCGA::clear() {
|
|||||||
|
|
||||||
if (this->initialized) {
|
if (this->initialized) {
|
||||||
this->scrollback_buffer->clear();
|
this->scrollback_buffer->clear();
|
||||||
mmem::zero<CGA::cga_page_t>(this->screen_buffer);
|
mmem::zero<CGA::cga_page_t>(this->screen_buffer.get());
|
||||||
} else {
|
} else {
|
||||||
if constexpr (DEBUG) kout << "ScrollbackBuffer not initialized" << endl;
|
if constexpr (DEBUG) { kout << "ScrollbackBuffer not initialized" << endl; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ void BufferedCGA::scroll_page_backward() {
|
|||||||
|
|
||||||
// If this is the first scrollback we have to save the current screen content
|
// If this is the first scrollback we have to save the current screen content
|
||||||
if (this->scrollback == 0) {
|
if (this->scrollback == 0) {
|
||||||
mmem::memcpy<CGA::cga_page_t>(this->screen_buffer, (CGA::cga_page_t*)CGA_START);
|
mmem::memcpy<CGA::cga_page_t>(this->screen_buffer.get(), (CGA::cga_page_t*)CGA_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
// current_page can be equal to scrollback_buffer->pages
|
// current_page can be equal to scrollback_buffer->pages
|
||||||
@ -78,7 +78,7 @@ void BufferedCGA::scroll_page_backward() {
|
|||||||
}
|
}
|
||||||
this->display_scrollback();
|
this->display_scrollback();
|
||||||
} else {
|
} else {
|
||||||
if constexpr (DEBUG) kout << "ScrollbackBuffer not initialized" << endl;
|
if constexpr (DEBUG) { kout << "ScrollbackBuffer not initialized" << endl; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +90,6 @@ void BufferedCGA::scroll_page_forward() {
|
|||||||
}
|
}
|
||||||
this->display_scrollback();
|
this->display_scrollback();
|
||||||
} else {
|
} else {
|
||||||
if constexpr (DEBUG) kout << "ScrollbackBuffer not initialized" << endl;
|
if constexpr (DEBUG) { kout << "ScrollbackBuffer not initialized" << endl; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "devices/CGA.h"
|
#include "devices/CGA.h"
|
||||||
#include "devices/Keyboard.h"
|
#include "devices/Keyboard.h"
|
||||||
#include "lib/ScrollbackBuffer.h"
|
#include "lib/ScrollbackBuffer.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// NOTE: I added this file, I don't know if it will be used till the end but right know it's nice to have
|
// NOTE: I added this file, I don't know if it will be used till the end but right know it's nice to have
|
||||||
|
|
||||||
@ -12,20 +13,14 @@
|
|||||||
// have to replace print with unbuffered_print or something, which I don't like.
|
// have to replace print with unbuffered_print or something, which I don't like.
|
||||||
class BufferedCGA : public CGA {
|
class BufferedCGA : public CGA {
|
||||||
private:
|
private:
|
||||||
ScrollbackBuffer* scrollback_buffer; // Contains previous pages
|
std::unique_ptr<ScrollbackBuffer> scrollback_buffer; // Contains previous pages
|
||||||
CGA::cga_page_t* screen_buffer; // Contains the current page separately from the scrollback.
|
std::unique_ptr<CGA::cga_page_t> screen_buffer; // Contains the current page separately from the scrollback.
|
||||||
bool initialized; // Don't do ScrollbackBuffer actions if not initialized
|
bool initialized; // Don't do ScrollbackBuffer actions if not initialized
|
||||||
|
|
||||||
BufferedCGA(const BufferedCGA&) = delete;
|
BufferedCGA(const BufferedCGA&) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BufferedCGA() : CGA(), initialized(false), scrollback(0) {};
|
BufferedCGA() : initialized(false), scrollback(0) {}
|
||||||
~BufferedCGA() {
|
|
||||||
if (this->initialized) {
|
|
||||||
delete this->scrollback_buffer;
|
|
||||||
delete this->screen_buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char scrollback; // The page that is displayed, public to enable page display
|
unsigned char scrollback; // The page that is displayed, public to enable page display
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ void CGA::setpos(int x, int y) {
|
|||||||
* *
|
* *
|
||||||
* Rückgabewerte: x und y *
|
* Rückgabewerte: x und y *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void CGA::getpos(int& x, int& y) {
|
void CGA::getpos(int& x, int& y) const {
|
||||||
|
|
||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ void CGA::show(int x, int y, char character, unsigned char attrib) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cga_char_t* pos = (cga_char_t*)(CGA_START + 2 * (x + y * COLUMNS));
|
cga_char_t* pos = (cga_char_t*)CGA_START + x + y * COLUMNS;
|
||||||
pos->cga_char = character;
|
pos->cga_char = character;
|
||||||
pos->cga_attribute = attrib;
|
pos->cga_attribute = attrib;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ void CGA::print(char* string, int n, unsigned char attrib) {
|
|||||||
int cursor_x, cursor_y; // Don't poll registers every stroke
|
int cursor_x, cursor_y; // Don't poll registers every stroke
|
||||||
this->getpos(cursor_x, cursor_y);
|
this->getpos(cursor_x, cursor_y);
|
||||||
|
|
||||||
for (unsigned short byte = 0; byte < n; ++byte) {
|
for (int byte = 0; byte < n; ++byte) {
|
||||||
char current = *(string + byte);
|
char current = *(string + byte);
|
||||||
if (current == '\n') {
|
if (current == '\n') {
|
||||||
cursor_x = 0;
|
cursor_x = 0;
|
||||||
@ -114,7 +114,9 @@ void CGA::print(char* string, int n, unsigned char attrib) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} else if (current == '\0') {
|
}
|
||||||
|
|
||||||
|
if (current == '\0') {
|
||||||
// Don't need to run to end if null terminated
|
// Don't need to run to end if null terminated
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -185,7 +187,7 @@ unsigned char CGA::attribute(CGA::color bg, CGA::color fg, bool blink) {
|
|||||||
|
|
||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
|
|
||||||
return blink << 7 // B0000000
|
return static_cast<int>(blink) << 7 // B0000000
|
||||||
| (bg & 0x7) << 4 // 0HHH0000 (Hintergrund)
|
| (bg & 0x7) << 4 // 0HHH0000 (Hintergrund)
|
||||||
| (fg & 0xF); // 0000VVVV (Vordergrund)
|
| (fg & 0xF); // 0000VVVV (Vordergrund)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,23 +16,23 @@
|
|||||||
|
|
||||||
#include "kernel/IOport.h"
|
#include "kernel/IOport.h"
|
||||||
#include "lib/MyStdLib.h"
|
#include "lib/MyStdLib.h"
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
class CGA {
|
class CGA {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOport index_port; // Auswahl eines Register der Grafikkarte
|
IOport index_port; // Auswahl eines Register der Grafikkarte
|
||||||
IOport data_port; // Lese-/Schreib-Zugriff auf Register der Grafikk.
|
IOport data_port; // Lese-/Schreib-Zugriff auf Register der Grafikk.
|
||||||
|
|
||||||
// Copy Konstrutkor unterbinden
|
// Copy Konstrutkor unterbinden
|
||||||
CGA(const CGA& copy);
|
CGA(const CGA& copy) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const char* CGA_START; // Startadresse des Buldschirmspeichers
|
// NOTE: I change CGA_START to this const because I think the address should be constant and macro-like,
|
||||||
|
// not the data at this address (we want that data to change).
|
||||||
|
static const unsigned int CGA_START = 0xb8000U;
|
||||||
|
|
||||||
// Konstruktur mit Initialisierung der Ports
|
// Konstruktur mit Initialisierung der Ports
|
||||||
CGA() : index_port(0x3d4), data_port(0x3d5) {
|
CGA() : index_port(0x3d4), data_port(0x3d5) {
|
||||||
CGA_START = (const char*)0xb8000;
|
|
||||||
|
|
||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
this->setpos(0, 0);
|
this->setpos(0, 0);
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ public:
|
|||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char cga_char;
|
char cga_char;
|
||||||
char cga_attribute;
|
unsigned char cga_attribute;
|
||||||
} cga_char_t;
|
} cga_char_t;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
cga_char_t cga_line[COLUMNS];
|
cga_char_t cga_line[COLUMNS];
|
||||||
@ -80,7 +80,7 @@ public:
|
|||||||
void setpos(int x, int y);
|
void setpos(int x, int y);
|
||||||
|
|
||||||
// Abfragen der Cursorpostion
|
// Abfragen der Cursorpostion
|
||||||
void getpos(int& x, int& y);
|
void getpos(int& x, int& y) const;
|
||||||
|
|
||||||
// Anzeige eines Zeichens mit Attribut an einer bestimmten Stelle
|
// Anzeige eines Zeichens mit Attribut an einer bestimmten Stelle
|
||||||
void show(int x, int y, char character, unsigned char attrib = STD_ATTR);
|
void show(int x, int y, char character, unsigned char attrib = STD_ATTR);
|
||||||
@ -96,7 +96,7 @@ public:
|
|||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
// Hilfsfunktion zur Erzeugung eines Attribut-Bytes
|
// Hilfsfunktion zur Erzeugung eines Attribut-Bytes
|
||||||
unsigned char attribute(CGA::color bg, CGA::color fg, bool blink);
|
static unsigned char attribute(CGA::color bg, CGA::color fg, bool blink);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
* verwendet werden, um eine Ausgabe zu erzwingen. *
|
* verwendet werden, um eine Ausgabe zu erzwingen. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void CGA_Stream::flush() {
|
void CGA_Stream::flush() {
|
||||||
print(buffer, pos, attribute(this->color_bg, this->color_fg, this->blink));
|
print((char*)buffer, pos, attribute(this->color_bg, this->color_fg, this->blink));
|
||||||
|
|
||||||
// TODO: Should not be reset like this
|
// TODO: Should not be reset like this
|
||||||
// Flushing resets attributes
|
// Flushing resets attributes
|
||||||
|
|||||||
@ -21,35 +21,28 @@
|
|||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
class fgc {
|
class fgc {
|
||||||
public:
|
public:
|
||||||
fgc() : fg(CGA::LIGHT_GREY) {};
|
fgc() : fg(CGA::LIGHT_GREY) {}
|
||||||
fgc(CGA::color fg) : fg(fg) {};
|
fgc(CGA::color fg) : fg(fg) {}
|
||||||
CGA::color fg;
|
CGA::color fg;
|
||||||
};
|
};
|
||||||
class bgc {
|
class bgc {
|
||||||
public:
|
public:
|
||||||
bgc() : bg(CGA::BLACK) {};
|
bgc() : bg(CGA::BLACK) {}
|
||||||
bgc(CGA::color bg) : bg(bg) {};
|
bgc(CGA::color bg) : bg(bg) {}
|
||||||
CGA::color bg;
|
CGA::color bg;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: I added this (changed this) to use BufferedCGA
|
// NOTE: I added this (changed this) to use BufferedCGA
|
||||||
class CGA_Stream : public OutStream, public BufferedCGA {
|
class CGA_Stream : public OutStream, public BufferedCGA {
|
||||||
// class CGA_Stream : public OutStream, public CGA {
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGA_Stream(CGA_Stream& copy); // Verhindere Kopieren
|
CGA_Stream(CGA_Stream& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGA::color color_fg;
|
CGA::color color_fg;
|
||||||
CGA::color color_bg;
|
CGA::color color_bg;
|
||||||
bool blink;
|
bool blink;
|
||||||
|
|
||||||
CGA_Stream() : OutStream(), BufferedCGA() {
|
CGA_Stream() : color_fg(CGA::LIGHT_GREY), color_bg(CGA::BLACK), blink(false) {
|
||||||
// CGA_Stream() : OutStream(), CGA() {
|
|
||||||
color_fg = CGA::LIGHT_GREY;
|
|
||||||
color_bg = CGA::BLACK;
|
|
||||||
blink = false;
|
|
||||||
|
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,16 +44,10 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Konstruktor: Allocator::Allocator *
|
* Konstruktor: Allocator::Allocator *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
Allocator::Allocator() {
|
Allocator::Allocator() : heap_start(HEAP_START), heap_end(HEAP_START + HEAP_SIZE), heap_size(HEAP_SIZE), initialized(1) {
|
||||||
// Groesse des Hauptspeichers (kann über das BIOS abgefragt werden,
|
// Groesse des Hauptspeichers (kann über das BIOS abgefragt werden,
|
||||||
// aber sehr umstaendlich, daher hier fest eingetragen
|
// aber sehr umstaendlich, daher hier fest eingetragen
|
||||||
total_mem = MEM_SIZE_DEF;
|
total_mem = MEM_SIZE_DEF;
|
||||||
|
|
||||||
heap_start = HEAP_START;
|
|
||||||
heap_end = HEAP_START + HEAP_SIZE;
|
|
||||||
heap_size = HEAP_SIZE;
|
|
||||||
|
|
||||||
initialized = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|||||||
@ -33,10 +33,13 @@
|
|||||||
#ifndef __Allocator_include__
|
#ifndef __Allocator_include__
|
||||||
#define __Allocator_include__
|
#define __Allocator_include__
|
||||||
|
|
||||||
class Allocator {
|
// TODO: Is it 8 or 4?
|
||||||
|
constexpr unsigned int BASIC_ALIGN = 8;
|
||||||
|
constexpr unsigned int HEAP_MIN_FREE_BLOCK_SIZE = 64; // min. Groesse eines freien Blocks
|
||||||
|
|
||||||
|
class Allocator {
|
||||||
private:
|
private:
|
||||||
Allocator(Allocator& copy); // Verhindere Kopieren
|
Allocator(Allocator& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int heap_start;
|
unsigned int heap_start;
|
||||||
|
|||||||
@ -18,5 +18,5 @@ IntDispatcher intdis; // Unterbrechungsverteilung
|
|||||||
PIC pic; // Interrupt-Controller
|
PIC pic; // Interrupt-Controller
|
||||||
unsigned int total_mem; // RAM total
|
unsigned int total_mem; // RAM total
|
||||||
// BumpAllocator allocator;
|
// BumpAllocator allocator;
|
||||||
// LinkedListAllocator allocator;
|
// LinkedListAllocator allocator;
|
||||||
TreeAllocator allocator;
|
TreeAllocator allocator;
|
||||||
|
|||||||
@ -28,7 +28,7 @@ extern IntDispatcher intdis; // Unterbrechungsverteilung
|
|||||||
extern PIC pic; // Interrupt-Controller
|
extern PIC pic; // Interrupt-Controller
|
||||||
extern unsigned int total_mem; // RAM total
|
extern unsigned int total_mem; // RAM total
|
||||||
// extern BumpAllocator allocator;
|
// extern BumpAllocator allocator;
|
||||||
// extern LinkedListAllocator allocator;
|
// extern LinkedListAllocator allocator;
|
||||||
extern TreeAllocator allocator;
|
extern TreeAllocator allocator;
|
||||||
|
|
||||||
constexpr bool DEBUG = true;
|
constexpr bool DEBUG = true;
|
||||||
|
|||||||
@ -25,7 +25,7 @@ void BumpAllocator::init() {
|
|||||||
this->allocations = 0;
|
this->allocations = 0;
|
||||||
this->next = (unsigned char*)heap_start;
|
this->next = (unsigned char*)heap_start;
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << "Initialized Bump Allocator" << endl;
|
if constexpr (DEBUG) { kout << "Initialized Bump Allocator" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -51,10 +51,10 @@ void* BumpAllocator::alloc(unsigned int req_size) {
|
|||||||
|
|
||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << "Requested " << hex << req_size << " Bytes" << endl;
|
if constexpr (DEBUG) { kout << "Requested " << hex << req_size << " Bytes" << endl; }
|
||||||
|
|
||||||
if (req_size + (unsigned int)this->next > this->heap_end) {
|
if (req_size + (unsigned int)this->next > this->heap_end) {
|
||||||
if constexpr (DEBUG) kout << " - More memory requested than available :(" << endl;
|
if constexpr (DEBUG) { kout << " - More memory requested than available :(" << endl; }
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ void* BumpAllocator::alloc(unsigned int req_size) {
|
|||||||
this->next = (unsigned char*)((unsigned int)this->next + req_size);
|
this->next = (unsigned char*)((unsigned int)this->next + req_size);
|
||||||
this->allocations = this->allocations + 1;
|
this->allocations = this->allocations + 1;
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << " - Allocated " << hex << req_size << " Bytes." << endl;
|
if constexpr (DEBUG) { kout << " - Allocated " << hex << req_size << " Bytes." << endl; }
|
||||||
|
|
||||||
return allocated;
|
return allocated;
|
||||||
}
|
}
|
||||||
@ -73,5 +73,5 @@ void* BumpAllocator::alloc(unsigned int req_size) {
|
|||||||
* Beschreibung: Nicht implementiert. *
|
* Beschreibung: Nicht implementiert. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void BumpAllocator::free(void* ptr) {
|
void BumpAllocator::free(void* ptr) {
|
||||||
if constexpr (DEBUG) kout << " mm_free: ptr= " << hex << (unsigned int)ptr << ", not supported" << endl;
|
if constexpr (DEBUG) { kout << " mm_free: ptr= " << hex << (unsigned int)ptr << ", not supported" << endl; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,15 +20,15 @@ private:
|
|||||||
unsigned char* next;
|
unsigned char* next;
|
||||||
unsigned int allocations;
|
unsigned int allocations;
|
||||||
|
|
||||||
BumpAllocator(Allocator& copy); // Verhindere Kopieren
|
BumpAllocator(Allocator& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BumpAllocator() {}; // Allocator() called implicitely in C++
|
BumpAllocator() {}; // Allocator() called implicitely in C++
|
||||||
|
|
||||||
void init();
|
void init() override;
|
||||||
void dump_free_memory();
|
void dump_free_memory() override;
|
||||||
void* alloc(unsigned int req_size);
|
void* alloc(unsigned int req_size) override;
|
||||||
void free(void* ptr);
|
void free(void* ptr) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -37,7 +37,7 @@ void LinkedListAllocator::init() {
|
|||||||
this->free_start->size = this->heap_size - sizeof(free_block_t);
|
this->free_start->size = this->heap_size - sizeof(free_block_t);
|
||||||
this->free_start->next = this->free_start; // Only one block, points to itself
|
this->free_start->next = this->free_start; // Only one block, points to itself
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << "Initialized LinkedList Allocator" << endl;
|
if constexpr (DEBUG) { kout << "Initialized LinkedList Allocator" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -75,10 +75,10 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
// NOTE: next pointer zeigt auf headeranfang, returned wird zeiger auf anfang des nutzbaren freispeichers
|
// NOTE: next pointer zeigt auf headeranfang, returned wird zeiger auf anfang des nutzbaren freispeichers
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << "Requested " << hex << req_size << " Bytes" << endl;
|
if constexpr (DEBUG) { kout << "Requested " << hex << req_size << " Bytes" << endl; }
|
||||||
|
|
||||||
if (this->free_start == NULL) {
|
if (this->free_start == NULL) {
|
||||||
if constexpr (DEBUG) kout << " - No free memory remaining :(" << endl;
|
if constexpr (DEBUG) { kout << " - No free memory remaining :(" << endl; }
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
unsigned int req_size_diff = (BASIC_ALIGN - req_size % BASIC_ALIGN) % BASIC_ALIGN;
|
unsigned int req_size_diff = (BASIC_ALIGN - req_size % BASIC_ALIGN) % BASIC_ALIGN;
|
||||||
unsigned int rreq_size = req_size + req_size_diff;
|
unsigned int rreq_size = req_size + req_size_diff;
|
||||||
if (req_size_diff > 0) {
|
if (req_size_diff > 0) {
|
||||||
if constexpr (DEBUG) kout << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl;
|
if constexpr (DEBUG) { kout << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
free_block_t* current = this->free_start;
|
free_block_t* current = this->free_start;
|
||||||
@ -117,7 +117,7 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
// Next-fit
|
// Next-fit
|
||||||
this->free_start = new_next;
|
this->free_start = new_next;
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << " - Allocated " << hex << rreq_size << " Bytes with cutting" << endl;
|
if constexpr (DEBUG) { kout << " - Allocated " << hex << rreq_size << " Bytes with cutting" << endl; }
|
||||||
} else {
|
} else {
|
||||||
// Block too small to be cut, allocate whole block
|
// Block too small to be cut, allocate whole block
|
||||||
|
|
||||||
@ -125,15 +125,15 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
this->free_start = current->next; // Pointer keeps pointing to current if last block
|
this->free_start = current->next; // Pointer keeps pointing to current if last block
|
||||||
if (this->free_start == current) {
|
if (this->free_start == current) {
|
||||||
// No free block remaining
|
// No free block remaining
|
||||||
if constexpr (DEBUG) kout << " - Disabled freelist" << endl;
|
if constexpr (DEBUG) { kout << " - Disabled freelist" << endl; }
|
||||||
this->free_start = NULL;
|
this->free_start = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << " - Allocated " << hex << current->size << " Bytes without cutting" << endl;
|
if constexpr (DEBUG) { kout << " - Allocated " << hex << current->size << " Bytes without cutting" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block aushängen
|
// Block aushängen
|
||||||
free_block_t* previous = this->find_previous_block(current);
|
free_block_t* previous = LinkedListAllocator::find_previous_block(current);
|
||||||
previous->next = current->next;
|
previous->next = current->next;
|
||||||
current->allocated = true;
|
current->allocated = true;
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
|
|||||||
current = current->next;
|
current = current->next;
|
||||||
} while (current != this->free_start); // Stop when arriving at the first block again
|
} while (current != this->free_start); // Stop when arriving at the first block again
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << " - More memory requested than available :(" << endl;
|
if constexpr (DEBUG) { kout << " - More memory requested than available :(" << endl; }
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << "Freeing " << hex << (unsigned int)ptr << endl;
|
if constexpr (DEBUG) { kout << "Freeing " << hex << (unsigned int)ptr << endl; }
|
||||||
|
|
||||||
free_block_t* block_start = (free_block_t*)((unsigned int)ptr - sizeof(free_block_t));
|
free_block_t* block_start = (free_block_t*)((unsigned int)ptr - sizeof(free_block_t));
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
block_start->allocated = false;
|
block_start->allocated = false;
|
||||||
block_start->next = block_start;
|
block_start->next = block_start;
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << " - Enabling freelist with one block" << endl;
|
if constexpr (DEBUG) { kout << " - Enabling freelist with one block" << endl; }
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
next_free = next_free->next;
|
next_free = next_free->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_block_t* previous_free = this->find_previous_block(next_free);
|
free_block_t* previous_free = LinkedListAllocator::find_previous_block(next_free);
|
||||||
free_block_t* previous_free_next =
|
free_block_t* previous_free_next =
|
||||||
(free_block_t*)((unsigned int)previous_free + sizeof(free_block_t) + previous_free->size);
|
(free_block_t*)((unsigned int)previous_free + sizeof(free_block_t) + previous_free->size);
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
// Try to merge forward ========================================================================
|
// Try to merge forward ========================================================================
|
||||||
if (next_block == next_free) {
|
if (next_block == next_free) {
|
||||||
if constexpr (DEBUG) kout << " - Merging block forward" << endl;
|
if constexpr (DEBUG) { kout << " - Merging block forward" << endl; }
|
||||||
|
|
||||||
// Current and next adjacent block can be merged
|
// Current and next adjacent block can be merged
|
||||||
// [previous_free | previous_free_next | <> | block_start | next_free]
|
// [previous_free | previous_free_next | <> | block_start | next_free]
|
||||||
@ -220,7 +220,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
if (this->free_start == next_free) {
|
if (this->free_start == next_free) {
|
||||||
// next_free is now invalid after merge
|
// next_free is now invalid after merge
|
||||||
if constexpr (DEBUG) kout << " - Moving freelist start to " << hex << (unsigned int)block_start << endl;
|
if constexpr (DEBUG) { kout << " - Moving freelist start to " << hex << (unsigned int)block_start << endl; }
|
||||||
this->free_start = block_start;
|
this->free_start = block_start;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -236,7 +236,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
// Try to merge backward =====================================================================
|
// Try to merge backward =====================================================================
|
||||||
if (previous_free_next == block_start) {
|
if (previous_free_next == block_start) {
|
||||||
if constexpr (DEBUG) kout << " - Merging block backward" << endl;
|
if constexpr (DEBUG) { kout << " - Merging block backward" << endl; }
|
||||||
|
|
||||||
// Current and previous adjacent block can be merged
|
// Current and previous adjacent block can be merged
|
||||||
// [previous_free | block_start]
|
// [previous_free | block_start]
|
||||||
@ -249,7 +249,7 @@ void LinkedListAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
if (this->free_start == block_start) {
|
if (this->free_start == block_start) {
|
||||||
// block_start is now invalid after merge
|
// block_start is now invalid after merge
|
||||||
if constexpr (DEBUG) kout << " - Moving freelist start to " << hex << (unsigned int)previous_free << endl;
|
if constexpr (DEBUG) { kout << " - Moving freelist start to " << hex << (unsigned int)previous_free << endl; }
|
||||||
this->free_start = previous_free;
|
this->free_start = previous_free;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,10 +14,6 @@
|
|||||||
|
|
||||||
#include "kernel/Allocator.h"
|
#include "kernel/Allocator.h"
|
||||||
|
|
||||||
// TODO: Is it 8 or 4?
|
|
||||||
#define BASIC_ALIGN 8
|
|
||||||
#define HEAP_MIN_FREE_BLOCK_SIZE 64 // min. Groesse eines freien Blocks
|
|
||||||
|
|
||||||
// Format eines freien Blocks, 4 + 4 + 4 Byte
|
// Format eines freien Blocks, 4 + 4 + 4 Byte
|
||||||
typedef struct free_block {
|
typedef struct free_block {
|
||||||
bool allocated; // NOTE: I added this to allow easier merging of free blocks:
|
bool allocated; // NOTE: I added this to allow easier merging of free blocks:
|
||||||
@ -37,21 +33,21 @@ private:
|
|||||||
// freie Bloecke werden verkettet
|
// freie Bloecke werden verkettet
|
||||||
struct free_block* free_start;
|
struct free_block* free_start;
|
||||||
|
|
||||||
LinkedListAllocator(Allocator& copy); // Verhindere Kopieren
|
LinkedListAllocator(Allocator& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
// Traverses the whole list forward till previous block is reached.
|
// Traverses the whole list forward till previous block is reached.
|
||||||
// This can only be called on free blocks as allocated blocks
|
// This can only be called on free blocks as allocated blocks
|
||||||
// aren't reachable from the freelist.
|
// aren't reachable from the freelist.
|
||||||
struct free_block* find_previous_block(struct free_block*);
|
static struct free_block* find_previous_block(struct free_block*);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LinkedListAllocator() {};
|
LinkedListAllocator() {}
|
||||||
|
|
||||||
void init();
|
void init() override;
|
||||||
void dump_free_memory();
|
void dump_free_memory() override;
|
||||||
void* alloc(unsigned int req_size);
|
void* alloc(unsigned int req_size) override;
|
||||||
void free(void* ptr);
|
void free(void* ptr) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -14,26 +14,22 @@ void TreeAllocator::init() {
|
|||||||
this->free_start->next = (list_block_t*)this->free_start;
|
this->free_start->next = (list_block_t*)this->free_start;
|
||||||
this->free_start->previous = (list_block_t*)this->free_start;
|
this->free_start->previous = (list_block_t*)this->free_start;
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << "Initialized Tree Allocator" << endl;
|
if constexpr (DEBUG) { kout << "Initialized Tree Allocator" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeAllocator::dump_free_memory() {
|
void TreeAllocator::dump_free_memory() {
|
||||||
kout << "Free Memory:" << endl;
|
kout << "Free Memory:" << endl;
|
||||||
this->dump_free_memory(this->free_start);
|
list_block_t* current = (list_block_t*)this->heap_start;
|
||||||
}
|
do {
|
||||||
|
if (!current->allocated) {
|
||||||
void TreeAllocator::dump_free_memory(tree_block_t* node) {
|
kout << " - Free Block at " << (unsigned int)current << ", Size: " << (unsigned int)current->next - (unsigned int)current << endl;
|
||||||
if (node == NULL) {
|
}
|
||||||
return;
|
current = current->next;
|
||||||
}
|
} while ((unsigned int)current != this->heap_start);
|
||||||
|
|
||||||
this->dump_free_memory(node->left);
|
|
||||||
kout << " - Free Block at " << hex << (unsigned int)node << " (" << hex << this->get_size(node) << " Byte)" << endl;
|
|
||||||
this->dump_free_memory(node->right);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* TreeAllocator::alloc(unsigned int req_size) {
|
void* TreeAllocator::alloc(unsigned int req_size) {
|
||||||
if constexpr (DEBUG) kout << "Requested " << dec << req_size << " Bytes" << endl;
|
if constexpr (DEBUG) { kout << "Requested " << dec << req_size << " Bytes" << endl; }
|
||||||
|
|
||||||
// Round to word borders + tree_block size
|
// Round to word borders + tree_block size
|
||||||
unsigned int rreq_size = req_size;
|
unsigned int rreq_size = req_size;
|
||||||
@ -41,35 +37,35 @@ void* TreeAllocator::alloc(unsigned int req_size) {
|
|||||||
// the list_block_t is part of every block, but when freeing
|
// the list_block_t is part of every block, but when freeing
|
||||||
// memory we need enough space to store the rbt metadata
|
// memory we need enough space to store the rbt metadata
|
||||||
rreq_size = sizeof(tree_block_t) - sizeof(list_block_t);
|
rreq_size = sizeof(tree_block_t) - sizeof(list_block_t);
|
||||||
if constexpr (DEBUG) kout << " - Increased block size for rbt metadata" << endl;
|
if constexpr (DEBUG) { kout << " - Increased block size for rbt metadata" << endl; }
|
||||||
}
|
}
|
||||||
unsigned int req_size_diff = (BASIC_ALIGN - rreq_size % BASIC_ALIGN) % BASIC_ALIGN;
|
unsigned int req_size_diff = (BASIC_ALIGN - rreq_size % BASIC_ALIGN) % BASIC_ALIGN;
|
||||||
rreq_size = rreq_size + req_size_diff;
|
rreq_size = rreq_size + req_size_diff;
|
||||||
if (req_size_diff > 0) {
|
if (req_size_diff > 0) {
|
||||||
if constexpr (DEBUG) kout << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl;
|
if constexpr (DEBUG) { kout << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finds smallest block that is large enough
|
// Finds smallest block that is large enough
|
||||||
tree_block_t* best_fit = this->rbt_search_bestfit(rreq_size);
|
tree_block_t* best_fit = this->rbt_search_bestfit(rreq_size);
|
||||||
if (best_fit == NULL) {
|
if (best_fit == NULL) {
|
||||||
if constexpr (DEBUG) kout << " - No block found" << endl;
|
if constexpr (DEBUG) { kout << " - No block found" << endl; }
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (best_fit->allocated) {
|
if (best_fit->allocated) {
|
||||||
// Something went really wrong
|
// Something went really wrong
|
||||||
if constexpr (DEBUG) kout << " - Block already allocated :(" << endl;
|
if constexpr (DEBUG) { kout << " - Block already allocated :(" << endl; }
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
best_fit->allocated = true;
|
best_fit->allocated = true;
|
||||||
unsigned int size = this->get_size(best_fit);
|
unsigned int size = this->get_size(best_fit);
|
||||||
if constexpr (DEBUG) kout << " - Found best-fit: " << hex << (unsigned int)best_fit << endl;
|
if constexpr (DEBUG) { kout << " - Found best-fit: " << hex << (unsigned int)best_fit << endl; }
|
||||||
|
|
||||||
// Remove the block first so we can insert correctly when cutting
|
// Remove the block first so we can insert correctly when cutting
|
||||||
// kout << " - Removing block from freelist" << endl;
|
// kout << " - Removing block from freelist" << endl;
|
||||||
this->rbt_remove(best_fit);
|
this->rbt_remove(best_fit);
|
||||||
if (size > HEAP_MIN_FREE_BLOCK_SIZE + rreq_size + sizeof(list_block_t)) {
|
if (size > HEAP_MIN_FREE_BLOCK_SIZE + rreq_size + sizeof(list_block_t)) {
|
||||||
// Block can be cut
|
// Block can be cut
|
||||||
if constexpr (DEBUG) kout << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl;
|
if constexpr (DEBUG) { kout << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl; }
|
||||||
|
|
||||||
// [best_fit_start | sizeof(list_block_t) | rreq_size | new_block_start]
|
// [best_fit_start | sizeof(list_block_t) | rreq_size | new_block_start]
|
||||||
tree_block_t* new_block = (tree_block_t*)((char*)best_fit + sizeof(list_block_t) + rreq_size);
|
tree_block_t* new_block = (tree_block_t*)((char*)best_fit + sizeof(list_block_t) + rreq_size);
|
||||||
@ -80,15 +76,15 @@ void* TreeAllocator::alloc(unsigned int req_size) {
|
|||||||
// Don't cut block
|
// Don't cut block
|
||||||
// The block is already correctly positioned in the linked list so we only
|
// The block is already correctly positioned in the linked list so we only
|
||||||
// need to remove it from the freelist, which is done for both cases
|
// need to remove it from the freelist, which is done for both cases
|
||||||
if constexpr (DEBUG) kout << " - Allocating " << dec << rreq_size << " Bytes without cutting" << endl;
|
if constexpr (DEBUG) { kout << " - Allocating " << dec << rreq_size << " Bytes without cutting" << endl; }
|
||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (DEBUG) kout << " - Returned address " << hex << (unsigned int)((char*)best_fit + sizeof(list_block_t)) << endl;
|
if constexpr (DEBUG) { kout << " - Returned address " << hex << (unsigned int)((char*)best_fit + sizeof(list_block_t)) << endl; }
|
||||||
return (void*)((char*)best_fit + sizeof(list_block_t));
|
return (void*)((char*)best_fit + sizeof(list_block_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeAllocator::free(void* ptr) {
|
void TreeAllocator::free(void* ptr) {
|
||||||
if constexpr (DEBUG) kout << "Freeing " << hex << (unsigned int)ptr << endl;
|
if constexpr (DEBUG) { kout << "Freeing " << hex << (unsigned int)ptr << endl; }
|
||||||
|
|
||||||
list_block_t* block = (list_block_t*)((char*)ptr - sizeof(list_block_t));
|
list_block_t* block = (list_block_t*)((char*)ptr - sizeof(list_block_t));
|
||||||
if (!block->allocated) {
|
if (!block->allocated) {
|
||||||
@ -107,7 +103,7 @@ void TreeAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
if (!next->allocated) {
|
if (!next->allocated) {
|
||||||
// Merge forward
|
// Merge forward
|
||||||
if constexpr (DEBUG) kout << " - Merging forward" << endl;
|
if constexpr (DEBUG) { kout << " - Merging forward" << endl; }
|
||||||
|
|
||||||
// Remove the next block from all lists as it is now part of our freed block
|
// Remove the next block from all lists as it is now part of our freed block
|
||||||
this->dll_remove(next);
|
this->dll_remove(next);
|
||||||
@ -120,7 +116,7 @@ void TreeAllocator::free(void* ptr) {
|
|||||||
|
|
||||||
if (!previous->allocated) {
|
if (!previous->allocated) {
|
||||||
// Merge backward
|
// Merge backward
|
||||||
if constexpr (DEBUG) kout << " - Merging backward" << endl;
|
if constexpr (DEBUG) { kout << " - Merging backward" << endl; }
|
||||||
|
|
||||||
// Remove the current block from all lists as it is now part of the previous block
|
// Remove the current block from all lists as it is now part of the previous block
|
||||||
// It doesn't have to be removed from rbt as it wasn't in there as it was allocated before
|
// It doesn't have to be removed from rbt as it wasn't in there as it was allocated before
|
||||||
|
|||||||
@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
#include "kernel/Allocator.h"
|
#include "kernel/Allocator.h"
|
||||||
|
|
||||||
#define HEAP_MIN_FREE_BLOCK_SIZE 64 // min. Groesse eines freien Blocks
|
|
||||||
#define BASIC_ALIGN 8
|
|
||||||
|
|
||||||
// NOTE: I added this file
|
// NOTE: I added this file
|
||||||
// NOTE: I can't imagine that this is very fast with all the tree logic?
|
// NOTE: I can't imagine that this is very fast with all the tree logic?
|
||||||
|
|
||||||
@ -40,7 +37,7 @@ private:
|
|||||||
// Root of the rbt
|
// Root of the rbt
|
||||||
tree_block_t* free_start;
|
tree_block_t* free_start;
|
||||||
|
|
||||||
TreeAllocator(Allocator& copy); // Verhindere Kopieren
|
TreeAllocator(Allocator& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
// Returns the size of the usable memory of a block
|
// Returns the size of the usable memory of a block
|
||||||
unsigned int get_size(list_block_t* block) const;
|
unsigned int get_size(list_block_t* block) const;
|
||||||
@ -50,7 +47,7 @@ private:
|
|||||||
|
|
||||||
// NOTE: Would be nice to have this stuff somewhere else for general use,
|
// NOTE: Would be nice to have this stuff somewhere else for general use,
|
||||||
// but that would require different rbt_node/dll_node structures.
|
// but that would require different rbt_node/dll_node structures.
|
||||||
// If I need this again later I should look into it.
|
// If I need this again later I should move it.
|
||||||
void rbt_rot_l(tree_block_t* x);
|
void rbt_rot_l(tree_block_t* x);
|
||||||
void rbt_rot_r(tree_block_t* x);
|
void rbt_rot_r(tree_block_t* x);
|
||||||
void rbt_transplant(tree_block_t* a, tree_block_t* b);
|
void rbt_transplant(tree_block_t* a, tree_block_t* b);
|
||||||
@ -71,10 +68,10 @@ private:
|
|||||||
public:
|
public:
|
||||||
TreeAllocator() {};
|
TreeAllocator() {};
|
||||||
|
|
||||||
void init();
|
void init() override;
|
||||||
void dump_free_memory();
|
void dump_free_memory() override;
|
||||||
void* alloc(unsigned int req_size);
|
void* alloc(unsigned int req_size) override;
|
||||||
void free(void* ptr);
|
void free(void* ptr) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -197,7 +197,7 @@ void TreeAllocator::rbt_remove(tree_block_t* z) {
|
|||||||
// fix the rb tree modified by the delete operation
|
// fix the rb tree modified by the delete operation
|
||||||
void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
|
void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
|
||||||
tree_block_t* s;
|
tree_block_t* s;
|
||||||
while (x != this->free_start && x->red == false) {
|
while (x != this->free_start && !x->red) {
|
||||||
if (x == x->parent->left) {
|
if (x == x->parent->left) {
|
||||||
s = x->parent->right;
|
s = x->parent->right;
|
||||||
if (s->red) {
|
if (s->red) {
|
||||||
@ -238,7 +238,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
|
|||||||
s = x->parent->left;
|
s = x->parent->left;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s->right->red && !s->right->red) {
|
if (!s->right->red) {
|
||||||
// case 3.2
|
// case 3.2
|
||||||
s->red = true;
|
s->red = true;
|
||||||
x = x->parent;
|
x = x->parent;
|
||||||
@ -264,6 +264,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
|
|||||||
}
|
}
|
||||||
// END copy from algorithmtutorprograms
|
// END copy from algorithmtutorprograms
|
||||||
|
|
||||||
|
// NOTE: This is recursive and depends on luck
|
||||||
tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, unsigned int req_size) {
|
tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, unsigned int req_size) {
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -275,7 +276,9 @@ tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, unsigned int
|
|||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
} else if (req_size > this->get_size(node)) {
|
}
|
||||||
|
|
||||||
|
if (req_size > this->get_size(node)) {
|
||||||
if (node->right != NULL && this->get_size(node->right) >= req_size) {
|
if (node->right != NULL && this->get_size(node->right) >= req_size) {
|
||||||
return this->rbt_search_bestfit(node->right, req_size);
|
return this->rbt_search_bestfit(node->right, req_size);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,9 +29,8 @@
|
|||||||
class Coroutine : public Chain {
|
class Coroutine : public Chain {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Coroutine(const Coroutine& copy); // Verhindere Kopieren
|
Coroutine(const Coroutine& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
private:
|
|
||||||
struct CoroutineState regs;
|
struct CoroutineState regs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -15,13 +15,13 @@
|
|||||||
class ISR {
|
class ISR {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ISR (const ISR ©); // Verhindere Kopieren
|
ISR(const ISR& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ISR () {}
|
ISR() {}
|
||||||
|
|
||||||
// Unterbrechungsbehandlungsroutine
|
// Unterbrechungsbehandlungsroutine
|
||||||
virtual void trigger () = 0;
|
virtual void trigger() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -94,7 +94,7 @@ int IntDispatcher::report(unsigned int vector) {
|
|||||||
ISR* isr = this->map[vector];
|
ISR* isr = this->map[vector];
|
||||||
|
|
||||||
if (isr == 0) {
|
if (isr == 0) {
|
||||||
if constexpr (DEBUG) kout << "No ISR registered for vector " << vector << endl;
|
if constexpr (DEBUG) { kout << "No ISR registered for vector " << vector << endl; }
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
class IntDispatcher {
|
class IntDispatcher {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IntDispatcher(const IntDispatcher& copy); // Verhindere Kopieren
|
IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
enum { size = 256 };
|
enum { size = 256 };
|
||||||
ISR* map[size];
|
ISR* map[size];
|
||||||
|
|||||||
@ -20,12 +20,11 @@
|
|||||||
class PIC {
|
class PIC {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PIC(const PIC& copy); // Verhindere Kopieren
|
PIC(const PIC& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PIC() {}
|
PIC() {}
|
||||||
|
|
||||||
public:
|
|
||||||
// IRQ-Nummern von Geraeten
|
// IRQ-Nummern von Geraeten
|
||||||
enum {
|
enum {
|
||||||
timer = 0, // Programmable Interrupt Timer (PIT)
|
timer = 0, // Programmable Interrupt Timer (PIT)
|
||||||
|
|||||||
@ -13,9 +13,8 @@
|
|||||||
#define __Chain_include__
|
#define __Chain_include__
|
||||||
|
|
||||||
class Chain {
|
class Chain {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Chain(const Chain ©); // Verhindere Kopieren
|
Chain(const Chain& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Chain* next;
|
Chain* next;
|
||||||
|
|||||||
@ -28,20 +28,20 @@
|
|||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
class fillw {
|
class fillw {
|
||||||
public:
|
public:
|
||||||
fillw() : w(0) {};
|
fillw() : w(0) {}
|
||||||
fillw(unsigned char w) : w(w) {};
|
fillw(unsigned char w) : w(w) {}
|
||||||
unsigned char w;
|
unsigned char w;
|
||||||
};
|
};
|
||||||
class fillc {
|
class fillc {
|
||||||
public:
|
public:
|
||||||
fillc() : c(' ') {};
|
fillc() : c(' ') {}
|
||||||
fillc(char c) : c(c) {};
|
fillc(char c) : c(c) {}
|
||||||
char c;
|
char c;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OutStream : public StringBuffer {
|
class OutStream : public StringBuffer {
|
||||||
private:
|
private:
|
||||||
OutStream(const OutStream& copy); // Verhindere Kopieren
|
OutStream(const OutStream& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
// NOTE: I added this
|
// NOTE: I added this
|
||||||
unsigned char fill_used; // indicates how many characters are already used by the text internally
|
unsigned char fill_used; // indicates how many characters are already used by the text internally
|
||||||
@ -55,13 +55,7 @@ public:
|
|||||||
unsigned char fill_width;
|
unsigned char fill_width;
|
||||||
char fill_char; // fill character for fixed width
|
char fill_char; // fill character for fixed width
|
||||||
|
|
||||||
OutStream() : StringBuffer() {
|
OutStream() : fill_used(0), base(10), fill_width(0), fill_char(' ') {}
|
||||||
base = 10; // initial Dezimalsystem
|
|
||||||
|
|
||||||
fill_width = 0; // no fixed width
|
|
||||||
fill_char = ' '; // fill with spaces
|
|
||||||
fill_used = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
|
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
|
||||||
void flush() override;
|
void flush() override;
|
||||||
@ -165,7 +159,7 @@ public:
|
|||||||
|
|
||||||
// Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die
|
// Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die
|
||||||
// noch kleiner als die darzustellende Zahl ist.
|
// noch kleiner als die darzustellende Zahl ist.
|
||||||
for (div = 1; ival / div >= (unsigned long)os.base; div *= os.base) {};
|
for (div = 1; ival / div >= (unsigned long)os.base; div *= os.base) {}
|
||||||
|
|
||||||
// ziffernweise Ausgabe der Zahl
|
// ziffernweise Ausgabe der Zahl
|
||||||
for (; div > 0; div /= (unsigned long)os.base) {
|
for (; div > 0; div /= (unsigned long)os.base) {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
// NOTE: I added this file
|
// NOTE: I added this file
|
||||||
|
|
||||||
void ScrollbackBuffer::put(CGA::cga_line_t* line) {
|
void ScrollbackBuffer::put(CGA::cga_line_t* line) {
|
||||||
CGA::cga_line_t* destination = (CGA::cga_line_t*)this->buffer + this->pos;
|
CGA::cga_line_t* destination = (CGA::cga_line_t*)this->buffer.get() + this->pos;
|
||||||
mmem::memcpy<CGA::cga_line_t>(destination, line);
|
mmem::memcpy<CGA::cga_line_t>(destination, line);
|
||||||
|
|
||||||
this->pos = (this->pos + 1) % this->rows;
|
this->pos = (this->pos + 1) % this->rows;
|
||||||
@ -21,13 +21,13 @@ void ScrollbackBuffer::get(CGA::cga_line_t* destination, unsigned char page) con
|
|||||||
unsigned int wrapline;
|
unsigned int wrapline;
|
||||||
for (unsigned int line = 0; line < (this->rows / this->pages); ++line) {
|
for (unsigned int line = 0; line < (this->rows / this->pages); ++line) {
|
||||||
wrapline = (this->pos + rpage * (this->rows / this->pages) + line) % this->rows;
|
wrapline = (this->pos + rpage * (this->rows / this->pages) + line) % this->rows;
|
||||||
mmem::memcpy<CGA::cga_line_t>(destination + line, (CGA::cga_line_t*)this->buffer + wrapline);
|
mmem::memcpy<CGA::cga_line_t>(destination + line, (CGA::cga_line_t*)this->buffer.get() + wrapline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollbackBuffer::clear() {
|
void ScrollbackBuffer::clear() {
|
||||||
for (unsigned char page = 0; page < this->pages; ++page) {
|
for (unsigned char page = 0; page < this->pages; ++page) {
|
||||||
mmem::zero<CGA::cga_page_t>(this->buffer + page);
|
mmem::zero<CGA::cga_page_t>(this->buffer.get() + page);
|
||||||
}
|
}
|
||||||
this->pos = 0;
|
this->pos = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,14 +3,15 @@
|
|||||||
|
|
||||||
#include "devices/CGA.h"
|
#include "devices/CGA.h"
|
||||||
#include "lib/MyStdLib.h"
|
#include "lib/MyStdLib.h"
|
||||||
|
#include <memory>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
// NOTE: I added this file
|
// NOTE: I added this file
|
||||||
|
|
||||||
class ScrollbackBuffer {
|
class ScrollbackBuffer {
|
||||||
private:
|
private:
|
||||||
CGA::cga_page_t* buffer; // Circular buffer to store lines that left the screen
|
std::unique_ptr<CGA::cga_page_t[]> buffer; // Circular buffer to store lines that left the screen
|
||||||
unsigned int pos; // Buffer write position
|
unsigned int pos; // Buffer write position
|
||||||
|
|
||||||
ScrollbackBuffer(const ScrollbackBuffer&) = delete;
|
ScrollbackBuffer(const ScrollbackBuffer&) = delete;
|
||||||
|
|
||||||
@ -20,12 +21,8 @@ public:
|
|||||||
|
|
||||||
ScrollbackBuffer(unsigned char rows, unsigned char pages)
|
ScrollbackBuffer(unsigned char rows, unsigned char pages)
|
||||||
: pos(0), pages(pages), rows(rows * pages) {
|
: pos(0), pages(pages), rows(rows * pages) {
|
||||||
this->buffer = new CGA::cga_page_t[pages]; // Allocate with new because it's quite large (and I want to use the allocator)
|
this->buffer = std::make_unique<CGA::cga_page_t[]>(pages); // Allocate with new because it's quite large (and I want to use the allocator)
|
||||||
this->clear(); // Null out the buffer so no crap gets displayed
|
this->clear(); // Null out the buffer so no crap gets displayed
|
||||||
}
|
|
||||||
|
|
||||||
~ScrollbackBuffer() {
|
|
||||||
delete[] this->buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void put(CGA::cga_line_t* line);
|
void put(CGA::cga_line_t* line);
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
void StringBuffer::put(char c) {
|
void StringBuffer::put(char c) {
|
||||||
buffer[pos] = c;
|
buffer[pos] = c;
|
||||||
pos++;
|
pos++;
|
||||||
if (pos == sizeof(buffer))
|
if (pos == sizeof(buffer)) {
|
||||||
flush();
|
flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
c_os/main.cc
23
c_os/main.cc
@ -13,7 +13,7 @@
|
|||||||
#include "kernel/Globals.h"
|
#include "kernel/Globals.h"
|
||||||
#include "user/CoroutineDemo.h"
|
#include "user/CoroutineDemo.h"
|
||||||
|
|
||||||
CoroutineDemo coroutineDemo;
|
const CoroutineDemo coroutineDemo;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
kout.clear();
|
kout.clear();
|
||||||
@ -25,17 +25,18 @@ int main() {
|
|||||||
kout.init(5);
|
kout.init(5);
|
||||||
|
|
||||||
// Startmeldung
|
// Startmeldung
|
||||||
if constexpr (!DEBUG)
|
if constexpr (!DEBUG) {
|
||||||
kout << "HHUos 0.5" << endl
|
kout << "HHUos 0.5\n"
|
||||||
<< "=========" << endl
|
<< "=========\n"
|
||||||
<< "Unterstuetzte Funktionen:" << endl
|
<< "Unterstuetzte Funktionen:\n"
|
||||||
<< " - Bildschirmausgaben" << endl
|
<< " - Bildschirmausgaben\n"
|
||||||
<< " - Sound ueber den PC-Lautsprecher" << endl
|
<< " - Sound ueber den PC-Lautsprecher\n"
|
||||||
<< " - Tastatureingaben per Abfrage" << endl
|
<< " - Tastatureingaben per Abfrage\n"
|
||||||
<< " - Einfache Heap verwaltung" << endl
|
<< " - Einfache Heap verwaltung\n"
|
||||||
<< " - Tastatureingaben per Interrupt" << endl
|
<< " - Tastatureingaben per Interrupt\n"
|
||||||
<< " - Koroutinen" << endl
|
<< " - Koroutinen\n"
|
||||||
<< endl;
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Tastatur-Unterbrechungsroutine 'einstoepseln'
|
// Tastatur-Unterbrechungsroutine 'einstoepseln'
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
*---------------------------------------------------------------------------*
|
*---------------------------------------------------------------------------*
|
||||||
* Beschreibung: main-Methode der Anwendung. *
|
* Beschreibung: main-Methode der Anwendung. *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void CoroutineDemo::main() {
|
void CoroutineDemo::main() const {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hier muss Code eingefuegt werden
|
* Hier muss Code eingefuegt werden
|
||||||
|
|||||||
@ -11,15 +11,14 @@
|
|||||||
#define __coroutinedemo_include__
|
#define __coroutinedemo_include__
|
||||||
|
|
||||||
class CoroutineDemo {
|
class CoroutineDemo {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CoroutineDemo(const CoroutineDemo& copy); // Verhindere Kopieren
|
CoroutineDemo(const CoroutineDemo& copy) = delete; // Verhindere Kopieren
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CoroutineDemo() {}
|
CoroutineDemo() {}
|
||||||
|
|
||||||
// Koroutine-Startmethode
|
// Koroutine-Startmethode
|
||||||
void main();
|
void main() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user