diff --git a/c_os/devices/CGA_Stream.h b/c_os/devices/CGA_Stream.h index 97c6d0c..7392138 100755 --- a/c_os/devices/CGA_Stream.h +++ b/c_os/devices/CGA_Stream.h @@ -40,8 +40,6 @@ constexpr const fgc lgrey = fgc(CGA::LIGHT_GREY); class CGA_Stream : public OutStream, public CGA { private: - CGA_Stream(CGA_Stream& copy) = delete; // Verhindere Kopieren - // 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 @@ -54,8 +52,10 @@ private: friend class Logger; // Give access to the color public: + CGA_Stream(CGA_Stream& copy) = delete; // Verhindere Kopieren + CGA_Stream() : sem(1), color_fg(CGA::LIGHT_GREY), color_bg(CGA::BLACK), blink(false) { - flush(); + pos = 0; } void lock() { sem.p(); } diff --git a/c_os/devices/VESA.h b/c_os/devices/VESA.h index d34e71a..cee2f7a 100644 --- a/c_os/devices/VESA.h +++ b/c_os/devices/VESA.h @@ -27,9 +27,9 @@ private: int mode_nr; // Nummer des Modus NamedLogger log; +public: VESA(const VESA& copy) = delete; // Verhindere Kopieren -public: VESA() : log("VESA") {} // Bestimmten Grafikmodus einschalten diff --git a/c_os/devices/fonts/Font_8x16.h b/c_os/devices/fonts/Font_8x16.h index 9b7753d..019f621 100644 --- a/c_os/devices/fonts/Font_8x16.h +++ b/c_os/devices/fonts/Font_8x16.h @@ -8,7 +8,7 @@ #define FONTDATAMAX_8x16 4096 -constexpr const unsigned char fontdata_8x16[FONTDATAMAX_8x16] = { +constexpr unsigned char fontdata_8x16[FONTDATAMAX_8x16] = { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/c_os/devices/fonts/Font_8x8.h b/c_os/devices/fonts/Font_8x8.h index dd524b8..cf550ec 100644 --- a/c_os/devices/fonts/Font_8x8.h +++ b/c_os/devices/fonts/Font_8x8.h @@ -8,7 +8,7 @@ #define FONTDATAMAX_8x8 2048 -constexpr const unsigned char fontdata_8x8[FONTDATAMAX_8x8] = { +constexpr unsigned char fontdata_8x8[FONTDATAMAX_8x8] = { /* 0 0x00 '^@' */ 0x00, /* 00000000 */ diff --git a/c_os/devices/fonts/Font_acorn_8x8.h b/c_os/devices/fonts/Font_acorn_8x8.h index 664ba16..30bc307 100644 --- a/c_os/devices/fonts/Font_acorn_8x8.h +++ b/c_os/devices/fonts/Font_acorn_8x8.h @@ -2,7 +2,7 @@ /* Acorn-like font definition, with PC graphics characters */ -constexpr const unsigned char acorndata_8x8[] = { +constexpr unsigned char acorndata_8x8[] = { /* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */ /* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */ /* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */ diff --git a/c_os/devices/fonts/Font_pearl_8x8.h b/c_os/devices/fonts/Font_pearl_8x8.h index c3369a7..b61cb7b 100644 --- a/c_os/devices/fonts/Font_pearl_8x8.h +++ b/c_os/devices/fonts/Font_pearl_8x8.h @@ -12,7 +12,7 @@ /**********************************************/ #define FONTDATAMAX_PEARL_8x8 2048 -constexpr const unsigned char fontdata_pearl_8x8[FONTDATAMAX_PEARL_8x8] = { +constexpr 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 b8a9d87..d79fcb4 100644 --- a/c_os/devices/fonts/Font_sun_12x22.h +++ b/c_os/devices/fonts/Font_sun_12x22.h @@ -2,7 +2,7 @@ #define FONTDATAMAX_SUN_12x22 11264 -constexpr const unsigned char fontdata_sun_12x22[FONTDATAMAX_SUN_12x22] = { +constexpr 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 83e6dac..8b11985 100644 --- a/c_os/devices/fonts/Font_sun_8x16.h +++ b/c_os/devices/fonts/Font_sun_8x16.h @@ -2,7 +2,7 @@ #define FONTDATAMAX_SUN8x16 4096 -constexpr const unsigned char fontdata_sun_8x16[FONTDATAMAX_SUN8x16] = { +constexpr 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/kernel/BIOS.h b/c_os/kernel/BIOS.h index d19c382..c3dd08a 100644 --- a/c_os/kernel/BIOS.h +++ b/c_os/kernel/BIOS.h @@ -34,10 +34,9 @@ struct BIOScall_params { extern struct BIOScall_params* BC_params; class BIOS { -private: - BIOS(const BIOS& copy); // Verhindere Kopieren - public: + BIOS(const BIOS& copy) = delete; // Verhindere Kopieren + // Initialisierung: manuelles Anlegen einer Funktion BIOS(); diff --git a/c_os/kernel/CPU.h b/c_os/kernel/CPU.h index 89e9f7d..c502ecb 100755 --- a/c_os/kernel/CPU.h +++ b/c_os/kernel/CPU.h @@ -13,11 +13,10 @@ #define __CPU_include__ class CPU { -private: - CPU(const CPU& copy); // Verhindere Kopieren - public: - CPU() {} + CPU(const CPU& copy) = delete; // Verhindere Kopieren + + CPU() = default; // Erlauben von (Hardware-)Interrupts static inline void enable_int() { diff --git a/c_os/kernel/Paging.cc b/c_os/kernel/Paging.cc index 4dd65c6..7c54c3a 100644 --- a/c_os/kernel/Paging.cc +++ b/c_os/kernel/Paging.cc @@ -99,7 +99,7 @@ unsigned int* pg_alloc_page() { * Beschreibung: Schreibschutz fuer die uebergebene Seite aktivieren. * * Dies fuer das Debugging nuetzlich. * *****************************************************************************/ -void pg_write_protect_page(unsigned int* p_page) { +void pg_write_protect_page(const unsigned int* p_page) { /* hier muss Code eingefügt werden */ @@ -114,7 +114,7 @@ void pg_write_protect_page(unsigned int* p_page) { *---------------------------------------------------------------------------* * Beschreibung: Seite als ausgelagert markieren. Nur fuer Testzwecke. * *****************************************************************************/ -void pg_notpresent_page(unsigned int* p_page) { +void pg_notpresent_page(const unsigned int* p_page) { /* hier muss Code eingefügt werden */ @@ -161,9 +161,9 @@ void pg_init() { // sodass genau der physikalische Adressraum abgedeckt ist? num_pages = total_mem / (4096 * 1024); - logger << INFO << "pg_init: " << total_mem << endl; - logger << INFO << " total_mem: " << total_mem << endl; - logger << INFO << " #pages: " << total_mem / (4096 * 1024) << endl; + Logger::instance() << INFO << "pg_init: " << total_mem << endl; + Logger::instance() << INFO << " total_mem: " << total_mem << endl; + Logger::instance() << INFO << " #pages: " << total_mem / (4096 * 1024) << endl; // // Aufbau des Page-Directory diff --git a/c_os/kernel/Paging.h b/c_os/kernel/Paging.h index b971785..a6e94d6 100644 --- a/c_os/kernel/Paging.h +++ b/c_os/kernel/Paging.h @@ -65,10 +65,10 @@ extern void pg_init(); extern unsigned int* pg_alloc_page(); // Schreibschutz auf Seite setzen -> fuer debugging nuetzlich -extern void pg_write_protect_page(unsigned int* p_page); +extern void pg_write_protect_page(const unsigned int* p_page); // Present Bit loeschen -extern void pg_notpresent_page(unsigned int* p_page); +extern void pg_notpresent_page(const unsigned int* p_page); // gibt eine 4 KB Page frei extern void pg_free_page(unsigned int* p_page); diff --git a/c_os/kernel/allocator/LinkedListAllocator.h b/c_os/kernel/allocator/LinkedListAllocator.h index ffa0c6b..a975ffc 100755 --- a/c_os/kernel/allocator/LinkedListAllocator.h +++ b/c_os/kernel/allocator/LinkedListAllocator.h @@ -34,8 +34,6 @@ private: // freie Bloecke werden verkettet struct free_block* free_start = nullptr; - LinkedListAllocator(Allocator& copy) = delete; // Verhindere Kopieren - // Traverses the whole list forward till previous block is reached. // This can only be called on free blocks as allocated blocks // aren't reachable from the freelist. @@ -45,6 +43,8 @@ private: SpinLock lock; public: + LinkedListAllocator(Allocator& copy) = delete; // Verhindere Kopieren + LinkedListAllocator() : log("LL-Alloc") {} void init() override; diff --git a/c_os/kernel/allocator/TreeAllocator.h b/c_os/kernel/allocator/TreeAllocator.h index d8787d2..b4ad0bc 100755 --- a/c_os/kernel/allocator/TreeAllocator.h +++ b/c_os/kernel/allocator/TreeAllocator.h @@ -38,17 +38,14 @@ private: NamedLogger log; - TreeAllocator(Allocator& copy) = delete; // Verhindere Kopieren - // 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); } void dump_free_memory(tree_block_t* node); - // NOTE: Would be nice to have this stuff somewhere else for general use (scheduling?) - // but that would require different rbt_node/dll_node structures. - // If I need this again later I should move it. + // NOTE: Would be nice to have this stuff somewhere else for general use (scheduling?), + // makes no sense to have this as members. I'll move it later void rbt_rot_l(tree_block_t* x); void rbt_rot_r(tree_block_t* x); void rbt_transplant(tree_block_t* a, tree_block_t* b); @@ -67,6 +64,8 @@ private: void dll_remove(list_block_t* node); public: + TreeAllocator(Allocator& copy) = delete; // Verhindere Kopieren + TreeAllocator() : log("RBT-Alloc") {}; void init() override; diff --git a/c_os/kernel/threads/IdleThread.h b/c_os/kernel/threads/IdleThread.h index 091acac..d1029d8 100644 --- a/c_os/kernel/threads/IdleThread.h +++ b/c_os/kernel/threads/IdleThread.h @@ -15,13 +15,12 @@ #include "kernel/threads/Thread.h" class IdleThread : public Thread { -private: +public: IdleThread(const Thread& copy) = delete; // Verhindere Kopieren -public: IdleThread() : Thread("IdleThread") {} - 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); diff --git a/c_os/kernel/threads/Scheduler.h b/c_os/kernel/threads/Scheduler.h index 88709b3..4407c4f 100644 --- a/c_os/kernel/threads/Scheduler.h +++ b/c_os/kernel/threads/Scheduler.h @@ -19,8 +19,6 @@ class Scheduler { private: - Scheduler(const Scheduler& copy) = delete; // Verhindere Kopieren - NamedLogger log; bse::vector> ready_queue; @@ -35,8 +33,8 @@ private: unsigned int idle_tid = 0U; // Roughly the old dispatcher functionality - 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 + /*[[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 // Kann nur vom Idle-Thread aufgerufen werden (erster Thread der vom Scheduler gestartet wird) void enable_preemption(unsigned int tid) { idle_tid = tid; } @@ -45,6 +43,8 @@ private: void ready(bse::unique_ptr&& thread); public: + Scheduler(const Scheduler& copy) = delete; // Verhindere Kopieren + Scheduler() : log("SCHED"), ready_queue(true), block_queue(true) {} // lazy queues, wait for allocator // The scheduler has to init the queues explicitly after the allocator is available @@ -63,7 +63,7 @@ public: bool preemption_enabled() const { return idle_tid != 0U; } // Scheduler starten - void schedule(); + /*[[noreturn]]*/ void schedule(); // Helper that directly constructs the thread, then readys it template @@ -80,13 +80,13 @@ 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... - void exit(); + /* [[noreturn]] */ void exit(); // Returns on error because we don't have exceptions // Thread mit 'Gewalt' terminieren void kill(unsigned int tid, bse::unique_ptr* ptr); void kill(unsigned int tid) { kill(tid, nullptr); } - // Ask thread to exit + // Asks thread to exit // NOTE: I had many problems with killing threads that were stuck in some semaphore // or were involved in any locking mechanisms, so with this a thread can make sure // to "set things right" before exiting itself (but could also be ignored) @@ -94,13 +94,13 @@ public: void nice_kill(unsigned int tid) { nice_kill(tid, nullptr); } // CPU freiwillig abgeben und Auswahl des naechsten Threads - void yield(); + /* [[noreturn]] */ void yield(); // Returns when only the idle thread runs // Thread umschalten; wird aus der ISR des PITs gerufen - void preempt(); + /* [[noreturn]] */ void preempt(); // Returns when only the idle thread runs // Blocks current thread (move to block_queue) - void block(); + /* [[noreturn]] */ 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 880ac0a..224c1e9 100755 --- a/c_os/kernel/threads/Thread.cc +++ b/c_os/kernel/threads/Thread.cc @@ -55,51 +55,10 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread* // Funktion muss daher dafuer sorgen, dass diese Adresse nie benoetigt // wird, sie darf also nicht terminieren, sonst kracht's. - // *(--sp) = (unsigned int*)object; // Parameter + // I thought this syntax was a bit clearer than decrementing a pointer stack[-1] = (unsigned int)object; - - // *(--sp) = (unsigned int*)0x131155; // Ruecksprungadresse (Dummy) stack[-2] = 0x131155U; - - // Nun legen wir noch die Adresse der Funktion "kickoff" ganz oben auf - // den Stack. Wenn dann bei der ersten Aktivierung dieser Koroutine der - // Stackpointer so initialisiert wird, dass er auf diesen Eintrag - // verweist, genuegt ein ret, um die Funktion kickoff zu starten. - // Genauso sollen auch alle spaeteren Threadwechsel ablaufen. - - // *(--sp) = (unsigned int*)kickoff; // Adresse stack[-3] = (unsigned int)kickoff; - - // Initialisierung der Struktur ThreadState mit den Werten, die die - // nicht-fluechtigen Register beim ersten Starten haben sollen. - // Wichtig ist dabei nur der Stackpointer. - - // NOTE: Old code before I used pusha/popa - // regs->ebx = 0; - // regs->esi = 0; - // regs->edi = 0; - // regs->ebp = 0; - // regs->esp = sp; // esp now points to the location of the address of kickoff - - // nachfolgend die fluechtige Register - // wichtig fuer preemptives Multitasking - // regs->eax = 0; - // regs->ecx = 0; - // regs->edx = 0; - - // flags initialisieren - // regs->efl = (void*)0x200; // Interrupt-Enable - - // NOTE: New code with pusha/popa - // unsigned int* temp = (unsigned int*)sp; - // *(--sp) = 0; // EAX - // *(--sp) = 0; // ECX - // *(--sp) = 0; // EDX - // *(--sp) = 0; // EBX - // *(--sp) = (unsigned int*)temp; // ESP - // *(--sp) = 0; // EBP - // *(--sp) = 0; // ESI - // *(--sp) = 0; // EDI stack[-4] = 0; // EAX stack[-5] = 0; // ECX stack[-6] = 0; // EDX @@ -108,12 +67,8 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread* stack[-9] = 0; // EBP stack[-10] = 0; // ESI stack[-11] = 0; // EDI - - // popf - // *(--sp) = (unsigned int*)0x200; // Interrupt-Enable stack[-12] = 0x200U; - // *esp = (unsigned int)sp; *esp = (unsigned int)&stack[-12]; } @@ -127,10 +82,10 @@ void Thread_init(unsigned int* esp, unsigned int* stack, void (*kickoff)(Thread* * wuerde ein sinnloser Wert als Ruecksprungadresse * * interpretiert werden und der Rechner abstuerzen. * *****************************************************************************/ -void kickoff(Thread* object) { +[[noreturn]] void kickoff(Thread* object) { object->run(); - // object->run() kehrt hoffentlich nie hierher zurueck + // object->run() kehrt (hoffentlich) nie hierher zurueck while (true) {} } diff --git a/c_os/kernel/threads/Thread.h b/c_os/kernel/threads/Thread.h index 9030553..f426d2d 100644 --- a/c_os/kernel/threads/Thread.h +++ b/c_os/kernel/threads/Thread.h @@ -32,8 +32,6 @@ class Thread { private: - Thread(const Thread& copy) = delete; // Verhindere Kopieren - unsigned int* stack; unsigned int esp; @@ -48,22 +46,24 @@ protected: friend class Scheduler; // Scheduler can access tid public: + Thread(const Thread& copy) = delete; // Verhindere Kopieren + virtual ~Thread() { log.info() << "Uninitialized thread, ID: " << dec << this->tid << " (" << name << ")" << endl; delete[] this->stack; } // Thread aktivieren - void start() const; + /*[[noreturn]]*/ void start() const; // Umschalten auf Thread 'next' - void switchTo(Thread& next); + /*[[noreturn]]*/ void switchTo(Thread& next); // Ask thread to terminate itself void suicide() { running = false; } // Methode des Threads, muss in Sub-Klasse implementiert werden - virtual void run() = 0; + [[noreturn]] virtual void run() = 0; }; #endif