1

merged cleanup

This commit is contained in:
2022-07-24 21:12:31 +02:00
parent 5ff3d72bfd
commit 6481bae5f6
92 changed files with 663 additions and 755 deletions

View File

@ -2,7 +2,7 @@ Makefile
====================================== ======================================
- Added the -std=c++17 flag to enable better constexpr support. - Added the -std=c++17 flag to enable better constexpr support.
- Removed optimizations as the system would crash with them. - Removed optimizations as the system would crash with them.
The BlueScreen would show an empty callstack on crashes with -O2 so I guess the problem is the missing ebp or something like that. The BlueScreen would show an empty callstack on crashes with -O2, so I guess the problem is the missing ebp or something like that.
- Added qemu-stdio target for easy access to the serial output - Added qemu-stdio target for easy access to the serial output
Changes Changes

View File

@ -59,7 +59,7 @@ void CGA::getpos(unsigned int& x, unsigned int& y) {
(cursor_low & 0xFF) | ((cursor_high << 8) & 0xFF00); (cursor_low & 0xFF) | ((cursor_high << 8) & 0xFF00);
x = cursor % COLUMNS; x = cursor % COLUMNS;
y = (int)(cursor / COLUMNS); y = (cursor / COLUMNS);
} }
/***************************************************************************** /*****************************************************************************
@ -146,11 +146,11 @@ void CGA::print(const char* string, unsigned int n, unsigned char attrib) const
} }
void CGA::print(const bse::string& string, const unsigned int n, const unsigned char attrib) const { void CGA::print(const bse::string& string, const unsigned int n, const unsigned char attrib) const {
print((const char*)string, n, attrib); print(static_cast<const char*>(string), n, attrib);
} }
void CGA::print(const bse::string& string, const unsigned char attrib) const { void CGA::print(const bse::string& string, const unsigned char attrib) const {
print((const char*)string, string.size(), attrib); print(static_cast<const char*>(string), string.size(), attrib);
} }
/***************************************************************************** /*****************************************************************************
@ -202,7 +202,7 @@ unsigned char CGA::attribute(CGA::color bg, CGA::color fg, bool blink) {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
return (int)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)
} }

View File

@ -11,8 +11,8 @@
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 21.8.2016 * * Aenderungen von Michael Schoettner, HHU, 21.8.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __CGA_include__ #ifndef CGA_include_H_
#define __CGA_include__ #define CGA_include_H_
#include "kernel/IOport.h" #include "kernel/IOport.h"
#include "user/lib/Array.h" #include "user/lib/Array.h"
@ -29,9 +29,11 @@ public:
// Konstruktur mit Initialisierung der Ports // Konstruktur mit Initialisierung der Ports
CGA() { CGA() {
this->setpos(0, 0); CGA::setpos(0, 0);
} }
// virtual ~CGA() = default;
static const unsigned int CGA_START = 0xb8000U; static const unsigned int CGA_START = 0xb8000U;
// Konstanten fuer die moeglichen Farben im Attribut-Byte. // Konstanten fuer die moeglichen Farben im Attribut-Byte.

View File

@ -24,11 +24,11 @@
* 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(color_bg, color_fg, blink)); // print(buffer...) would work syntactically print(buffer.data(), pos, attribute(color_bg, color_fg, blink)); // print(buffer...) would work syntactically
// but the system wouldn't start, as the bse::array // but the system wouldn't start, as the bse::array
// would be implicitly converted to bse::string and // would be implicitly converted to bse::string and
// that is dynamically allocated. // that is dynamically allocated.
// print(&buffer...) just uses the stack location of // print(buffer.data()...) just uses the stack location of
// the internal buffer of bse::array // the internal buffer of bse::array
// Flushing resets attributes // Flushing resets attributes

View File

@ -12,8 +12,8 @@
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 06.04.20 * * Aenderungen von Michael Schoettner, HHU, 06.04.20 *
*****************************************************************************/ *****************************************************************************/
#ifndef __CGA_Stream_include__ #ifndef CGA_Stream_include_H_
#define __CGA_Stream_include__ #define CGA_Stream_include_H_
#include "devices/CGA.h" #include "devices/CGA.h"
#include "lib/OutStream.h" #include "lib/OutStream.h"
@ -42,7 +42,7 @@ class CGA_Stream : public OutStream, public CGA {
private: private:
// Allow for synchronization of output text, needed when running something in parallel to // Allow for synchronization of output text, needed when running something in parallel to
// the PreemptiveThreadDemo for example // the PreemptiveThreadDemo for example
// NOTE: Should only be used by threads (like the demos) to not deadlock the system // NOTE: Should only be used by threads (like the demos) to not lock the system
Semaphore sem; Semaphore sem;
CGA::color color_fg; CGA::color color_fg;
@ -58,6 +58,8 @@ public:
pos = 0; pos = 0;
} }
// ~CGA_Stream() override = default;
void lock() { sem.p(); } void lock() { sem.p(); }
void unlock() { sem.v(); } void unlock() { sem.v(); }

View File

