diff --git a/README.md b/README.md index 5cfb5c3..fa04b3d 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Makefile ====================================== - Added the -std=c++17 flag to enable better constexpr support. - 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 Changes diff --git a/c_os/devices/CGA.cc b/c_os/devices/CGA.cc index 42d3484..61c8c84 100755 --- a/c_os/devices/CGA.cc +++ b/c_os/devices/CGA.cc @@ -59,7 +59,7 @@ void CGA::getpos(unsigned int& x, unsigned int& y) { (cursor_low & 0xFF) | ((cursor_high << 8) & 0xFF00); 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 { - print((const char*)string, n, attrib); + print(static_cast(string), n, attrib); } void CGA::print(const bse::string& string, const unsigned char attrib) const { - print((const char*)string, string.size(), attrib); + print(static_cast(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 */ - return (int)blink << 7 // B0000000 + return static_cast(blink) << 7 // B0000000 | (bg & 0x7) << 4 // 0HHH0000 (Hintergrund) | (fg & 0xF); // 0000VVVV (Vordergrund) } diff --git a/c_os/devices/CGA.h b/c_os/devices/CGA.h index 0e9a43f..e6430fa 100755 --- a/c_os/devices/CGA.h +++ b/c_os/devices/CGA.h @@ -11,8 +11,8 @@ * Autor: Olaf Spinczyk, TU Dortmund * * Aenderungen von Michael Schoettner, HHU, 21.8.2016 * *****************************************************************************/ -#ifndef __CGA_include__ -#define __CGA_include__ +#ifndef CGA_include_H_ +#define CGA_include_H_ #include "kernel/IOport.h" #include "user/lib/Array.h" @@ -29,9 +29,11 @@ public: // Konstruktur mit Initialisierung der Ports CGA() { - this->setpos(0, 0); + CGA::setpos(0, 0); } +// virtual ~CGA() = default; + static const unsigned int CGA_START = 0xb8000U; // Konstanten fuer die moeglichen Farben im Attribut-Byte. diff --git a/c_os/devices/CGA_Stream.cc b/c_os/devices/CGA_Stream.cc index 8f1412c..c54d74d 100755 --- a/c_os/devices/CGA_Stream.cc +++ b/c_os/devices/CGA_Stream.cc @@ -24,11 +24,11 @@ * verwendet werden, um eine Ausgabe zu erzwingen. * *****************************************************************************/ 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 // would be implicitly converted to bse::string and // 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 // Flushing resets attributes diff --git a/c_os/devices/CGA_Stream.h b/c_os/devices/CGA_Stream.h index 7392138..faebb28 100755 --- a/c_os/devices/CGA_Stream.h +++ b/c_os/devices/CGA_Stream.h @@ -12,8 +12,8 @@ * Autor: Olaf Spinczyk, TU Dortmund * * Aenderungen von Michael Schoettner, HHU, 06.04.20 * *****************************************************************************/ -#ifndef __CGA_Stream_include__ -#define __CGA_Stream_include__ +#ifndef CGA_Stream_include_H_ +#define CGA_Stream_include_H_ #include "devices/CGA.h" #include "lib/OutStream.h" @@ -42,7 +42,7 @@ class CGA_Stream : public OutStream, public CGA { private: // Allow for synchronization of output text, needed when running something in parallel to // 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; CGA::color color_fg; @@ -58,6 +58,8 @@ public: pos = 0; } +// ~CGA_Stream() override = default; + void lock() { sem.p(); } void unlock() { sem.v(); } diff --git a/c_os/devices/Key.h b/c_os/devices/Key.h index 8a34c64..40ac21e 100755 --- a/c_os/devices/Key.h +++ b/c_os/devices/Key.h @@ -7,8 +7,8 @@ * * * Autor: Olaf Spinczyk, TU Dortmund * *****************************************************************************/ -#ifndef __Key_include__ -#define __Key_include__ +#ifndef Key_include__ +#define Key_include__ class Key { // Kopieren erlaubt! @@ -98,7 +98,7 @@ public: bool alt() const { return alt_left() || alt_right(); } bool ctrl() const { return ctrl_left() || ctrl_right(); } - operator char() const { return (char)asc; } + operator char() const { return static_cast(asc); } // Scan-Codes einiger spezieller Tasten struct scan { diff --git a/c_os/devices/Keyboard.cc b/c_os/devices/Keyboard.cc index 6e7ebbf..6fe1140 100755 --- a/c_os/devices/Keyboard.cc +++ b/c_os/devices/Keyboard.cc @@ -16,7 +16,7 @@ const IOport Keyboard::data_port(0x60); /* 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, '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, '#', @@ -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}; -constexpr unsigned char Keyboard::shift_tab[] = { +constexpr const unsigned char Keyboard::shift_tab[] = { 0, 0, '!', '"', 21, '$', '%', '&', '/', '(', ')', '=', '?', 96, 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, @@ -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}; -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, 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}; -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', ','}; -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}; /***************************************************************************** @@ -269,7 +269,7 @@ Key Keyboard::key_hit() { return invalid; } - code = (unsigned char)data_port.inb(); + code = data_port.inb(); if (key_decoded()) { return gather; } @@ -287,7 +287,7 @@ void Keyboard::reboot() { // Dem BIOS mitteilen, dass das Reset beabsichtigt war // und kein Speichertest durchgefuehrt werden muss. - *(unsigned short*)0x472 = 0x1234; + *reinterpret_cast(0x472) = 0x1234; // Der Tastaturcontroller soll das Reset ausloesen. do { @@ -332,17 +332,17 @@ void Keyboard::set_led(char led, bool on) { // und erlaubt den keyboard interrupt im PIC void Keyboard::plugin() { intdis.assign(IntDispatcher::keyboard, *this); - pic.allow(PIC::keyboard); + PIC::allow(PIC::keyboard); } void Keyboard::trigger() { - Key key = this->key_hit(); - this->lastkey = key.ascii(); + Key key = key_hit(); + // lastkey = key.ascii(); // NOTE: My keyboard has no delete key... - if (key.ctrl_left() && key.alt_left() && (char)key == 'r') { - this->reboot(); + if (key.ctrl_left() && key.alt_left() && static_cast(key) == 'r') { + reboot(); } else if (key != 0) { - kevman.broadcast(key); + kevman.broadcast(key); // Send key to all subscribed threads } } diff --git a/c_os/devices/Keyboard.h b/c_os/devices/Keyboard.h index c9cfcb9..de1efdb 100755 --- a/c_os/devices/Keyboard.h +++ b/c_os/devices/Keyboard.h @@ -8,8 +8,8 @@ * Autor: Olaf Spinczyk, TU Dortmund * * Modifikationen, Michael Schoettner, 2.6.2022 * *****************************************************************************/ -#ifndef __Keyboard_include__ -#define __Keyboard_include__ +#ifndef Keyboard_include__ +#define Keyboard_include__ #include "devices/Key.h" #include "kernel/interrupts/ISR.h" @@ -74,13 +74,15 @@ private: public: Keyboard(const Keyboard& copy) = delete; // Verhindere Kopieren - unsigned int lastkey; // speichert den ASCII-Code der zuletzt gedrückten Taste - // Initialisierung der Tastatur. Keyboard(); +// ~Keyboard() override = default; + + // unsigned int lastkey; // speichert den ASCII-Code der zuletzt gedrückten Taste + // Fuehrt einen Neustart des Rechners durch. - void reboot(); + static void reboot(); // Einstellen der Wiederholungsrate der Tastatur. void set_repeat_rate(int speed, int delay); diff --git a/c_os/devices/LFBgraphics.cc b/c_os/devices/LFBgraphics.cc index ad5ba20..2260cad 100644 --- a/c_os/devices/LFBgraphics.cc +++ b/c_os/devices/LFBgraphics.cc @@ -13,7 +13,6 @@ *****************************************************************************/ #include "devices/LFBgraphics.h" -#include "kernel/Globals.h" /* Hilfsfunktionen */ 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); for (unsigned int yoff = 0; yoff < height; ++yoff) { - int xpos = x; - int ypos = y + yoff; + unsigned int xpos = x; + unsigned int ypos = y + yoff; for (unsigned int xb = 0; xb < width_byte; ++xb) { for (int src = 7; src >= 0; --src) { if ((1 << src) & *bitmap) { @@ -86,14 +85,14 @@ void LFBgraphics::drawString(const Font& fnt, unsigned int x, unsigned int y, * Beschreibung: Zeichnen eines Pixels. * *****************************************************************************/ void LFBgraphics::drawPixel(unsigned int x, unsigned int y, unsigned int col) const { - unsigned char* ptr = (unsigned char*)lfb; + unsigned char* ptr = reinterpret_cast(lfb); if (hfb == 0 || lfb == 0) { return; } if (mode == BUFFER_INVISIBLE) { - ptr = (unsigned char*)hfb; + ptr = reinterpret_cast(hfb); } // 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++; *ptr = ((col >> 16) & 0xFF); - ptr++; + ptr; return; case 32: 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++; *ptr = ((col >> 16) & 0xFF); - ptr++; + ptr; return; } } @@ -139,12 +138,12 @@ void LFBgraphics::drawStraightLine(unsigned int x1, unsigned int y1, unsigned in if (x1 == x2 && y2 > y1) { // Vertical line for (unsigned int i = y1; i <= y2; ++i) { - this->drawPixel(x1, i, col); + drawPixel(x1, i, col); } } else if (y1 == y2 && x2 > x1) { // Horizontal line for (unsigned int i = x1; i <= x2; ++i) { - this->drawPixel(i, y1, col); + drawPixel(i, y1, col); } } else { // Not straight @@ -155,32 +154,32 @@ void LFBgraphics::drawStraightLine(unsigned int x1, unsigned int y1, unsigned in // | | // (x1, y2)---(x2, y2) 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); - this->drawStraightLine(x2, y1, x2, y2, col); - this->drawStraightLine(x1, y2, x2, y2, col); - this->drawStraightLine(x1, y1, x1, y2, col); + drawStraightLine(x1, y1, x2, y1, col); + drawStraightLine(x2, y1, x2, y2, col); + drawStraightLine(x1, y2, x2, y2, col); + drawStraightLine(x1, y1, x1, y2, col); } void LFBgraphics::drawCircle(unsigned int x, unsigned int y, unsigned int rad, unsigned int col) const { // TODO } -void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, unsigned char* pixel_data) const { - unsigned char* ptr; +void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned int bytes_pp, const unsigned char* pixel_data) const { + const unsigned char* ptr; for (unsigned int x = 0; x < width; ++x) { 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) { case 2: // 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 break; case 3: case 4: // 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; } } @@ -193,7 +192,7 @@ void LFBgraphics::drawSprite(unsigned int width, unsigned int height, unsigned i * Beschreibung: Bildschirm loeschen. * *****************************************************************************/ void LFBgraphics::clear() const { - unsigned int* ptr = (unsigned int*)lfb; + unsigned int* ptr = reinterpret_cast(lfb); unsigned int i; if (hfb == 0 || lfb == 0) { @@ -201,7 +200,7 @@ void LFBgraphics::clear() const { } if (mode == 0) { - ptr = (unsigned int*)hfb; + ptr = reinterpret_cast(hfb); } switch (bpp) { @@ -244,8 +243,8 @@ void LFBgraphics::setDrawingBuff(int v) { * Beschreibung: Kopiert den versteckten Puffer in den sichtbaren LFB. * *****************************************************************************/ void LFBgraphics::copyHiddenToVisible() const { - unsigned int* sptr = (unsigned int*)hfb; - unsigned int* dptr = (unsigned int*)lfb; + unsigned int* sptr = reinterpret_cast(hfb); + unsigned int* dptr = reinterpret_cast(lfb); unsigned int i; if (hfb == 0 || lfb == 0) { @@ -278,7 +277,7 @@ void LFBgraphics::copyHiddenToVisible() const { } void swap(unsigned int* a, unsigned int* b) { - int h = *a; + unsigned int h = *a; *a = *b; *b = h; diff --git a/c_os/devices/LFBgraphics.h b/c_os/devices/LFBgraphics.h index a2a7240..5896e19 100644 --- a/c_os/devices/LFBgraphics.h +++ b/c_os/devices/LFBgraphics.h @@ -12,16 +12,18 @@ * https://blog.demofox.org/2015/01/17/bresenhams-drawing-algorithms * *****************************************************************************/ -#ifndef __LFBgraphics_include__ -#define __LFBgraphics_include__ +#ifndef LFBgraphics_include__ +#define LFBgraphics_include__ #include "devices/fonts/Fonts.h" // 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 -#define BUFFER_VISIBLE 1 +constexpr const bool BUFFER_INVISIBLE = false; +constexpr const bool BUFFER_VISIBLE = true; class LFBgraphics { 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 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 void setDrawingBuff(int v); diff --git a/c_os/devices/PCSPK.cc b/c_os/devices/PCSPK.cc index 3759e72..031f0da 100755 --- a/c_os/devices/PCSPK.cc +++ b/c_os/devices/PCSPK.cc @@ -16,7 +16,6 @@ #include "kernel/Globals.h" const IOport PCSPK::control(0x43); -const IOport PCSPK::data0(0x40); const IOport PCSPK::data2(0x42); const IOport PCSPK::ppi(0x61); @@ -29,7 +28,7 @@ const IOport PCSPK::ppi(0x61); * len: Laenge des Tons in ms * *****************************************************************************/ void PCSPK::play(float f, int len) { - int freq = (int)f; + int freq = static_cast(f); int cntStart = 1193180 / freq; int status; @@ -39,7 +38,7 @@ void PCSPK::play(float f, int len) { data2.outb(cntStart / 256); // Zaehler-2 laden (Hibyte) // Lautsprecher einschalten - status = (int)ppi.inb(); // Status-Register des PPI auslesen + status = static_cast(ppi.inb()); // Status-Register des PPI auslesen ppi.outb(status | 3); // Lautpsrecher Einschalten // Pause @@ -57,7 +56,7 @@ void PCSPK::play(float f, int len) { void PCSPK::off() { int status; - status = (int)ppi.inb(); // Status-Register des PPI auslesen + status = static_cast(ppi.inb()); // Status-Register des PPI auslesen ppi.outb((status >> 2) << 2); // Lautsprecher ausschalten } diff --git a/c_os/devices/PCSPK.h b/c_os/devices/PCSPK.h index 7e3dd9e..c6d0fba 100755 --- a/c_os/devices/PCSPK.h +++ b/c_os/devices/PCSPK.h @@ -12,67 +12,66 @@ * Autor: Michael Schoettner, HHU, 22.9.2016 * *****************************************************************************/ -#ifndef __PCSPK_include__ -#define __PCSPK_include__ +#ifndef PCSPK_include__ +#define PCSPK_include__ #include "kernel/IOport.h" // Note, Frequenz -#define C0 130.81 -#define C0X 138.59 -#define D0 146.83 -#define D0X 155.56 -#define E0 164.81 -#define F0 174.61 -#define F0X 185.00 -#define G0 196.00 -#define G0X 207.65 -#define A0 220.00 -#define A0X 233.08 -#define B0 246.94 +constexpr const float C0 = 130.81; +constexpr const float C0X = 138.59; +constexpr const float D0 = 146.83; +constexpr const float D0X = 155.56; +constexpr const float E0 = 164.81; +constexpr const float F0 = 174.61; +constexpr const float F0X = 185.00; +constexpr const float G0 = 196.00; +constexpr const float G0X = 207.65; +constexpr const float A0 = 220.00; +constexpr const float A0X = 233.08; +constexpr const float B0 = 246.94; -#define C1 261.63 -#define C1X 277.18 -#define D1 293.66 -#define D1X 311.13 -#define E1 329.63 -#define F1 349.23 -#define F1X 369.99 -#define G1 391.00 -#define G1X 415.30 -#define A1 440.00 -#define A1X 466.16 -#define B1 493.88 +constexpr const float C1 = 261.63; +constexpr const float C1X = 277.18; +constexpr const float D1 = 293.66; +constexpr const float D1X = 311.13; +constexpr const float E1 = 329.63; +constexpr const float F1 = 349.23; +constexpr const float F1X = 369.99; +constexpr const float G1 = 391.00; +constexpr const float G1X = 415.30; +constexpr const float A1 = 440.00; +constexpr const float A1X = 466.16; +constexpr const float B1 = 493.88; -#define C2 523.25 -#define C2X 554.37 -#define D2 587.33 -#define D2X 622.25 -#define E2 659.26 -#define F2 698.46 -#define F2X 739.99 -#define G2 783.99 -#define G2X 830.61 -#define A2 880.00 -#define A2X 923.33 -#define B2 987.77 -#define C3 1046.50 +constexpr const float C2 = 523.25; +constexpr const float C2X = 554.37; +constexpr const float D2 = 587.33; +constexpr const float D2X = 622.25; +constexpr const float E2 = 659.26; +constexpr const float F2 = 698.46; +constexpr const float F2X = 739.99; +constexpr const float G2 = 783.99; +constexpr const float G2X = 830.61; +constexpr const float A2 = 880.00; +constexpr const float A2X = 923.33; +constexpr const float B2 = 987.77; +constexpr const float C3 = 1046.50; class PCSPK { private: 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 ppi; // Status-Register des PPI // Verzoegerung um X ms (in 1ms Schritten; Min. 1ms) - inline void delay(int time); + static inline void delay(int time); public: PCSPK(const PCSPK& copy) = delete; // Verhindere Kopieren // Konstruktor. Initialisieren der Ports. - PCSPK() {} + PCSPK() = default; // Demo Sounds void tetris(); @@ -82,7 +81,7 @@ public: void play(float f, int len); // Lautsprecher ausschalten - void off(); + static void off(); }; #endif diff --git a/c_os/devices/PIT.cc b/c_os/devices/PIT.cc index c371105..9715521 100755 --- a/c_os/devices/PIT.cc +++ b/c_os/devices/PIT.cc @@ -30,7 +30,7 @@ void PIT::interval(int us) { control.outb(0x36); // Zähler 0 Mode 3 - unsigned int cntStart = (1193180.0 / 1000000.0) * us; // 1.19Mhz PIT + unsigned int cntStart = static_cast((1193180.0 / 1000000.0) * us); // 1.19Mhz PIT data0.outb(cntStart & 0xFF); // Zaehler-0 laden (Lobyte) data0.outb(cntStart >> 8); // Zaehler-0 laden (Hibyte) @@ -75,10 +75,10 @@ void PIT::trigger() { /* hier muss Code eingefuegt werden */ // Indicator - if (systime - this->last_indicator_refresh >= 10) { - this->indicator_pos = (this->indicator_pos + 1) % 4; - CGA::show(79, 0, this->indicator[this->indicator_pos]); - this->last_indicator_refresh = systime; + if (systime - last_indicator_refresh >= 10) { + indicator_pos = (indicator_pos + 1) % 4; + CGA::show(79, 0, indicator[indicator_pos]); + last_indicator_refresh = systime; } // Preemption diff --git a/c_os/devices/PIT.h b/c_os/devices/PIT.h index 8a63821..ac251af 100755 --- a/c_os/devices/PIT.h +++ b/c_os/devices/PIT.h @@ -8,11 +8,12 @@ * Autor: Michael Schoettner, 23.8.2016 * *****************************************************************************/ -#ifndef __PIT_include__ -#define __PIT_include__ +#ifndef PIT_include__ +#define PIT_include__ #include "kernel/interrupts/ISR.h" #include "kernel/IOport.h" +#include "user/lib/Array.h" class PIT : public ISR { private: @@ -22,13 +23,15 @@ private: enum { time_base = 838 }; /* ns */ int timer_interval; - const char indicator[4] = {'|', '/', '-', '\\'}; + const bse::array indicator{'|', '/', '-', '\\'}; unsigned int indicator_pos = 0; unsigned long last_indicator_refresh = 0; public: PIT(const PIT& copy) = delete; // Verhindere Kopieren +// ~PIT() override = default; + // Zeitgeber initialisieren. explicit PIT(int us) { PIT::interval(us); diff --git a/c_os/devices/VESA.cc b/c_os/devices/VESA.cc index 98ef3f2..83ceb80 100644 --- a/c_os/devices/VESA.cc +++ b/c_os/devices/VESA.cc @@ -56,10 +56,9 @@ struct VbeInfoBlock { * Beschreibung: Schalter in den Text-Modus 80x25 Zeichen. * *****************************************************************************/ 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->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->ES = RETURN_MEM >> 4; BC_params->DI = RETURN_MEM & 0xF; - bios.Int(0x10); + BIOS::Int(0x10); - struct VbeInfoBlock* ib = (struct VbeInfoBlock*)RETURN_MEM; + VbeInfoBlock* ib = reinterpret_cast(RETURN_MEM); // Signaturen pruefen if (BC_params->AX != 0x004F) { @@ -94,18 +93,18 @@ bool VESA::initGraphicMode(unsigned short mode) { // kout << "TotalVideoMemory: " << ((ib->TotalMemory*65536) / (1024*1024)) << " MB" << endl; // Gewuenschten Grafikmodus aus Antwort suchen - unsigned short* modePtr = (unsigned short*)((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]); + unsigned short* modePtr = reinterpret_cast((ib->VideoModePtr[1] << 4) + ib->VideoModePtr[0]); for (int i = 0; modePtr[i] != 0xFFFF; ++i) { // Gewuenschter Grafikmodus gefunden? if (modePtr[i] == mode) { - struct VbeModeInfoBlock* minf = (struct VbeModeInfoBlock*)RETURN_MEM; + VbeModeInfoBlock* minf = reinterpret_cast(RETURN_MEM); // Weitere Infos ueber diesen Grafikmodus abfragen BC_params->AX = 0x4F01; BC_params->CX = mode; BC_params->ES = RETURN_MEM >> 4; BC_params->DI = RETURN_MEM & 0xF; - bios.Int(0x10); + BIOS::Int(0x10); // Text-Modi 0-3 haben keinen LFB if (mode > 3 && (minf->attributes & 0x90) == 0) { @@ -116,15 +115,15 @@ bool VESA::initGraphicMode(unsigned short mode) { mode_nr = mode; xres = minf->Xres; yres = minf->Yres; - bpp = (int)minf->bpp; + bpp = static_cast(minf->bpp); lfb = minf->physbase; - hfb = (unsigned int)new char[xres * yres * bpp / 8]; + hfb = reinterpret_cast(new char[xres * yres * bpp / 8]); // Grafikmodus einschalten BC_params->AX = 0x4f02; // SVFA BIOS, init mode BC_params->BX = mode; - bios.Int(0x10); + BIOS::Int(0x10); return true; } } diff --git a/c_os/devices/VESA.h b/c_os/devices/VESA.h index cee2f7a..82decd7 100644 --- a/c_os/devices/VESA.h +++ b/c_os/devices/VESA.h @@ -8,19 +8,19 @@ * Autor: Michael Schoettner, HHU, 19.5.2022 * *****************************************************************************/ -#ifndef __VESA_include__ -#define __VESA_include__ +#ifndef VESA_include__ +#define VESA_include__ #include "devices/LFBgraphics.h" #include "user/lib/Logger.h" // Ausgewaehlte Grafikmodi mit Mode-Nummer -#define MODE_640_480_16BITS 0x111 -#define MODE_640_480_24BITS 0x112 -#define MODE_800_600_16BITS 0x114 -#define MODE_800_600_24BITS 0x115 -#define MODE_1024_768_16BITS 0x117 -#define MODE_1024_768_24BITS 0x118 +constexpr const unsigned int MODE_640_480_16BITS = 0x111; +constexpr const unsigned int MODE_640_480_24BITS = 0x112; +constexpr const unsigned int MODE_800_600_16BITS = 0x114; +constexpr const unsigned int MODE_800_600_24BITS = 0x115; +constexpr const unsigned int MODE_1024_768_16BITS = 0x117; +constexpr const unsigned int MODE_1024_768_24BITS = 0x118; class VESA : public LFBgraphics { private: @@ -34,7 +34,7 @@ public: // Bestimmten Grafikmodus einschalten bool initGraphicMode(unsigned short mode); - void initTextMode(); + static void initTextMode(); }; #endif diff --git a/c_os/devices/fonts/Font_8x16.h b/c_os/devices/fonts/Font_8x16.h index 019f621..197717d 100644 --- a/c_os/devices/fonts/Font_8x16.h +++ b/c_os/devices/fonts/Font_8x16.h @@ -6,7 +6,7 @@ /* */ /**********************************************/ -#define FONTDATAMAX_8x16 4096 +constexpr unsigned int FONTDATAMAX_8x16 = 4096; constexpr unsigned char fontdata_8x16[FONTDATAMAX_8x16] = { diff --git a/c_os/devices/fonts/Font_8x8.h b/c_os/devices/fonts/Font_8x8.h index cf550ec..6b13c1d 100644 --- a/c_os/devices/fonts/Font_8x8.h +++ b/c_os/devices/fonts/Font_8x8.h @@ -6,7 +6,7 @@ /* */ /**********************************************/ -#define FONTDATAMAX_8x8 2048 +constexpr unsigned int FONTDATAMAX_8x8 = 2048; constexpr unsigned char fontdata_8x8[FONTDATAMAX_8x8] = { diff --git a/c_os/devices/fonts/Font_pearl_8x8.h b/c_os/devices/fonts/Font_pearl_8x8.h index b61cb7b..7826cf7 100644 --- a/c_os/devices/fonts/Font_pearl_8x8.h +++ b/c_os/devices/fonts/Font_pearl_8x8.h @@ -10,9 +10,10 @@ /* 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 '^@' */ 0x00, /* 00000000 */ diff --git a/c_os/devices/fonts/Font_sun_12x22.h b/c_os/devices/fonts/Font_sun_12x22.h index d79fcb4..ae1ea2d 100644 --- a/c_os/devices/fonts/Font_sun_12x22.h +++ b/c_os/devices/fonts/Font_sun_12x22.h @@ -1,8 +1,8 @@ // 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 '^@' */ 0x00, 0x00, /* 000000000000 */ diff --git a/c_os/devices/fonts/Font_sun_8x16.h b/c_os/devices/fonts/Font_sun_8x16.h index 8b11985..b556459 100644 --- a/c_os/devices/fonts/Font_sun_8x16.h +++ b/c_os/devices/fonts/Font_sun_8x16.h @@ -1,8 +1,8 @@ // 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,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, diff --git a/c_os/devices/fonts/Fonts.h b/c_os/devices/fonts/Fonts.h index d129e49..64c187b 100644 --- a/c_os/devices/fonts/Fonts.h +++ b/c_os/devices/fonts/Fonts.h @@ -8,11 +8,13 @@ // Je nach Breite wird auf Bytegrenzen aufgerundet: // 8 Pixel -> 1 Byte; 12 Pixel -> 2 Byte -#ifndef __FONTS_H__ -#define __FONTS_H__ +#ifndef FONTS_H__ +#define FONTS_H__ class Font { public: + virtual ~Font() = default; + virtual const unsigned char* getChar(int c) const = 0; virtual unsigned int get_char_width() const = 0; virtual unsigned int get_char_height() const = 0; diff --git a/c_os/kernel/Allocator.cc b/c_os/kernel/Allocator.cc index f0d0b7a..b361589 100755 --- a/c_os/kernel/Allocator.cc +++ b/c_os/kernel/Allocator.cc @@ -34,9 +34,9 @@ #include "kernel/Allocator.h" #include "kernel/Globals.h" -#define MEM_SIZE_DEF 8 * 1024 * 1024 // Groesse des Speichers = 8 MB -#define HEAP_START 0x300000 // Startadresse des Heaps -#define HEAP_SIZE 1024 * 1024 // Default-Groesse des Heaps, falls \ +constexpr const unsigned int MEM_SIZE_DEF = 8 * 1024 * 1024; // Groesse des Speichers = 8 MB +constexpr const unsigned int HEAP_START = 0x300000; // Startadresse des Heaps +constexpr const unsigned int HEAP_SIZE = 1024 * 1024; // Default-Groesse des Heaps, falls \ // nicht über das BIOS ermittelbar /***************************************************************************** diff --git a/c_os/kernel/Allocator.h b/c_os/kernel/Allocator.h index b33978b..d1ef5bc 100755 --- a/c_os/kernel/Allocator.h +++ b/c_os/kernel/Allocator.h @@ -30,11 +30,11 @@ * * * Autor: Michael Schoettner, HHU, 13.6.2020 * *****************************************************************************/ -#ifndef __Allocator_include__ -#define __Allocator_include__ +#ifndef Allocator_include__ +#define Allocator_include__ -constexpr 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 BASIC_ALIGN = 4; // 32 Bit so 4 Bytes? +constexpr const unsigned int HEAP_MIN_FREE_BLOCK_SIZE = 64; // min. Groesse eines freien Blocks class Allocator { public: @@ -42,6 +42,8 @@ public: Allocator(); +// virtual ~Allocator() = default; + unsigned int heap_start; unsigned int heap_end; unsigned int heap_size; diff --git a/c_os/kernel/BIOS.cc b/c_os/kernel/BIOS.cc index a213e80..10a95b0 100644 --- a/c_os/kernel/BIOS.cc +++ b/c_os/kernel/BIOS.cc @@ -17,13 +17,13 @@ extern "C" { } // 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) -#define BIOS16_PARAM_BASE 0x26000 +constexpr const unsigned int BIOS16_PARAM_BASE = 0x26000; // 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(BIOS16_PARAM_BASE); /***************************************************************************** * 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). * *****************************************************************************/ BIOS::BIOS() { - unsigned char* codeAddr = (unsigned char*)BIOS16_CODE_MEMORY_START; + unsigned char* codeAddr = reinterpret_cast(BIOS16_CODE_MEMORY_START); // mov eax, 25000 (Adresse wohin aktuelles esp gesichert wird) *codeAddr = 0x66; @@ -305,7 +305,6 @@ BIOS::BIOS() { *codeAddr = 0x66; codeAddr++; *codeAddr = 0xCB; - codeAddr++; } /***************************************************************************** @@ -314,10 +313,10 @@ BIOS::BIOS() { * Beschreibung: Fuehrt einen BIOS-Aufruf per Software-Interrupt durch. * *****************************************************************************/ void BIOS::Int(int inter) { - unsigned char* ptr = (unsigned char*)BIOS16_CODE_MEMORY_START; + unsigned char* ptr = reinterpret_cast(BIOS16_CODE_MEMORY_START); // Interrupt-Nummer in 16-Bit Code-Segment schreiben (unschoen, aber ...) - *(ptr + 48) = (unsigned char)inter; + *(ptr + 48) = static_cast(inter); CPU::disable_int(); // Interrupts abschalten bios_call(); diff --git a/c_os/kernel/BIOS.h b/c_os/kernel/BIOS.h index c3dd08a..6d9e4e4 100644 --- a/c_os/kernel/BIOS.h +++ b/c_os/kernel/BIOS.h @@ -7,11 +7,11 @@ * * * Autor: Michael Schoettner, 13.9.2016 * *****************************************************************************/ -#ifndef __BIOS_include__ -#define __BIOS_include__ +#ifndef BIOS_include__ +#define BIOS_include__ // Speicherseite fuer Rueckgabewerte von BIOS-Aufrufen -#define RETURN_MEM 0x9F000 +constexpr const unsigned int RETURN_MEM = 0x9F000; // Struktur fuer Parameteruebergabe fuer einen BIOS-Aufruf struct BIOScall_params { @@ -31,7 +31,7 @@ struct BIOScall_params { // kein Auffuellen von bytes auf Wortgrenzen // Zeiger auf Speichbereich fuer Parameter fuer BIOS-Aufruf -extern struct BIOScall_params* BC_params; +extern BIOScall_params* BC_params; class BIOS { public: @@ -41,7 +41,7 @@ public: BIOS(); // BIOS-Aufruf, per Software-Interrupt - void Int(int inter); + static void Int(int inter); }; #endif diff --git a/c_os/kernel/CPU.h b/c_os/kernel/CPU.h index c502ecb..fa6ed57 100755 --- a/c_os/kernel/CPU.h +++ b/c_os/kernel/CPU.h @@ -9,8 +9,8 @@ * * * Autor: Michael Schoettner, 30.7.16 * *****************************************************************************/ -#ifndef __CPU_include__ -#define __CPU_include__ +#ifndef CPU_include__ +#define CPU_include__ class CPU { public: diff --git a/c_os/kernel/Globals.h b/c_os/kernel/Globals.h index 395bc27..b13374d 100755 --- a/c_os/kernel/Globals.h +++ b/c_os/kernel/Globals.h @@ -7,8 +7,8 @@ * * * Autor: Michael Schoettner, 30.7.16 * *****************************************************************************/ -#ifndef __Globals_include__ -#define __Globals_include__ +#ifndef Globals_include__ +#define Globals_include__ #include "devices/CGA_Stream.h" #include "devices/Keyboard.h" diff --git a/c_os/kernel/IOport.h b/c_os/kernel/IOport.h index c934ee3..f109ea8 100755 --- a/c_os/kernel/IOport.h +++ b/c_os/kernel/IOport.h @@ -13,8 +13,8 @@ * * * Autor: Michael Schoettner, 28.8.2016 * *****************************************************************************/ -#ifndef __IOport_include__ -#define __IOport_include__ +#ifndef IOport_include__ +#define IOport_include__ class IOport { private: @@ -36,7 +36,7 @@ public: void outb(unsigned char offset, unsigned char val) const { asm volatile("outb %0, %1" : - : "a"(val), "Nd"((unsigned short)(address + offset))); + : "a"(val), "Nd"(static_cast(address + offset))); } // Wortweise Ausgabe eines Wertes ueber einen I/O-Port. @@ -69,7 +69,7 @@ public: asm volatile("inb %1, %0" : "=a"(ret) - : "Nd"((unsigned short)(address + offset))); + : "Nd"(static_cast(address + offset))); return ret; } diff --git a/c_os/kernel/Paging.cc b/c_os/kernel/Paging.cc index 7c54c3a..215b21e 100644 --- a/c_os/kernel/Paging.cc +++ b/c_os/kernel/Paging.cc @@ -53,20 +53,20 @@ #include "user/lib/Logger.h" // Bits fuer Eintraege in der Page-Table -#define PAGE_PRESENT 0x001 -#define PAGE_WRITEABLE 0x002 -#define PAGE_BIGSIZE 0x080 -#define PAGE_RESERVED 0x800 // Bit 11 ist frei fuer das OS +constexpr const unsigned int PAGE_PRESENT = 0x001; +constexpr const unsigned int PAGE_WRITEABLE = 0x002; +constexpr const unsigned int PAGE_BIGSIZE = 0x080; +constexpr const unsigned int PAGE_RESERVED = 0x800; // Bit 11 ist frei fuer das OS // 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) -#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 -#define FST_ALLOCABLE_PAGE 0x202000 -#define LST_ALLOCABLE_PAGE 0x2FF000 +constexpr const unsigned int FST_ALLOCABLE_PAGE = 0x202000; +constexpr const unsigned int LST_ALLOCABLE_PAGE = 0x2FF000; /***************************************************************************** * Funktion: pg_alloc_page * @@ -77,7 +77,7 @@ unsigned int* pg_alloc_page() { unsigned int* p_page; - p_page = (unsigned int*)PAGE_TABLE; + p_page = reinterpret_cast(PAGE_TABLE); // 1. Eintrag ist fuer Null-Pointer-Exception reserviert // ausserdem liegt an die Page-Table an Adresse PAGE_TABLE @@ -87,10 +87,10 @@ unsigned int* pg_alloc_page() { // pruefe ob Page frei if (((*p_page) & PAGE_RESERVED) == 0) { *p_page = (*p_page | PAGE_RESERVED); - return (unsigned int*)(i << 12); // Address without flags (Offset 0) + return reinterpret_cast(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 */ - unsigned int* page = (unsigned int*)PAGE_TABLE + ((unsigned int)p_page >> 12); // Pagetable entry + unsigned int* page = reinterpret_cast(PAGE_TABLE) + (reinterpret_cast(p_page) >> 12); // Pagetable entry unsigned int mask = PAGE_WRITEABLE; // fill to 32bit *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 */ - unsigned int* page = (unsigned int*)PAGE_TABLE + ((unsigned int)p_page >> 12); // Pagetable entry + unsigned int* page = reinterpret_cast(PAGE_TABLE) + (reinterpret_cast(p_page) >> 12); // Pagetable entry unsigned int mask = PAGE_PRESENT; *page = *page & ~mask; // set present to 0 @@ -131,7 +131,7 @@ void pg_notpresent_page(const unsigned int* p_page) { * Bit geloescht. * *****************************************************************************/ void pg_free_page(unsigned int* p_page) { - int idx = (unsigned int)p_page >> 12; + unsigned int idx = reinterpret_cast(p_page) >> 12; // ausserhalb Page ? if (idx < 1 || idx > 1023) { @@ -139,7 +139,7 @@ void pg_free_page(unsigned int* p_page) { } // Eintrag einlesen und aendern (PAGE_WRITEABLE loeschen) - p_page = (unsigned int*)PAGE_TABLE; + p_page = reinterpret_cast(PAGE_TABLE); p_page += idx; *p_page = ((idx << 12) | PAGE_WRITEABLE | PAGE_PRESENT); @@ -170,7 +170,7 @@ void pg_init() { // // Eintrag 0: Zeiger auf 4 KB Page-Table - p_pdir = (unsigned int*)PAGE_DIRECTORY; + p_pdir = reinterpret_cast(PAGE_DIRECTORY); *p_pdir = PAGE_TABLE | PAGE_WRITEABLE | PAGE_PRESENT; // Eintraege 1-1023: Direktes Mapping (1:1) auf 4 MB Pages (ohne Page-Table) @@ -186,7 +186,7 @@ void pg_init() { // // 1. Page-Table // - p_page = (unsigned int*)PAGE_TABLE; + p_page = reinterpret_cast(PAGE_TABLE); // ersten Eintrag loeschen -> not present, write protected -> Null-Pointer abfangen *p_page = 0; @@ -205,5 +205,5 @@ void pg_init() { } // Paging aktivieren (in startup.asm) - paging_on((unsigned int*)PAGE_DIRECTORY); + paging_on(reinterpret_cast(PAGE_DIRECTORY)); } diff --git a/c_os/kernel/Paging.h b/c_os/kernel/Paging.h index a6e94d6..826a4c3 100644 --- a/c_os/kernel/Paging.h +++ b/c_os/kernel/Paging.h @@ -49,8 +49,8 @@ * Autor: Michael Schoettner, 2.2.2017 * *****************************************************************************/ -#ifndef __Paging_include__ -#define __Paging_include__ +#ifndef Paging_include__ +#define Paging_include__ // Externe Funktionen in startup.asm extern "C" { diff --git a/c_os/kernel/allocator/BumpAllocator.cc b/c_os/kernel/allocator/BumpAllocator.cc index 1c988ed..6594e97 100755 --- a/c_os/kernel/allocator/BumpAllocator.cc +++ b/c_os/kernel/allocator/BumpAllocator.cc @@ -20,8 +20,8 @@ void BumpAllocator::init() { /* Hier muess Code eingefuegt werden */ - this->allocations = 0; - this->next = (unsigned char*)heap_start; + allocations = 0; + next = reinterpret_cast(heap_start); log.info() << "Initialized Bump Allocator" << endl; } @@ -36,8 +36,8 @@ void BumpAllocator::dump_free_memory() { /* Hier muess Code eingefuegt werden */ kout << "Freier Speicher:" << endl - << " - Next: " << hex << (unsigned int)this->next - << ", Allocations: " << dec << this->allocations << endl; + << " - Next: " << hex << reinterpret_cast(next) + << ", Allocations: " << dec << allocations << endl; } /***************************************************************************** @@ -51,14 +51,14 @@ void* BumpAllocator::alloc(unsigned int req_size) { log.debug() << "Requested " << hex << req_size << " Bytes" << endl; - if (req_size + (unsigned int)this->next > this->heap_end) { + if (req_size + reinterpret_cast(next) > heap_end) { log.error() << " - More memory requested than available :(" << endl; return nullptr; } - void* allocated = this->next; - this->next = (unsigned char*)((unsigned int)this->next + req_size); - this->allocations = this->allocations + 1; + void* allocated = next; + next = reinterpret_cast(reinterpret_cast(next) + req_size); + allocations = allocations + 1; log.trace() << " - Allocated " << hex << req_size << " Bytes." << endl; @@ -71,5 +71,5 @@ void* BumpAllocator::alloc(unsigned int req_size) { * Beschreibung: Nicht implementiert. * *****************************************************************************/ 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(ptr) << ", not supported" << endl; } diff --git a/c_os/kernel/allocator/BumpAllocator.h b/c_os/kernel/allocator/BumpAllocator.h index 2d5372d..28aea7a 100755 --- a/c_os/kernel/allocator/BumpAllocator.h +++ b/c_os/kernel/allocator/BumpAllocator.h @@ -9,8 +9,8 @@ * Autor: Michael Schoettner, HHU, 3.3.2022 * *****************************************************************************/ -#ifndef __BumpAllocator_include__ -#define __BumpAllocator_include__ +#ifndef BumpAllocator_include__ +#define BumpAllocator_include__ #include "kernel/Allocator.h" #include "user/lib/Logger.h" @@ -27,6 +27,8 @@ public: BumpAllocator() : log("BMP-Alloc") {}; // Allocator() called implicitely in C++ +// ~BumpAllocator() override = default; + void init() override; void dump_free_memory() override; void* alloc(unsigned int req_size) override; diff --git a/c_os/kernel/allocator/LinkedListAllocator.cc b/c_os/kernel/allocator/LinkedListAllocator.cc index 48fac41..db60bf7 100755 --- a/c_os/kernel/allocator/LinkedListAllocator.cc +++ b/c_os/kernel/allocator/LinkedListAllocator.cc @@ -32,10 +32,10 @@ void LinkedListAllocator::init() { /* Hier muess Code eingefuegt werden */ - this->free_start = (free_block_t*)this->heap_start; - this->free_start->allocated = false; - this->free_start->size = this->heap_size - sizeof(free_block_t); - this->free_start->next = this->free_start; // Only one block, points to itself + free_start = reinterpret_cast(heap_start); + free_start->allocated = false; + free_start->size = heap_size - sizeof(free_block_t); + free_start->next = free_start; // Only one block, points to itself log.info() << "Initialized LinkedList Allocator" << endl; } @@ -51,14 +51,14 @@ void LinkedListAllocator::dump_free_memory() { kout << "Freier Speicher:" << endl; - if (this->free_start == nullptr) { + if (free_start == nullptr) { kout << " - No free Blocks" << endl; } else { - kout << " - Freelist start: " << hex << (unsigned int)this->free_start << endl; + kout << " - Freelist start: " << hex << reinterpret_cast(free_start) << endl; - free_block_t* current = this->free_start; + free_block_t* current = free_start; do { - kout << " - Free Block (Start: " << hex << (unsigned int)current + kout << " - Free Block (Start: " << hex << reinterpret_cast(current) << " Size: " << hex << current->size << ")" << endl; current = current->next; } while (current != free_start); @@ -71,16 +71,16 @@ void LinkedListAllocator::dump_free_memory() { * Beschreibung: Einen neuen Speicherblock allozieren. * *****************************************************************************/ void* LinkedListAllocator::alloc(unsigned int req_size) { - this->lock.acquire(); + lock.acquire(); /* Hier muess Code eingefuegt werden */ // NOTE: next pointer zeigt auf headeranfang, returned wird zeiger auf anfang des nutzbaren freispeichers log.debug() << "Requested " << hex << req_size << " Bytes" << endl; - if (this->free_start == nullptr) { + if (free_start == nullptr) { log.error() << " - No free memory remaining :(" << endl; - this->lock.release(); + lock.release(); 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; } - free_block_t* current = this->free_start; + free_block_t* current = free_start; do { if (current->size >= rreq_size) { // Size doesn't contain header, only usable // Current block large enough @@ -106,7 +106,7 @@ void* LinkedListAllocator::alloc(unsigned int req_size) { // In case of only one freeblock: // [current | new_next] free_block_t* new_next = - (free_block_t*)((unsigned int)current + sizeof(free_block_t) + rreq_size); + reinterpret_cast(reinterpret_cast(current) + sizeof(free_block_t) + rreq_size); // If only one block exists, current->next is current // 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; // Next-fit - this->free_start = new_next; + free_start = new_next; log.trace() << " - Allocated " << hex << rreq_size << " Bytes with cutting" << endl; } else { // Block too small to be cut, allocate whole block // Next-fit - this->free_start = current->next; // Pointer keeps pointing to current if last block - if (this->free_start == current) { + free_start = current->next; // Pointer keeps pointing to current if last block + if (free_start == current) { // No free block remaining log.trace() << " - Disabled freelist" << endl; - this->free_start = nullptr; + free_start = nullptr; } 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() << "Returning memory address " << hex << ((unsigned int)current + sizeof(free_block_t)) << endl; - this->lock.release(); - return (void*)((unsigned int)current + sizeof(free_block_t)); // Speicheranfang, nicht header + log.debug() << "returning memory address " << hex << reinterpret_cast(current) + sizeof(free_block_t) << endl; + lock.release(); + return reinterpret_cast(reinterpret_cast(current) + sizeof(free_block_t)); // Speicheranfang, nicht header } 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; - this->lock.release(); + lock.release(); return nullptr; } @@ -174,35 +174,35 @@ void* LinkedListAllocator::alloc(unsigned int req_size) { * Beschreibung: Einen Speicherblock freigeben. * *****************************************************************************/ void LinkedListAllocator::free(void* ptr) { - this->lock.acquire(); + lock.acquire(); /* Hier muess Code eingefuegt werden */ // 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(reinterpret_cast(ptr) - sizeof(free_block_t)); - log.debug() << "Freeing " << hex << (unsigned int)ptr << ", Size: " << block_start->size << endl; + log.debug() << "Freeing " << hex << reinterpret_cast(ptr) << ", Size: " << block_start->size << endl; if (!block_start->allocated) { log.error() << "Block already free" << endl; - this->lock.release(); + lock.release(); return; } // Reenable the freelist if no block was available // This also means that no merging can be done - if (this->free_start == nullptr) { - this->free_start = block_start; + if (free_start == nullptr) { + free_start = block_start; block_start->allocated = false; block_start->next = block_start; log.trace() << " - Enabling freelist with one block" << endl; - this->lock.release(); + lock.release(); return; } free_block_t* next_block = - (free_block_t*)((unsigned int)block_start + sizeof(free_block_t) + block_start->size); + reinterpret_cast(reinterpret_cast(block_start) + sizeof(free_block_t) + block_start->size); // Find the next free block, multiple next blocks can be allocated so walk through them 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_next = - (free_block_t*)((unsigned int)previous_free + sizeof(free_block_t) + previous_free->size); + reinterpret_cast(reinterpret_cast(previous_free) + sizeof(free_block_t) + previous_free->size); // 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 @@ -254,10 +254,10 @@ void LinkedListAllocator::free(void* ptr) { // If thats the case I should set the next pointer to the next adjacent block // when allocating a new block - if (this->free_start == next_free) { + if (free_start == next_free) { // next_free is now invalid after merge - log.trace() << " - Moving freelist start to " << hex << (unsigned int)block_start << endl; - this->free_start = block_start; + log.trace() << " - Moving freelist start to " << hex << reinterpret_cast(block_start) << endl; + free_start = block_start; } } else { // 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 // 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 - log.trace() << " - Moving freelist start to " << hex << (unsigned int)previous_free << endl; - this->free_start = previous_free; + log.trace() << " - Moving freelist start to " << hex << reinterpret_cast(previous_free) << endl; + free_start = previous_free; } } // Depending on the merging this might write into the block, but doesn't matter block_start->allocated = false; - this->lock.release(); + lock.release(); } free_block_t* LinkedListAllocator::find_previous_block(free_block_t* next_block) { diff --git a/c_os/kernel/allocator/LinkedListAllocator.h b/c_os/kernel/allocator/LinkedListAllocator.h index a975ffc..d5a7b68 100755 --- a/c_os/kernel/allocator/LinkedListAllocator.h +++ b/c_os/kernel/allocator/LinkedListAllocator.h @@ -9,8 +9,8 @@ * Autor: Michael Schoettner, HHU, 13.6.2020 * *****************************************************************************/ -#ifndef __LinkedListAllocator_include__ -#define __LinkedListAllocator_include__ +#ifndef LinkedListAllocator_include__ +#define LinkedListAllocator_include__ #include "kernel/Allocator.h" #include "lib/SpinLock.h" @@ -47,6 +47,8 @@ public: LinkedListAllocator() : log("LL-Alloc") {} +// ~LinkedListAllocator() override = default; + void init() override; void dump_free_memory() override; void* alloc(unsigned int req_size) override; diff --git a/c_os/kernel/allocator/TreeAllocator.cc b/c_os/kernel/allocator/TreeAllocator.cc index 1791bc4..06a1521 100755 --- a/c_os/kernel/allocator/TreeAllocator.cc +++ b/c_os/kernel/allocator/TreeAllocator.cc @@ -2,27 +2,29 @@ #include "kernel/Globals.h" void TreeAllocator::init() { - this->free_start = (tree_block_t*)this->heap_start; - this->free_start->allocated = false; - this->free_start->left = nullptr; - this->free_start->right = nullptr; - this->free_start->parent = nullptr; - this->free_start->red = false; // The root is always black - this->free_start->next = (list_block_t*)this->free_start; - this->free_start->previous = (list_block_t*)this->free_start; + free_start = reinterpret_cast(heap_start); + free_start->allocated = false; + free_start->left = nullptr; + free_start->right = nullptr; + free_start->parent = nullptr; + free_start->red = false; // The root is always black + free_start->next = reinterpret_cast(free_start); + free_start->previous = reinterpret_cast(free_start); log.info() << "Initialized Tree Allocator" << endl; } void TreeAllocator::dump_free_memory() { kout << "Free Memory:" << endl; - list_block_t* current = (list_block_t*)this->heap_start; + list_block_t* current = reinterpret_cast(heap_start); do { 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(current) << ", Size: " + << reinterpret_cast(current->next) - reinterpret_cast(current) + << endl; } current = current->next; - } while ((unsigned int)current != this->heap_start); + } while (reinterpret_cast(current) != heap_start); } 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 - 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) { log.error() << " - No block found" << endl; return nullptr; @@ -54,8 +56,8 @@ void* TreeAllocator::alloc(unsigned int req_size) { return nullptr; } best_fit->allocated = true; - unsigned int size = this->get_size(best_fit); - log.trace() << " - Found best-fit: " << hex << (unsigned int)best_fit << endl; + unsigned int size = get_size(best_fit); + log.trace() << " - Found best-fit: " << hex << reinterpret_cast(best_fit) << endl; // 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 @@ -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 tree_block_t dummy; 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 - 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)) { // Block can be cut log.trace() << " - Allocating " << dec << rreq_size << " Bytes with cutting" << endl; // [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(reinterpret_cast(best_fit) + sizeof(list_block_t) + rreq_size); new_block->allocated = false; - this->dll_insert(best_fit, new_block); - this->rbt_insert(new_block); + dll_insert(best_fit, new_block); + rbt_insert(new_block); } else { // Don't cut block // 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 - this->rbt_remove(&dummy); + rbt_remove(&dummy); - log.trace() << " - Returned address " << hex << (unsigned int)((char*)best_fit + sizeof(list_block_t)) << endl; - return (void*)((char*)best_fit + sizeof(list_block_t)); + log.trace() << " - Returned address " << hex + << reinterpret_cast(reinterpret_cast(best_fit) + sizeof(list_block_t)) + << endl; + return reinterpret_cast(reinterpret_cast(best_fit) + sizeof(list_block_t)); } void TreeAllocator::free(void* ptr) { - log.info() << "Freeing " << hex << (unsigned int)ptr << endl; + log.info() << "Freeing " << hex << reinterpret_cast(ptr) << endl; - list_block_t* block = (list_block_t*)((char*)ptr - sizeof(list_block_t)); + list_block_t* block = reinterpret_cast(reinterpret_cast(ptr) - sizeof(list_block_t)); if (!block->allocated) { // Block already free return; @@ -105,25 +110,25 @@ void TreeAllocator::free(void* ptr) { if (next->allocated && previous->allocated) { // No merge - this->rbt_insert((tree_block_t*)block); + rbt_insert(reinterpret_cast(block)); return; } // HACK: Same as when allocating tree_block_t dummy; 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) { // Merge forward log.trace() << " - Merging forward" << endl; // Remove the next block from all lists as it is now part of our freed block - this->dll_remove(next); - this->rbt_remove((tree_block_t*)next); // BUG: Bluescreen if next is the only block in the freelist + dll_remove(next); + rbt_remove(reinterpret_cast(next)); // BUG: Bluescreen if next is the only block in the freelist if (previous->allocated) { // Don't insert if removed later because of backward merge - this->rbt_insert((tree_block_t*)block); + rbt_insert(reinterpret_cast(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 // It doesn't have to be removed from rbt as it wasn't in there as it was allocated before - this->dll_remove(block); - this->rbt_remove((tree_block_t*)previous); - this->rbt_insert((tree_block_t*)previous); // Reinsert with new size + dll_remove(block); + rbt_remove(reinterpret_cast(previous)); + rbt_insert(reinterpret_cast(previous)); // Reinsert with new size } // HACK: Same as when allocating - this->rbt_remove(&dummy); + rbt_remove(&dummy); } unsigned int TreeAllocator::get_size(list_block_t* block) const { if (block->next == block) { // Only one block exists - return this->heap_end - ((unsigned int)block + sizeof(list_block_t)); + return heap_end - (reinterpret_cast(block) + sizeof(list_block_t)); } - if ((unsigned int)block->next > (unsigned int)block) { + if (reinterpret_cast(block->next) > reinterpret_cast(block)) { // Next block is placed later in memory - return (unsigned int)block->next - ((unsigned int)block + sizeof(list_block_t)); + return reinterpret_cast(block->next) - (reinterpret_cast(block) + sizeof(list_block_t)); } // 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(heap_end) - (reinterpret_cast(block) + sizeof(list_block_t)); } diff --git a/c_os/kernel/allocator/TreeAllocator.h b/c_os/kernel/allocator/TreeAllocator.h index b4ad0bc..e04e393 100755 --- a/c_os/kernel/allocator/TreeAllocator.h +++ b/c_os/kernel/allocator/TreeAllocator.h @@ -1,5 +1,5 @@ -#ifndef __TreeAllocator_include__ -#define __TreeAllocator_include__ +#ifndef TreeAllocator_include__ +#define TreeAllocator_include__ #include "kernel/Allocator.h" #include "user/lib/Logger.h" @@ -40,7 +40,7 @@ private: // Returns the size of the usable memory of a block 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(block)); } void dump_free_memory(tree_block_t* node); @@ -57,10 +57,12 @@ private: 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(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(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(previous), reinterpret_cast(node)); + } void dll_remove(list_block_t* node); public: @@ -68,6 +70,8 @@ public: TreeAllocator() : log("RBT-Alloc") {}; +// ~TreeAllocator() override = default; + void init() override; void dump_free_memory() override; void* alloc(unsigned int req_size) override; diff --git a/c_os/kernel/allocator/TreeAllocatorOperations.cc b/c_os/kernel/allocator/TreeAllocatorOperations.cc index 2087920..8818a3b 100755 --- a/c_os/kernel/allocator/TreeAllocatorOperations.cc +++ b/c_os/kernel/allocator/TreeAllocatorOperations.cc @@ -1,12 +1,11 @@ #include "kernel/allocator/TreeAllocator.h" -#include "kernel/Globals.h" // RBT code taken from https://github.com/Bibeknam/algorithmtutorprograms // START copy from algorithmtutorprograms void TreeAllocator::rbt_transplant(tree_block_t* a, tree_block_t* b) { if (a->parent == nullptr) { - this->free_start = b; + free_start = b; } else if (a == a->parent->left) { a->parent->left = b; } else { @@ -25,11 +24,11 @@ void TreeAllocator::rbt_insert(tree_block_t* node) { node->red = true; // new node must be red tree_block_t* y = nullptr; - tree_block_t* x = this->free_start; + tree_block_t* x = free_start; while (x != nullptr) { y = x; - if (this->get_size(node) < this->get_size(x)) { + if (get_size(node) < get_size(x)) { x = x->left; } else { x = x->right; @@ -39,8 +38,8 @@ void TreeAllocator::rbt_insert(tree_block_t* node) { // y is parent of x node->parent = y; if (y == nullptr) { - this->free_start = node; - } else if (this->get_size(node) < this->get_size(y)) { + free_start = node; + } else if (get_size(node) < get_size(y)) { y->left = node; } else { y->right = node; @@ -58,7 +57,7 @@ void TreeAllocator::rbt_insert(tree_block_t* node) { } // Fix the tree - this->rbt_fix_insert(node); + rbt_fix_insert(node); } // fix the red-black tree @@ -77,12 +76,12 @@ void TreeAllocator::rbt_fix_insert(tree_block_t* k) { if (k == k->parent->left) { // case 3.2.2 k = k->parent; - this->rbt_rot_r(k); + rbt_rot_r(k); } // case 3.2.1 k->parent->red = false; k->parent->parent->red = true; - this->rbt_rot_l(k->parent->parent); + rbt_rot_l(k->parent->parent); } } else { u = k->parent->parent->right; // uncle @@ -97,19 +96,19 @@ void TreeAllocator::rbt_fix_insert(tree_block_t* k) { if (k == k->parent->right) { // mirror case 3.2.2 k = k->parent; - this->rbt_rot_l(k); + rbt_rot_l(k); } // mirror case 3.2.1 k->parent->red = false; 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; } } - this->free_start->red = false; + free_start->red = false; } // rotate left at node x @@ -121,7 +120,7 @@ void TreeAllocator::rbt_rot_l(tree_block_t* x) { } y->parent = x->parent; if (x->parent == nullptr) { - this->free_start = y; + free_start = y; } else if (x == x->parent->left) { x->parent->left = y; } else { @@ -140,7 +139,7 @@ void TreeAllocator::rbt_rot_r(tree_block_t* x) { } y->parent = x->parent; if (x->parent == nullptr) { - this->free_start = y; + free_start = y; } else if (x == x->parent->right) { x->parent->right = y; } else { @@ -166,43 +165,43 @@ void TreeAllocator::rbt_remove(tree_block_t* z) { bool y_original_red = y->red; if (z->left == nullptr) { x = z->right; - this->rbt_transplant(z, z->right); + rbt_transplant(z, z->right); } else if (z->right == nullptr) { x = z->left; - this->rbt_transplant(z, z->left); + rbt_transplant(z, z->left); } else { - y = this->rbt_minimum(z->right); + y = rbt_minimum(z->right); y_original_red = y->red; x = y->right; if (y->parent == z) { x->parent = y; } else { - this->rbt_transplant(y, y->right); + rbt_transplant(y, y->right); y->right = z->right; y->right->parent = y; } - this->rbt_transplant(z, y); + rbt_transplant(z, y); y->left = z->left; y->left->parent = y; y->red = z->red; } if (!y_original_red) { - this->rbt_fix_remove(x); + rbt_fix_remove(x); } } // fix the rb tree modified by the delete operation void TreeAllocator::rbt_fix_remove(tree_block_t* x) { tree_block_t* s; - while (x != this->free_start && !x->red) { + while (x != free_start && !x->red) { if (x == x->parent->left) { s = x->parent->right; if (s->red) { // case 3.1 s->red = false; x->parent->red = true; - this->rbt_rot_l(x->parent); + rbt_rot_l(x->parent); s = x->parent->right; } @@ -215,7 +214,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) { // case 3.3 s->left->red = false; s->red = true; - this->rbt_rot_r(s); + rbt_rot_r(s); s = x->parent->right; } @@ -223,8 +222,8 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) { s->red = x->parent->red; x->parent->red = false; s->right->red = false; - this->rbt_rot_l(x->parent); - x = this->free_start; + rbt_rot_l(x->parent); + x = free_start; } } else { s = x->parent->left; @@ -232,7 +231,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) { // case 3.1 s->red = false; x->parent->red = true; - this->rbt_rot_r(x->parent); + rbt_rot_r(x->parent); s = x->parent->left; } @@ -245,7 +244,7 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) { // case 3.3 s->right->red = false; s->red = true; - this->rbt_rot_l(s); + rbt_rot_l(s); s = x->parent->left; } @@ -253,8 +252,8 @@ void TreeAllocator::rbt_fix_remove(tree_block_t* x) { s->red = x->parent->red; x->parent->red = false; s->left->red = false; - this->rbt_rot_r(x->parent); - x = this->free_start; + rbt_rot_r(x->parent); + x = free_start; } } } @@ -268,17 +267,17 @@ tree_block_t* TreeAllocator::rbt_search_bestfit(tree_block_t* node, unsigned int return nullptr; } - if (req_size < this->get_size(node)) { - if (node->left != nullptr && this->get_size(node->left) >= req_size) { - return this->rbt_search_bestfit(node->left, req_size); + if (req_size < get_size(node)) { + if (node->left != nullptr && get_size(node->left) >= req_size) { + return rbt_search_bestfit(node->left, req_size); } return node; } - if (req_size > this->get_size(node)) { - if (node->right != nullptr && this->get_size(node->right) >= req_size) { - return this->rbt_search_bestfit(node->right, req_size); + if (req_size > get_size(node)) { + if (node->right != nullptr && get_size(node->right) >= req_size) { + return rbt_search_bestfit(node->right, req_size); } // Block doesn't fit diff --git a/c_os/kernel/interrupts/Bluescreen.cc b/c_os/kernel/interrupts/Bluescreen.cc index 1cd36b8..0d3695e 100644 --- a/c_os/kernel/interrupts/Bluescreen.cc +++ b/c_os/kernel/interrupts/Bluescreen.cc @@ -9,7 +9,6 @@ * * * Autor: Michael Schoettner, 11.12.2018 * *****************************************************************************/ -#include "devices/CGA.h" #include "kernel/Globals.h" // in startup.asm @@ -68,11 +67,11 @@ int bs_ypos = 0; void bs_clear() { unsigned int x; unsigned int y; - unsigned short* ptr = (unsigned short*)0xb8000; + unsigned short* ptr = reinterpret_cast(0xb8000); for (x = 0; x < 80; x++) { for (y = 0; y < 25; y++) { - *(ptr + y * 80 + x) = (short)0x1F00; + *(ptr + y * 80 + x) = static_cast(0x1F00); } } @@ -96,7 +95,7 @@ void bs_lf() { * Beschreibung: Ein Zeichen ausgeben. * *****************************************************************************/ void bs_print_char(char c) { - unsigned char* ptr = (unsigned char*)0xb8000; + unsigned char* ptr = reinterpret_cast(0xb8000); *(ptr + bs_ypos * 80 * 2 + bs_xpos * 2) = c; bs_xpos++; @@ -122,9 +121,9 @@ void bs_print_string(char* str) { *****************************************************************************/ void bs_printHexDigit(int c) { if (c < 10) { - bs_print_char('0' + (unsigned char)c); + bs_print_char('0' + static_cast(c)); } else { - bs_print_char('A' + (unsigned char)(c - 10)); + bs_print_char('A' + static_cast(c - 10)); } } @@ -145,7 +144,7 @@ void bs_print_uintHex(unsigned int c) { * Beschreibung: String mit Integer ausgeben. Wird verwendet um ein * * Register auszugeben. * *****************************************************************************/ -void bs_printReg(char* str, int value) { +void bs_printReg(char* str, unsigned int value) { bs_print_string(str); bs_print_uintHex(value); bs_print_string(" \0"); @@ -211,7 +210,7 @@ void bs_dump(unsigned int exceptionNr) { get_int_esp(&int_esp); // wir müssen den Inhalt auslesen und das als Zeiger verwenden, um den Stack auszulesen - sptr = (unsigned int*)*int_esp; + sptr = reinterpret_cast(*int_esp); bs_lf(); @@ -252,7 +251,7 @@ void bs_dump(unsigned int exceptionNr) { // Exception mit Error-Code? if (has_error_code == 1) { - int error_nr = *(sptr + 8); + unsigned int error_nr = *(sptr + 8); if (exceptionNr == 14) { if (error_nr == 3) { @@ -278,7 +277,7 @@ void bs_dump(unsigned int exceptionNr) { bs_print_string("Calling Stack:\0"); bs_lf(); int x = 0; - unsigned int* ebp = (unsigned int*)*(sptr + 2); + unsigned int* ebp = reinterpret_cast(*(sptr + 2)); unsigned int raddr; // solange eip > 1 MB && ebp < 128 MB, max. Aufruftiefe 10 @@ -289,7 +288,7 @@ void bs_dump(unsigned int exceptionNr) { bs_lf(); // dynamische Kette -> zum Aufrufer - ebp = (unsigned int*)*ebp; + ebp = reinterpret_cast(*ebp); x++; } diff --git a/c_os/kernel/interrupts/Bluescreen.h b/c_os/kernel/interrupts/Bluescreen.h index bcc5e62..0c9c215 100644 --- a/c_os/kernel/interrupts/Bluescreen.h +++ b/c_os/kernel/interrupts/Bluescreen.h @@ -10,8 +10,8 @@ * Autor: Michael Schoettner, 2.2.2017 * *****************************************************************************/ -#ifndef __Bluescreen_include__ -#define __Bluescreen_include__ +#ifndef Bluescreen_include__ +#define Bluescreen_include__ // dump blue screen (will not return) void bs_dump(unsigned int exceptionNr); diff --git a/c_os/kernel/interrupts/ISR.h b/c_os/kernel/interrupts/ISR.h index 73d753c..ce8bdcd 100755 --- a/c_os/kernel/interrupts/ISR.h +++ b/c_os/kernel/interrupts/ISR.h @@ -9,16 +9,16 @@ * * * Autor: Michael Schoettner, 06.04.20 * *****************************************************************************/ -#ifndef __ISR_include__ -#define __ISR_include__ +#ifndef ISR_include__ +#define ISR_include__ class ISR { - -private: +public: ISR(const ISR& copy) = delete; // Verhindere Kopieren -public: - ISR() {} +// virtual ~ISR() = default; + + ISR() = default; // Unterbrechungsbehandlungsroutine virtual void trigger() = 0; diff --git a/c_os/kernel/interrupts/IntDispatcher.cc b/c_os/kernel/interrupts/IntDispatcher.cc index 392d866..c6220c4 100755 --- a/c_os/kernel/interrupts/IntDispatcher.cc +++ b/c_os/kernel/interrupts/IntDispatcher.cc @@ -15,7 +15,7 @@ #include "kernel/Globals.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 * @@ -60,12 +60,12 @@ int IntDispatcher::assign(unsigned int vector, ISR& isr) { /* hier muss Code eingefuegt werden */ - if (vector >= this->size) { + if (vector >= size) { log.error() << "Invalid vector number when assigning" << endl; return -1; } - this->map[vector] = &isr; + map[vector] = &isr; log.info() << "Registered ISR for vector " << dec << vector << endl; return 0; @@ -85,11 +85,11 @@ int IntDispatcher::report(unsigned int vector) { /* hier muss Code eingefuegt werden */ - if (vector >= this->size) { + if (vector >= size) { return -1; } - ISR* isr = this->map[vector]; + ISR* isr = map[vector]; if (isr == nullptr) { log.error() << "No ISR registered for vector " << vector << endl; diff --git a/c_os/kernel/interrupts/IntDispatcher.h b/c_os/kernel/interrupts/IntDispatcher.h index a1da8ad..a3ee707 100755 --- a/c_os/kernel/interrupts/IntDispatcher.h +++ b/c_os/kernel/interrupts/IntDispatcher.h @@ -10,18 +10,19 @@ * * * Autor: Michael Schoettner, 30.7.16 * *****************************************************************************/ -#ifndef __IntDispatcher_include__ -#define __IntDispatcher_include__ +#ifndef IntDispatcher_include__ +#define IntDispatcher_include__ #include "kernel/interrupts/ISR.h" #include "user/lib/Logger.h" +#include "user/lib/Array.h" class IntDispatcher { private: NamedLogger log; enum { size = 256 }; - ISR* map[size]; + bse::array map; public: IntDispatcher(const IntDispatcher& copy) = delete; // Verhindere Kopieren diff --git a/c_os/kernel/interrupts/PIC.h b/c_os/kernel/interrupts/PIC.h index 8f8c6b2..af96c88 100755 --- a/c_os/kernel/interrupts/PIC.h +++ b/c_os/kernel/interrupts/PIC.h @@ -14,8 +14,8 @@ * * * Autor: Olaf Spinczyk, TU Dortmund * *****************************************************************************/ -#ifndef __PIC_include__ -#define __PIC_include__ +#ifndef PIC_include__ +#define PIC_include__ #include "kernel/IOport.h" diff --git a/c_os/kernel/threads/IdleThread.h b/c_os/kernel/threads/IdleThread.h index d1029d8..f92c2f6 100644 --- a/c_os/kernel/threads/IdleThread.h +++ b/c_os/kernel/threads/IdleThread.h @@ -8,8 +8,8 @@ * Autor: Michael, Schoettner, HHU, 13.8.2016 * *****************************************************************************/ -#ifndef __IdleThread_include__ -#define __IdleThread_include__ +#ifndef IdleThread_include__ +#define IdleThread_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" @@ -20,10 +20,10 @@ public: IdleThread() : Thread("IdleThread") {} - /*[[noreturn]]*/ void run() override { + [[noreturn]] void run() override { // Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert log.info() << "IdleThread enabled preemption" << endl; - scheduler.enable_preemption(this->tid); + scheduler.enable_preemption(tid); if (!scheduler.preemption_enabled()) { log.error() << "Preemption disabled" << endl; } diff --git a/c_os/kernel/threads/Scheduler.h b/c_os/kernel/threads/Scheduler.h index 4407c4f..aac9be7 100644 --- a/c_os/kernel/threads/Scheduler.h +++ b/c_os/kernel/threads/Scheduler.h @@ -9,8 +9,8 @@ * Autor: Michael, Schoettner, HHU, 22.8.2016 * *****************************************************************************/ -#ifndef __Scheduler_include__ -#define __Scheduler_include__ +#ifndef Scheduler_include__ +#define Scheduler_include__ #include "kernel/threads/Thread.h" #include "user/lib/Logger.h" @@ -33,8 +33,8 @@ private: unsigned int idle_tid = 0U; // Roughly the old dispatcher functionality - /*[[noreturn]]*/ void start(bse::vector>::iterator next); // Start next without prev - /*[[noreturn]]*/ void switch_to(Thread* prev_raw, bse::vector>::iterator next); // Switch from prev to next + void start(bse::vector>::iterator next); // Start next without prev + void switch_to(Thread* prev_raw, bse::vector>::iterator next); // Switch from prev to next // Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird) void enable_preemption(unsigned int tid) { idle_tid = tid; } @@ -63,7 +63,7 @@ public: bool preemption_enabled() const { return idle_tid != 0U; } // Scheduler starten - /*[[noreturn]]*/ void schedule(); + void schedule(); // Helper that directly constructs the thread, then readys it template @@ -80,7 +80,7 @@ public: // NOTE: When a thread exits itself it will disappear... // Maybe put exited threads in an exited queue? // 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 void kill(unsigned int tid, bse::unique_ptr* ptr); @@ -94,13 +94,13 @@ public: void nice_kill(unsigned int tid) { nice_kill(tid, nullptr); } // 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 - /* [[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) - /* [[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) void deblock(unsigned int tid); diff --git a/c_os/kernel/threads/Thread.cc b/c_os/kernel/threads/Thread.cc index 224c1e9..c263391 100755 --- a/c_os/kernel/threads/Thread.cc +++ b/c_os/kernel/threads/Thread.cc @@ -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. // I thought this syntax was a bit clearer than decrementing a pointer - stack[-1] = (unsigned int)object; + stack[-1] = reinterpret_cast(object); stack[-2] = 0x131155U; - stack[-3] = (unsigned int)kickoff; + stack[-3] = reinterpret_cast(kickoff); stack[-4] = 0; // EAX stack[-5] = 0; // ECX stack[-6] = 0; // EDX stack[-7] = 0; // EBX - stack[-8] = (unsigned int)&stack[-3]; // ESP + stack[-8] = reinterpret_cast(&stack[-3]); // ESP stack[-9] = 0; // EBP stack[-10] = 0; // ESI stack[-11] = 0; // EDI stack[-12] = 0x200U; - *esp = (unsigned int)&stack[-12]; + *esp = reinterpret_cast(&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 * *****************************************************************************/ 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 } @@ -124,5 +124,5 @@ void Thread::start() const { /* hier muss Code eingefügt werden */ - Thread_start(this->esp); + Thread_start(esp); } diff --git a/c_os/kernel/threads/Thread.h b/c_os/kernel/threads/Thread.h index f426d2d..0dea417 100644 --- a/c_os/kernel/threads/Thread.h +++ b/c_os/kernel/threads/Thread.h @@ -7,9 +7,9 @@ * Thread-Objekte werden vom Scheduler in einer verketteten * * 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. * - * Die CPU sollte mit 'yield' freiwillig abgegeben werden. * + * Die CPU sollte mit 'yield' freiwillig abgegeben werden. * * Um bei einem Threadwechsel den Kontext sichern zu * * koennen, enthaelt jedes Threadobjekt eine Struktur * * ThreadState, in dem die Werte der nicht-fluechtigen * @@ -25,8 +25,8 @@ * Autor: Michael, Schoettner, HHU, 16.12.2016 * *****************************************************************************/ -#ifndef __Thread_include__ -#define __Thread_include__ +#ifndef Thread_include__ +#define Thread_include__ #include "user/lib/Logger.h" @@ -49,21 +49,21 @@ public: Thread(const Thread& copy) = delete; // Verhindere Kopieren virtual ~Thread() { - log.info() << "Uninitialized thread, ID: " << dec << this->tid << " (" << name << ")" << endl; - delete[] this->stack; + log.info() << "Uninitialized thread, ID: " << dec << tid << " (" << name << ")" << endl; + delete[] stack; } // Thread aktivieren - /*[[noreturn]]*/ void start() const; + void start() const; // Umschalten auf Thread 'next' - /*[[noreturn]]*/ void switchTo(Thread& next); + void switchTo(Thread& next); // Ask thread to terminate itself void suicide() { running = false; } // Methode des Threads, muss in Sub-Klasse implementiert werden - [[noreturn]] virtual void run() = 0; + virtual void run() = 0; }; #endif diff --git a/c_os/lib/OutStream.h b/c_os/lib/OutStream.h index 24a5e24..77d49a7 100755 --- a/c_os/lib/OutStream.h +++ b/c_os/lib/OutStream.h @@ -19,8 +19,8 @@ * Autor: Olaf Spinczyk, TU Dortmund * * Aenderungen von Michael Schoettner, HHU, 06.04.20 * *****************************************************************************/ -#ifndef __OutStream_include__ -#define __OutStream_include__ +#ifndef OutStream_include__ +#define OutStream_include__ #include "lib/StringBuffer.h" #include "user/lib/String.h" @@ -40,8 +40,6 @@ public: class OutStream : public StringBuffer { private: - OutStream(const OutStream& copy) = delete; // Verhindere Kopieren - // Some stream formatting 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 @@ -52,8 +50,12 @@ private: void fill_finalize(); // does the filling after text has been written to buffer public: + OutStream(const OutStream& copy) = delete; // Verhindere Kopieren + OutStream() : fill_used(0), fill_width(0), fill_char(' '), base(10) {} +// ~OutStream() override = default; + // Methode zur Ausgabe des Pufferinhalts der Basisklasse StringBuffer. void flush() override; @@ -79,7 +81,7 @@ public: } template - friend T& operator<<(T& os, unsigned char c) { return os << (char)c; } + friend T& operator<<(T& os, unsigned char c) { return os << static_cast(c); } // Darstellung einer nullterminierten Zeichenkette template @@ -97,22 +99,22 @@ public: // Can not use this exclusively for strings as these are heap allocated template friend T& operator<<(T& os, const bse::string& string) { - os << (const char*)string; + os << static_cast(string); return os; } // Darstellung ganzer Zahlen im Zahlensystem zur Basis base template - friend T& operator<<(T& os, short ival) { return os << (long)ival; } + friend T& operator<<(T& os, short ival) { return os << static_cast(ival); } template - 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(ival); } template - friend T& operator<<(T& os, int ival) { return os << (long)ival; } + friend T& operator<<(T& os, int ival) { return os << static_cast(ival); } template - 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(ival); } template friend T& operator<<(T& os, long ival) { @@ -122,13 +124,13 @@ public: ival = -ival; } // Dann wird der Absolutwert als vorzeichenlose Zahl ausgegeben. - return os << (unsigned long)ival; + return os << static_cast(ival); } template friend T& operator<<(T& os, unsigned long ival) { - unsigned long div = 0; - char digit = 0; + unsigned long div; + char digit; if (os.base == 8) { os.put('0'); // oktale Zahlen erhalten eine fuehrende Null @@ -139,10 +141,10 @@ public: // Bestimmung der groessten Potenz der gewaehlten Zahlenbasis, die // 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(os.base); div *= os.base) {} // ziffernweise Ausgabe der Zahl - for (; div > 0; div /= (unsigned long)os.base) { + for (; div > 0; div /= static_cast(os.base)) { digit = ival / div; if (digit < 10) { os.put('0' + digit); @@ -160,7 +162,7 @@ public: friend T& operator<<(T& os, void* ptr) { int oldbase = os.base; os.base = 16; - os << (unsigned long)ptr; + os << reinterpret_cast(ptr); os.base = oldbase; return os; } diff --git a/c_os/lib/Semaphore.cc b/c_os/lib/Semaphore.cc index 2161a65..d9b6884 100644 --- a/c_os/lib/Semaphore.cc +++ b/c_os/lib/Semaphore.cc @@ -3,39 +3,39 @@ void Semaphore::p() { // Lock to allow deterministic operations on counter/queue - this->lock.acquire(); + lock.acquire(); - if (this->counter > 0) { + if (counter > 0) { // Semaphore can be acquired - this->counter = this->counter - 1; - this->lock.release(); + counter = counter - 1; + lock.release(); } else { // 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 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 - this->lock.release(); + lock.release(); scheduler.block(); // Moves to next thread, enables int } } 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 - unsigned int tid = this->wait_queue.front(); - this->wait_queue.erase(wait_queue.begin()); + unsigned int tid = wait_queue.front(); + wait_queue.erase(wait_queue.begin()); CPU::disable_int(); // Make sure the deblock() comes through after releasing the lock - this->lock.release(); + lock.release(); scheduler.deblock(tid); // Enables int } else { // No more threads want to work so free semaphore - this->counter = this->counter + 1; - this->lock.release(); + counter = counter + 1; + lock.release(); } } diff --git a/c_os/lib/Semaphore.h b/c_os/lib/Semaphore.h index da81982..7c3f807 100755 --- a/c_os/lib/Semaphore.h +++ b/c_os/lib/Semaphore.h @@ -8,8 +8,8 @@ * Autor: Michael Schoettner, 2.9.2016 * *****************************************************************************/ -#ifndef __Semaphore_include__ -#define __Semaphore_include__ +#ifndef Semaphore_include__ +#define Semaphore_include__ #include "kernel/threads/Thread.h" #include "lib/SpinLock.h" @@ -17,8 +17,6 @@ class Semaphore { private: - Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren - // Queue fuer wartende Threads. bse::vector wait_queue; SpinLock lock; @@ -26,6 +24,8 @@ private: int counter; public: + Semaphore(const Semaphore& copy) = delete; // Verhindere Kopieren + // Konstruktor: Initialisieren des Semaphorzaehlers Semaphore(int c) : wait_queue(true), counter(c) {} diff --git a/c_os/lib/SpinLock.cc b/c_os/lib/SpinLock.cc index cfcf279..c15b3cd 100644 --- a/c_os/lib/SpinLock.cc +++ b/c_os/lib/SpinLock.cc @@ -10,7 +10,6 @@ *****************************************************************************/ #include "lib/SpinLock.h" -#include "kernel/Globals.h" /***************************************************************************** * Methode: CAS * @@ -24,7 +23,7 @@ * *ptr := _new * * 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; /* @@ -38,7 +37,7 @@ static inline unsigned long CAS(unsigned long* ptr, unsigned long old, unsigned "cmpxchg %1, %2;" // %1 = _new; %2 = *ptr // constraints : "=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 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() { // If lock == 0 the SpinLock can be aquired without waiting // If lock == 1 the while loop blocks until aquired - while (CAS(ptr, 0, 1) != 0) {} + while (CAS(ptr) != 0) {} } /***************************************************************************** diff --git a/c_os/lib/SpinLock.h b/c_os/lib/SpinLock.h index c4c64e9..20169ee 100644 --- a/c_os/lib/SpinLock.h +++ b/c_os/lib/SpinLock.h @@ -9,17 +9,17 @@ * Autor: Michael Schoettner, 2.2.2018 * *****************************************************************************/ -#ifndef __SpinLock_include__ -#define __SpinLock_include__ +#ifndef SpinLock_include__ +#define SpinLock_include__ class SpinLock { private: - SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren - unsigned long lock; unsigned long* ptr; public: + SpinLock(const SpinLock& copy) = delete; // Verhindere Kopieren + SpinLock() : lock(0), ptr(&lock) {} void acquire(); diff --git a/c_os/lib/StringBuffer.h b/c_os/lib/StringBuffer.h index 67c1e78..9ab9c45 100755 --- a/c_os/lib/StringBuffer.h +++ b/c_os/lib/StringBuffer.h @@ -15,15 +15,12 @@ * Autor: Olaf Spinczyk, TU Dortmund * * Aenderungen von Michael Schoettner, HHU, 06.04.20 * *****************************************************************************/ -#ifndef __StringBuffer_include__ -#define __StringBuffer_include__ +#ifndef StringBuffer_include__ +#define StringBuffer_include__ #include "user/lib/Array.h" class StringBuffer { -private: - StringBuffer(const StringBuffer& copy); // Verhindere Kopieren - // Alle Variablen und Methoden dieser Klasse sind "protected", // da die abgeleiteten Klassen einen direkten Zugriff auf den // Puffer, den Konstruktor, den Destruktor und die Methode put @@ -42,6 +39,10 @@ protected: // Methode zur Ausgabe des Pufferinhalts virtual void flush() = 0; +public: + StringBuffer(const StringBuffer& copy) = delete; // Verhindere Kopieren + +// virtual ~StringBuffer() = default; }; #endif diff --git a/c_os/main.cc b/c_os/main.cc index 5e40234..0ed0a64 100755 --- a/c_os/main.cc +++ b/c_os/main.cc @@ -107,7 +107,7 @@ int main() { // 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 // 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 // CANCELED: Add some fixed point math like sine approximation or fractions? // 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: Kevman unsubscribe is needed, because exited threads will still be woken up by kevman // 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? // 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: Remove Iterator from List.h // DONE: Move Array/ArrayList/LinkedList/List to bse namespace // 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) // Scheduler doesn't return diff --git a/c_os/test/VectorTest.h b/c_os/test/VectorTest.h deleted file mode 100644 index 5d5f4d1..0000000 --- a/c_os/test/VectorTest.h +++ /dev/null @@ -1,119 +0,0 @@ -#include "kernel/Globals.h" -#include "user/lib/Vector.h" - -void print(const bse::Vector& vec) { - kout << "Print: "; - for (const int i : vec) { - kout << i << " "; - } - kout << endl; -} - -void run_test() { - bse::Vector 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(success) << endl; - success = true; - - // ================================= - - kout << "Basic iteration" << endl; - int current = 0; - for (int i : vec) { - success = success && i == current; - current++; - } - kout << "Success: " << static_cast(success) << endl; - success = true; - - // ================================= - - kout << "Basic functions" << endl; - kout << "Size: " << vec.size() << endl; - kout << "Empty: " << static_cast(vec.empty()) << endl; - - // ================================= - - kout << "Basic deletion" << endl; - bse::Vector::Iterator it = vec.begin(); - while (it != vec.end()) { - it = vec.erase(it); - } - kout << "Size: " << vec.size() << endl; - kout << "Empty: " << static_cast(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(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(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(success) << endl; - success = true; - - // ================================= - // 1 2 4 5 6 7 8 - - kout << "Index removal" << endl; - bse::Vector::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(success) << endl; - success = true; -} diff --git a/c_os/user/MainMenu.cc b/c_os/user/MainMenu.cc index d63b23d..96f2ddb 100644 --- a/c_os/user/MainMenu.cc +++ b/c_os/user/MainMenu.cc @@ -37,7 +37,7 @@ void MainMenu::run() { char input = '\0'; unsigned int running_demo = 0; while (running) { - input = this->listener.waitForKeyEvent(); + input = listener.waitForKeyEvent(); if ((input >= '0' && input <= '9') || input == '!') { switch (input) { diff --git a/c_os/user/MainMenu.h b/c_os/user/MainMenu.h index 78bb947..b6dcb73 100644 --- a/c_os/user/MainMenu.h +++ b/c_os/user/MainMenu.h @@ -1,5 +1,5 @@ -#ifndef __MainMenu_Inlucde_H_ -#define __MainMenu_Inlucde_H_ +#ifndef MainMenu_Inlucde_H_ +#define MainMenu_Inlucde_H_ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" @@ -7,17 +7,17 @@ class MainMenu : public Thread { private: - MainMenu(const MainMenu& copy) = delete; - KeyEventListener listener; public: - MainMenu() : Thread("MainMenu"), listener(this->tid) { - kevman.subscribe(this->listener); + MainMenu(const MainMenu& copy) = delete; + + MainMenu() : Thread("MainMenu"), listener(tid) { + kevman.subscribe(listener); } ~MainMenu() override { - kevman.unsubscribe(this->listener); + kevman.unsubscribe(listener); } void run() override; diff --git a/c_os/user/bmp/bmp_hhu.cc b/c_os/user/bmp/bmp_hhu.cc index 76679fe..74c7591 100644 --- a/c_os/user/bmp/bmp_hhu.cc +++ b/c_os/user/bmp/bmp_hhu.cc @@ -1,6 +1,6 @@ /* GIMP RGB C-Source image dump (hhulogo.c) */ -static constexpr const struct { +static constexpr struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ diff --git a/c_os/user/demo/ArrayDemo.cc b/c_os/user/demo/ArrayDemo.cc index 3b3510f..94ec850 100644 --- a/c_os/user/demo/ArrayDemo.cc +++ b/c_os/user/demo/ArrayDemo.cc @@ -3,7 +3,6 @@ void ArrayDemo::run() { bse::array arr1 {}; bse::array arr2 {}; - bse::array arr3 {}; kout.lock(); kout.clear(); diff --git a/c_os/user/demo/ArrayDemo.h b/c_os/user/demo/ArrayDemo.h index 1221b62..c44ccf3 100644 --- a/c_os/user/demo/ArrayDemo.h +++ b/c_os/user/demo/ArrayDemo.h @@ -1,14 +1,13 @@ -#ifndef __ArrayDemo_include__ -#define __ArrayDemo_include__ +#ifndef ArrayDemo_include__ +#define ArrayDemo_include__ #include "kernel/Globals.h" #include "user/lib/Array.h" class ArrayDemo : public Thread { -private: +public: ArrayDemo(const ArrayDemo& copy) = delete; -public: ArrayDemo() : Thread("ArrayDemo") {} void run() override; diff --git a/c_os/user/demo/BlueScreenDemo.h b/c_os/user/demo/BlueScreenDemo.h index dd6df24..ea5351d 100644 --- a/c_os/user/demo/BlueScreenDemo.h +++ b/c_os/user/demo/BlueScreenDemo.h @@ -1,14 +1,13 @@ -#ifndef __BlueScreenDemo_include__ -#define __BlueScreenDemo_include__ +#ifndef BlueScreenDemo_include__ +#define BlueScreenDemo_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" class BlueScreenDemo : public Thread { -private: +public: BlueScreenDemo(const BlueScreenDemo& copy) = delete; -public: BlueScreenDemo() : Thread("BlueScreenDemo") {} void run() override; diff --git a/c_os/user/demo/HeapDemo.h b/c_os/user/demo/HeapDemo.h index c9700ea..380d9eb 100755 --- a/c_os/user/demo/HeapDemo.h +++ b/c_os/user/demo/HeapDemo.h @@ -7,8 +7,8 @@ * * * Autor: Michael Schoettner, HHU, 25.9.2016 * *****************************************************************************/ -#ifndef __HeapDemo_include__ -#define __HeapDemo_include__ +#ifndef HeapDemo_include__ +#define HeapDemo_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" @@ -21,10 +21,9 @@ public: }; class HeapDemo : public Thread { -private: +public: HeapDemo(const HeapDemo& copy) = delete; -public: HeapDemo() : Thread("HeapDemo") {} void run() override; diff --git a/c_os/user/demo/KeyboardDemo.h b/c_os/user/demo/KeyboardDemo.h index d7101b6..6dcf673 100755 --- a/c_os/user/demo/KeyboardDemo.h +++ b/c_os/user/demo/KeyboardDemo.h @@ -8,8 +8,8 @@ * Autor: Michael Schoettner, HHU, 26.10.2018 * *****************************************************************************/ -#ifndef __KeyboardDemo_include__ -#define __KeyboardDemo_include__ +#ifndef KeyboardDemo_include__ +#define KeyboardDemo_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" @@ -17,13 +17,13 @@ class KeyboardDemo : public Thread { private: - KeyboardDemo(const KeyboardDemo& copy) = delete; - KeyEventListener listener; public: - KeyboardDemo() : Thread("KeyboardDemo"), listener(this->tid) { - kevman.subscribe(this->listener); + KeyboardDemo(const KeyboardDemo& copy) = delete; + + KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) { + kevman.subscribe(listener); } // Base class destructor will be called automatically @@ -35,7 +35,7 @@ public: // thread set it (so use nice_kill) kout.unlock(); } - kevman.unsubscribe(this->listener); + kevman.unsubscribe(listener); } void run() override; diff --git a/c_os/user/demo/PCSPKdemo.cc b/c_os/user/demo/PCSPKdemo.cc index c6d03e4..6c2eb22 100644 --- a/c_os/user/demo/PCSPKdemo.cc +++ b/c_os/user/demo/PCSPKdemo.cc @@ -6,7 +6,7 @@ void PCSPKdemo::run() { kout << "Playing..." << endl; kout.unlock(); - (pcspk.*this->melody)(); // This syntax is confusing as hell + (pcspk.*melody)(); // This syntax is confusing as hell kout.lock(); kout << "Finished" << endl; diff --git a/c_os/user/demo/PCSPKdemo.h b/c_os/user/demo/PCSPKdemo.h index 32b04b9..9635e00 100644 --- a/c_os/user/demo/PCSPKdemo.h +++ b/c_os/user/demo/PCSPKdemo.h @@ -1,20 +1,20 @@ -#ifndef __PCSPKdemo_INCLUDE_H_ -#define __PCSPKdemo_INCLUDE_H_ +#ifndef PCSPKdemo_INCLUDE_H_ +#define PCSPKdemo_INCLUDE_H_ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" class PCSPKdemo : public Thread { private: - PCSPKdemo(const PCSPKdemo& copy) = delete; - - void (PCSPK::*melody)(void); // Allow to pass a melody to play when initializing the demo + void (PCSPK::*melody)(); // Allow to pass a melody to play when initializing the demo 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 { - pcspk.off(); + PCSPK::off(); } void run() override; diff --git a/c_os/user/demo/PreemptiveThreadDemo.cc b/c_os/user/demo/PreemptiveThreadDemo.cc index b60fb82..17c41f6 100644 --- a/c_os/user/demo/PreemptiveThreadDemo.cc +++ b/c_os/user/demo/PreemptiveThreadDemo.cc @@ -8,8 +8,8 @@ void PreemptiveLoopThread::run() { kout.lock(); // Saving + restoring kout position doesn't help much as preemption still occurs - kout.setpos(55, this->id); - kout << fillw(3) << this->id << fillw(0) << ": " << dec << cnt++ << endl; + CGA_Stream::setpos(55, id); + kout << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl; kout.unlock(); } @@ -24,7 +24,7 @@ void PreemptiveThreadDemo::run() { kout << "Preemptive Thread Demo:" << 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(i); } diff --git a/c_os/user/demo/PreemptiveThreadDemo.h b/c_os/user/demo/PreemptiveThreadDemo.h index e677f3f..017b6f5 100644 --- a/c_os/user/demo/PreemptiveThreadDemo.h +++ b/c_os/user/demo/PreemptiveThreadDemo.h @@ -1,5 +1,5 @@ -#ifndef __preemptive_thread_include__ -#define __preemptive_thread_include__ +#ifndef preemptive_thread_include__ +#define preemptive_thread_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" @@ -8,9 +8,10 @@ class PreemptiveLoopThread : public Thread { private: int id; - PreemptiveLoopThread(const PreemptiveLoopThread& copy) = delete; // Verhindere Kopieren public: + PreemptiveLoopThread(const PreemptiveLoopThread& copy) = delete; // Verhindere Kopieren + // Gibt der Loop einen Stack und eine Id. PreemptiveLoopThread(int i) : Thread("LoopThread"), id(i) {} @@ -20,11 +21,11 @@ public: class PreemptiveThreadDemo : public Thread { private: - PreemptiveThreadDemo(const PreemptiveThreadDemo& copy) = delete; // Verhindere Kopieren - unsigned int number_of_threads; public: + PreemptiveThreadDemo(const PreemptiveThreadDemo& copy) = delete; // Verhindere Kopieren + PreemptiveThreadDemo(unsigned int n) : Thread("PreemptiveThreadDemo"), number_of_threads(n) {} // Thread-Startmethode diff --git a/c_os/user/demo/SmartPointerDemo.cc b/c_os/user/demo/SmartPointerDemo.cc index 8605541..4a9ec0e 100644 --- a/c_os/user/demo/SmartPointerDemo.cc +++ b/c_os/user/demo/SmartPointerDemo.cc @@ -21,10 +21,10 @@ void SmartPointerDemo::run() { bse::unique_ptr ptr1 = bse::make_unique(1); bse::unique_ptr ptr2; - log.info() << "*ptr1 == " << *ptr1 << ", (bool)ptr2 == " << (bool)ptr2 << endl; + log.info() << "*ptr1 == " << *ptr1 << ", (bool)ptr2 == " << static_cast(ptr2) << endl; log.info() << "Moving ptr1 => ptr2 (no allocations should happen)..." << endl; ptr2 = std::move(ptr1); - log.info() << "(bool)ptr1 == " << (bool)ptr1 << ", *ptr2 == " << *ptr2 << endl; + log.info() << "(bool)ptr1 == " << static_cast(ptr1) << ", *ptr2 == " << *ptr2 << endl; log.info() << "Leaving scope..." << endl; } diff --git a/c_os/user/demo/SmartPointerDemo.h b/c_os/user/demo/SmartPointerDemo.h index 121840b..f3b5e1c 100644 --- a/c_os/user/demo/SmartPointerDemo.h +++ b/c_os/user/demo/SmartPointerDemo.h @@ -1,13 +1,12 @@ -#ifndef __SmartPointerDemo_include__ -#define __SmartPointerDemo_include__ +#ifndef SmartPointerDemo_include__ +#define SmartPointerDemo_include__ #include "kernel/Globals.h" class SmartPointerDemo : public Thread { -private: +public: SmartPointerDemo(const SmartPointerDemo& copy) = delete; -public: SmartPointerDemo() : Thread("SmartPointerDemo") {} void run() override; diff --git a/c_os/user/demo/StringDemo.cc b/c_os/user/demo/StringDemo.cc index cb86919..dfe54b3 100644 --- a/c_os/user/demo/StringDemo.cc +++ b/c_os/user/demo/StringDemo.cc @@ -40,14 +40,14 @@ void StringDemo::run() { log.info() << "Reassign str2" << endl; str2 = "Hello"; - bse::array arr; + bse::array arr{}; arr[0] = 'H'; arr[1] = 'e'; arr[2] = 'l'; arr[3] = 'l'; arr[4] = 'o'; - kout << "bse::array to bse::string: " << arr << ", size: " << ((bse::string)arr).size() << endl; - kout << "(bse::string)arr (" << arr << ") == str2 (" << str2 << "): " << static_cast((bse::string)arr == str2) << endl; + kout << "bse::array to bse::string: " << static_cast(arr) << ", size: " << (bse::string(arr)).size() << endl; + kout << "(bse::string)arr (" << static_cast(arr) << ") == str2 (" << str2 << "): " << static_cast(bse::string(arr) == str2) << endl; kout.unlock(); scheduler.exit(); diff --git a/c_os/user/demo/StringDemo.h b/c_os/user/demo/StringDemo.h index cf82807..a7eb8ce 100644 --- a/c_os/user/demo/StringDemo.h +++ b/c_os/user/demo/StringDemo.h @@ -1,13 +1,12 @@ -#ifndef __StringDemo_include__ -#define __StringDemo_include__ +#ifndef StringDemo_include__ +#define StringDemo_include__ #include "kernel/Globals.h" class StringDemo : public Thread { -private: +public: StringDemo(const StringDemo& copy) = delete; -public: StringDemo() : Thread("StringDemo") {} void run() override; diff --git a/c_os/user/demo/TextDemo.h b/c_os/user/demo/TextDemo.h index b0b19c9..1302e67 100755 --- a/c_os/user/demo/TextDemo.h +++ b/c_os/user/demo/TextDemo.h @@ -8,17 +8,16 @@ * Autor: Michael Schoettner, HHU, 26.10.2018 * *****************************************************************************/ -#ifndef __TextDemo_include__ -#define __TextDemo_include__ +#ifndef TextDemo_include__ +#define TextDemo_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" class TextDemo : public Thread { -private: +public: TextDemo(const TextDemo& copy) = delete; -public: TextDemo() : Thread("TextDemo") {} void run() override; diff --git a/c_os/user/demo/VBEdemo.cc b/c_os/user/demo/VBEdemo.cc index 84e4c05..3ce093a 100644 --- a/c_os/user/demo/VBEdemo.cc +++ b/c_os/user/demo/VBEdemo.cc @@ -59,7 +59,7 @@ void VBEdemo::drawBitmap() { unsigned int sprite_width = hhu.width; unsigned int sprite_height = hhu.height; unsigned int sprite_bpp = hhu.bytes_per_pixel; - unsigned char* sprite_pixel = (unsigned char*)hhu.pixel_data; + const unsigned char* sprite_pixel = reinterpret_cast(hhu.pixel_data); /* Hier muss Code eingefuegt werden */ diff --git a/c_os/user/demo/VBEdemo.h b/c_os/user/demo/VBEdemo.h index 6409f64..3d2be94 100644 --- a/c_os/user/demo/VBEdemo.h +++ b/c_os/user/demo/VBEdemo.h @@ -7,27 +7,27 @@ * * * Autor: Michael Schoettner, HHU, 26.12.2016 * *****************************************************************************/ -#ifndef __VBEdemo_include__ -#define __VBEdemo_include__ +#ifndef VBEdemo_include__ +#define VBEdemo_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" class VBEdemo : public Thread { - private: - VBEdemo(const VBEdemo& copy) = delete; // Verhindere Kopieren - // Hilfsfunktionen fuer drawColors() - 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 linInterPol1D(int x, int xr, int l, int r); + static int linInterPol2D(int x, int y, int lt, int rt, int lb, int rb); public: + VBEdemo(const VBEdemo& copy) = delete; // Verhindere Kopieren + // Gib dem Anwendungsthread einen Stack. VBEdemo() : Thread("VBEdemo") {} ~VBEdemo() override { - vesa.initTextMode(); + allocator.free(reinterpret_cast(vesa.hfb)); // Memory is allocated after every start and never deleted, so add that + VESA::initTextMode(); } // Thread-Startmethode @@ -37,10 +37,10 @@ public: void drawColors(); // Bitmap aus GIMP ausgeben - void drawBitmap(); + static void drawBitmap(); // Fonts ausgeben - void drawFonts(); + static void drawFonts(); }; #endif diff --git a/c_os/user/demo/VectorDemo.cc b/c_os/user/demo/VectorDemo.cc index c52b7a4..19e29a1 100644 --- a/c_os/user/demo/VectorDemo.cc +++ b/c_os/user/demo/VectorDemo.cc @@ -18,7 +18,7 @@ void VectorDemo::run() { log.info() << "Initial list size: " << dec << list.size() << 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); } print(log.info(), list); @@ -32,7 +32,7 @@ void VectorDemo::run() { // ============================================================ 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; 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); } print(log.info(), list); diff --git a/c_os/user/demo/VectorDemo.h b/c_os/user/demo/VectorDemo.h index 953f78f..67c2623 100644 --- a/c_os/user/demo/VectorDemo.h +++ b/c_os/user/demo/VectorDemo.h @@ -1,15 +1,14 @@ -#ifndef __VectorDemo_include__ -#define __VectorDemo_include__ +#ifndef VectorDemo_include__ +#define VectorDemo_include__ #include "kernel/Globals.h" #include "kernel/threads/Thread.h" #include "user/lib/Vector.h" class VectorDemo : public Thread { -private: +public: VectorDemo(const VectorDemo& copy) = delete; -public: VectorDemo() : Thread("VectorDemo") {} void run() override; diff --git a/c_os/user/devices/SerialOut.cc b/c_os/user/devices/SerialOut.cc index 90f0f67..a858280 100644 --- a/c_os/user/devices/SerialOut.cc +++ b/c_os/user/devices/SerialOut.cc @@ -1,6 +1,8 @@ #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 com1.outb(1, 0x00); // Disable all interrupts 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) // Check if serial is faulty (i.e: not same byte as sent) - if (com1.inb() != 0xAE) { - return 1; + if (com1.inb() == 0xAE) { + // 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() { @@ -44,11 +43,11 @@ void SerialOut::write(const char a) { void SerialOut::write(const char* a) { const char* current = a; do { - this->write(*current); + write(*current); current = current + 1; } while (*current != '\0'); } void SerialOut::write(const bse::string& a) { - write((const char*)a); + write(static_cast(a)); } diff --git a/c_os/user/devices/SerialOut.h b/c_os/user/devices/SerialOut.h index b9e7dfa..f71e785 100644 --- a/c_os/user/devices/SerialOut.h +++ b/c_os/user/devices/SerialOut.h @@ -1,5 +1,5 @@ -#ifndef __SerialOut_Include_H_ -#define __SerialOut_Include_H_ +#ifndef SerialOut_Include_H_ +#define SerialOut_Include_H_ #include "kernel/IOport.h" #include "user/lib/String.h" @@ -8,24 +8,19 @@ class SerialOut { private: - const IOport com1; + static const IOport com1; - SerialOut(const SerialOut& copy) = delete; - - int serial_received(); - int is_transmit_empty(); + static int serial_received(); + static int is_transmit_empty(); public: - SerialOut() : com1(0x3f8) { - this->init(); - } + SerialOut(const SerialOut& copy) = delete; + SerialOut(); - int init() const; - - char read(); - void write(char a); - void write(const char* a); - void write(const bse::string& a); + static char read(); + static void write(char a); + static void write(const char* a); + static void write(const bse::string& a); }; #endif diff --git a/c_os/user/event/KeyEventListener.cc b/c_os/user/event/KeyEventListener.cc index 53b4186..1dba0dc 100644 --- a/c_os/user/event/KeyEventListener.cc +++ b/c_os/user/event/KeyEventListener.cc @@ -2,11 +2,11 @@ #include "kernel/Globals.h" void KeyEventListener::trigger(char c) { - this->lastChar = c; + lastChar = c; } char KeyEventListener::waitForKeyEvent() const { Logger::instance() << DEBUG << "KEvLis:: Thread with id: " << tid << " waiting for key event" << endl; 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 } diff --git a/c_os/user/event/KeyEventListener.h b/c_os/user/event/KeyEventListener.h index b03b3e5..044d36f 100644 --- a/c_os/user/event/KeyEventListener.h +++ b/c_os/user/event/KeyEventListener.h @@ -1,17 +1,18 @@ -#ifndef __KeyEventListener_Include_H_ -#define __KeyEventListener_Include_H_ +#ifndef KeyEventListener_Include_H_ +#define KeyEventListener_Include_H_ #include "kernel/threads/Thread.h" class KeyEventListener { private: - KeyEventListener(const KeyEventListener& copy) = delete; - char lastChar = '\0'; -public: + friend class KeyEventManager; 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) {} char waitForKeyEvent() const; // Blocks the thread until woken up by manager diff --git a/c_os/user/event/KeyEventManager.cc b/c_os/user/event/KeyEventManager.cc index 5d6dfe9..6cd0562 100644 --- a/c_os/user/event/KeyEventManager.cc +++ b/c_os/user/event/KeyEventManager.cc @@ -3,14 +3,14 @@ void KeyEventManager::subscribe(KeyEventListener& sub) { log.debug() << "Subscribe, Thread ID: " << dec << sub.tid << endl; - this->listeners.push_back(&sub); + listeners.push_back(&sub); } void KeyEventManager::unsubscribe(KeyEventListener& unsub) { log.debug() << "Unsubscribe, Thread ID: " << dec << unsub.tid << endl; for (bse::vector::iterator it = listeners.begin(); it != listeners.end(); ++it) { if ((*it)->tid == unsub.tid) { - this->listeners.erase(it); + listeners.erase(it); return; } } @@ -18,7 +18,7 @@ void KeyEventManager::unsubscribe(KeyEventListener& unsub) { void KeyEventManager::broadcast(char c) { 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; listener->trigger(c); scheduler.deblock(listener->tid); diff --git a/c_os/user/event/KeyEventManager.h b/c_os/user/event/KeyEventManager.h index 3cccb93..f9811ac 100644 --- a/c_os/user/event/KeyEventManager.h +++ b/c_os/user/event/KeyEventManager.h @@ -1,5 +1,5 @@ -#ifndef __KeyEventManager_Include_H_ -#define __KeyEventManager_Include_H_ +#ifndef KeyEventManager_Include_H_ +#define KeyEventManager_Include_H_ #include "user/event/KeyEventListener.h" #include "user/lib/Logger.h" @@ -10,13 +10,13 @@ class KeyEventManager { private: - KeyEventManager(const KeyEventManager& copy) = delete; - NamedLogger log; bse::vector listeners; public: + KeyEventManager(const KeyEventManager& copy) = delete; + KeyEventManager() : log("KEvMan"), listeners(true) {} void init() { diff --git a/c_os/user/lib/Array.h b/c_os/user/lib/Array.h index 17a5f48..7c77480 100644 --- a/c_os/user/lib/Array.h +++ b/c_os/user/lib/Array.h @@ -1,5 +1,5 @@ -#ifndef __ARRAY_INCLUDE_H -#define __ARRAY_INCLUDE_H +#ifndef ARRAY_INCLUDE_H +#define ARRAY_INCLUDE_H #include "user/lib/Iterator.h" #include @@ -15,22 +15,30 @@ namespace bse { T buf[N]; public: - array() {}; // If i write default something like bse::array arr; is not initialized... + array() = default;; // If i write default something like bse::array arr; is not initialized... + + array(std::initializer_list list) { + typename std::initializer_list::iterator it = list.begin(); + for (unsigned int i = 0; i < N; ++i) { + buf[i] = *it; + ++it; + } + } iterator begin() { return iterator(&buf[0]); } iterator begin() const { return iterator(&buf[0]); } iterator end() { return iterator(&buf[N]); } iterator end() const { return iterator(&buf[N]); } - T& operator[](std::size_t i) { return this->buf[i]; } - constexpr const T& operator[](std::size_t i) const { return this->buf[i]; } + T& operator[](std::size_t i) { return 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 - const T* operator&() const { return &buf[0]; } + T* data() { return &buf[0]; } // Not standard, I don't know yet if this will turn out to be a bad idea + const T* data() const { return &buf[0]; } void swap(array& other) { 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 void swap_n(array& other) { for (std::size_t i = 0; i < n; ++i) { - std::swap(this->buf[i], other[i]); + std::swap(buf[i], other[i]); } } diff --git a/c_os/user/lib/Iterator.h b/c_os/user/lib/Iterator.h index e1a0fc0..18019ac 100644 --- a/c_os/user/lib/Iterator.h +++ b/c_os/user/lib/Iterator.h @@ -1,5 +1,5 @@ -#ifndef __Iterator_Include_H_ -#define __Iterator_Include_H_ +#ifndef Iterator_Include_H_ +#define Iterator_Include_H_ namespace bse { @@ -9,45 +9,41 @@ namespace bse { private: T* ptr = nullptr; + public: ContinuousIterator() = delete; - public: ContinuousIterator(T* ptr) : ptr(ptr) {} - T* get() const { - return ptr; - } - ContinuousIterator& operator++() { - ++this->ptr; + ++ptr; return *this; } ContinuousIterator& operator--() { - --this->ptr; + --ptr; return *this; } ContinuousIterator operator+(unsigned int add) { - return ContinuousIterator(this->ptr + add); + return ContinuousIterator(ptr + add); } ContinuousIterator operator-(unsigned int sub) { - return ContinuousIterator(this->ptr - sub); + return ContinuousIterator(ptr - sub); } // Convenience - T* operator->() { return this->ptr; } - const T* operator->() const { return this->ptr; } - T& operator*() { return *this->ptr; } - const T& operator*() const { return *this->ptr; } + T* operator->() { return ptr; } + const T* operator->() const { return ptr; } + T& operator*() { return *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 this->ptr <= other.ptr; } - bool operator>(const ContinuousIterator& other) const { return this->ptr > other.ptr; } - bool operator>=(const ContinuousIterator& other) const { return this->ptr >= other.ptr; } - bool operator==(const ContinuousIterator& other) const { return this->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 ptr <= other.ptr; } + bool operator>(const ContinuousIterator& other) const { return ptr > other.ptr; } + bool operator>=(const ContinuousIterator& other) const { return ptr >= other.ptr; } + bool operator==(const ContinuousIterator& other) const { return ptr == other.ptr; } + bool operator!=(const ContinuousIterator& other) const { return ptr != other.ptr; } template friend unsigned int distance(const ContinuousIterator& first, const ContinuousIterator& last); diff --git a/c_os/user/lib/Logger.cc b/c_os/user/lib/Logger.cc index 67a517c..2d1482e 100644 --- a/c_os/user/lib/Logger.cc +++ b/c_os/user/lib/Logger.cc @@ -19,61 +19,61 @@ void Logger::log(const char* message, CGA::color col) const { if (Logger::kout_enabled) { CGA::color old_col = kout.color_fg; kout << fgc(col) - << Logger::level_to_string(this->current_message_level) << "::" + << Logger::level_to_string(current_message_level) << "::" << message << fgc(old_col); kout.flush(); // Don't add newline, Logger already does that } if (Logger::serial_enabled) { switch (col) { case CGA::WHITE: - serial.write(ansi_white); + SerialOut::write(ansi_white); break; case CGA::LIGHT_MAGENTA: - serial.write(ansi_magenta); + SerialOut::write(ansi_magenta); break; case CGA::LIGHT_RED: - serial.write(ansi_red); + SerialOut::write(ansi_red); break; case CGA::LIGHT_BLUE: - serial.write(ansi_blue); + SerialOut::write(ansi_blue); break; default: - serial.write(ansi_default); + SerialOut::write(ansi_default); } - serial.write(Logger::level_to_string(this->current_message_level)); - serial.write(":: "); - serial.write(message); - serial.write('\r'); + SerialOut::write(Logger::level_to_string(current_message_level)); + SerialOut::write(":: "); + SerialOut::write(message); + SerialOut::write('\r'); // serial.write("\r\n"); } } void Logger::flush() { - this->buffer[this->pos] = '\0'; + buffer[pos] = '\0'; - switch (this->current_message_level) { + switch (current_message_level) { case Logger::TRACE: - this->trace(&buffer); + trace(buffer.data()); break; case Logger::DEBUG: - this->debug(&buffer); + debug(buffer.data()); break; case Logger::ERROR: - this->error(&buffer); + error(buffer.data()); break; case Logger::INFO: - this->info(&buffer); + info(buffer.data()); break; } - this->current_message_level = Logger::INFO; - this->pos = 0; + current_message_level = Logger::INFO; + pos = 0; Logger::unlock(); } void Logger::trace(const char* message) const { if (Logger::level <= Logger::TRACE) { - this->log(message, CGA::WHITE); + log(message, CGA::WHITE); } } 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 { if (Logger::level <= Logger::DEBUG) { - this->log(message, CGA::LIGHT_MAGENTA); + log(message, CGA::LIGHT_MAGENTA); } } 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 { if (Logger::level <= Logger::ERROR) { - this->log(message, CGA::LIGHT_RED); + log(message, CGA::LIGHT_RED); } } 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 { if (Logger::level <= Logger::INFO) { - this->log(message, CGA::LIGHT_BLUE); + log(message, CGA::LIGHT_BLUE); } } void Logger::info(const bse::string& message) const { diff --git a/c_os/user/lib/Logger.h b/c_os/user/lib/Logger.h index af8297c..a3bf2db 100644 --- a/c_os/user/lib/Logger.h +++ b/c_os/user/lib/Logger.h @@ -1,5 +1,5 @@ -#ifndef __Logger_Include_H_ -#define __Logger_Include_H_ +#ifndef Logger_Include_H_ +#define Logger_Include_H_ #include "devices/CGA.h" #include "lib/OutStream.h" @@ -15,8 +15,6 @@ public: private: Logger() = default; - Logger(const Logger& copy) = delete; - void operator=(const Logger& copy) = delete; static bool kout_enabled; static bool serial_enabled; @@ -24,6 +22,7 @@ private: void log(const char* message, CGA::color col) const; friend class NamedLogger; // Allow NamedLogger to lock/unlock + SpinLock sem; // Semaphore would be a cyclic include static void lock() { Logger::instance().sem.acquire(); } static void unlock() { Logger::instance().sem.release(); } @@ -31,6 +30,11 @@ private: // static void unlock() {} public: +// ~Logger() override = default; + + Logger(const Logger& copy) = delete; + void operator=(const Logger& copy) = delete; + enum LogLevel { TRACE, DEBUG, @@ -51,13 +55,13 @@ public: void info(const char* message) const; void info(const bse::string& message) const; - // TODO: Make level change accessible over menu - static void set_level(LogLevel level) { - Logger::level = level; + // TODO: Make lvl change accessible over menu + static void set_level(LogLevel lvl) { + Logger::level = lvl; } - static char* level_to_string(LogLevel level) { - switch (level) { + static char* level_to_string(LogLevel lvl) { + switch (lvl) { case Logger::TRACE: return "TRACE"; case Logger::DEBUG: @@ -94,7 +98,7 @@ private: const char* name; public: - NamedLogger(const char* name) : name(name) {} + explicit NamedLogger(const char* name) : name(name) {} Logger& trace() { Logger::lock(); diff --git a/c_os/user/lib/Math.h b/c_os/user/lib/Math.h index f45f8ec..7316801 100644 --- a/c_os/user/lib/Math.h +++ b/c_os/user/lib/Math.h @@ -1,12 +1,19 @@ -#ifndef __MATH_INCLUDE_H_ -#define __MATH_INCLUDE_H_ +#ifndef MATH_INCLUDE_H_ +#define MATH_INCLUDE_H_ namespace bse { + + // I didn't add any numeric constraints, will do with c++20 + template T& min(const T& a, const T& b) { return a < b ? a : b; } template T& max(const T& a, const T& b) { return a > b ? a : b; } + + template + std::make_unsigned abs(const T& a) { return a < 0 ? -a : a; } + } // namespace bse #endif diff --git a/c_os/user/lib/Memory.h b/c_os/user/lib/Memory.h index dfa11c1..93b9697 100755 --- a/c_os/user/lib/Memory.h +++ b/c_os/user/lib/Memory.h @@ -1,8 +1,10 @@ -#ifndef __MYSTDLIB_INCLUDE_H_ -#define __MYSTDLIB_INCLUDE_H_ +#ifndef MYSTDLIB_INCLUDE_H_ +#define MYSTDLIB_INCLUDE_H_ namespace bse { + // add using byte or sth to replace char + template void memcpy(T* destination, const T* source, const unsigned int count = 1) { for (unsigned int i = 0; i < count; ++i) { @@ -14,7 +16,7 @@ namespace bse { template void zero(T* destination) { - memset((char*)destination, '\0', sizeof(T)); + memset(reinterpret_cast(destination), '\0', sizeof(T)); } // void strcpy(char* destination, char* source); diff --git a/c_os/user/lib/String.h b/c_os/user/lib/String.h index f6ced45..d81bdc9 100644 --- a/c_os/user/lib/String.h +++ b/c_os/user/lib/String.h @@ -1,5 +1,5 @@ -#ifndef __String_Include_H_ -#define __String_Include_H_ +#ifndef String_Include_H_ +#define String_Include_H_ #include "user/lib/Array.h" #include "user/lib/Iterator.h" @@ -24,8 +24,9 @@ namespace bse { strncpy(buf, len + 1, str); } + // Convert char array to string template - string(const array& arr) : len(N), buf(new char[len + 1]) { + explicit string(const array& arr) : len(N), buf(new char[len + 1]) { for (unsigned int i = 0; i < N; ++i) { buf[i] = arr[i]; } diff --git a/c_os/user/lib/Vector.h b/c_os/user/lib/Vector.h index 8efb98b..50e5d1a 100644 --- a/c_os/user/lib/Vector.h +++ b/c_os/user/lib/Vector.h @@ -1,5 +1,5 @@ -#ifndef __VECTOR_INCLUDE_H_ -#define __VECTOR_INCLUDE_H_ +#ifndef 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). // 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: - 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 // away because when the scheduler is started the allocator is not ready. init(); } }; - vector(const vector& copy) { - buf_cap = copy.buf_cap; - buf_pos = copy.buf_pos; + vector(const vector& copy) : buf_pos(copy.buf_pos), buf_cap(copy.buf_cap) { buf = new T[buf_cap]; for (unsigned int i = 0; i < buf_pos; ++i) { buf[i] = copy[i]; // Does a copy since copy is marked const reference @@ -131,9 +129,7 @@ namespace bse { return *this; } - vector(vector&& move) noexcept { - buf_cap = move.buf_cap; - buf_pos = move.buf_pos; + vector(vector&& move) noexcept : buf_pos(move.buf_pos), buf_cap(move.buf_cap) { buf = move.buf; move.buf_cap = 0; diff --git a/c_os/user/lib/mem/UniquePointer.h b/c_os/user/lib/mem/UniquePointer.h index ec8f359..1e55f45 100644 --- a/c_os/user/lib/mem/UniquePointer.h +++ b/c_os/user/lib/mem/UniquePointer.h @@ -1,5 +1,5 @@ -#ifndef __UniquePointer_Include_H_ -#define __UniquePointer_Include_H_ +#ifndef UniquePointer_Include_H_ +#define UniquePointer_Include_H_ #include @@ -34,11 +34,11 @@ namespace bse { ptr = nullptr; } + public: // Forbid copying unique_ptr(const unique_ptr& copy) = delete; unique_ptr& operator=(const unique_ptr& copy) = delete; - public: // Construction unique_ptr() = default; // Allow declaration without explicit definition @@ -74,9 +74,9 @@ namespace bse { // Resetting: Replaces managed object, deleting the old one void reset() { del(); } - void reset(T_* ptr) { + void reset(T_* pt) { del(); - this->ptr = ptr; + ptr = pt; } // Release: Releases ownership without deletion @@ -92,7 +92,7 @@ namespace bse { return ptr; } - // Nice to have operators + // Pointer operators T_* operator->() { return ptr; } const T_* operator->() const { return ptr; } T_& operator*() { return *ptr; } @@ -103,7 +103,7 @@ namespace bse { 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]; } const T_& operator[](std::size_t i) const { return ptr[i]; } };