@ -7,8 +7,8 @@
* * * *
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
*****************************************************************************/ *****************************************************************************/
#ifndef __Key_include__ #ifndef Key_include__
#define __Key_include__ #define Key_include__
class Key { class Key {
// Kopieren erlaubt! // Kopieren erlaubt!
@ -98,7 +98,7 @@ public:
bool alt() const { return alt_left() || alt_right(); } bool alt() const { return alt_left() || alt_right(); }
bool ctrl() const { return ctrl_left() || ctrl_right(); } bool ctrl() const { return ctrl_left() || ctrl_right(); }
operator char() const { return (char)asc; } operator char() const { return static_cast<char>(asc); }
// Scan-Codes einiger spezieller Tasten // Scan-Codes einiger spezieller Tasten
struct scan { struct scan {

View File

@ -16,7 +16,7 @@ const IOport Keyboard::data_port(0x60);
/* Tabellen fuer ASCII-Codes (Klassenvariablen) intiialisieren */ /* Tabellen fuer ASCII-Codes (Klassenvariablen) intiialisieren */
constexpr unsigned char Keyboard::normal_tab[] = { constexpr const unsigned char Keyboard::normal_tab[] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 225, 39, '\b', 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 225, 39, '\b',
0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 129, '+', '\n', 0, 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 129, '+', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 148, 132, '^', 0, '#', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 148, 132, '^', 0, '#',
@ -24,7 +24,7 @@ constexpr unsigned char Keyboard::normal_tab[] = {
'*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-',
0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, '<', 0, 0}; 0, 0, 0, '+', 0, 0, 0, 0, 0, 0, 0, '<', 0, 0};
constexpr unsigned char Keyboard::shift_tab[] = { constexpr const unsigned char Keyboard::shift_tab[] = {
0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 0, 0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 0,
0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 154, '*', 0, 0, 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 154, '*', 0,
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 153, 142, 248, 0, 39, 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 153, 142, 248, 0, 39,
@ -32,7 +32,7 @@ constexpr unsigned char Keyboard::shift_tab[] = {
0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '>', 0, 0}; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '>', 0, 0};
constexpr unsigned char Keyboard::alt_tab[] = { constexpr const unsigned char Keyboard::alt_tab[] = {
0, 0, 0, 253, 0, 0, 0, 0, '{', '[', ']', '}', '\\', 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, '{', '[', ']', '}', '\\', 0, 0,
0, '@', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '~', 0, 0, '@', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '~', 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -40,10 +40,10 @@ constexpr unsigned char Keyboard::alt_tab[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0}; 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '|', 0, 0};
constexpr unsigned char Keyboard::asc_num_tab[] = { constexpr const unsigned char Keyboard::asc_num_tab[] = {
'7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','}; '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', ','};
constexpr unsigned char Keyboard::scan_num_tab[] = { constexpr const unsigned char Keyboard::scan_num_tab[] = {
8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51}; 8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51};
/***************************************************************************** /*****************************************************************************
@ -269,7 +269,7 @@ Key Keyboard::key_hit() {
return invalid; return invalid;
} }
code = (unsigned char)data_port.inb(); code = data_port.inb();
if (key_decoded()) { if (key_decoded()) {
return gather; return gather;
} }
@ -287,7 +287,7 @@ void Keyboard::reboot() {
// Dem BIOS mitteilen, dass das Reset beabsichtigt war // Dem BIOS mitteilen, dass das Reset beabsichtigt war
// und kein Speichertest durchgefuehrt werden muss. // und kein Speichertest durchgefuehrt werden muss.
*(unsigned short*)0x472 = 0x1234; *reinterpret_cast<unsigned short*>(0x472) = 0x1234;
// Der Tastaturcontroller soll das Reset ausloesen. // Der Tastaturcontroller soll das Reset ausloesen.
do { do {
@ -332,17 +332,17 @@ void Keyboard::set_led(char led, bool on) {
// und erlaubt den keyboard interrupt im PIC // und erlaubt den keyboard interrupt im PIC
void Keyboard::plugin() { void Keyboard::plugin() {
intdis.assign(IntDispatcher::keyboard, *this); intdis.assign(IntDispatcher::keyboard, *this);
pic.allow(PIC::keyboard); PIC::allow(PIC::keyboard);
} }
void Keyboard::trigger() { void Keyboard::trigger() {
Key key = this->key_hit(); Key key = key_hit();
this->lastkey = key.ascii(); // lastkey = key.ascii();
// NOTE: My keyboard has no delete key... // NOTE: My keyboard has no delete key...
if (key.ctrl_left() && key.alt_left() && (char)key == 'r') { if (key.ctrl_left() && key.alt_left() && static_cast<char>(key) == 'r') {
this->reboot(); reboot();
} else if (key != 0) { } else if (key != 0) {
kevman.broadcast(key); kevman.broadcast(key); // Send key to all subscribed threads
} }
} }

View File

@ -8,8 +8,8 @@
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
* Modifikationen, Michael Schoettner, 2.6.2022 * * Modifikationen, Michael Schoettner, 2.6.2022 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Keyboard_include__ #ifndef Keyboard_include__
#define __Keyboard_include__ #define Keyboard_include__
#include "devices/Key.h" #include "devices/Key.h"
#include "kernel/interrupts/ISR.h" #include "kernel/interrupts/ISR.h"
@ -74,13 +74,15 @@ private:
public: public:
Keyboard(const Keyboard& copy) = delete; // Verhindere Kopieren Keyboard(const Keyboard& copy) = delete; // Verhindere Kopieren
unsigned int lastkey; // speichert den ASCII-Code der zuletzt gedrückten Taste
// Initialisierung der Tastatur. // Initialisierung der Tastatur.
Keyboard(); Keyboard();
// ~Keyboard() override = default;
// unsigned int lastkey; // speichert den ASCII-Code der zuletzt gedrückten Taste
// Fuehrt einen Neustart des Rechners durch. // Fuehrt einen Neustart des Rechners durch.
void reboot(); static void reboot();
// Einstellen der Wiederholungsrate der Tastatur. // Einstellen der Wiederholungsrate der Tastatur.
void set_repeat_rate(int speed, int delay); void set_repeat_rate(int speed, int delay);

View File

@ -13,7 +13,6 @@
*****************************************************************************/ *****************************************************************************/
#include "devices/LFBgraphics.h" #include "devices/LFBgraphics.h"
#include "kernel/Globals.h"
/* Hilfsfunktionen */ /* Hilfsfunktionen */
void swap(unsigned int* a, unsigned int* b); void swap(unsigned int* a, unsigned int* b);
@ -43,8 +42,8 @@ inline void LFBgraphics::drawMonoBitmap(unsigned int x, unsigned int y,
unsigned short width_byte = width / 8 + ((width % 8 != 0) ? 1 : 0); unsigned short width_byte = width / 8 + ((width % 8 != 0) ? 1 : 0);
for (unsigned int yoff = 0; yoff < height; ++yoff) { for (unsigned int yoff = 0; yoff < height; ++yoff) {
int xpos = x; unsigned int xpos = x;
int ypos = y + yoff; unsigned int ypos = y + yoff;
for (unsigned int xb = 0; xb < width_byte; ++xb) { for (unsigned int xb = 0; xb < width_byte; ++xb) {
for (int src = 7; src >= 0; --src) { for (int src = 7; src >= 0; --src) {
if ((1 << src) & *bitmap) { if ((1 << src) & *bitmap) {
@ -86,14 +85,14 @@ void LFBgraphics::drawString(const Font& fnt, unsigned int x, unsigned int y,
* Beschreibung: Zeichnen eines Pixels. * * Beschreibung: Zeichnen eines Pixels. *
*****************************************************************************/ *****************************************************************************/
void LFBgraphics::drawPixel(unsigned int x, unsigned int y, unsigned int col) const { void LFBgraphics::drawPixel(unsigned int x, unsigned int y, unsigned int col) const {
unsigned char* ptr = (unsigned char*)lfb; unsigned char* ptr = reinterpret_cast<unsigned char*>(lfb);
if (hfb == 0 || lfb == 0) { if (hfb == 0 || lfb == 0) {
return; return;
} }
if (mode == BUFFER_INVISIBLE) { if (mode == BUFFER_INVISIBLE) {
ptr = (unsigned char*)hfb; ptr = reinterpret_cast<unsigned char*>(hfb);
} }
// Pixel ausserhalb des sichtbaren Bereichs? // Pixel ausserhalb des sichtbaren Bereichs?
@ -119,7 +118,7 @@ void LFBgraphics::drawPixel(unsigned int x, unsigned int y, unsigned int col) co
*ptr = ((col >> 8) & 0xFF); *ptr = ((col >> 8) & 0xFF);
ptr++; ptr++;
*ptr = ((col >> 16) & 0xFF); *ptr = ((col >> 16) & 0xFF);
ptr++; ptr;
return; return;
case 32: case 32:
ptr += (4 * x + 4 * y * xres); ptr += (4 * x + 4 * y * xres);
@ -128,7 +127,7 @@ void LFBgraphics::drawPixel(unsigned int x, unsigned int y, unsigned int col) co
*ptr = ((col >> 8) & 0xFF); *ptr = ((col >> 8) & 0xFF);
ptr++; ptr++;
*ptr = ((col >> 16) & 0xFF); *ptr = ((col >> 16) & 0xFF);
ptr++; ptr;
return; return;
} }
} }
@ -139,12 +138,12 @@ void LFBgraphics::drawStraightLine(unsigned int x1, unsigned int y1, unsigned in
if (x1 == x2 && y2 > y1) { if (x1 == x2 && y2 > y1) {
// Vertical line // Vertical line
for (unsigned int i = y1; i <= y2; ++i) { for (unsigned int i = y1; i <= y2; ++i) {
this->drawPixel(x1, i, col); drawPixel(x1, i, col);
} }
} else if (y1 == y2 && x2 > x1) { } else if (y1 == y2 && x2 > x1) {
// Horizontal line // Horizontal line
for (unsigned int i = x1; i <= x2; ++i) { for (unsigned int i = x1; i <= x2; ++i) {
this->drawPixel(i, y1, col); drawPixel(i, y1, col);
} }
} else { } else {
// Not straight // Not straight
@ -155,32 +154,32 @@ void LFBgraphics::drawStraightLine(unsigned int x1, unsigned int y1, unsigned in
// | | // | |
// (x1, y2)---(x2, y2) // (x1, y2)---(x2, y2)
void LFBgraphics::drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const { void LFBgraphics::drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const {
this->drawStraightLine(x1, y1, x2, y1, col); drawStraightLine(x1, y1, x2, y1, col);
this->drawStraightLine(x2, y1, x2, y2, col); drawStraightLine(x2, y1, x2, y2, col);
this->drawStraightLine(x1, y2, x2, y2, col); drawStraightLine(x1, y2, x2, y2, col);
this->drawStraightLine(x1, y1, x1, y2, col); drawStraightLine(x1, y1, x1, y2, col);
} }
void LFBgraphics::drawCircle(unsigned int x, unsigned int y, unsigned int rad, unsigned int col) const { void LFBgraphics::drawCircle(unsigned int x, unsigned int y, unsigned int rad, unsigned int col) const {
// TODO // TODO
} }
void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, unsigned char* pixel_data) const { void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const unsigned char* pixel_data) const {
unsigned char* ptr; const unsigned char* ptr;
for (unsigned int x = 0; x < width; ++x) { for (unsigned int x = 0; x < width; ++x) {
for (unsigned int y = 0; y < height; ++y) { for (unsigned int y = 0; y < height; ++y) {
ptr = (unsigned char*)pixel_data + (x + y * width) * bytes_pp; ptr = pixel_data + (x + y * width) * bytes_pp;
switch (bytes_pp) { switch (bytes_pp) {
case 2: case 2:
// TODO: Never tested, probably doesn't work // TODO: Never tested, probably doesn't work
this->drawPixel(x, y, RGB_24(*ptr & 0b11111000, ((*ptr & 0b111) << 3) | (*(ptr + 1) >> 5), drawPixel(x, y, RGB_24(*ptr & 0b11111000, ((*ptr & 0b111) << 3) | (*(ptr + 1) >> 5),
*(ptr + 1) & 0b11111)); // RGB 565 *(ptr + 1) & 0b11111)); // RGB 565
break; break;
case 3: case 3:
case 4: case 4:
// Alpha gets ignored anyway // Alpha gets ignored anyway
this->drawPixel(x, y, RGB_24(*ptr, *(ptr + 1), *(ptr + 2))); drawPixel(x, y, RGB_24(*ptr, *(ptr + 1), *(ptr + 2)));
break; break;
} }
} }
@ -193,7 +192,7 @@ void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned i
* Beschreibung: Bildschirm loeschen. * * Beschreibung: Bildschirm loeschen. *
*****************************************************************************/ *****************************************************************************/
void LFBgraphics::clear() const { void LFBgraphics::clear() const {
unsigned int* ptr = (unsigned int*)lfb; unsigned int* ptr = reinterpret_cast<unsigned int*>(lfb);
unsigned int i; unsigned int i;
if (hfb == 0 || lfb == 0) { if (hfb == 0 || lfb == 0) {
@ -201,7 +200,7 @@ void LFBgraphics::clear() const {
} }
if (mode == 0) { if (mode == 0) {
ptr = (unsigned int*)hfb; ptr = reinterpret_cast<unsigned int*>(hfb);
} }
switch (bpp) { switch (bpp) {
@ -244,8 +243,8 @@ void LFBgraphics::setDrawingBuff(int v) {
* Beschreibung: Kopiert den versteckten Puffer in den sichtbaren LFB. * * Beschreibung: Kopiert den versteckten Puffer in den sichtbaren LFB. *
*****************************************************************************/ *****************************************************************************/
void LFBgraphics::copyHiddenToVisible() const { void LFBgraphics::copyHiddenToVisible() const {
unsigned int* sptr = (unsigned int*)hfb; unsigned int* sptr = reinterpret_cast<unsigned int*>(hfb);
unsigned int* dptr = (unsigned int*)lfb; unsigned int* dptr = reinterpret_cast<unsigned int*>(lfb);
unsigned int i; unsigned int i;
if (hfb == 0 || lfb == 0) { if (hfb == 0 || lfb == 0) {
@ -278,7 +277,7 @@ void LFBgraphics::copyHiddenToVisible() const {
} }
void swap(unsigned int* a, unsigned int* b) { void swap(unsigned int* a, unsigned int* b) {
int h = *a; unsigned int h = *a;
*a = *b; *a = *b;
*b = h; *b = h;

View File

@ -12,16 +12,18 @@
* https://blog.demofox.org/2015/01/17/bresenhams-drawing-algorithms * * https://blog.demofox.org/2015/01/17/bresenhams-drawing-algorithms *
*****************************************************************************/ *****************************************************************************/
#ifndef __LFBgraphics_include__ #ifndef LFBgraphics_include__
#define __LFBgraphics_include__ #define LFBgraphics_include__
#include "devices/fonts/Fonts.h" #include "devices/fonts/Fonts.h"
// Hilfsfunktionen um Farbwerte fuer einen Pixel zu erzeugen // Hilfsfunktionen um Farbwerte fuer einen Pixel zu erzeugen
#define RGB_24(r, g, b) (unsigned int)((r << 16) + (g << 8) + b) constexpr unsigned int RGB_24(unsigned int r, unsigned int g, unsigned int b) {
return ((r << 16) + (g << 8) + b);
}
#define BUFFER_INVISIBLE 0 constexpr const bool BUFFER_INVISIBLE = false;
#define BUFFER_VISIBLE 1 constexpr const bool BUFFER_VISIBLE = true;
class LFBgraphics { class LFBgraphics {
private: private:
@ -50,7 +52,7 @@ public:
void drawStraightLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const; void drawStraightLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const;
void drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const; void drawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int col) const;
void drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, unsigned char* pixel_data) const; void drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const unsigned char* pixel_data) const;
// stellt ein, ob in den sichtbaren Puffer gezeichnet wird // stellt ein, ob in den sichtbaren Puffer gezeichnet wird
void setDrawingBuff(int v); void setDrawingBuff(int v);

View File

@ -16,7 +16,6 @@
#include "kernel/Globals.h" #include "kernel/Globals.h"
const IOport PCSPK::control(0x43); const IOport PCSPK::control(0x43);
const IOport PCSPK::data0(0x40);
const IOport PCSPK::data2(0x42); const IOport PCSPK::data2(0x42);
const IOport PCSPK::ppi(0x61); const IOport PCSPK::ppi(0x61);
@ -29,7 +28,7 @@ const IOport PCSPK::ppi(0x61);
* len: Laenge des Tons in ms * * len: Laenge des Tons in ms *
*****************************************************************************/ *****************************************************************************/
void PCSPK::play(float f, int len) { void PCSPK::play(float f, int len) {
int freq = (int)f; int freq = static_cast<int>(f);
int cntStart = 1193180 / freq; int cntStart = 1193180 / freq;
int status; int status;
@ -39,7 +38,7 @@ void PCSPK::play(float f, int len) {
data2.outb(cntStart / 256); // Zaehler-2 laden (Hibyte) data2.outb(cntStart / 256); // Zaehler-2 laden (Hibyte)
// Lautsprecher einschalten // Lautsprecher einschalten
status = (int)ppi.inb(); // Status-Register des PPI auslesen status = static_cast<int>(ppi.inb()); // Status-Register des PPI auslesen
ppi.outb(status | 3); // Lautpsrecher Einschalten ppi.outb(status | 3); // Lautpsrecher Einschalten
// Pause // Pause
@ -57,7 +56,7 @@ void PCSPK::play(float f, int len) {
void PCSPK::off() { void PCSPK::off() {
int status; int status;
status = (int)ppi.inb(); // Status-Register des PPI auslesen status = static_cast<int>(ppi.inb()); // Status-Register des PPI auslesen
ppi.outb((status >> 2) << 2); // Lautsprecher ausschalten ppi.outb((status >> 2) << 2); // Lautsprecher ausschalten
} }

View File

@ -12,67 +12,66 @@
* Autor: Michael Schoettner, HHU, 22.9.2016 * * Autor: Michael Schoettner, HHU, 22.9.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __PCSPK_include__ #ifndef PCSPK_include__
#define __PCSPK_include__ #define PCSPK_include__
#include "kernel/IOport.h" #include "kernel/IOport.h"
// Note, Frequenz // Note, Frequenz
#define C0 130.81 constexpr const float C0 = 130.81;
#define C0X 138.59 constexpr const float C0X = 138.59;
#define D0 146.83 constexpr const float D0 = 146.83;
#define D0X 155.56 constexpr const float D0X = 155.56;
#define E0 164.81 constexpr const float E0 = 164.81;
#define F0 174.61 constexpr const float F0 = 174.61;
#define F0X 185.00 constexpr const float F0X = 185.00;
#define G0 196.00 constexpr const float G0 = 196.00;
#define G0X 207.65 constexpr const float G0X = 207.65;
#define A0 220.00 constexpr const float A0 = 220.00;
#define A0X 233.08 constexpr const float A0X = 233.08;
#define B0 246.94 constexpr const float B0 = 246.94;
#define C1 261.63 constexpr const float C1 = 261.63;
#define C1X 277.18 constexpr const float C1X = 277.18;
#define D1 293.66 constexpr const float D1 = 293.66;
#define D1X 311.13 constexpr const float D1X = 311.13;
#define E1 329.63 constexpr const float E1 = 329.63;
#define F1 349.23 constexpr const float F1 = 349.23;
#define F1X 369.99 constexpr const float F1X = 369.99;
#define G1 391.00 constexpr const float G1 = 391.00;
#define G1X 415.30 constexpr const float G1X = 415.30;
#define A1 440.00 constexpr const float A1 = 440.00;
#define A1X 466.16 constexpr const float A1X = 466.16;
#define B1 493.88 constexpr const float B1 = 493.88;
#define C2 523.25 constexpr const float C2 = 523.25;
#define C2X 554.37 constexpr const float C2X = 554.37;
#define D2 587.33 constexpr const float D2 = 587.33;
#define D2X 622.25 constexpr const float D2X = 622.25;
#define E2 659.26 constexpr const float E2 = 659.26;
#define F2 698.46 constexpr const float F2 = 698.46;
#define F2X 739.99 constexpr const float F2X = 739.99;
#define G2 783.99 constexpr const float G2 = 783.99;
#define G2X 830.61 constexpr const float G2X = 830.61;
#define A2 880.00 constexpr const float A2 = 880.00;
#define A2X 923.33 constexpr const float A2X = 923.33;
#define B2 987.77 constexpr const float B2 = 987.77;
#define C3 1046.50 constexpr const float C3 = 1046.50;
class PCSPK { class PCSPK {
private: private:
static const IOport control; // Steuerregister (write only) static const IOport control; // Steuerregister (write only)
static const IOport data0; // Zaehler-0 Datenregister (read/write)
static const IOport data2; // Zaehler-2 Datenregister static const IOport data2; // Zaehler-2 Datenregister
static const IOport ppi; // Status-Register des PPI static const IOport ppi; // Status-Register des PPI
// Verzoegerung um X ms (in 1ms Schritten; Min. 1ms) // Verzoegerung um X ms (in 1ms Schritten; Min. 1ms)
inline void delay(int time); static inline void delay(int time);
public: public:
PCSPK(const PCSPK& copy) = delete; // Verhindere Kopieren PCSPK(const PCSPK& copy) = delete; // Verhindere Kopieren
// Konstruktor. Initialisieren der Ports. // Konstruktor. Initialisieren der Ports.
PCSPK() {} PCSPK() = default;
// Demo Sounds // Demo Sounds
void tetris(); void tetris();
@ -82,7 +81,7 @@ public:
void play(float f, int len); void play(float f, int len);
// Lautsprecher ausschalten // Lautsprecher ausschalten
void off(); static void off();
}; };
#endif #endif

View File

@ -30,7 +30,7 @@ void PIT::interval(int us) {
control.outb(0x36); // Zähler 0 Mode 3 control.outb(0x36); // Zähler 0 Mode 3
unsigned int cntStart = (1193180.0 / 1000000.0) * us; // 1.19Mhz PIT unsigned int cntStart = static_cast<unsigned int>((1193180.0 / 1000000.0) * us); // 1.19Mhz PIT
data0.outb(cntStart & 0xFF); // Zaehler-0 laden (Lobyte) data0.outb(cntStart & 0xFF); // Zaehler-0 laden (Lobyte)
data0.outb(cntStart >> 8); // Zaehler-0 laden (Hibyte) data0.outb(cntStart >> 8); // Zaehler-0 laden (Hibyte)
@ -75,10 +75,10 @@ void PIT::trigger() {
/* hier muss Code eingefuegt werden */ /* hier muss Code eingefuegt werden */
// Indicator // Indicator
if (systime - this->last_indicator_refresh >= 10) { if (systime - last_indicator_refresh >= 10) {
this->indicator_pos = (this->indicator_pos + 1) % 4; indicator_pos = (indicator_pos + 1) % 4;
CGA::show(79, 0, this->indicator[this->indicator_pos]); CGA::show(79, 0, indicator[indicator_pos]);
this->last_indicator_refresh = systime; last_indicator_refresh = systime;
} }
// Preemption // Preemption

View File

@ -8,11 +8,12 @@
* Autor: Michael Schoettner, 23.8.2016 * * Autor: Michael Schoettner, 23.8.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __PIT_include__ #ifndef PIT_include__
#define __PIT_include__ #define PIT_include__
#include "kernel/interrupts/ISR.h" #include "kernel/interrupts/ISR.h"
#include "kernel/IOport.h" #include "kernel/IOport.h"
#include "user/lib/Array.h"
class PIT : public ISR { class PIT : public ISR {
private: private:
@ -22,13 +23,15 @@ private:
enum { time_base = 838 }; /* ns */ enum { time_base = 838 }; /* ns */
int timer_interval; int timer_interval;
const char indicator[4] = {'|', '/', '-', '\\'}; const bse::array<char, 4> indicator{'|', '/', '-', '\\'};
unsigned int indicator_pos = 0; unsigned int indicator_pos = 0;
unsigned long last_indicator_refresh = 0; unsigned long last_indicator_refresh = 0;
public: public:
PIT(const PIT& copy) = delete; // Verhindere Kopieren PIT(const PIT& copy) = delete; // Verhindere Kopieren
// ~PIT() override = default;
// Zeitgeber initialisieren. // Zeitgeber initialisieren.
explicit PIT(int us) { explicit PIT(int us) {
PIT::interval(us); PIT::interval(us);

View File

@ -56,10 +56,9 @@ struct VbeInfoBlock {
* Beschreibung: Schalter in den Text-Modus 80x25 Zeichen. * * Beschreibung: Schalter in den Text-Modus 80x25 Zeichen. *
*****************************************************************************/ *****************************************************************************/
void VESA::initTextMode() { void VESA::initTextMode() {
allocator.free((void*)hfb); // Memory is allocated after every start and never deleted, so add that
BC_params->AX = 0x4f02; // SVFA BIOS, init mode BC_params->AX = 0x4f02; // SVFA BIOS, init mode
BC_params->BX = 0x4003; // 80x25 BC_params->BX = 0x4003; // 80x25
bios.Int(0x10); BIOS::Int(0x10);
} }
/***************************************************************************** /*****************************************************************************
@ -76,9 +75,9 @@ bool VESA::initGraphicMode(unsigned short mode) {
BC_params->AX = 0x4F00; BC_params->AX = 0x4F00;
BC_params->ES = RETURN_MEM >> 4; BC_params->ES = RETURN_MEM >> 4;
BC_params->DI = RETURN_MEM & 0xF; BC_params->DI = RETURN_MEM & 0xF;
bios.Int(0x10); BIOS::Int(0x10);
struct VbeInfoBlock* ib = (struct VbeInfoBlock*)RETURN_MEM; VbeInfoBlock* ib = reinterpret_cast<VbeInfoBlock*>(RETURN_MEM);
// Signaturen pruefen // Signaturen pruefen
if (BC_params->AX != 0x004F) { if (BC_params->AX != 0x004F) {
@ -94,18 +93,18 @@ bool VESA::initGraphicMode(unsigned short mode) {
// kout << "TotalVideoMemory: " << ((ib->TotalMemory*65536) / (1024*1024)) << " MB" << endl; // kout << "TotalVideoMemory: " << ((ib->TotalMemory*65536) / (1024*1024)) << " MB" << endl;
// Gewuenschten Grafikmodus aus Antwort suchen // Gewuenschten Grafikmodus aus Antwort suchen
unsigned short* modePtr = (unsigned short*)((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]); unsigned short* modePtr = reinterpret_cast<unsigned short*>((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]);
for (int i = 0; modePtr[i] != 0xFFFF; ++i) { for (int i = 0; modePtr[i] != 0xFFFF; ++i) {
// Gewuenschter Grafikmodus gefunden? // Gewuenschter Grafikmodus gefunden?
if (modePtr[i] == mode) { if (modePtr[i] == mode) {
struct VbeModeInfoBlock* minf = (struct VbeModeInfoBlock*)RETURN_MEM; VbeModeInfoBlock* minf = reinterpret_cast<VbeModeInfoBlock*>(RETURN_MEM);
// Weitere Infos ueber diesen Grafikmodus abfragen // Weitere Infos ueber diesen Grafikmodus abfragen
BC_params->AX = 0x4F01; BC_params->AX = 0x4F01;
BC_params->CX = mode; BC_params->CX = mode;
BC_params->ES = RETURN_MEM >> 4; BC_params->ES = RETURN_MEM >> 4;
BC_params->DI = RETURN_MEM & 0xF; BC_params->DI = RETURN_MEM & 0xF;
bios.Int(0x10); BIOS::Int(0x10);
// Text-Modi 0-3 haben keinen LFB // Text-Modi 0-3 haben keinen LFB
if (mode > 3 && (minf->attributes & 0x90) == 0) { if (mode > 3 && (minf->attributes & 0x90) == 0) {
@ -116,15 +115,15 @@ bool VESA::initGraphicMode(unsigned short mode) {
mode_nr = mode; mode_nr = mode;
xres = minf->Xres; xres = minf->Xres;
yres = minf->Yres; yres = minf->Yres;
bpp = (int)minf->bpp; bpp = static_cast<int>(minf->bpp);
lfb = minf->physbase; lfb = minf->physbase;
hfb = (unsigned int)new char[xres * yres * bpp / 8]; hfb = reinterpret_cast<unsigned int>(new char[xres * yres * bpp / 8]);
// Grafikmodus einschalten // Grafikmodus einschalten
BC_params->AX = 0x4f02; // SVFA BIOS, init mode BC_params->AX = 0x4f02; // SVFA BIOS, init mode
BC_params->BX = mode; BC_params->BX = mode;
bios.Int(0x10); BIOS::Int(0x10);
return true; return true;
} }
} }

View File

@ -8,19 +8,19 @@
* Autor: Michael Schoettner, HHU, 19.5.2022 * * Autor: Michael Schoettner, HHU, 19.5.2022 *
*****************************************************************************/ *****************************************************************************/
#ifndef __VESA_include__ #ifndef VESA_include__
#define __VESA_include__ #define VESA_include__
#include "devices/LFBgraphics.h" #include "devices/LFBgraphics.h"
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
// Ausgewaehlte Grafikmodi mit Mode-Nummer // Ausgewaehlte Grafikmodi mit Mode-Nummer
#define MODE_640_480_16BITS 0x111 constexpr const unsigned int MODE_640_480_16BITS = 0x111;
#define MODE_640_480_24BITS 0x112 constexpr const unsigned int MODE_640_480_24BITS = 0x112;
#define MODE_800_600_16BITS 0x114 constexpr const unsigned int MODE_800_600_16BITS = 0x114;
#define MODE_800_600_24BITS 0x115 constexpr const unsigned int MODE_800_600_24BITS = 0x115;
#define MODE_1024_768_16BITS 0x117 constexpr const unsigned int MODE_1024_768_16BITS = 0x117;
#define MODE_1024_768_24BITS 0x118 constexpr const unsigned int MODE_1024_768_24BITS = 0x118;
class VESA : public LFBgraphics { class VESA : public LFBgraphics {
private: private:
@ -34,7 +34,7 @@ public:
// Bestimmten Grafikmodus einschalten // Bestimmten Grafikmodus einschalten
bool initGraphicMode(unsigned short mode); bool initGraphicMode(unsigned short mode);
void initTextMode(); static void initTextMode();
}; };
#endif #endif

View File

@ -6,7 +6,7 @@
/* */ /* */
/**********************************************/ /**********************************************/
#define FONTDATAMAX_8x16 4096 constexpr unsigned int FONTDATAMAX_8x16 = 4096;
constexpr unsigned char fontdata_8x16[FONTDATAMAX_8x16] = { constexpr unsigned char fontdata_8x16[FONTDATAMAX_8x16] = {

View File

@ -6,7 +6,7 @@
/* */ /* */
/**********************************************/ /**********************************************/
#define FONTDATAMAX_8x8 2048 constexpr unsigned int FONTDATAMAX_8x8 = 2048;
constexpr unsigned char fontdata_8x8[FONTDATAMAX_8x8] = { constexpr unsigned char fontdata_8x8[FONTDATAMAX_8x8] = {

View File

@ -10,9 +10,10 @@
/* linux-m86k) by John Shifflett */ /* linux-m86k) by John Shifflett */
/* */ /* */
/**********************************************/ /**********************************************/
#define FONTDATAMAX_PEARL_8x8 2048
constexpr unsigned char fontdata_pearl_8x8[FONTDATAMAX_PEARL_8x8] = { constexpr const unsigned int FONTDATAMAX_PEARL_8x8 = 2048;
constexpr const unsigned char fontdata_pearl_8x8[FONTDATAMAX_PEARL_8x8] = {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, /* 00000000 */ 0x00, /* 00000000 */

View File

@ -1,8 +1,8 @@
// vim: set et ts=4 sw=4: // vim: set et ts=4 sw=4:
#define FONTDATAMAX_SUN_12x22 11264 constexpr const unsigned int FONTDATAMAX_SUN_12x22 = 11264;
constexpr unsigned char fontdata_sun_12x22[FONTDATAMAX_SUN_12x22] = { constexpr const unsigned char fontdata_sun_12x22[FONTDATAMAX_SUN_12x22] = {
/* 0 0x00 '^@' */ /* 0 0x00 '^@' */
0x00, 0x00, /* 000000000000 */ 0x00, 0x00, /* 000000000000 */

View File

@ -1,8 +1,8 @@
// vim: set et ts=4 sw=4: // vim: set et ts=4 sw=4:
#define FONTDATAMAX_SUN8x16 4096 constexpr const unsigned int FONTDATAMAX_SUN8x16 = 4096;
constexpr unsigned char fontdata_sun_8x16[FONTDATAMAX_SUN8x16] = { constexpr const unsigned char fontdata_sun_8x16[FONTDATAMAX_SUN8x16] = {
/* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00,
/* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, /* */ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00,

View File

@ -8,11 +8,13 @@
// Je nach Breite wird auf Bytegrenzen aufgerundet: // Je nach Breite wird auf Bytegrenzen aufgerundet:
// 8 Pixel -> 1 Byte; 12 Pixel -> 2 Byte // 8 Pixel -> 1 Byte; 12 Pixel -> 2 Byte
#ifndef __FONTS_H__ #ifndef FONTS_H__
#define __FONTS_H__ #define FONTS_H__
class Font { class Font {
public: public:
virtual ~Font() = default;
virtual const unsigned char* getChar(int c) const = 0; virtual const unsigned char* getChar(int c) const = 0;
virtual unsigned int get_char_width() const = 0; virtual unsigned int get_char_width() const = 0;
virtual unsigned int get_char_height() const = 0; virtual unsigned int get_char_height() const = 0;

View File

@ -34,9 +34,9 @@
#include "kernel/Allocator.h" #include "kernel/Allocator.h"
#include "kernel/Globals.h" #include "kernel/Globals.h"
#define MEM_SIZE_DEF 8 * 1024 * 1024 // Groesse des Speichers = 8 MB constexpr const unsigned int MEM_SIZE_DEF = 8 * 1024 * 1024; // Groesse des Speichers = 8 MB
#define HEAP_START 0x300000 // Startadresse des Heaps constexpr const unsigned int HEAP_START = 0x300000; // Startadresse des Heaps
#define HEAP_SIZE 1024 * 1024 // Default-Groesse des Heaps, falls \ constexpr const unsigned int HEAP_SIZE = 1024 * 1024; // Default-Groesse des Heaps, falls \
// nicht über das BIOS ermittelbar // nicht über das BIOS ermittelbar
/***************************************************************************** /*****************************************************************************

View File

@ -30,11 +30,11 @@
* * * *
* Autor: Michael Schoettner, HHU, 13.6.2020 * * Autor: Michael Schoettner, HHU, 13.6.2020 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Allocator_include__ #ifndef Allocator_include__
#define __Allocator_include__ #define Allocator_include__
constexpr unsigned int BASIC_ALIGN = 4; // 32 Bit so 4 Bytes? constexpr const unsigned int BASIC_ALIGN = 4; // 32 Bit so 4 Bytes?
constexpr unsigned int HEAP_MIN_FREE_BLOCK_SIZE = 64; // min. Groesse eines freien Blocks constexpr const unsigned int HEAP_MIN_FREE_BLOCK_SIZE = 64; // min. Groesse eines freien Blocks
class Allocator { class Allocator {
public: public:
@ -42,6 +42,8 @@ public:
Allocator(); Allocator();
// virtual ~Allocator() = default;
unsigned int heap_start; unsigned int heap_start;
unsigned int heap_end; unsigned int heap_end;
unsigned int heap_size; unsigned int heap_size;

View File

@ -17,13 +17,13 @@ extern "C" {
} }
// in startup.asm im GDT-Eintrag so festgeschrieben! // in startup.asm im GDT-Eintrag so festgeschrieben!
#define BIOS16_CODE_MEMORY_START 0x24000 constexpr const unsigned int BIOS16_CODE_MEMORY_START = 0x24000;
// Parameter fuer BIOS-Aufrufe (Register) // Parameter fuer BIOS-Aufrufe (Register)
#define BIOS16_PARAM_BASE 0x26000 constexpr const unsigned int BIOS16_PARAM_BASE = 0x26000;
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h) // Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf (siehe BIOS.h)
struct BIOScall_params* BC_params = (struct BIOScall_params*)BIOS16_PARAM_BASE; BIOScall_params* BC_params = reinterpret_cast<BIOScall_params*>(BIOS16_PARAM_BASE);
/***************************************************************************** /*****************************************************************************
* Methode: BIOS::BIOS * * Methode: BIOS::BIOS *
@ -33,7 +33,7 @@ struct BIOScall_params* BC_params = (struct BIOScall_params*)BIOS16_PARAM_BASE;
* im 4. GDT-Eintrag (siehe startup.asm). * * im 4. GDT-Eintrag (siehe startup.asm). *
*****************************************************************************/ *****************************************************************************/
BIOS::BIOS() { BIOS::BIOS() {
unsigned char* codeAddr = (unsigned char*)BIOS16_CODE_MEMORY_START; unsigned char* codeAddr = reinterpret_cast<unsigned char*>(BIOS16_CODE_MEMORY_START);
// mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird) // mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird)
*codeAddr = 0x66; *codeAddr = 0x66;
@ -305,7 +305,6 @@ BIOS::BIOS() {
*codeAddr = 0x66; *codeAddr = 0x66;
codeAddr++; codeAddr++;
*codeAddr = 0xCB; *codeAddr = 0xCB;
codeAddr++;
} }
/***************************************************************************** /*****************************************************************************
@ -314,10 +313,10 @@ BIOS::BIOS() {
* Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. * * Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. *
*****************************************************************************/ *****************************************************************************/
void BIOS::Int(int inter) { void BIOS::Int(int inter) {
unsigned char* ptr = (unsigned char*)BIOS16_CODE_MEMORY_START; unsigned char* ptr = reinterpret_cast<unsigned char*>(BIOS16_CODE_MEMORY_START);
// Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...) // Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...)
*(ptr + 48) = (unsigned char)inter; *(ptr + 48) = static_cast<unsigned char>(inter);
CPU::disable_int(); // Interrupts abschalten CPU::disable_int(); // Interrupts abschalten
bios_call(); bios_call();

View File

@ -7,11 +7,11 @@
* * * *
* Autor: Michael Schoettner, 13.9.2016 * * Autor: Michael Schoettner, 13.9.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __BIOS_include__ #ifndef BIOS_include__
#define __BIOS_include__ #define BIOS_include__
// Speicherseite fuer Rueckgabewerte von BIOS-Aufrufen // Speicherseite fuer Rueckgabewerte von BIOS-Aufrufen
#define RETURN_MEM 0x9F000 constexpr const unsigned int RETURN_MEM = 0x9F000;
// Struktur fuer Parameteruebergabe fuer einen BIOS-Aufruf // Struktur fuer Parameteruebergabe fuer einen BIOS-Aufruf
struct BIOScall_params { struct BIOScall_params {
@ -31,7 +31,7 @@ struct BIOScall_params {
// kein Auffuellen von bytes auf Wortgrenzen // kein Auffuellen von bytes auf Wortgrenzen
// Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf // Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf
extern struct BIOScall_params* BC_params; extern BIOScall_params* BC_params;
class BIOS { class BIOS {
public: public:
@ -41,7 +41,7 @@ public:
BIOS(); BIOS();
// BIOS-Aufruf, per Software-Interrupt // BIOS-Aufruf, per Software-Interrupt
void Int(int inter); static void Int(int inter);
}; };
#endif #endif

View File

@ -9,8 +9,8 @@
* * * *
* Autor: Michael Schoettner, 30.7.16 * * Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/ *****************************************************************************/
#ifndef __CPU_include__ #ifndef CPU_include__
#define __CPU_include__ #define CPU_include__
class CPU { class CPU {
public: public:

View File

@ -7,8 +7,8 @@
* * * *
* Autor: Michael Schoettner, 30.7.16 * * Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Globals_include__ #ifndef Globals_include__
#define __Globals_include__ #define Globals_include__
#include "devices/CGA_Stream.h" #include "devices/CGA_Stream.h"
#include "devices/Keyboard.h" #include "devices/Keyboard.h"

View File

@ -13,8 +13,8 @@
* * * *
* Autor: Michael Schoettner, 28.8.2016 * * Autor: Michael Schoettner, 28.8.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __IOport_include__ #ifndef IOport_include__
#define __IOport_include__ #define IOport_include__
class IOport { class IOport {
private: private:
@ -36,7 +36,7 @@ public:
void outb(unsigned char offset, unsigned char val) const { void outb(unsigned char offset, unsigned char val) const {
asm volatile("outb %0, %1" asm volatile("outb %0, %1"
: :
: "a"(val), "Nd"((unsigned short)(address + offset))); : "a"(val), "Nd"(static_cast<unsigned short>(address + offset)));
} }
// Wortweise Ausgabe eines Wertes ueber einen I/O-Port. // Wortweise Ausgabe eines Wertes ueber einen I/O-Port.
@ -69,7 +69,7 @@ public:
asm volatile("inb %1, %0" asm volatile("inb %1, %0"
: "=a"(ret) : "=a"(ret)
: "Nd"((unsigned short)(address + offset))); : "Nd"(static_cast<unsigned short>(address + offset)));
return ret; return ret;
} }

View File

@ -53,20 +53,20 @@
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
// Bits fuer Eintraege in der Page-Table // Bits fuer Eintraege in der Page-Table
#define PAGE_PRESENT 0x001 constexpr const unsigned int PAGE_PRESENT = 0x001;
#define PAGE_WRITEABLE 0x002 constexpr const unsigned int PAGE_WRITEABLE = 0x002;
#define PAGE_BIGSIZE 0x080 constexpr const unsigned int PAGE_BIGSIZE = 0x080;
#define PAGE_RESERVED 0x800 // Bit 11 ist frei fuer das OS constexpr const unsigned int PAGE_RESERVED = 0x800; // Bit 11 ist frei fuer das OS
// Adresse des Page-Directory (benoetigt 4 KB) // Adresse des Page-Directory (benoetigt 4 KB)
#define PAGE_DIRECTORY 0x200000 constexpr const unsigned int PAGE_DIRECTORY = 0x200000;
// Adresse der Page-Table (benoetigt 4 KB) // Adresse der Page-Table (benoetigt 4 KB)
#define PAGE_TABLE 0x201000 constexpr const unsigned int PAGE_TABLE = 0x201000;
// Start- und End-Adresse der 4 KB Seiten die durch die Page-Table adressiert werden // Start- und End-Adresse der 4 KB Seiten die durch die Page-Table adressiert werden
#define FST_ALLOCABLE_PAGE 0x202000 constexpr const unsigned int FST_ALLOCABLE_PAGE = 0x202000;
#define LST_ALLOCABLE_PAGE 0x2FF000 constexpr const unsigned int LST_ALLOCABLE_PAGE = 0x2FF000;
/***************************************************************************** /*****************************************************************************
* Funktion: pg_alloc_page * * Funktion: pg_alloc_page *
@ -77,7 +77,7 @@
unsigned int* pg_alloc_page() { unsigned int* pg_alloc_page() {
unsigned int* p_page; unsigned int* p_page;
p_page = (unsigned int*)PAGE_TABLE; p_page = reinterpret_cast<unsigned int*>(PAGE_TABLE);
// 1. Eintrag ist fuer Null-Pointer-Exception reserviert // 1. Eintrag ist fuer Null-Pointer-Exception reserviert
// ausserdem liegt an die Page-Table an Adresse PAGE_TABLE // ausserdem liegt an die Page-Table an Adresse PAGE_TABLE
@ -87,10 +87,10 @@ unsigned int* pg_alloc_page() {
// pruefe ob Page frei // pruefe ob Page frei
if (((*p_page) & PAGE_RESERVED) == 0) { if (((*p_page) & PAGE_RESERVED) == 0) {
*p_page = (*p_page | PAGE_RESERVED); *p_page = (*p_page | PAGE_RESERVED);
return (unsigned int*)(i << 12); // Address without flags (Offset 0) return reinterpret_cast<unsigned int*>(i << 12); // Address without flags (Offset 0)
} }
} }
return 0; return nullptr;
} }
/***************************************************************************** /*****************************************************************************
@ -103,7 +103,7 @@ void pg_write_protect_page(const unsigned int* p_page) {
/* hier muss Code eingefügt werden */ /* hier muss Code eingefügt werden */
unsigned int* page = (unsigned int*)PAGE_TABLE + ((unsigned int)p_page >> 12); // Pagetable entry unsigned int* page = reinterpret_cast<unsigned int*>(PAGE_TABLE) + (reinterpret_cast<unsigned int>(p_page) >> 12); // Pagetable entry
unsigned int mask = PAGE_WRITEABLE; // fill to 32bit unsigned int mask = PAGE_WRITEABLE; // fill to 32bit
*page = *page & ~mask; // set writable to 0 *page = *page & ~mask; // set writable to 0
@ -118,7 +118,7 @@ void pg_notpresent_page(const unsigned int* p_page) {
/* hier muss Code eingefügt werden */ /* hier muss Code eingefügt werden */
unsigned int* page = (unsigned int*)PAGE_TABLE + ((unsigned int)p_page >> 12); // Pagetable entry unsigned int* page = reinterpret_cast<unsigned int*>(PAGE_TABLE) + (reinterpret_cast<unsigned int>(p_page) >> 12); // Pagetable entry
unsigned int mask = PAGE_PRESENT; unsigned int mask = PAGE_PRESENT;
*page = *page & ~mask; // set present to 0 *page = *page & ~mask; // set present to 0
@ -131,7 +131,7 @@ void pg_notpresent_page(const unsigned int* p_page) {
* Bit geloescht. * * Bit geloescht. *
*****************************************************************************/ *****************************************************************************/
void pg_free_page(unsigned int* p_page) { void pg_free_page(unsigned int* p_page) {
int idx = (unsigned int)p_page >> 12; unsigned int idx = reinterpret_cast<unsigned int>(p_page) >> 12;
// ausserhalb Page ? // ausserhalb Page ?
if (idx < 1 || idx > 1023) { if (idx < 1 || idx > 1023) {
@ -139,7 +139,7 @@ void pg_free_page(unsigned int* p_page) {
} }
// Eintrag einlesen und aendern (PAGE_WRITEABLE loeschen) // Eintrag einlesen und aendern (PAGE_WRITEABLE loeschen)
p_page = (unsigned int*)PAGE_TABLE; p_page = reinterpret_cast<unsigned int*>(PAGE_TABLE);
p_page += idx; p_page += idx;
*p_page = ((idx << 12) | PAGE_WRITEABLE | PAGE_PRESENT); *p_page = ((idx << 12) | PAGE_WRITEABLE | PAGE_PRESENT);
@ -170,7 +170,7 @@ void pg_init() {
// //
// Eintrag 0: Zeiger auf 4 KB Page-Table // Eintrag 0: Zeiger auf 4 KB Page-Table
p_pdir = (unsigned int*)PAGE_DIRECTORY; p_pdir = reinterpret_cast<unsigned int*>(PAGE_DIRECTORY);
*p_pdir = PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT; *p_pdir = PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT;
// Eintraege 1-1023: Direktes Mapping (1:1) auf 4 MB Pages (ohne Page-Table) // Eintraege 1-1023: Direktes Mapping (1:1) auf 4 MB Pages (ohne Page-Table)
@ -186,7 +186,7 @@ void pg_init() {
// //
// 1. Page-Table // 1. Page-Table
// //
p_page = (unsigned int*)PAGE_TABLE; p_page = reinterpret_cast<unsigned int*>(PAGE_TABLE);
// ersten Eintrag loeschen -> not present, write protected -> Null-Pointer abfangen // ersten Eintrag loeschen -> not present, write protected -> Null-Pointer abfangen
*p_page = 0; *p_page = 0;
@ -205,5 +205,5 @@ void pg_init() {
} }
// Paging aktivieren (in startup.asm) // Paging aktivieren (in startup.asm)
paging_on((unsigned int*)PAGE_DIRECTORY); paging_on(reinterpret_cast<unsigned int*>(PAGE_DIRECTORY));
} }

View File

@ -49,8 +49,8 @@
* Autor: Michael Schoettner, 2.2.2017 * * Autor: Michael Schoettner, 2.2.2017 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Paging_include__ #ifndef Paging_include__
#define __Paging_include__ #define Paging_include__
// Externe Funktionen in startup.asm // Externe Funktionen in startup.asm
extern "C" { extern "C" {

View File

@ -20,8 +20,8 @@ void BumpAllocator::init() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
this->allocations = 0; allocations = 0;
this->next = (unsigned char*)heap_start; next = reinterpret_cast<unsigned char*>(heap_start);
log.info() << "Initialized Bump Allocator" << endl; log.info() << "Initialized Bump Allocator" << endl;
} }
@ -36,8 +36,8 @@ void BumpAllocator::dump_free_memory() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
kout << "Freier Speicher:" << endl kout << "Freier Speicher:" << endl
<< " - Next: " << hex << (unsigned int)this->next << " - Next: " << hex << reinterpret_cast<unsigned int>(next)
<< ", Allocations: " << dec << this->allocations << endl; << ", Allocations: " << dec << allocations << endl;
} }
/***************************************************************************** /*****************************************************************************
@ -51,14 +51,14 @@ void* BumpAllocator::alloc(unsigned int req_size) {
log.debug() << "Requested " << hex << req_size << " Bytes" << endl; log.debug() << "Requested " << hex << req_size << " Bytes" << endl;
if (req_size + (unsigned int)this->next > this->heap_end) { if (req_size + reinterpret_cast<unsigned int>(next) > heap_end) {
log.error() << " - More memory requested than available :(" << endl; log.error() << " - More memory requested than available :(" << endl;
return nullptr; return nullptr;
} }
void* allocated = this->next; void* allocated = next;
this->next = (unsigned char*)((unsigned int)this->next + req_size); next = reinterpret_cast<unsigned char*>(reinterpret_cast<unsigned int>(next) + req_size);
this->allocations = this->allocations + 1; allocations = allocations + 1;
log.trace() << " - Allocated " << hex << req_size << " Bytes." << endl; log.trace() << " - Allocated " << hex << req_size << " Bytes." << endl;
@ -71,5 +71,5 @@ void* BumpAllocator::alloc(unsigned int req_size) {
* Beschreibung: Nicht implementiert. * * Beschreibung: Nicht implementiert. *
*****************************************************************************/ *****************************************************************************/
void BumpAllocator::free(void* ptr) { void BumpAllocator::free(void* ptr) {
log.error() << " mm_free: ptr= " << hex << (unsigned int)ptr << ", not supported" << endl; log.error() << " mm_free: ptr= " << hex << reinterpret_cast<unsigned int>(ptr) << ", not supported" << endl;
} }

View File

@ -9,8 +9,8 @@
* Autor: Michael Schoettner, HHU, 3.3.2022 * * Autor: Michael Schoettner, HHU, 3.3.2022 *
*****************************************************************************/ *****************************************************************************/
#ifndef __BumpAllocator_include__ #ifndef BumpAllocator_include__
#define __BumpAllocator_include__ #define BumpAllocator_include__
#include "kernel/Allocator.h" #include "kernel/Allocator.h"
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
@ -27,6 +27,8 @@ public:
BumpAllocator() : log("BMP-Alloc") {}; // Allocator() called implicitely in C++ BumpAllocator() : log("BMP-Alloc") {}; // Allocator() called implicitely in C++
// ~BumpAllocator() override = default;
void init() override; void init() override;
void dump_free_memory() override; void dump_free_memory() override;
void* alloc(unsigned int req_size) override; void* alloc(unsigned int req_size) override;

View File

@ -32,10 +32,10 @@ void LinkedListAllocator::init() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
this->free_start = (free_block_t*)this->heap_start; free_start = reinterpret_cast<free_block_t*>(heap_start);
this->free_start->allocated = false; free_start->allocated = false;
this->free_start->size = this->heap_size - sizeof(free_block_t); free_start->size = heap_size - sizeof(free_block_t);
this->free_start->next = this->free_start; // Only one block, points to itself free_start->next = free_start; // Only one block, points to itself
log.info() << "Initialized LinkedList Allocator" << endl; log.info() << "Initialized LinkedList Allocator" << endl;
} }
@ -51,14 +51,14 @@ void LinkedListAllocator::dump_free_memory() {
kout << "Freier Speicher:" << endl; kout << "Freier Speicher:" << endl;
if (this->free_start == nullptr) { if (free_start == nullptr) {
kout << " - No free Blocks" << endl; kout << " - No free Blocks" << endl;
} else { } else {
kout << " - Freelist start: " << hex << (unsigned int)this->free_start << endl; kout << " - Freelist start: " << hex << reinterpret_cast<unsigned int>(free_start) << endl;
free_block_t* current = this->free_start; free_block_t* current = free_start;
do { do {
kout << " - Free Block (Start: " << hex << (unsigned int)current kout << " - Free Block (Start: " << hex << reinterpret_cast<unsigned int>(current)
<< " Size: " << hex << current->size << ")" << endl; << " Size: " << hex << current->size << ")" << endl;
current = current->next; current = current->next;
} while (current != free_start); } while (current != free_start);
@ -71,16 +71,16 @@ void LinkedListAllocator::dump_free_memory() {
* Beschreibung: Einen neuen Speicherblock allozieren. * * Beschreibung: Einen neuen Speicherblock allozieren. *
*****************************************************************************/ *****************************************************************************/
void* LinkedListAllocator::alloc(unsigned int req_size) { void* LinkedListAllocator::alloc(unsigned int req_size) {
this->lock.acquire(); lock.acquire();
/* 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
log.debug() << "Requested " << hex << req_size << " Bytes" << endl; log.debug() << "Requested " << hex << req_size << " Bytes" << endl;
if (this->free_start == nullptr) { if (free_start == nullptr) {
log.error() << " - No free memory remaining :(" << endl; log.error() << " - No free memory remaining :(" << endl;
this->lock.release(); lock.release();
return nullptr; return nullptr;
} }
@ -91,7 +91,7 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
log.trace() << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl; log.trace() << " - Rounded to word border (+" << dec << req_size_diff << " bytes)" << endl;
} }
free_block_t* current = this->free_start; free_block_t* current = free_start;
do { do {
if (current->size >= rreq_size) { // Size doesn't contain header, only usable if (current->size >= rreq_size) { // Size doesn't contain header, only usable
// Current block large enough // Current block large enough
@ -106,7 +106,7 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
// In case of only one freeblock: // In case of only one freeblock:
// [current | new_next] // [current | new_next]
free_block_t* new_next = free_block_t* new_next =
(free_block_t*)((unsigned int)current + sizeof(free_block_t) + rreq_size); reinterpret_cast<free_block_t*>(reinterpret_cast<unsigned int>(current) + sizeof(free_block_t) + rreq_size);
// If only one block exists, current->next is current // If only one block exists, current->next is current
// This shouldn't be a problem since the block gets removed from the list later // This shouldn't be a problem since the block gets removed from the list later
@ -118,18 +118,18 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
current->size = rreq_size; current->size = rreq_size;
// Next-fit // Next-fit
this->free_start = new_next; free_start = new_next;
log.trace() << " - Allocated " << hex << rreq_size << " Bytes with cutting" << endl; log.trace() << " - 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
// Next-fit // Next-fit
this->free_start = current->next; // Pointer keeps pointing to current if last block free_start = current->next; // Pointer keeps pointing to current if last block
if (this->free_start == current) { if (free_start == current) {
// No free block remaining // No free block remaining
log.trace() << " - Disabled freelist" << endl; log.trace() << " - Disabled freelist" << endl;
this->free_start = nullptr; free_start = nullptr;
} }
log.trace() << " - Allocated " << hex << current->size << " Bytes without cutting" << endl; log.trace() << " - Allocated " << hex << current->size << " Bytes without cutting" << endl;
@ -155,16 +155,16 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
// } // }
// log.debug() << "Finished check" << endl; // log.debug() << "Finished check" << endl;
log.debug() << "Returning memory address " << hex << ((unsigned int)current + sizeof(free_block_t)) << endl; log.debug() << "returning memory address " << hex << reinterpret_cast<unsigned int>(current) + sizeof(free_block_t) << endl;
this->lock.release(); lock.release();
return (void*)((unsigned int)current + sizeof(free_block_t)); // Speicheranfang, nicht header return reinterpret_cast<void*>(reinterpret_cast<unsigned int>(current) + sizeof(free_block_t)); // Speicheranfang, nicht header
} }
current = current->next; current = current->next;
} while (current != this->free_start); // Stop when arriving at the first block again } while (current != free_start); // Stop when arriving at the first block again
log.error() << " - More memory requested than available :(" << endl; log.error() << " - More memory requested than available :(" << endl;
this->lock.release(); lock.release();
return nullptr; return nullptr;
} }
@ -174,35 +174,35 @@ void* LinkedListAllocator::alloc(unsigned int req_size) {
* Beschreibung: Einen Speicherblock freigeben. * * Beschreibung: Einen Speicherblock freigeben. *
*****************************************************************************/ *****************************************************************************/
void LinkedListAllocator::free(void* ptr) { void LinkedListAllocator::free(void* ptr) {
this->lock.acquire(); lock.acquire();
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
// Account for header // Account for header
free_block_t* block_start = (free_block_t*)((unsigned int)ptr - sizeof(free_block_t)); free_block_t* block_start = reinterpret_cast<free_block_t*>(reinterpret_cast<unsigned int>(ptr) - sizeof(free_block_t));
log.debug() << "Freeing " << hex << (unsigned int)ptr << ", Size: " << block_start->size << endl; log.debug() << "Freeing " << hex << reinterpret_cast<unsigned int>(ptr) << ", Size: " << block_start->size << endl;
if (!block_start->allocated) { if (!block_start->allocated) {
log.error() << "Block already free" << endl; log.error() << "Block already free" << endl;
this->lock.release(); lock.release();
return; return;
} }
// Reenable the freelist if no block was available // Reenable the freelist if no block was available
// This also means that no merging can be done // This also means that no merging can be done
if (this->free_start == nullptr) { if (free_start == nullptr) {
this->free_start = block_start; free_start = block_start;
block_start->allocated = false; block_start->allocated = false;
block_start->next = block_start; block_start->next = block_start;
log.trace() << " - Enabling freelist with one block" << endl; log.trace() << " - Enabling freelist with one block" << endl;
this->lock.release(); lock.release();
return; return;
} }
free_block_t* next_block = free_block_t* next_block =
(free_block_t*)((unsigned int)block_start + sizeof(free_block_t) + block_start->size); reinterpret_cast<free_block_t*>(reinterpret_cast<unsigned int>(block_start) + sizeof(free_block_t) + block_start->size);
// Find the next free block, multiple next blocks can be allocated so walk through them // Find the next free block, multiple next blocks can be allocated so walk through them
free_block_t* next_free = block_start->next; free_block_t* next_free = block_start->next;
@ -212,7 +212,7 @@ void LinkedListAllocator::free(void* ptr) {
free_block_t* previous_free = LinkedListAllocator::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); reinterpret_cast<free_block_t*>(reinterpret_cast<unsigned int>(previous_free) + sizeof(free_block_t) + previous_free->size);
// We have: [previous_free | previous_free_next | <> | block_start | next_block | <> | next_free] // We have: [previous_free | previous_free_next | <> | block_start | next_block | <> | next_free]
// The <> spaces don't have to exist and next_block could be the same as next_free // The <> spaces don't have to exist and next_block could be the same as next_free
@ -254,10 +254,10 @@ void LinkedListAllocator::free(void* ptr) {
// If thats the case I should set the next pointer to the next adjacent block // If thats the case I should set the next pointer to the next adjacent block
// when allocating a new block // when allocating a new block
if (this->free_start == next_free) { if (free_start == next_free) {
// next_free is now invalid after merge // next_free is now invalid after merge
log.trace() << " - Moving freelist start to " << hex << (unsigned int)block_start << endl; log.trace() << " - Moving freelist start to " << hex << reinterpret_cast<unsigned int>(block_start) << endl;
this->free_start = block_start; free_start = block_start;
} }
} else { } else {
// Can't merge forward so size stays the same // Can't merge forward so size stays the same
@ -283,16 +283,16 @@ void LinkedListAllocator::free(void* ptr) {
// For pointers to block_start the same as above applies // For pointers to block_start the same as above applies
// so I don't think I have to manage anything else here // so I don't think I have to manage anything else here
if (this->free_start == block_start) { if (free_start == block_start) {
// block_start is now invalid after merge // block_start is now invalid after merge
log.trace() << " - Moving freelist start to " << hex << (unsigned int)previous_free << endl; log.trace() << " - Moving freelist start to " << hex << reinterpret_cast<unsigned int>(previous_free) << endl;
this->free_start = previous_free; free_start = previous_free;
} }
} }
// Depending on the merging this might write into the block, but doesn't matter // Depending on the merging this might write into the block, but doesn't matter
block_start->allocated = false; block_start->allocated = false;
this->lock.release(); lock.release();
} }
free_block_t* LinkedListAllocator::find_previous_block(free_block_t* next_block) { free_block_t* LinkedListAllocator::find_previous_block(free_block_t* next_block) {

View File

@ -9,8 +9,8 @@
* Autor: Michael Schoettner, HHU, 13.6.2020 * * Autor: Michael Schoettner, HHU, 13.6.2020 *
*****************************************************************************/ *****************************************************************************/
#ifndef __LinkedListAllocator_include__ #ifndef LinkedListAllocator_include__
#define __LinkedListAllocator_include__ #define LinkedListAllocator_include__
#include "kernel/Allocator.h" #include "kernel/Allocator.h"
#include "lib/SpinLock.h" #include "lib/SpinLock.h"
@ -47,6 +47,8 @@ public:
LinkedListAllocator() : log("LL-Alloc") {} LinkedListAllocator() : log("LL-Alloc") {}
// ~LinkedListAllocator() override = default;
void init() override; void init() override;
void dump_free_memory() override; void dump_free_memory() override;
void* alloc(unsigned int req_size) override; void* alloc(unsigned int req_size) override;

View File

@ -2,27 +2,29 @@
#include "kernel/Globals.h" #include "kernel/Globals.h"
void TreeAllocator::init() { void TreeAllocator::init() {
this->free_start = (tree_block_t*)this->heap_start; free_start = reinterpret_cast<tree_block_t*>(heap_start);
this->free_start->allocated = false; free_start->allocated = false;
this->free_start->left = nullptr; free_start->left = nullptr;
this->free_start->right = nullptr; free_start->right = nullptr;
this->free_start->parent = nullptr; free_start->parent = nullptr;
this->free_start->red = false; // The root is always black free_start->red = false; // The root is always black
this->free_start->next = (list_block_t*)this->free_start; free_start->next = reinterpret_cast<list_block_t*>(free_start);
this->free_start->previous = (list_block_t*)this->free_start; free_start->previous = reinterpret_cast<list_block_t*>(free_start);
log.info() << "Initialized Tree Allocator" << endl; log.info() << "Initialized Tree Allocator" << endl;
} }
void TreeAllocator::dump_free_memory() { void TreeAllocator::dump_free_memory() {
kout << "Free Memory:" << endl; kout << "Free Memory:" << endl;
list_block_t* current = (list_block_t*)this->heap_start; list_block_t* current = reinterpret_cast<list_block_t*>(heap_start);
do { do {
if (!current->allocated) { if (!current->allocated) {
kout << " - Free Block at " << (unsigned int)current << ", Size: " << (unsigned int)current->next - (unsigned int)current << endl; kout << " - Free Block at " << reinterpret_cast<unsigned int>(current) << ", Size: "
<< reinterpret_cast<unsigned int>(current->next) - reinterpret_cast<unsigned int>(current)
<< endl;
} }
current = current->next; current = current->next;
} while ((unsigned int)current != this->heap_start); } while (reinterpret_cast<unsigned int>(current) != heap_start);
} }
void* TreeAllocator::alloc(unsigned int req_size) { void* TreeAllocator::alloc(unsigned int req_size) {
@ -43,7 +45,7 @@ void* TreeAllocator::alloc(unsigned int req_size) {
} }
// 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 = rbt_search_bestfit(rreq_size);
if (best_fit == nullptr) { if (best_fit == nullptr) {
log.error() << " - No block found" << endl; log.error() << " - No block found" << endl;
return nullptr; return nullptr;
@ -54,8 +56,8 @@ void* TreeAllocator::alloc(unsigned int req_size) {
return nullptr; return nullptr;
} }
best_fit->allocated = true; best_fit->allocated = true;
unsigned int size = this->get_size(best_fit); unsigned int size = get_size(best_fit);
log.trace() << " - Found best-fit: " << hex << (unsigned int)best_fit << endl; log.trace() << " - Found best-fit: " << hex << reinterpret_cast<unsigned int>(best_fit) << endl;
// HACK: I didn't want to handle situations with only one block (where the tree root would // HACK: I didn't want to handle situations with only one block (where the tree root would
// get removed), so I make sure there are always at least 2 blocks by inserting a dummy // get removed), so I make sure there are always at least 2 blocks by inserting a dummy
@ -63,19 +65,20 @@ void* TreeAllocator::alloc(unsigned int req_size) {
// I should change this so it only happens when only one block exists in the freelist // I should change this so it only happens when only one block exists in the freelist
tree_block_t dummy; tree_block_t dummy;
dummy.allocated = false; dummy.allocated = false;
this->rbt_insert(&dummy); // I use the address of the stack allocated struct because it is rbt_insert(&dummy); // I use the address of the stack allocated struct because it is
// removed before exiting the function // removed before exiting the function
this->rbt_remove(best_fit); // BUG: Can trigger bluescreen rbt_remove(best_fit); // BUG: Can trigger bluescreen
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
log.trace() << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl; log.trace() << " - 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
= reinterpret_cast<tree_block_t*>(reinterpret_cast<char*>(best_fit) + sizeof(list_block_t) + rreq_size);
new_block->allocated = false; new_block->allocated = false;
this->dll_insert(best_fit, new_block); dll_insert(best_fit, new_block);
this->rbt_insert(new_block); rbt_insert(new_block);
} else { } else {
// 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
@ -84,16 +87,18 @@ void* TreeAllocator::alloc(unsigned int req_size) {
} }
// HACK: Remove the dummy element // HACK: Remove the dummy element
this->rbt_remove(&dummy); rbt_remove(&dummy);
log.trace() << " - Returned address " << hex << (unsigned int)((char*)best_fit + sizeof(list_block_t)) << endl; log.trace() << " - Returned address " << hex
return (void*)((char*)best_fit + sizeof(list_block_t)); << reinterpret_cast<unsigned int>(reinterpret_cast<char*>(best_fit) + sizeof(list_block_t))
<< endl;
return reinterpret_cast<void*>(reinterpret_cast<char*>(best_fit) + sizeof(list_block_t));
} }
void TreeAllocator::free(void* ptr) { void TreeAllocator::free(void* ptr) {
log.info() << "Freeing " << hex << (unsigned int)ptr << endl; log.info() << "Freeing " << hex << reinterpret_cast<unsigned int>(ptr) << endl;
list_block_t* block = (list_block_t*)((char*)ptr - sizeof(list_block_t)); list_block_t* block = reinterpret_cast<list_block_t*>(reinterpret_cast<char*>(ptr) - sizeof(list_block_t));
if (!block->allocated) { if (!block->allocated) {
// Block already free // Block already free
return; return;
@ -105,25 +110,25 @@ void TreeAllocator::free(void* ptr) {
if (next->allocated && previous->allocated) { if (next->allocated && previous->allocated) {
// No merge // No merge
this->rbt_insert((tree_block_t*)block); rbt_insert(reinterpret_cast<tree_block_t*>(block));
return; return;
} }
// HACK: Same as when allocating // HACK: Same as when allocating
tree_block_t dummy; tree_block_t dummy;
dummy.allocated = false; dummy.allocated = false;
this->rbt_insert(&dummy); // I use the address of the stack allocated struct because it is rbt_insert(&dummy); // I use the address of the stack allocated struct because it is
if (!next->allocated) { if (!next->allocated) {
// Merge forward // Merge forward
log.trace() << " - Merging forward" << endl; log.trace() << " - 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); dll_remove(next);
this->rbt_remove((tree_block_t*)next); // BUG: Bluescreen if next is the only block in the freelist rbt_remove(reinterpret_cast<tree_block_t*>(next)); // BUG: Bluescreen if next is the only block in the freelist
if (previous->allocated) { if (previous->allocated) {
// Don't insert if removed later because of backward merge // Don't insert if removed later because of backward merge
this->rbt_insert((tree_block_t*)block); rbt_insert(reinterpret_cast<tree_block_t*>(block));
} }
} }
@ -133,26 +138,26 @@ void TreeAllocator::free(void* ptr) {
// 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
this->dll_remove(block); dll_remove(block);
this->rbt_remove((tree_block_t*)previous); rbt_remove(reinterpret_cast<tree_block_t*>(previous));
this->rbt_insert((tree_block_t*)previous); // Reinsert with new size rbt_insert(reinterpret_cast<tree_block_t*>(previous)); // Reinsert with new size
} }
// HACK: Same as when allocating // HACK: Same as when allocating
this->rbt_remove(&dummy); rbt_remove(&dummy);
} }
unsigned int TreeAllocator::get_size(list_block_t* block) const { unsigned int TreeAllocator::get_size(list_block_t* block) const {
if (block->next == block) { if (block->next == block) {
// Only one block exists // Only one block exists
return this->heap_end - ((unsigned int)block + sizeof(list_block_t)); return heap_end - (reinterpret_cast<unsigned int>(block) + sizeof(list_block_t));
} }
if ((unsigned int)block->next > (unsigned int)block) { if (reinterpret_cast<unsigned int>(block->next) > reinterpret_cast<unsigned int>(block)) {
// Next block is placed later in memory // Next block is placed later in memory
return (unsigned int)block->next - ((unsigned int)block + sizeof(list_block_t)); return reinterpret_cast<unsigned int>(block->next) - (reinterpret_cast<unsigned int>(block) + sizeof(list_block_t));
} }
// Next block is placed earlier in memory which means block is at memory end // Next block is placed earlier in memory which means block is at memory end
return (unsigned int)this->heap_end - ((unsigned int)block + sizeof(list_block_t)); return reinterpret_cast<unsigned int>(heap_end) - (reinterpret_cast<unsigned int>(block) + sizeof(list_block_t));
} }

View File

@ -1,5 +1,5 @@
#ifndef __TreeAllocator_include__ #ifndef TreeAllocator_include__
#define __TreeAllocator_include__ #define TreeAllocator_include__
#include "kernel/Allocator.h" #include "kernel/Allocator.h"
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
@ -40,7 +40,7 @@ private:
// 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;
unsigned int get_size(tree_block_t* block) const { return this->get_size((list_block_t*)block); } unsigned int get_size(tree_block_t* block) const { return get_size(reinterpret_cast<list_block_t*>(block)); }
void dump_free_memory(tree_block_t* node); void dump_free_memory(tree_block_t* node);
@ -57,10 +57,12 @@ private:
void rbt_fix_remove(tree_block_t* x); void rbt_fix_remove(tree_block_t* x);
tree_block_t* rbt_search_bestfit(tree_block_t* node, unsigned int req_size); tree_block_t* rbt_search_bestfit(tree_block_t* node, unsigned int req_size);
tree_block_t* rbt_search_bestfit(unsigned int req_size) { return this->rbt_search_bestfit(this->free_start, req_size); } tree_block_t* rbt_search_bestfit(unsigned int req_size) { return rbt_search_bestfit(free_start, req_size); }
void dll_insert(list_block_t* previous, list_block_t* node); void dll_insert(list_block_t* previous, list_block_t* node);
void dll_insert(tree_block_t* previous, tree_block_t* node) { this->dll_insert((list_block_t*)previous, (list_block_t*)node); } void dll_insert(tree_block_t* previous, tree_block_t* node) {
dll_insert(reinterpret_cast<list_block_t*>(previous), reinterpret_cast<list_block_t*>(node));
}
void dll_remove(list_block_t* node); void dll_remove(list_block_t* node);
public: public:
@ -68,6 +70,8 @@ public:
TreeAllocator() : log("RBT-Alloc") {}; TreeAllocator() : log("RBT-Alloc") {};
// ~TreeAllocator() override = default;
void init() override; void init() override;
void dump_free_memory() override; void dump_free_memory() override;
void* alloc(unsigned int req_size) override; void* alloc(unsigned int req_size) override;

View File

@ -1,12 +1,11 @@
#include "kernel/allocator/TreeAllocator.h" #include "kernel/allocator/TreeAllocator.h"
#include "kernel/Globals.h"
// RBT code taken from https://github.com/Bibeknam/algorithmtutorprograms // RBT code taken from https://github.com/Bibeknam/algorithmtutorprograms
// START copy from algorithmtutorprograms // START copy from algorithmtutorprograms
void TreeAllocator::rbt_transplant(tree_block_t* a, tree_block_t* b) { void TreeAllocator::rbt_transplant(tree_block_t* a, tree_block_t* b) {
if (a->parent == nullptr) { if (a->parent == nullptr) {
this->free_start = b; free_start = b;
} else if (a == a->parent->left) { } else if (a == a->parent->left) {
a->parent->left = b; a->parent->left = b;
} else { } else {
@ -25,11 +24,11 @@ void TreeAllocator::rbt_insert(tree_block_t* node) {
node->red = true; // new node must be red node->red = true; // new node must be red
tree_block_t* y = nullptr; tree_block_t* y = nullptr;
tree_block_t* x = this->free_start; tree_block_t* x = free_start;
while (x != nullptr) { while (x != nullptr) {
y = x; y = x;
if (this->get_size(node) < this->get_size(x)) { if (get_size(node) < get_size(x)) {
x = x->left; x = x->left;
} else { } else {
x = x->right; x = x->right;
@ -39,8 +38,8 @@ void TreeAllocator::rbt_insert(tree_block_t* node) {
// y is parent of x // y is parent of x
node->parent = y; node->parent = y;
if (y == nullptr) { if (y == nullptr) {
this->free_start = node; free_start = node;
} else if (this->get_size(node) < this->get_size(y)) { } else if (get_size(node) < get_size(y)) {
y->left = node; y->left = node;
} else { } else {
y->right = node; y->right = node;
@ -58,7 +57,7 @@ void TreeAllocator::rbt_insert(tree_block_t* node) {
} }
// Fix the tree // Fix the tree
this->rbt_fix_insert(node); rbt_fix_insert(node);
} }
// fix the red-black tree // fix the red-black tree
@ -77,12 +76,12 @@ void TreeAllocator::rbt_fix_insert(tree_block_t* k) {
if (k == k->parent->left) { if (k == k->parent->left) {
// case 3.2.2 // case 3.2.2
k = k->parent; k = k->parent;
this->rbt_rot_r(k); rbt_rot_r(k);
} }
// case 3.2.1 // case 3.2.1
k->parent->red = false; k->parent->red = false;
k->parent->parent->red = true; k->parent->parent->red = true;
this->rbt_rot_l(k->parent->parent); rbt_rot_l(k->parent->parent);
} }
} else { } else {
u = k->parent->parent->right; // uncle u = k->parent->parent->right; // uncle
@ -97,19 +96,19 @@ void TreeAllocator::rbt_fix_insert(tree_block_t* k) {
if (k == k->parent->right) { if (k == k->parent->right) {
// mirror case 3.2.2 // mirror case 3.2.2
k = k->parent; k = k->parent;
this->rbt_rot_l(k); rbt_rot_l(k);
} }
// mirror case 3.2.1 // mirror case 3.2.1
k->parent->red = false; k->parent->red = false;
k->parent->parent->red = true; k->parent->parent->red = true;
this->rbt_rot_r(k->parent->parent); rbt_rot_r(k->parent->parent);
} }
} }
if (k == this->free_start) { if (k == free_start) {
break; break;
} }
} }
this->free_start->red = false; free_start->red = false;
} }
// rotate left at node x // rotate left at node x
@ -121,7 +120,7 @@ void TreeAllocator::rbt_rot_l(tree_block_t* x) {
} }
y->parent = x->parent; y->parent = x->parent;
if (x->parent == nullptr) { if (x->parent == nullptr) {
this->free_start = y; free_start = y;
} else if (x == x->parent->left) { } else if (x == x->parent->left) {
x->parent->left = y; x->parent->left = y;
} else { } else {
@ -140,7 +139,7 @@ void TreeAllocator::rbt_rot_r(tree_block_t* x) {
} }
y->parent = x->parent; y->parent = x->parent;
if (x->parent == nullptr) { if (x->parent == nullptr) {
this->free_start = y; free_start = y;
} else if (x == x->parent->right) { } else if (x == x->parent->right) {
x->parent->right = y; x->parent->right = y;
} else { } else {
@ -166,43 +165,43 @@ void TreeAllocator::rbt_remove(tree_block_t* z) {
bool y_original_red = y->red; bool y_original_red = y->red;
if (z->left == nullptr) { if (z->left == nullptr) {
x = z->right; x = z->right;
this->rbt_transplant(z, z->right); rbt_transplant(z, z->right);
} else if (z->right == nullptr) { } else if (z->right == nullptr) {
x = z->left; x = z->left;
this->rbt_transplant(z, z->left); rbt_transplant(z, z->left);
} else { } else {
y = this->rbt_minimum(z->right); y = rbt_minimum(z->right);
y_original_red = y->red; y_original_red = y->red;
x = y->right; x = y->right;
if (y->parent == z) { if (y->parent == z) {
x->parent = y; x->parent = y;
} else { } else {
this->rbt_transplant(y, y->right); rbt_transplant(y, y->right);
y->right = z->right; y->right = z->right;
y->right->parent = y; y->right->parent = y;
} }
this->rbt_transplant(z, y); rbt_transplant(z, y);
y->left = z->left; y->left = z->left;
y->left->parent = y; y->left->parent = y;
y->red = z->red; y->red = z->red;
} }
if (!y_original_red) { if (!y_original_red) {
this->rbt_fix_remove(x); rbt_fix_remove(x);
} }
} }
// 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) { while (x != 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) {
// case 3.1 // case 3.1
s->red = false; s->red = false;
x->parent->red = true; x->parent->red = true;
this->rbt_rot_l(x->parent); rbt_rot_l(x->parent);
s = x->parent->right; s = x->parent->right;
} }
@ -215,7 +214,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
// case 3.3 // case 3.3
s->left->red = false; s->left->red = false;
s->red = true; s->red = true;
this->rbt_rot_r(s); rbt_rot_r(s);
s = x->parent->right; s = x->parent->right;
} }
@ -223,8 +222,8 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
s->red = x->parent->red; s->red = x->parent->red;
x->parent->red = false; x->parent->red = false;
s->right->red = false; s->right->red = false;
this->rbt_rot_l(x->parent); rbt_rot_l(x->parent);
x = this->free_start; x = free_start;
} }
} else { } else {
s = x->parent->left; s = x->parent->left;
@ -232,7 +231,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
// case 3.1 // case 3.1
s->red = false; s->red = false;
x->parent->red = true; x->parent->red = true;
this->rbt_rot_r(x->parent); rbt_rot_r(x->parent);
s = x->parent->left; s = x->parent->left;
} }
@ -245,7 +244,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
// case 3.3 // case 3.3
s->right->red = false; s->right->red = false;
s->red = true; s->red = true;
this->rbt_rot_l(s); rbt_rot_l(s);
s = x->parent->left; s = x->parent->left;
} }
@ -253,8 +252,8 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) {
s->red = x->parent->red; s->red = x->parent->red;
x->parent->red = false; x->parent->red = false;
s->left->red = false; s->left->red = false;
this->rbt_rot_r(x->parent); rbt_rot_r(x->parent);
x = this->free_start; x = free_start;
} }
} }
} }
@ -268,17 +267,17 @@ tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, unsigned int
return nullptr; return nullptr;
} }
if (req_size < this->get_size(node)) { if (req_size < get_size(node)) {
if (node->left != nullptr && this->get_size(node->left) >= req_size) { if (node->left != nullptr && get_size(node->left) >= req_size) {
return this->rbt_search_bestfit(node->left, req_size); return rbt_search_bestfit(node->left, req_size);
} }
return node; return node;
} }
if (req_size > this->get_size(node)) { if (req_size > get_size(node)) {
if (node->right != nullptr && this->get_size(node->right) >= req_size) { if (node->right != nullptr && get_size(node->right) >= req_size) {
return this->rbt_search_bestfit(node->right, req_size); return rbt_search_bestfit(node->right, req_size);
} }
// Block doesn't fit // Block doesn't fit

View File

@ -9,7 +9,6 @@
* * * *
* Autor: Michael Schoettner, 11.12.2018 * * Autor: Michael Schoettner, 11.12.2018 *
*****************************************************************************/ *****************************************************************************/
#include "devices/CGA.h"
#include "kernel/Globals.h" #include "kernel/Globals.h"
// in startup.asm // in startup.asm
@ -68,11 +67,11 @@ int bs_ypos = 0;
void bs_clear() { void bs_clear() {
unsigned int x; unsigned int x;
unsigned int y; unsigned int y;
unsigned short* ptr = (unsigned short*)0xb8000; unsigned short* ptr = reinterpret_cast<unsigned short*>(0xb8000);
for (x = 0; x < 80; x++) { for (x = 0; x < 80; x++) {
for (y = 0; y < 25; y++) { for (y = 0; y < 25; y++) {
*(ptr + y * 80 + x) = (short)0x1F00; *(ptr + y * 80 + x) = static_cast<short>(0x1F00);
} }
} }
@ -96,7 +95,7 @@ void bs_lf() {
* Beschreibung: Ein Zeichen ausgeben. * * Beschreibung: Ein Zeichen ausgeben. *
*****************************************************************************/ *****************************************************************************/
void bs_print_char(char c) { void bs_print_char(char c) {
unsigned char* ptr = (unsigned char*)0xb8000; unsigned char* ptr = reinterpret_cast<unsigned char*>(0xb8000);
*(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c; *(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c;
bs_xpos++; bs_xpos++;
@ -122,9 +121,9 @@ void bs_print_string(char* str) {
*****************************************************************************/ *****************************************************************************/
void bs_printHexDigit(int c) { void bs_printHexDigit(int c) {
if (c < 10) { if (c < 10) {
bs_print_char('0' + (unsigned char)c); bs_print_char('0' + static_cast<unsigned char>(c));
} else { } else {
bs_print_char('A' + (unsigned char)(c - 10)); bs_print_char('A' + static_cast<unsigned char>(c - 10));
} }
} }
@ -145,7 +144,7 @@ void bs_print_uintHex(unsigned int c) {
* Beschreibung: String mit Integer ausgeben. Wird verwendet um ein * * Beschreibung: String mit Integer ausgeben. Wird verwendet um ein *
* Register auszugeben. * * Register auszugeben. *
*****************************************************************************/ *****************************************************************************/
void bs_printReg(char* str, int value) { void bs_printReg(char* str, unsigned int value) {
bs_print_string(str); bs_print_string(str);
bs_print_uintHex(value); bs_print_uintHex(value);
bs_print_string(" \0"); bs_print_string(" \0");
@ -211,7 +210,7 @@ void bs_dump(unsigned int exceptionNr) {
get_int_esp(&int_esp); get_int_esp(&int_esp);
// wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen // wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen
sptr = (unsigned int*)*int_esp; sptr = reinterpret_cast<unsigned int*>(*int_esp);
bs_lf(); bs_lf();
@ -252,7 +251,7 @@ void bs_dump(unsigned int exceptionNr) {
// Exception mit Error-Code? // Exception mit Error-Code?
if (has_error_code == 1) { if (has_error_code == 1) {
int error_nr = *(sptr + 8); unsigned int error_nr = *(sptr + 8);
if (exceptionNr == 14) { if (exceptionNr == 14) {
if (error_nr == 3) { if (error_nr == 3) {
@ -278,7 +277,7 @@ void bs_dump(unsigned int exceptionNr) {
bs_print_string("Calling Stack:\0"); bs_print_string("Calling Stack:\0");
bs_lf(); bs_lf();
int x = 0; int x = 0;
unsigned int* ebp = (unsigned int*)*(sptr + 2); unsigned int* ebp = reinterpret_cast<unsigned int*>(*(sptr + 2));
unsigned int raddr; unsigned int raddr;
// solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10 // solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10
@ -289,7 +288,7 @@ void bs_dump(unsigned int exceptionNr) {
bs_lf(); bs_lf();
// dynamische Kette -> zum Aufrufer // dynamische Kette -> zum Aufrufer
ebp = (unsigned int*)*ebp; ebp = reinterpret_cast<unsigned int*>(*ebp);
x++; x++;
} }

View File

@ -10,8 +10,8 @@
* Autor: Michael Schoettner, 2.2.2017 * * Autor: Michael Schoettner, 2.2.2017 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Bluescreen_include__ #ifndef Bluescreen_include__
#define __Bluescreen_include__ #define Bluescreen_include__
// dump blue screen (will not return) // dump blue screen (will not return)
void bs_dump(unsigned int exceptionNr); void bs_dump(unsigned int exceptionNr);

View File

@ -9,16 +9,16 @@
* * * *
* Autor: Michael Schoettner, 06.04.20 * * Autor: Michael Schoettner, 06.04.20 *
*****************************************************************************/ *****************************************************************************/
#ifndef __ISR_include__ #ifndef ISR_include__
#define __ISR_include__ #define ISR_include__
class ISR { class ISR {
public:
private:
ISR(const ISR& copy) = delete; // Verhindere Kopieren ISR(const ISR& copy) = delete; // Verhindere Kopieren
public: // virtual ~ISR() = default;
ISR() {}
ISR() = default;
// Unterbrechungsbehandlungsroutine // Unterbrechungsbehandlungsroutine
virtual void trigger() = 0; virtual void trigger() = 0;

View File

@ -15,7 +15,7 @@
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/interrupts/Bluescreen.h" #include "kernel/interrupts/Bluescreen.h"
extern "C" void int_disp(unsigned int slot); extern "C" void int_disp(unsigned int vector);
/***************************************************************************** /*****************************************************************************
* Prozedur: int_disp * * Prozedur: int_disp *
@ -60,12 +60,12 @@ int IntDispatcher::assign(unsigned int vector, ISR& isr) {
/* hier muss Code eingefuegt werden */ /* hier muss Code eingefuegt werden */
if (vector >= this->size) { if (vector >= size) {
log.error() << "Invalid vector number when assigning" << endl; log.error() << "Invalid vector number when assigning" << endl;
return -1; return -1;
} }
this->map[vector] = &isr; map[vector] = &isr;
log.info() << "Registered ISR for vector " << dec << vector << endl; log.info() << "Registered ISR for vector " << dec << vector << endl;
return 0; return 0;
@ -85,11 +85,11 @@ int IntDispatcher::report(unsigned int vector) {
/* hier muss Code eingefuegt werden */ /* hier muss Code eingefuegt werden */
if (vector >= this->size) { if (vector >= size) {
return -1; return -1;
} }
ISR* isr = this->map[vector]; ISR* isr = map[vector];
if (isr == nullptr) { if (isr == nullptr) {
log.error() << "No ISR registered for vector " << vector << endl; log.error() << "No ISR registered for vector " << vector << endl;

View File

@ -10,18 +10,19 @@
* * * *
* Autor: Michael Schoettner, 30.7.16 * * Autor: Michael Schoettner, 30.7.16 *
*****************************************************************************/ *****************************************************************************/
#ifndef __IntDispatcher_include__ #ifndef IntDispatcher_include__
#define __IntDispatcher_include__ #define IntDispatcher_include__
#include "kernel/interrupts/ISR.h" #include "kernel/interrupts/ISR.h"
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
#include "user/lib/Array.h"
class IntDispatcher { class IntDispatcher {
private: private:
NamedLogger log; NamedLogger log;
enum { size = 256 }; enum { size = 256 };
ISR* map[size]; bse::array<ISR*, size> map;
public: public:
IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren

View File

@ -14,8 +14,8 @@
* * * *
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
*****************************************************************************/ *****************************************************************************/
#ifndef __PIC_include__ #ifndef PIC_include__
#define __PIC_include__ #define PIC_include__
#include "kernel/IOport.h" #include "kernel/IOport.h"

View File

@ -8,8 +8,8 @@
* Autor: Michael, Schoettner, HHU, 13.8.2016 * * Autor: Michael, Schoettner, HHU, 13.8.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __IdleThread_include__ #ifndef IdleThread_include__
#define __IdleThread_include__ #define IdleThread_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
@ -20,10 +20,10 @@ public:
IdleThread() : Thread("IdleThread") {} IdleThread() : Thread("IdleThread") {}
/*[[noreturn]]*/ void run() override { [[noreturn]] void run() override {
// Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert // Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert
log.info() << "IdleThread enabled preemption" << endl; log.info() << "IdleThread enabled preemption" << endl;
scheduler.enable_preemption(this->tid); scheduler.enable_preemption(tid);
if (!scheduler.preemption_enabled()) { if (!scheduler.preemption_enabled()) {
log.error() << "Preemption disabled" << endl; log.error() << "Preemption disabled" << endl;
} }

View File

@ -9,8 +9,8 @@
* Autor: Michael, Schoettner, HHU, 22.8.2016 * * Autor: Michael, Schoettner, HHU, 22.8.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Scheduler_include__ #ifndef Scheduler_include__
#define __Scheduler_include__ #define Scheduler_include__
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
@ -33,8 +33,8 @@ private:
unsigned int idle_tid = 0U; unsigned int idle_tid = 0U;
// Roughly the old dispatcher functionality // Roughly the old dispatcher functionality
/*[[noreturn]]*/ void start(bse::vector<bse::unique_ptr<Thread>>::iterator next); // Start next without prev void start(bse::vector<bse::unique_ptr<Thread>>::iterator next); // Start next without prev
/*[[noreturn]]*/ void switch_to(Thread* prev_raw, bse::vector<bse::unique_ptr<Thread>>::iterator next); // Switch from prev to next void switch_to(Thread* prev_raw, bse::vector<bse::unique_ptr<Thread>>::iterator next); // Switch from prev to next
// Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird) // Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird)
void enable_preemption(unsigned int tid) { idle_tid = tid; } void enable_preemption(unsigned int tid) { idle_tid = tid; }
@ -63,7 +63,7 @@ public:
bool preemption_enabled() const { return idle_tid != 0U; } bool preemption_enabled() const { return idle_tid != 0U; }
// Scheduler starten // Scheduler starten
/*[[noreturn]]*/ void schedule(); void schedule();
// Helper that directly constructs the thread, then readys it // Helper that directly constructs the thread, then readys it
template<typename T, typename... Args> template<typename T, typename... Args>
@ -80,7 +80,7 @@ public:
// NOTE: When a thread exits itself it will disappear... // NOTE: When a thread exits itself it will disappear...
// Maybe put exited threads in an exited queue? // Maybe put exited threads in an exited queue?
// Then they would have to be acquired from there to exit... // Then they would have to be acquired from there to exit...
/* [[noreturn]] */ void exit(); // Returns on error because we don't have exceptions void exit(); // Returns on error because we don't have exceptions
// Thread mit 'Gewalt' terminieren // Thread mit 'Gewalt' terminieren
void kill(unsigned int tid, bse::unique_ptr<Thread>* ptr); void kill(unsigned int tid, bse::unique_ptr<Thread>* ptr);
@ -94,13 +94,13 @@ public:
void nice_kill(unsigned int tid) { nice_kill(tid, nullptr); } void nice_kill(unsigned int tid) { nice_kill(tid, nullptr); }
// CPU freiwillig abgeben und Auswahl des naechsten Threads // CPU freiwillig abgeben und Auswahl des naechsten Threads
/* [[noreturn]] */ void yield(); // Returns when only the idle thread runs void yield(); // Returns when only the idle thread runs
// Thread umschalten; wird aus der ISR des PITs gerufen // Thread umschalten; wird aus der ISR des PITs gerufen
/* [[noreturn]] */ void preempt(); // Returns when only the idle thread runs void preempt(); // Returns when only the idle thread runs
// Blocks current thread (move to block_queue) // Blocks current thread (move to block_queue)
/* [[noreturn]] */ void block(); // Returns on error because we don't have exceptions void block(); // Returns on error because we don't have exceptions
// Deblock by tid (move to ready_queue) // Deblock by tid (move to ready_queue)
void deblock(unsigned int tid); void deblock(unsigned int tid);

View File

@ -56,20 +56,20 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread*
// wird, sie darf also nicht terminieren, sonst kracht's. // wird, sie darf also nicht terminieren, sonst kracht's.
// I thought this syntax was a bit clearer than decrementing a pointer // I thought this syntax was a bit clearer than decrementing a pointer
stack[-1] = (unsigned int)object; stack[-1] = reinterpret_cast<unsigned int>(object);
stack[-2] = 0x131155U; stack[-2] = 0x131155U;
stack[-3] = (unsigned int)kickoff; stack[-3] = reinterpret_cast<unsigned int>(kickoff);
stack[-4] = 0; // EAX stack[-4] = 0; // EAX
stack[-5] = 0; // ECX stack[-5] = 0; // ECX
stack[-6] = 0; // EDX stack[-6] = 0; // EDX
stack[-7] = 0; // EBX stack[-7] = 0; // EBX
stack[-8] = (unsigned int)&stack[-3]; // ESP stack[-8] = reinterpret_cast<unsigned int>(&stack[-3]); // ESP
stack[-9] = 0; // EBP stack[-9] = 0; // EBP
stack[-10] = 0; // ESI stack[-10] = 0; // ESI
stack[-11] = 0; // EDI stack[-11] = 0; // EDI
stack[-12] = 0x200U; stack[-12] = 0x200U;
*esp = (unsigned int)&stack[-12]; *esp = reinterpret_cast<unsigned int>(&stack[-12]);
} }
/***************************************************************************** /*****************************************************************************
@ -98,7 +98,7 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread*
* stack Stack für die neue Koroutine * * stack Stack für die neue Koroutine *
*****************************************************************************/ *****************************************************************************/
Thread::Thread(char* name) : stack(new unsigned int[1024]), esp(0), log(name), name(name), tid(ThreadCnt++) { Thread::Thread(char* name) : stack(new unsigned int[1024]), esp(0), log(name), name(name), tid(ThreadCnt++) {
log.info() << "Initialized thread with ID: " << this->tid << " (" << name << ")" << endl; log.info() << "Initialized thread with ID: " << tid << " (" << name << ")" << endl;
Thread_init(&esp, &stack[1024], kickoff, this); // Stack grows from top to bottom Thread_init(&esp, &stack[1024], kickoff, this); // Stack grows from top to bottom
} }
@ -124,5 +124,5 @@ void Thread::start() const {
/* hier muss Code eingefügt werden */ /* hier muss Code eingefügt werden */
Thread_start(this->esp); Thread_start(esp);
} }

View File

@ -7,9 +7,9 @@
* Thread-Objekte werden vom Scheduler in einer verketteten * * Thread-Objekte werden vom Scheduler in einer verketteten *
* Liste 'readylist' verwaltet. * * Liste 'readylist' verwaltet. *
* * * *
* Im Konstruktor wird der initialie Kontext des Threads * * Im Konstruktor wird der initialie Kontext des Threads *
* eingerichtet. Mit 'start' wird ein Thread aktiviert. * * eingerichtet. Mit 'start' wird ein Thread aktiviert. *
* Die CPU sollte mit 'yield' freiwillig abgegeben werden. * * Die CPU sollte mit 'yield' freiwillig abgegeben werden. *
* Um bei einem Threadwechsel den Kontext sichern zu * * Um bei einem Threadwechsel den Kontext sichern zu *
* koennen, enthaelt jedes Threadobjekt eine Struktur * * koennen, enthaelt jedes Threadobjekt eine Struktur *
* ThreadState, in dem die Werte der nicht-fluechtigen * * ThreadState, in dem die Werte der nicht-fluechtigen *
@ -25,8 +25,8 @@
* Autor: Michael, Schoettner, HHU, 16.12.2016 * * Autor: Michael, Schoettner, HHU, 16.12.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Thread_include__ #ifndef Thread_include__
#define __Thread_include__ #define Thread_include__
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
@ -49,21 +49,21 @@ public:
Thread(const Thread& copy) = delete; // Verhindere Kopieren Thread(const Thread& copy) = delete; // Verhindere Kopieren
virtual ~Thread() { virtual ~Thread() {
log.info() << "Uninitialized thread, ID: " << dec << this->tid << " (" << name << ")" << endl; log.info() << "Uninitialized thread, ID: " << dec << tid << " (" << name << ")" << endl;
delete[] this->stack; delete[] stack;
} }
// Thread aktivieren // Thread aktivieren
/*[[noreturn]]*/ void start() const; void start() const;
// Umschalten auf Thread 'next' // Umschalten auf Thread 'next'
/*[[noreturn]]*/ void switchTo(Thread& next); void switchTo(Thread& next);
// Ask thread to terminate itself // Ask thread to terminate itself
void suicide() { running = false; } void suicide() { running = false; }
// Methode des Threads, muss in Sub-Klasse implementiert werden // Methode des Threads, muss in Sub-Klasse implementiert werden
[[noreturn]] virtual void run() = 0; virtual void run() = 0;
}; };
#endif #endif

View File

@ -19,8 +19,8 @@
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 06.04.20 * * Aenderungen von Michael Schoettner, HHU, 06.04.20 *
*****************************************************************************/ *****************************************************************************/
#ifndef __OutStream_include__ #ifndef OutStream_include__
#define __OutStream_include__ #define OutStream_include__
#include "lib/StringBuffer.h" #include "lib/StringBuffer.h"
#include "user/lib/String.h" #include "user/lib/String.h"
@ -40,8 +40,6 @@ public:
class OutStream : public StringBuffer { class OutStream : public StringBuffer {
private: private:
OutStream(const OutStream& copy) = delete; // Verhindere Kopieren
// Some stream formatting // Some stream formatting
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
unsigned char fill_width; // If input is shorter than fill_width fill remaining space up with fill_char unsigned char fill_width; // If input is shorter than fill_width fill remaining space up with fill_char
@ -52,8 +50,12 @@ private:
void fill_finalize(); // does the filling after text has been written to buffer void fill_finalize(); // does the filling after text has been written to buffer
public: public:
OutStream(const OutStream& copy) = delete; // Verhindere Kopieren
OutStream() : fill_used(0), fill_width(0), fill_char(' '), base(10) {} OutStream() : fill_used(0), fill_width(0), fill_char(' '), base(10) {}
// ~OutStream() override = default;
// Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer. // Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer.
void flush() override; void flush() override;
@ -79,7 +81,7 @@ public:
} }
template<typename T> template<typename T>
friend T& operator<<(T& os, unsigned char c) { return os << (char)c; } friend T& operator<<(T& os, unsigned char c) { return os << static_cast<char>(c); }
// Darstellung einer nullterminierten Zeichenkette // Darstellung einer nullterminierten Zeichenkette
template<typename T> template<typename T>
@ -97,22 +99,22 @@ public:
// Can not use this exclusively for strings as these are heap allocated // Can not use this exclusively for strings as these are heap allocated
template<typename T> template<typename T>
friend T& operator<<(T& os, const bse::string& string) { friend T& operator<<(T& os, const bse::string& string) {
os << (const char*)string; os << static_cast<const char*>(string);
return os; return os;
} }
// Darstellung ganzer Zahlen im Zahlensystem zur Basis base // Darstellung ganzer Zahlen im Zahlensystem zur Basis base
template<typename T> template<typename T>
friend T& operator<<(T& os, short ival) { return os << (long)ival; } friend T& operator<<(T& os, short ival) { return os << static_cast<long>(ival); }
template<typename T> template<typename T>
friend T& operator<<(T& os, unsigned short ival) { return os << (unsigned long)ival; } friend T& operator<<(T& os, unsigned short ival) { return os << static_cast<unsigned long>(ival); }
template<typename T> template<typename T>
friend T& operator<<(T& os, int ival) { return os << (long)ival; } friend T& operator<<(T& os, int ival) { return os << static_cast<long>(ival); }
template<typename T> template<typename T>
friend T& operator<<(T& os, unsigned int ival) { return os << (unsigned long)ival; } friend T& operator<<(T& os, unsigned int ival) { return os << static_cast<unsigned long>(ival); }
template<typename T> template<typename T>
friend T& operator<<(T& os, long ival) { friend T& operator<<(T& os, long ival) {
@ -122,13 +124,13 @@ public:
ival = -ival; ival = -ival;
} }
// Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben. // Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben.
return os << (unsigned long)ival; return os << static_cast<unsigned long>(ival);
} }
template<typename T> template<typename T>
friend T& operator<<(T& os, unsigned long ival) { friend T& operator<<(T& os, unsigned long ival) {
unsigned long div = 0; unsigned long div;
char digit = 0; char digit;
if (os.base == 8) { if (os.base == 8) {
os.put('0'); // oktale Zahlen erhalten eine fuehrende Null os.put('0'); // oktale Zahlen erhalten eine fuehrende Null
@ -139,10 +141,10 @@ 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 >= static_cast<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 /= static_cast<unsigned long>(os.base)) {
digit = ival / div; digit = ival / div;
if (digit < 10) { if (digit < 10) {
os.put('0' + digit); os.put('0' + digit);
@ -160,7 +162,7 @@ public:
friend T& operator<<(T& os, void* ptr) { friend T& operator<<(T& os, void* ptr) {
int oldbase = os.base; int oldbase = os.base;
os.base = 16; os.base = 16;
os << (unsigned long)ptr; os << reinterpret_cast<unsigned long>(ptr);
os.base = oldbase; os.base = oldbase;
return os; return os;
} }

View File

@ -3,39 +3,39 @@
void Semaphore::p() { void Semaphore::p() {
// Lock to allow deterministic operations on counter/queue // Lock to allow deterministic operations on counter/queue
this->lock.acquire(); lock.acquire();
if (this->counter > 0) { if (counter > 0) {
// Semaphore can be acquired // Semaphore can be acquired
this->counter = this->counter - 1; counter = counter - 1;
this->lock.release(); lock.release();
} else { } else {
// Block and manage thread in semaphore queue until it's woken up by v() again // Block and manage thread in semaphore queue until it's woken up by v() again
if (!wait_queue.initialized()) { // TODO: I will replace this suboptimal datastructure in the future if (!wait_queue.initialized()) { // TODO: I will replace this suboptimal datastructure in the future
wait_queue.reserve(); wait_queue.reserve();
} }
this->wait_queue.push_back(scheduler.get_active()); wait_queue.push_back(scheduler.get_active());
CPU::disable_int(); // Make sure the block() comes through after releasing the lock CPU::disable_int(); // Make sure the block() comes through after releasing the lock
this->lock.release(); lock.release();
scheduler.block(); // Moves to next thread, enables int scheduler.block(); // Moves to next thread, enables int
} }
} }
void Semaphore::v() { void Semaphore::v() {
this->lock.acquire(); lock.acquire();
if (!this->wait_queue.empty()) { if (!wait_queue.empty()) {
// Semaphore stays busy and unblocks next thread to work in critical section // Semaphore stays busy and unblocks next thread to work in critical section
unsigned int tid = this->wait_queue.front(); unsigned int tid = wait_queue.front();
this->wait_queue.erase(wait_queue.begin()); wait_queue.erase(wait_queue.begin());
CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock
this->lock.release(); lock.release();
scheduler.deblock(tid); // Enables int scheduler.deblock(tid); // Enables int
} else { } else {
// No more threads want to work so free semaphore // No more threads want to work so free semaphore
this->counter = this->counter + 1; counter = counter + 1;
this->lock.release(); lock.release();
} }
} }

View File

@ -8,8 +8,8 @@
* Autor: Michael Schoettner, 2.9.2016 * * Autor: Michael Schoettner, 2.9.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __Semaphore_include__ #ifndef Semaphore_include__
#define __Semaphore_include__ #define Semaphore_include__
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
#include "lib/SpinLock.h" #include "lib/SpinLock.h"
@ -17,8 +17,6 @@
class Semaphore { class Semaphore {
private: private:
Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren
// Queue fuer wartende Threads. // Queue fuer wartende Threads.
bse::vector<unsigned int> wait_queue; bse::vector<unsigned int> wait_queue;
SpinLock lock; SpinLock lock;
@ -26,6 +24,8 @@ private:
int counter; int counter;
public: public:
Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren
// Konstruktor: Initialisieren des Semaphorzaehlers // Konstruktor: Initialisieren des Semaphorzaehlers
Semaphore(int c) : wait_queue(true), counter(c) {} Semaphore(int c) : wait_queue(true), counter(c) {}

View File

@ -10,7 +10,6 @@
*****************************************************************************/ *****************************************************************************/
#include "lib/SpinLock.h" #include "lib/SpinLock.h"
#include "kernel/Globals.h"
/***************************************************************************** /*****************************************************************************
* Methode: CAS * * Methode: CAS *
@ -24,7 +23,7 @@
* *ptr := _new * * *ptr := _new *
* return prev * * return prev *
*****************************************************************************/ *****************************************************************************/
static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned long _new) { static inline unsigned long CAS(const unsigned long* ptr) {
unsigned long prev; unsigned long prev;
/* /*
@ -38,7 +37,7 @@ static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned
"cmpxchg %1, %2;" // %1 = _new; %2 = *ptr "cmpxchg %1, %2;" // %1 = _new; %2 = *ptr
// constraints // constraints
: "=a"(prev) // output: =a: RAX -> prev (%0)) : "=a"(prev) // output: =a: RAX -> prev (%0))
: "r"(_new), "m"(*ptr), "a"(old) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax : "r"(1), "m"(*ptr), "a"(0) // input = %1, %2, %3 (r=register, m=memory, a=accumlator = eax
: "memory"); // ensures assembly block will not be moved by gcc : "memory"); // ensures assembly block will not be moved by gcc
return prev; // return pointer instead of prev to prevent unnecessary second call return prev; // return pointer instead of prev to prevent unnecessary second call
@ -52,7 +51,7 @@ static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned
void SpinLock::acquire() { void SpinLock::acquire() {
// If lock == 0 the SpinLock can be aquired without waiting // If lock == 0 the SpinLock can be aquired without waiting
// If lock == 1 the while loop blocks until aquired // If lock == 1 the while loop blocks until aquired
while (CAS(ptr, 0, 1) != 0) {} while (CAS(ptr) != 0) {}
} }
/***************************************************************************** /*****************************************************************************

View File

@ -9,17 +9,17 @@
* Autor: Michael Schoettner, 2.2.2018 * * Autor: Michael Schoettner, 2.2.2018 *
*****************************************************************************/ *****************************************************************************/
#ifndef __SpinLock_include__ #ifndef SpinLock_include__
#define __SpinLock_include__ #define SpinLock_include__
class SpinLock { class SpinLock {
private: private:
SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren
unsigned long lock; unsigned long lock;
unsigned long* ptr; unsigned long* ptr;
public: public:
SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren
SpinLock() : lock(0), ptr(&lock) {} SpinLock() : lock(0), ptr(&lock) {}
void acquire(); void acquire();

View File

@ -15,15 +15,12 @@
* Autor: Olaf Spinczyk, TU Dortmund * * Autor: Olaf Spinczyk, TU Dortmund *
* Aenderungen von Michael Schoettner, HHU, 06.04.20 * * Aenderungen von Michael Schoettner, HHU, 06.04.20 *
*****************************************************************************/ *****************************************************************************/
#ifndef __StringBuffer_include__ #ifndef StringBuffer_include__
#define __StringBuffer_include__ #define StringBuffer_include__
#include "user/lib/Array.h" #include "user/lib/Array.h"
class StringBuffer { class StringBuffer {
private:
StringBuffer(const StringBuffer& copy); // Verhindere Kopieren
// Alle Variablen und Methoden dieser Klasse sind "protected", // Alle Variablen und Methoden dieser Klasse sind "protected",
// da die abgeleiteten Klassen einen direkten Zugriff auf den // da die abgeleiteten Klassen einen direkten Zugriff auf den
// Puffer, den Konstruktor, den Destruktor und die Methode put // Puffer, den Konstruktor, den Destruktor und die Methode put
@ -42,6 +39,10 @@ protected:
// Methode zur Ausgabe des Pufferinhalts // Methode zur Ausgabe des Pufferinhalts
virtual void flush() = 0; virtual void flush() = 0;
public:
StringBuffer(const StringBuffer& copy) = delete; // Verhindere Kopieren
// virtual ~StringBuffer() = default;
}; };
#endif #endif

View File

@ -107,7 +107,7 @@ int main() {
// DONE: Use templates for queue so threads don't have to be casted down from chain // DONE: Use templates for queue so threads don't have to be casted down from chain
// TODO: Only use references instead of pointers where possible // TODO: Only use references instead of pointers where possible
// DONE: Unify debug output format // DONE: Unify debug output format
// TODO: Cleanup: Remove I added this... Notes, just leave explanations // DONE: Cleanup: Remove I added this... Notes, just leave explanations
// DONE: Remove Math "lib" or do something with it // DONE: Remove Math "lib" or do something with it
// CANCELED: Add some fixed point math like sine approximation or fractions? // CANCELED: Add some fixed point math like sine approximation or fractions?
// TODO: Cleanup imports: Only import stuff in implementation when only needed there // TODO: Cleanup imports: Only import stuff in implementation when only needed there
@ -117,15 +117,15 @@ int main() {
// DONE: Remove ArrayList init and do this inside ArrayList when an operation on the list is done // DONE: Remove ArrayList init and do this inside ArrayList when an operation on the list is done
// DONE: Kevman unsubscribe is needed, because exited threads will still be woken up by kevman // DONE: Kevman unsubscribe is needed, because exited threads will still be woken up by kevman
// Or check if thread is still running // Or check if thread is still running
// TODO: Delete copy constructors that weren't already deleted // DONE: Delete copy constructors that weren't already deleted
// DONE: Switch out semaphore Queue with ArrayList? Or switch back Scheduler to Queue? // DONE: Switch out semaphore Queue with ArrayList? Or switch back Scheduler to Queue?
// CANCELED: Add virtual destructors and make sure to call them with delete when objects are removed // CANCELED: Add virtual destructors and make sure to call them with delete when objects are removed
// TODO: Replace empty constructors/destructors with default keyword // DONE: Replace empty constructors/destructors with default keyword
// DONE: Synchronize the outstream // DONE: Synchronize the outstream
// DONE: Remove Iterator from List.h // DONE: Remove Iterator from List.h
// DONE: Move Array/ArrayList/LinkedList/List to bse namespace // DONE: Move Array/ArrayList/LinkedList/List to bse namespace
// DONE: Remove the Input.h file and replace functionality with kevman // DONE: Remove the Input.h file and replace functionality with kevman
// TODO: Replace C style casts with C++ casts // DONE: Replace C style casts with C++ casts
// TODO: Add Move/Copy/Assignment stuff to vector, array etc (all where it's missing) // TODO: Add Move/Copy/Assignment stuff to vector, array etc (all where it's missing)
// Scheduler doesn't return // Scheduler doesn't return

View File

@ -1,119 +0,0 @@
#include "kernel/Globals.h"
#include "user/lib/Vector.h"
void print(const bse::Vector<int>& vec) {
kout << "Print: ";
for (const int i : vec) {
kout << i << " ";
}
kout << endl;
}
void run_test() {
bse::Vector<int> vec;
constexpr const int count = 10;
bool success = true;
// =================================
kout.clear();
kout << "Vector Test" << endl;
// =================================
kout << "Basic push_back" << endl;
for (int i = 0; i < count; ++i) {
vec.push_back(i);
}
for (unsigned int i = 0; i < count; ++i) {
success = success && (vec[i] == i);
}
kout << "Success: " << static_cast<int>(success) << endl;
success = true;
// =================================
kout << "Basic iteration" << endl;
int current = 0;
for (int i : vec) {
success = success && i == current;
current++;
}
kout << "Success: " << static_cast<int>(success) << endl;
success = true;
// =================================
kout << "Basic functions" << endl;
kout << "Size: " << vec.size() << endl;
kout << "Empty: " << static_cast<int>(vec.empty()) << endl;
// =================================
kout << "Basic deletion" << endl;
bse::Vector<int>::Iterator it = vec.begin();
while (it != vec.end()) {
it = vec.erase(it);
}
kout << "Size: " << vec.size() << endl;
kout << "Empty: " << static_cast<int>(vec.empty()) << endl;
// =================================
kout << "Index insertion in order" << endl;
for (int i = 0; i < count; ++i) {
vec.insert(vec.begin() + i, i);
}
for (unsigned int i = 0; i < count; ++i) {
success = success && (vec[i] == i);
}
kout << "Success: " << static_cast<int>(success) << endl;
success = true;
vec.clear();
// =================================
kout << "Index insertion at front" << endl;
for (int i = 0; i < count; ++i) {
vec.insert(vec.begin(), i);
}
// print(vec);
for (unsigned int i = 0; i < count; ++i) {
// kout << vec[i] << " == " << count - i - 1 << "?" << endl;
success = success && (vec[i] == count - i - 1);
}
kout << "Success: " << static_cast<int>(success) << endl;
success = true;
vec.clear();
// =================================
kout << "Index insertion in back" << endl;
for (int i = 0; i < count; ++i) {
vec.insert(vec.end(), i);
}
// print(vec);
for (unsigned int i = 0; i < count; ++i) {
// kout << vec[i] << " == " << i << "?" << endl;
success = success && (vec[i] == i);
}
kout << "Success: " << static_cast<int>(success) << endl;
success = true;
// =================================
// 1 2 4 5 6 7 8
kout << "Index removal" << endl;
bse::Vector<int>::Iterator ret = vec.erase(vec.begin());
success = success && (ret == vec.begin());
ret = vec.erase(vec.end() - 1);
success = success && (ret == vec.end());
ret = vec.erase(vec.begin() + 2);
success = success && (vec.size() == count - 3);
success = success && (vec[0] == 1);
success = success && (vec[1] == 2);
success = success && (vec[2] == 4);
success = success && (*(vec.end() - 1) == 8);
kout << "Success: " << static_cast<int>(success) << endl;
success = true;
}

View File

@ -37,7 +37,7 @@ void MainMenu::run() {
char input = '\0'; char input = '\0';
unsigned int running_demo = 0; unsigned int running_demo = 0;
while (running) { while (running) {
input = this->listener.waitForKeyEvent(); input = listener.waitForKeyEvent();
if ((input >= '0' && input <= '9') || input == '!') { if ((input >= '0' && input <= '9') || input == '!') {
switch (input) { switch (input) {

View File

@ -1,5 +1,5 @@
#ifndef __MainMenu_Inlucde_H_ #ifndef MainMenu_Inlucde_H_
#define __MainMenu_Inlucde_H_ #define MainMenu_Inlucde_H_
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
@ -7,17 +7,17 @@
class MainMenu : public Thread { class MainMenu : public Thread {
private: private:
MainMenu(const MainMenu& copy) = delete;
KeyEventListener listener; KeyEventListener listener;
public: public:
MainMenu() : Thread("MainMenu"), listener(this->tid) { MainMenu(const MainMenu& copy) = delete;
kevman.subscribe(this->listener);
MainMenu() : Thread("MainMenu"), listener(tid) {
kevman.subscribe(listener);
} }
~MainMenu() override { ~MainMenu() override {
kevman.unsubscribe(this->listener); kevman.unsubscribe(listener);
} }
void run() override; void run() override;

View File

@ -1,6 +1,6 @@
/* GIMP RGB C-Source image dump (hhulogo.c) */ /* GIMP RGB C-Source image dump (hhulogo.c) */
static constexpr const struct { static constexpr struct {
unsigned int width; unsigned int width;
unsigned int height; unsigned int height;
unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */

View File

@ -3,7 +3,6 @@
void ArrayDemo::run() { void ArrayDemo::run() {
bse::array<int, 10> arr1 {}; bse::array<int, 10> arr1 {};
bse::array<int, 10> arr2 {}; bse::array<int, 10> arr2 {};
bse::array<Thread*, 10> arr3 {};
kout.lock(); kout.lock();
kout.clear(); kout.clear();

View File

@ -1,14 +1,13 @@
#ifndef __ArrayDemo_include__ #ifndef ArrayDemo_include__
#define __ArrayDemo_include__ #define ArrayDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "user/lib/Array.h" #include "user/lib/Array.h"
class ArrayDemo : public Thread { class ArrayDemo : public Thread {
private: public:
ArrayDemo(const ArrayDemo& copy) = delete; ArrayDemo(const ArrayDemo& copy) = delete;
public:
ArrayDemo() : Thread("ArrayDemo") {} ArrayDemo() : Thread("ArrayDemo") {}
void run() override; void run() override;

View File

@ -1,14 +1,13 @@
#ifndef __BlueScreenDemo_include__ #ifndef BlueScreenDemo_include__
#define __BlueScreenDemo_include__ #define BlueScreenDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
class BlueScreenDemo : public Thread { class BlueScreenDemo : public Thread {
private: public:
BlueScreenDemo(const BlueScreenDemo& copy) = delete; BlueScreenDemo(const BlueScreenDemo& copy) = delete;
public:
BlueScreenDemo() : Thread("BlueScreenDemo") {} BlueScreenDemo() : Thread("BlueScreenDemo") {}
void run() override; void run() override;

View File

@ -7,8 +7,8 @@
* * * *
* Autor: Michael Schoettner, HHU, 25.9.2016 * * Autor: Michael Schoettner, HHU, 25.9.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __HeapDemo_include__ #ifndef HeapDemo_include__
#define __HeapDemo_include__ #define HeapDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
@ -21,10 +21,9 @@ public:
}; };
class HeapDemo : public Thread { class HeapDemo : public Thread {
private: public:
HeapDemo(const HeapDemo& copy) = delete; HeapDemo(const HeapDemo& copy) = delete;
public:
HeapDemo() : Thread("HeapDemo") {} HeapDemo() : Thread("HeapDemo") {}
void run() override; void run() override;

View File

@ -8,8 +8,8 @@
* Autor: Michael Schoettner, HHU, 26.10.2018 * * Autor: Michael Schoettner, HHU, 26.10.2018 *
*****************************************************************************/ *****************************************************************************/
#ifndef __KeyboardDemo_include__ #ifndef KeyboardDemo_include__
#define __KeyboardDemo_include__ #define KeyboardDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
@ -17,13 +17,13 @@
class KeyboardDemo : public Thread { class KeyboardDemo : public Thread {
private: private:
KeyboardDemo(const KeyboardDemo& copy) = delete;
KeyEventListener listener; KeyEventListener listener;
public: public:
KeyboardDemo() : Thread("KeyboardDemo"), listener(this->tid) { KeyboardDemo(const KeyboardDemo& copy) = delete;
kevman.subscribe(this->listener);
KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) {
kevman.subscribe(listener);
} }
// Base class destructor will be called automatically // Base class destructor will be called automatically
@ -35,7 +35,7 @@ public:
// thread set it (so use nice_kill) // thread set it (so use nice_kill)
kout.unlock(); kout.unlock();
} }
kevman.unsubscribe(this->listener); kevman.unsubscribe(listener);
} }
void run() override; void run() override;

View File

@ -6,7 +6,7 @@ void PCSPKdemo::run() {
kout << "Playing..." << endl; kout << "Playing..." << endl;
kout.unlock(); kout.unlock();
(pcspk.*this->melody)(); // This syntax is confusing as hell (pcspk.*melody)(); // This syntax is confusing as hell
kout.lock(); kout.lock();
kout << "Finished" << endl; kout << "Finished" << endl;

View File

@ -1,20 +1,20 @@
#ifndef __PCSPKdemo_INCLUDE_H_ #ifndef PCSPKdemo_INCLUDE_H_
#define __PCSPKdemo_INCLUDE_H_ #define PCSPKdemo_INCLUDE_H_
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
class PCSPKdemo : public Thread { class PCSPKdemo : public Thread {
private: private:
PCSPKdemo(const PCSPKdemo& copy) = delete; void (PCSPK::*melody)(); // Allow to pass a melody to play when initializing the demo
void (PCSPK::*melody)(void); // Allow to pass a melody to play when initializing the demo
public: public:
PCSPKdemo(void (PCSPK::*melody)(void)) : Thread("PCSPKdemo"), melody(melody) {} PCSPKdemo(const PCSPKdemo& copy) = delete;
explicit PCSPKdemo(void (PCSPK::*melody)()) : Thread("PCSPKdemo"), melody(melody) {}
~PCSPKdemo() override { ~PCSPKdemo() override {
pcspk.off(); PCSPK::off();
} }
void run() override; void run() override;

View File

@ -8,8 +8,8 @@ void PreemptiveLoopThread::run() {
kout.lock(); kout.lock();
// Saving + restoring kout position doesn't help much as preemption still occurs // Saving + restoring kout position doesn't help much as preemption still occurs
kout.setpos(55, this->id); CGA_Stream::setpos(55, id);
kout << fillw(3) << this->id << fillw(0) << ": " << dec << cnt++ << endl; kout << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl;
kout.unlock(); kout.unlock();
} }
@ -24,7 +24,7 @@ void PreemptiveThreadDemo::run() {
kout << "Preemptive Thread Demo:" << endl; kout << "Preemptive Thread Demo:" << endl;
kout << "Readying LoopThreads" << endl; kout << "Readying LoopThreads" << endl;
for (unsigned int i = 0; i < this->number_of_threads; ++i) { for (unsigned int i = 0; i < number_of_threads; ++i) {
scheduler.ready<PreemptiveLoopThread>(i); scheduler.ready<PreemptiveLoopThread>(i);
} }

View File

@ -1,5 +1,5 @@
#ifndef __preemptive_thread_include__ #ifndef preemptive_thread_include__
#define __preemptive_thread_include__ #define preemptive_thread_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
@ -8,9 +8,10 @@
class PreemptiveLoopThread : public Thread { class PreemptiveLoopThread : public Thread {
private: private:
int id; int id;
PreemptiveLoopThread(const PreemptiveLoopThread& copy) = delete; // Verhindere Kopieren
public: public:
PreemptiveLoopThread(const PreemptiveLoopThread& copy) = delete; // Verhindere Kopieren
// Gibt der Loop einen Stack und eine Id. // Gibt der Loop einen Stack und eine Id.
PreemptiveLoopThread(int i) : Thread("LoopThread"), id(i) {} PreemptiveLoopThread(int i) : Thread("LoopThread"), id(i) {}
@ -20,11 +21,11 @@ public:
class PreemptiveThreadDemo : public Thread { class PreemptiveThreadDemo : public Thread {
private: private:
PreemptiveThreadDemo(const PreemptiveThreadDemo& copy) = delete; // Verhindere Kopieren
unsigned int number_of_threads; unsigned int number_of_threads;
public: public:
PreemptiveThreadDemo(const PreemptiveThreadDemo& copy) = delete; // Verhindere Kopieren
PreemptiveThreadDemo(unsigned int n) : Thread("PreemptiveThreadDemo"), number_of_threads(n) {} PreemptiveThreadDemo(unsigned int n) : Thread("PreemptiveThreadDemo"), number_of_threads(n) {}
// Thread-Startmethode // Thread-Startmethode

View File

@ -21,10 +21,10 @@ void SmartPointerDemo::run() {
bse::unique_ptr<int> ptr1 = bse::make_unique<int>(1); bse::unique_ptr<int> ptr1 = bse::make_unique<int>(1);
bse::unique_ptr<int> ptr2; bse::unique_ptr<int> ptr2;
log.info() << "*ptr1 == " << *ptr1 << ", (bool)ptr2 == " << (bool)ptr2 << endl; log.info() << "*ptr1 == " << *ptr1 << ", (bool)ptr2 == " << static_cast<bool>(ptr2) << endl;
log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl; log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl;
ptr2 = std::move(ptr1); ptr2 = std::move(ptr1);
log.info() << "(bool)ptr1 == " << (bool)ptr1 << ", *ptr2 == " << *ptr2 << endl; log.info() << "(bool)ptr1 == " << static_cast<bool>(ptr1) << ", *ptr2 == " << *ptr2 << endl;
log.info() << "Leaving scope..." << endl; log.info() << "Leaving scope..." << endl;
} }

View File

@ -1,13 +1,12 @@
#ifndef __SmartPointerDemo_include__ #ifndef SmartPointerDemo_include__
#define __SmartPointerDemo_include__ #define SmartPointerDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
class SmartPointerDemo : public Thread { class SmartPointerDemo : public Thread {
private: public:
SmartPointerDemo(const SmartPointerDemo& copy) = delete; SmartPointerDemo(const SmartPointerDemo& copy) = delete;
public:
SmartPointerDemo() : Thread("SmartPointerDemo") {} SmartPointerDemo() : Thread("SmartPointerDemo") {}
void run() override; void run() override;

View File

@ -40,14 +40,14 @@ void StringDemo::run() {
log.info() << "Reassign str2" << endl; log.info() << "Reassign str2" << endl;
str2 = "Hello"; str2 = "Hello";
bse::array<char, 5> arr; bse::array<char, 5> arr{};
arr[0] = 'H'; arr[0] = 'H';
arr[1] = 'e'; arr[1] = 'e';
arr[2] = 'l'; arr[2] = 'l';
arr[3] = 'l'; arr[3] = 'l';
arr[4] = 'o'; arr[4] = 'o';
kout << "bse::array<char, 5> to bse::string: " << arr << ", size: " << ((bse::string)arr).size() << endl; kout << "bse::array<char, 5> to bse::string: " << static_cast<bse::string>(arr) << ", size: " << (bse::string(arr)).size() << endl;
kout << "(bse::string)arr (" << arr << ") == str2 (" << str2 << "): " << static_cast<int>((bse::string)arr == str2) << endl; kout << "(bse::string)arr (" << static_cast<bse::string>(arr) << ") == str2 (" << str2 << "): " << static_cast<int>(bse::string(arr) == str2) << endl;
kout.unlock(); kout.unlock();
scheduler.exit(); scheduler.exit();

View File

@ -1,13 +1,12 @@
#ifndef __StringDemo_include__ #ifndef StringDemo_include__
#define __StringDemo_include__ #define StringDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
class StringDemo : public Thread { class StringDemo : public Thread {
private: public:
StringDemo(const StringDemo& copy) = delete; StringDemo(const StringDemo& copy) = delete;
public:
StringDemo() : Thread("StringDemo") {} StringDemo() : Thread("StringDemo") {}
void run() override; void run() override;

View File

@ -8,17 +8,16 @@
* Autor: Michael Schoettner, HHU, 26.10.2018 * * Autor: Michael Schoettner, HHU, 26.10.2018 *
*****************************************************************************/ *****************************************************************************/
#ifndef __TextDemo_include__ #ifndef TextDemo_include__
#define __TextDemo_include__ #define TextDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
class TextDemo : public Thread { class TextDemo : public Thread {
private: public:
TextDemo(const TextDemo& copy) = delete; TextDemo(const TextDemo& copy) = delete;
public:
TextDemo() : Thread("TextDemo") {} TextDemo() : Thread("TextDemo") {}
void run() override; void run() override;

View File

@ -59,7 +59,7 @@ void VBEdemo::drawBitmap() {
unsigned int sprite_width = hhu.width; unsigned int sprite_width = hhu.width;
unsigned int sprite_height = hhu.height; unsigned int sprite_height = hhu.height;
unsigned int sprite_bpp = hhu.bytes_per_pixel; unsigned int sprite_bpp = hhu.bytes_per_pixel;
unsigned char* sprite_pixel = (unsigned char*)hhu.pixel_data; const unsigned char* sprite_pixel = reinterpret_cast<const unsigned char*>(hhu.pixel_data);
/* Hier muss Code eingefuegt werden */ /* Hier muss Code eingefuegt werden */

View File

@ -7,27 +7,27 @@
* * * *
* Autor: Michael Schoettner, HHU, 26.12.2016 * * Autor: Michael Schoettner, HHU, 26.12.2016 *
*****************************************************************************/ *****************************************************************************/
#ifndef __VBEdemo_include__ #ifndef VBEdemo_include__
#define __VBEdemo_include__ #define VBEdemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
class VBEdemo : public Thread { class VBEdemo : public Thread {
private: private:
VBEdemo(const VBEdemo& copy) = delete; // Verhindere Kopieren
// Hilfsfunktionen fuer drawColors() // Hilfsfunktionen fuer drawColors()
int linInterPol1D(int x, int xr, int l, int r); static int linInterPol1D(int x, int xr, int l, int r);
int linInterPol2D(int x, int y, int lt, int rt, int lb, int rb); static int linInterPol2D(int x, int y, int lt, int rt, int lb, int rb);
public: public:
VBEdemo(const VBEdemo& copy) = delete; // Verhindere Kopieren
// Gib dem Anwendungsthread einen Stack. // Gib dem Anwendungsthread einen Stack.
VBEdemo() : Thread("VBEdemo") {} VBEdemo() : Thread("VBEdemo") {}
~VBEdemo() override { ~VBEdemo() override {
vesa.initTextMode(); allocator.free(reinterpret_cast<void*>(vesa.hfb)); // Memory is allocated after every start and never deleted, so add that
VESA::initTextMode();
} }
// Thread-Startmethode // Thread-Startmethode
@ -37,10 +37,10 @@ public:
void drawColors(); void drawColors();
// Bitmap aus GIMP ausgeben // Bitmap aus GIMP ausgeben
void drawBitmap(); static void drawBitmap();
// Fonts ausgeben // Fonts ausgeben
void drawFonts(); static void drawFonts();
}; };
#endif #endif

View File

@ -18,7 +18,7 @@ void VectorDemo::run() {
log.info() << "Initial list size: " << dec << list.size() << endl; log.info() << "Initial list size: " << dec << list.size() << endl;
log.info() << "Adding elements in order" << endl; log.info() << "Adding elements in order" << endl;
for (unsigned int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
list.push_back(i); list.push_back(i);
} }
print(log.info(), list); print(log.info(), list);
@ -32,7 +32,7 @@ void VectorDemo::run() {
// ============================================================ // ============================================================
log.info() << "Adding elements in order with realloc" << endl; log.info() << "Adding elements in order with realloc" << endl;
for (unsigned int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
log.info() << "Add " << dec << i << endl; log.info() << "Add " << dec << i << endl;
list.push_back(i); list.push_back(i);
} }
@ -46,7 +46,7 @@ void VectorDemo::run() {
// ============================================================ // ============================================================
for (unsigned int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
list.push_back(i); list.push_back(i);
} }
print(log.info(), list); print(log.info(), list);

View File

@ -1,15 +1,14 @@
#ifndef __VectorDemo_include__ #ifndef VectorDemo_include__
#define __VectorDemo_include__ #define VectorDemo_include__
#include "kernel/Globals.h" #include "kernel/Globals.h"
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
#include "user/lib/Vector.h" #include "user/lib/Vector.h"
class VectorDemo : public Thread { class VectorDemo : public Thread {
private: public:
VectorDemo(const VectorDemo& copy) = delete; VectorDemo(const VectorDemo& copy) = delete;
public:
VectorDemo() : Thread("VectorDemo") {} VectorDemo() : Thread("VectorDemo") {}
void run() override; void run() override;

View File

@ -1,6 +1,8 @@
#include "user/devices/SerialOut.h" #include "user/devices/SerialOut.h"
int SerialOut::init() const { const IOport SerialOut::com1(0x3f8);
SerialOut::SerialOut() {
// NOTE: I could add different ports for every register but this was easier as it's that way on OSDev // NOTE: I could add different ports for every register but this was easier as it's that way on OSDev
com1.outb(1, 0x00); // Disable all interrupts com1.outb(1, 0x00); // Disable all interrupts
com1.outb(3, 0x80); // Enable DLAB (set baud rate divisor) com1.outb(3, 0x80); // Enable DLAB (set baud rate divisor)
@ -13,14 +15,11 @@ int SerialOut::init() const {
com1.outb(0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) com1.outb(0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
// Check if serial is faulty (i.e: not same byte as sent) // Check if serial is faulty (i.e: not same byte as sent)
if (com1.inb() != 0xAE) { if (com1.inb() == 0xAE) {
return 1; // If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
com1.outb(4, 0x0F);
} }
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
com1.outb(4, 0x0F);
return 0;
} }
int SerialOut::serial_received() { int SerialOut::serial_received() {
@ -44,11 +43,11 @@ void SerialOut::write(const char a) {
void SerialOut::write(const char* a) { void SerialOut::write(const char* a) {
const char* current = a; const char* current = a;
do { do {
this->write(*current); write(*current);
current = current + 1; current = current + 1;
} while (*current != '\0'); } while (*current != '\0');
} }
void SerialOut::write(const bse::string& a) { void SerialOut::write(const bse::string& a) {
write((const char*)a); write(static_cast<const char*>(a));
} }

View File

@ -1,5 +1,5 @@
#ifndef __SerialOut_Include_H_ #ifndef SerialOut_Include_H_
#define __SerialOut_Include_H_ #define SerialOut_Include_H_
#include "kernel/IOport.h" #include "kernel/IOport.h"
#include "user/lib/String.h" #include "user/lib/String.h"
@ -8,24 +8,19 @@
class SerialOut { class SerialOut {
private: private:
const IOport com1; static const IOport com1;
SerialOut(const SerialOut& copy) = delete; static int serial_received();
static int is_transmit_empty();
int serial_received();
int is_transmit_empty();
public: public:
SerialOut() : com1(0x3f8) { SerialOut(const SerialOut& copy) = delete;
this->init(); SerialOut();
}
int init() const; static char read();
static void write(char a);
char read(); static void write(const char* a);
void write(char a); static void write(const bse::string& a);
void write(const char* a);
void write(const bse::string& a);
}; };
#endif #endif

View File

@ -2,11 +2,11 @@
#include "kernel/Globals.h" #include "kernel/Globals.h"
void KeyEventListener::trigger(char c) { void KeyEventListener::trigger(char c) {
this->lastChar = c; lastChar = c;
} }
char KeyEventListener::waitForKeyEvent() const { char KeyEventListener::waitForKeyEvent() const {
Logger::instance() << DEBUG << "KEvLis:: Thread with id: " << tid << " waiting for key event" << endl; Logger::instance() << DEBUG << "KEvLis:: Thread with id: " << tid << " waiting for key event" << endl;
scheduler.block(); scheduler.block();
return this->lastChar; // This is only executed after thread is woken up by manager return lastChar; // This is only executed after thread is woken up by manager
} }

View File

@ -1,17 +1,18 @@
#ifndef __KeyEventListener_Include_H_ #ifndef KeyEventListener_Include_H_
#define __KeyEventListener_Include_H_ #define KeyEventListener_Include_H_
#include "kernel/threads/Thread.h" #include "kernel/threads/Thread.h"
class KeyEventListener { class KeyEventListener {
private: private:
KeyEventListener(const KeyEventListener& copy) = delete;
char lastChar = '\0'; char lastChar = '\0';
public: friend class KeyEventManager;
unsigned int tid; // Thread which contains this listener, so the listener can block the thread unsigned int tid; // Thread which contains this listener, so the listener can block the thread
public:
KeyEventListener(const KeyEventListener& copy) = delete;
KeyEventListener(unsigned int tid) : tid(tid) {} KeyEventListener(unsigned int tid) : tid(tid) {}
char waitForKeyEvent() const; // Blocks the thread until woken up by manager char waitForKeyEvent() const; // Blocks the thread until woken up by manager

View File

@ -3,14 +3,14 @@
void KeyEventManager::subscribe(KeyEventListener& sub) { void KeyEventManager::subscribe(KeyEventListener& sub) {
log.debug() << "Subscribe, Thread ID: " << dec << sub.tid << endl; log.debug() << "Subscribe, Thread ID: " << dec << sub.tid << endl;
this->listeners.push_back(&sub); listeners.push_back(&sub);
} }
void KeyEventManager::unsubscribe(KeyEventListener& unsub) { void KeyEventManager::unsubscribe(KeyEventListener& unsub) {
log.debug() << "Unsubscribe, Thread ID: " << dec << unsub.tid << endl; log.debug() << "Unsubscribe, Thread ID: " << dec << unsub.tid << endl;
for (bse::vector<KeyEventListener*>::iterator it = listeners.begin(); it != listeners.end(); ++it) { for (bse::vector<KeyEventListener*>::iterator it = listeners.begin(); it != listeners.end(); ++it) {
if ((*it)->tid == unsub.tid) { if ((*it)->tid == unsub.tid) {
this->listeners.erase(it); listeners.erase(it);
return; return;
} }
} }
@ -18,7 +18,7 @@ void KeyEventManager::unsubscribe(KeyEventListener& unsub) {
void KeyEventManager::broadcast(char c) { void KeyEventManager::broadcast(char c) {
log.trace() << "Beginning Broadcast" << endl; log.trace() << "Beginning Broadcast" << endl;
for (KeyEventListener* listener : this->listeners) { for (KeyEventListener* listener : listeners) {
log.trace() << "Broadcasting " << c << " to Thread ID: " << dec << listener->tid << endl; log.trace() << "Broadcasting " << c << " to Thread ID: " << dec << listener->tid << endl;
listener->trigger(c); listener->trigger(c);
scheduler.deblock(listener->tid); scheduler.deblock(listener->tid);

View File

@ -1,5 +1,5 @@
#ifndef __KeyEventManager_Include_H_ #ifndef KeyEventManager_Include_H_
#define __KeyEventManager_Include_H_ #define KeyEventManager_Include_H_
#include "user/event/KeyEventListener.h" #include "user/event/KeyEventListener.h"
#include "user/lib/Logger.h" #include "user/lib/Logger.h"
@ -10,13 +10,13 @@
class KeyEventManager { class KeyEventManager {
private: private:
KeyEventManager(const KeyEventManager& copy) = delete;
NamedLogger log; NamedLogger log;
bse::vector<KeyEventListener*> listeners; bse::vector<KeyEventListener*> listeners;
public: public:
KeyEventManager(const KeyEventManager& copy) = delete;
KeyEventManager() : log("KEvMan"), listeners(true) {} KeyEventManager() : log("KEvMan"), listeners(true) {}
void init() { void init() {

View File

@ -1,5 +1,5 @@
#ifndef __ARRAY_INCLUDE_H #ifndef ARRAY_INCLUDE_H
#define __ARRAY_INCLUDE_H #define ARRAY_INCLUDE_H
#include "user/lib/Iterator.h" #include "user/lib/Iterator.h"
#include <utility> #include <utility>
@ -15,22 +15,30 @@ namespace bse {
T buf[N]; T buf[N];
public: public:
array() {}; // If i write default something like bse::array<int, 10> arr; is not initialized... array() = default;; // If i write default something like bse::array<int, 10> arr; is not initialized...
array(std::initializer_list<T> list) {
typename std::initializer_list<T>::iterator it = list.begin();
for (unsigned int i = 0; i < N; ++i) {
buf[i] = *it;
++it;
}
}
iterator begin() { return iterator(&buf[0]); } iterator begin() { return iterator(&buf[0]); }
iterator begin() const { return iterator(&buf[0]); } iterator begin() const { return iterator(&buf[0]); }
iterator end() { return iterator(&buf[N]); } iterator end() { return iterator(&buf[N]); }
iterator end() const { return iterator(&buf[N]); } iterator end() const { return iterator(&buf[N]); }
T& operator[](std::size_t i) { return this->buf[i]; } T& operator[](std::size_t i) { return buf[i]; }
constexpr const T& operator[](std::size_t i) const { return this->buf[i]; } constexpr const T& operator[](std::size_t i) const { return buf[i]; }
T* operator&() { return &buf[0]; } // Not standard, I don't know yet if this will turn out to be a bad idea T* data() { return &buf[0]; } // Not standard, I don't know yet if this will turn out to be a bad idea
const T* operator&() const { return &buf[0]; } const T* data() const { return &buf[0]; }
void swap(array<T, N>& other) { void swap(array<T, N>& other) {
for (std::size_t i = 0; i < N; ++i) { for (std::size_t i = 0; i < N; ++i) {
std::swap(this->buf[i], other[i]); std::swap(buf[i], other[i]);
} }
} }
@ -39,7 +47,7 @@ namespace bse {
template<std::size_t n> template<std::size_t n>
void swap_n(array<T, n>& other) { void swap_n(array<T, n>& other) {
for (std::size_t i = 0; i < n; ++i) { for (std::size_t i = 0; i < n; ++i) {
std::swap(this->buf[i], other[i]); std::swap(buf[i], other[i]);
} }
} }

View File

@ -1,5 +1,5 @@
#ifndef __Iterator_Include_H_ #ifndef Iterator_Include_H_
#define __Iterator_Include_H_ #define Iterator_Include_H_
namespace bse { namespace bse {
@ -9,45 +9,41 @@ namespace bse {
private: private:
T* ptr = nullptr; T* ptr = nullptr;
public:
ContinuousIterator() = delete; ContinuousIterator() = delete;
public:
ContinuousIterator(T* ptr) : ptr(ptr) {} ContinuousIterator(T* ptr) : ptr(ptr) {}
T* get() const {
return ptr;
}
ContinuousIterator& operator++() { ContinuousIterator& operator++() {
++this->ptr; ++ptr;
return *this; return *this;
} }
ContinuousIterator& operator--() { ContinuousIterator& operator--() {
--this->ptr; --ptr;
return *this; return *this;
} }
ContinuousIterator operator+(unsigned int add) { ContinuousIterator operator+(unsigned int add) {
return ContinuousIterator(this->ptr + add); return ContinuousIterator(ptr + add);
} }
ContinuousIterator operator-(unsigned int sub) { ContinuousIterator operator-(unsigned int sub) {
return ContinuousIterator(this->ptr - sub); return ContinuousIterator(ptr - sub);
} }
// Convenience // Convenience
T* operator->() { return this->ptr; } T* operator->() { return ptr; }
const T* operator->() const { return this->ptr; } const T* operator->() const { return ptr; }
T& operator*() { return *this->ptr; } T& operator*() { return *ptr; }
const T& operator*() const { return *this->ptr; } const T& operator*() const { return *ptr; }
bool operator<(const ContinuousIterator& other) const { return this->ptr < other.ptr; } bool operator<(const ContinuousIterator& other) const { return ptr < other.ptr; }
bool operator<=(const ContinuousIterator& other) const { return this->ptr <= other.ptr; } bool operator<=(const ContinuousIterator& other) const { return ptr <= other.ptr; }
bool operator>(const ContinuousIterator& other) const { return this->ptr > other.ptr; } bool operator>(const ContinuousIterator& other) const { return ptr > other.ptr; }
bool operator>=(const ContinuousIterator& other) const { return this->ptr >= other.ptr; } bool operator>=(const ContinuousIterator& other) const { return ptr >= other.ptr; }
bool operator==(const ContinuousIterator& other) const { return this->ptr == other.ptr; } bool operator==(const ContinuousIterator& other) const { return ptr == other.ptr; }
bool operator!=(const ContinuousIterator& other) const { return this->ptr != other.ptr; } bool operator!=(const ContinuousIterator& other) const { return ptr != other.ptr; }
template<typename t> template<typename t>
friend unsigned int distance(const ContinuousIterator<t>& first, const ContinuousIterator<t>& last); friend unsigned int distance(const ContinuousIterator<t>& first, const ContinuousIterator<t>& last);

View File

@ -19,61 +19,61 @@ void Logger::log(const char* message, CGA::color col) const {
if (Logger::kout_enabled) { if (Logger::kout_enabled) {
CGA::color old_col = kout.color_fg; CGA::color old_col = kout.color_fg;
kout << fgc(col) kout << fgc(col)
<< Logger::level_to_string(this->current_message_level) << "::" << Logger::level_to_string(current_message_level) << "::"
<< message << fgc(old_col); << message << fgc(old_col);
kout.flush(); // Don't add newline, Logger already does that kout.flush(); // Don't add newline, Logger already does that
} }
if (Logger::serial_enabled) { if (Logger::serial_enabled) {
switch (col) { switch (col) {
case CGA::WHITE: case CGA::WHITE:
serial.write(ansi_white); SerialOut::write(ansi_white);
break; break;
case CGA::LIGHT_MAGENTA: case CGA::LIGHT_MAGENTA:
serial.write(ansi_magenta); SerialOut::write(ansi_magenta);
break; break;
case CGA::LIGHT_RED: case CGA::LIGHT_RED:
serial.write(ansi_red); SerialOut::write(ansi_red);
break; break;
case CGA::LIGHT_BLUE: case CGA::LIGHT_BLUE:
serial.write(ansi_blue); SerialOut::write(ansi_blue);
break; break;
default: default:
serial.write(ansi_default); SerialOut::write(ansi_default);
} }
serial.write(Logger::level_to_string(this->current_message_level)); SerialOut::write(Logger::level_to_string(current_message_level));
serial.write(":: "); SerialOut::write(":: ");
serial.write(message); SerialOut::write(message);
serial.write('\r'); SerialOut::write('\r');
// serial.write("\r\n"); // serial.write("\r\n");
} }
} }
void Logger::flush() { void Logger::flush() {
this->buffer[this->pos] = '\0'; buffer[pos] = '\0';
switch (this->current_message_level) { switch (current_message_level) {
case Logger::TRACE: case Logger::TRACE:
this->trace(&buffer); trace(buffer.data());
break; break;
case Logger::DEBUG: case Logger::DEBUG:
this->debug(&buffer); debug(buffer.data());
break; break;
case Logger::ERROR: case Logger::ERROR:
this->error(&buffer); error(buffer.data());
break; break;
case Logger::INFO: case Logger::INFO:
this->info(&buffer); info(buffer.data());
break; break;
} }
this->current_message_level = Logger::INFO; current_message_level = Logger::INFO;
this->pos = 0; pos = 0;
Logger::unlock(); Logger::unlock();
} }
void Logger::trace(const char* message) const { void Logger::trace(const char* message) const {
if (Logger::level <= Logger::TRACE) { if (Logger::level <= Logger::TRACE) {
this->log(message, CGA::WHITE); log(message, CGA::WHITE);
} }
} }
void Logger::trace(const bse::string& message) const { void Logger::trace(const bse::string& message) const {
@ -82,7 +82,7 @@ void Logger::trace(const bse::string& message) const {
void Logger::debug(const char* message) const { void Logger::debug(const char* message) const {
if (Logger::level <= Logger::DEBUG) { if (Logger::level <= Logger::DEBUG) {
this->log(message, CGA::LIGHT_MAGENTA); log(message, CGA::LIGHT_MAGENTA);
} }
} }
void Logger::debug(const bse::string& message) const { void Logger::debug(const bse::string& message) const {
@ -91,7 +91,7 @@ void Logger::debug(const bse::string& message) const {
void Logger::error(const char* message) const { void Logger::error(const char* message) const {
if (Logger::level <= Logger::ERROR) { if (Logger::level <= Logger::ERROR) {
this->log(message, CGA::LIGHT_RED); log(message, CGA::LIGHT_RED);
} }
} }
void Logger::error(const bse::string& message) const { void Logger::error(const bse::string& message) const {
@ -100,7 +100,7 @@ void Logger::error(const bse::string& message) const {
void Logger::info(const char* message) const { void Logger::info(const char* message) const {
if (Logger::level <= Logger::INFO) { if (Logger::level <= Logger::INFO) {
this->log(message, CGA::LIGHT_BLUE); log(message, CGA::LIGHT_BLUE);
} }
} }
void Logger::info(const bse::string& message) const { void Logger::info(const bse::string& message) const {

View File

@ -1,5 +1,5 @@
#ifndef __Logger_Include_H_ #ifndef Logger_Include_H_
#define __Logger_Include_H_ #define Logger_Include_H_
#include "devices/CGA.h" #include "devices/CGA.h"
#include "lib/OutStream.h" #include "lib/OutStream.h"
@ -15,8 +15,6 @@ public:
private: private:
Logger() = default; Logger() = default;
Logger(const Logger& copy) = delete;
void operator=(const Logger& copy) = delete;
static bool kout_enabled; static bool kout_enabled;
static bool serial_enabled; static bool serial_enabled;
@ -24,6 +22,7 @@ private:
void log(const char* message, CGA::color col) const; void log(const char* message, CGA::color col) const;
friend class NamedLogger; // Allow NamedLogger to lock/unlock friend class NamedLogger; // Allow NamedLogger to lock/unlock
SpinLock sem; // Semaphore would be a cyclic include SpinLock sem; // Semaphore would be a cyclic include
static void lock() { Logger::instance().sem.acquire(); } static void lock() { Logger::instance().sem.acquire(); }
static void unlock() { Logger::instance().sem.release(); } static void unlock() { Logger::instance().sem.release(); }
@ -31,6 +30,11 @@ private:
// static void unlock() {} // static void unlock() {}
public: public:
// ~Logger() override = default;
Logger(const Logger& copy) = delete;
void operator=(const Logger& copy) = delete;
enum LogLevel { enum LogLevel {
TRACE, TRACE,
DEBUG, DEBUG,
@ -51,13 +55,13 @@ public:
void info(const char* message) const; void info(const char* message) const;
void info(const bse::string& message) const; void info(const bse::string& message) const;
// TODO: Make level change accessible over menu // TODO: Make lvl change accessible over menu
static void set_level(LogLevel level) { static void set_level(LogLevel lvl) {
Logger::level = level; Logger::level = lvl;
} }
static char* level_to_string(LogLevel level) { static char* level_to_string(LogLevel lvl) {
switch (level) { switch (lvl) {
case Logger::TRACE: case Logger::TRACE:
return "TRACE"; return "TRACE";
case Logger::DEBUG: case Logger::DEBUG:
@ -94,7 +98,7 @@ private:
const char* name; const char* name;
public: public:
NamedLogger(const char* name) : name(name) {} explicit NamedLogger(const char* name) : name(name) {}
Logger& trace() { Logger& trace() {
Logger::lock(); Logger::lock();

View File

@ -1,12 +1,19 @@
#ifndef __MATH_INCLUDE_H_ #ifndef MATH_INCLUDE_H_
#define __MATH_INCLUDE_H_ #define MATH_INCLUDE_H_
namespace bse { namespace bse {
// I didn't add any numeric constraints, will do with c++20
template<typename T> template<typename T>
T& min(const T& a, const T& b) { return a < b ? a : b; } T& min(const T& a, const T& b) { return a < b ? a : b; }
template<typename T> template<typename T>
T& max(const T& a, const T& b) { return a > b ? a : b; } T& max(const T& a, const T& b) { return a > b ? a : b; }
template<typename T>
std::make_unsigned<T> abs(const T& a) { return a < 0 ? -a : a; }
} // namespace bse } // namespace bse
#endif #endif

View File

@ -1,8 +1,10 @@
#ifndef __MYSTDLIB_INCLUDE_H_ #ifndef MYSTDLIB_INCLUDE_H_
#define __MYSTDLIB_INCLUDE_H_ #define MYSTDLIB_INCLUDE_H_
namespace bse { namespace bse {
// add using byte or sth to replace char
template<typename T> template<typename T>
void memcpy(T* destination, const T* source, const unsigned int count = 1) { void memcpy(T* destination, const T* source, const unsigned int count = 1) {
for (unsigned int i = 0; i < count; ++i) { for (unsigned int i = 0; i < count; ++i) {
@ -14,7 +16,7 @@ namespace bse {
template<typename T> template<typename T>
void zero(T* destination) { void zero(T* destination) {
memset((char*)destination, '\0', sizeof(T)); memset(reinterpret_cast<char*>(destination), '\0', sizeof(T));
} }
// void strcpy(char* destination, char* source); // void strcpy(char* destination, char* source);

View File

@ -1,5 +1,5 @@
#ifndef __String_Include_H_ #ifndef String_Include_H_
#define __String_Include_H_ #define String_Include_H_
#include "user/lib/Array.h" #include "user/lib/Array.h"
#include "user/lib/Iterator.h" #include "user/lib/Iterator.h"
@ -24,8 +24,9 @@ namespace bse {
strncpy(buf, len + 1, str); strncpy(buf, len + 1, str);
} }
// Convert char array to string
template<unsigned int N> template<unsigned int N>
string(const array<char, N>& arr) : len(N), buf(new char[len + 1]) { explicit string(const array<char, N>& arr) : len(N), buf(new char[len + 1]) {
for (unsigned int i = 0; i < N; ++i) { for (unsigned int i = 0; i < N; ++i) {
buf[i] = arr[i]; buf[i] = arr[i];
} }

View File

@ -1,5 +1,5 @@
#ifndef __VECTOR_INCLUDE_H_ #ifndef VECTOR_INCLUDE_H_
#define __VECTOR_INCLUDE_H_ #define VECTOR_INCLUDE_H_
// NOTE: I decided to implement this because I wanted some sort of dynamic array (for example for the keyeventmanager). // NOTE: I decided to implement this because I wanted some sort of dynamic array (for example for the keyeventmanager).
// Also I wanted to template the Queue (for the scheduler) but with this I can just replace the Queue and use the // Also I wanted to template the Queue (for the scheduler) but with this I can just replace the Queue and use the
@ -101,16 +101,14 @@ namespace bse {
} }
public: public:
vector(bool lazy = false) { explicit vector(bool lazy = false) {
if (!lazy) { // I added this as a work around, the scheduler can't initialize the queues right if (!lazy) { // I added this as a work around, the scheduler can't initialize the queues right
// away because when the scheduler is started the allocator is not ready. // away because when the scheduler is started the allocator is not ready.
init(); init();
} }
}; };
vector(const vector& copy) { vector(const vector& copy) : buf_pos(copy.buf_pos), buf_cap(copy.buf_cap) {
buf_cap = copy.buf_cap;
buf_pos = copy.buf_pos;
buf = new T[buf_cap]; buf = new T[buf_cap];
for (unsigned int i = 0; i < buf_pos; ++i) { for (unsigned int i = 0; i < buf_pos; ++i) {
buf[i] = copy[i]; // Does a copy since copy is marked const reference buf[i] = copy[i]; // Does a copy since copy is marked const reference
@ -131,9 +129,7 @@ namespace bse {
return *this; return *this;
} }
vector(vector&& move) noexcept { vector(vector&& move) noexcept : buf_pos(move.buf_pos), buf_cap(move.buf_cap) {
buf_cap = move.buf_cap;
buf_pos = move.buf_pos;
buf = move.buf; buf = move.buf;
move.buf_cap = 0; move.buf_cap = 0;

View File

@ -1,5 +1,5 @@
#ifndef __UniquePointer_Include_H_ #ifndef UniquePointer_Include_H_
#define __UniquePointer_Include_H_ #define UniquePointer_Include_H_
#include <utility> #include <utility>
@ -34,11 +34,11 @@ namespace bse {
ptr = nullptr; ptr = nullptr;
} }
public:
// Forbid copying // Forbid copying
unique_ptr(const unique_ptr& copy) = delete; unique_ptr(const unique_ptr& copy) = delete;
unique_ptr& operator=(const unique_ptr& copy) = delete; unique_ptr& operator=(const unique_ptr& copy) = delete;
public:
// Construction // Construction
unique_ptr() = default; // Allow declaration without explicit definition unique_ptr() = default; // Allow declaration without explicit definition
@ -74,9 +74,9 @@ namespace bse {
// Resetting: Replaces managed object, deleting the old one // Resetting: Replaces managed object, deleting the old one
void reset() { del(); } void reset() { del(); }
void reset(T_* ptr) { void reset(T_* pt) {
del(); del();
this->ptr = ptr; ptr = pt;
} }
// Release: Releases ownership without deletion // Release: Releases ownership without deletion
@ -92,7 +92,7 @@ namespace bse {
return ptr; return ptr;
} }
// Nice to have operators // Pointer operators
T_* operator->() { return ptr; } T_* operator->() { return ptr; }
const T_* operator->() const { return ptr; } const T_* operator->() const { return ptr; }
T_& operator*() { return *ptr; } T_& operator*() { return *ptr; }
@ -103,7 +103,7 @@ namespace bse {
bool operator==(const unique_ptr& other) const { return ptr == other.ptr; } bool operator==(const unique_ptr& other) const { return ptr == other.ptr; }
// These are only for array unique_ptr but I didn't want to define a full template specialization just for this // These are only for array unique_ptr but I didn't enforce that
T_& operator[](std::size_t i) { return ptr[i]; } T_& operator[](std::size_t i) { return ptr[i]; }
const T_& operator[](std::size_t i) const { return ptr[i]; } const T_& operator[](std::size_t i) const { return ptr[i]; }
}; };