1

Implement Util::System to keep system utility functions like streams

This commit is contained in:
2022-12-08 02:19:52 +01:00
parent 56eb074192
commit 663fabf074
18 changed files with 236 additions and 191 deletions

View File

@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.14)
target_sources(lib PUBLIC
${CHURLOS_SRC_DIR}/lib/util/System.cpp
)

View File

@ -11,6 +11,7 @@
#include "BumpAllocator.h" #include "BumpAllocator.h"
#include "kernel/system/Globals.h" #include "kernel/system/Globals.h"
#include "lib/util/System.h"
namespace Kernel { namespace Kernel {
@ -38,9 +39,9 @@ void BumpAllocator::dump_free_memory() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
Kernel::kout << "Freier Speicher:" << endl Util::System::out << "Freier Speicher:" << endl
<< " - Next: " << hex << reinterpret_cast<uint32_t>(next) << " - Next: " << hex << reinterpret_cast<uint32_t>(next)
<< ", Allocations: " << dec << allocations << endl; << ", Allocations: " << dec << allocations << endl;
} }
/***************************************************************************** /*****************************************************************************

View File

@ -11,6 +11,7 @@
#include "LinkedListAllocator.h" #include "LinkedListAllocator.h"
#include "kernel/system/Globals.h" #include "kernel/system/Globals.h"
#include "lib/util/System.h"
// I don't order the list by size so that the block order corresponds to the location in memory // I don't order the list by size so that the block order corresponds to the location in memory
// Then I can easily merge adjacent free blocks by finding the previous block without looking at // Then I can easily merge adjacent free blocks by finding the previous block without looking at
@ -50,17 +51,17 @@ void LinkedListAllocator::dump_free_memory() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
Kernel::kout << "Freier Speicher:" << endl; Util::System::out << "Freier Speicher:" << endl;
if (free_start == nullptr) { if (free_start == nullptr) {
Kernel::kout << " - No free Blocks" << endl; Util::System::out << " - No free Blocks" << endl;
} else { } else {
Kernel::kout << " - Freelist start: " << hex << reinterpret_cast<uint32_t>(free_start) << endl; Util::System::out << " - Freelist start: " << hex << reinterpret_cast<uint32_t>(free_start) << endl;
free_block_t *current = free_start; free_block_t *current = free_start;
do { do {
Kernel::kout << " - Free Block (Start: " << hex << reinterpret_cast<uint32_t>(current) Util::System::out << " - Free Block (Start: " << hex << reinterpret_cast<uint32_t>(current)
<< " Size: " << hex << current->size << ")" << endl; << " Size: " << hex << current->size << ")" << endl;
current = current->next; current = current->next;
} while (current != free_start); } while (current != free_start);
} }
@ -312,7 +313,7 @@ free_block_t *LinkedListAllocator::find_previous_block(free_block_t *next_block)
} }
// if (current == next_block) { // if (current == next_block) {
// Kernel::kout << "LinkedListAllocator::find_previous_block returned the input block" << endl; // Util::System::out << "LinkedListAllocator::find_previous_block returned the input block" << endl;
// } // }
return current; return current;

View File

@ -17,13 +17,13 @@ void TreeAllocator::init() {
} }
void TreeAllocator::dump_free_memory() { void TreeAllocator::dump_free_memory() {
Kernel::kout << "Free Memory:" << endl; Util::System::out << "Free Memory:" << endl;
list_block_t *current = reinterpret_cast<list_block_t *>(heap_start); list_block_t *current = reinterpret_cast<list_block_t *>(heap_start);
do { do {
if (!current->allocated) { if (!current->allocated) {
Kernel::kout << " - Free Block at " << reinterpret_cast<uint32_t>(current) << ", Size: " Util::System::out << " - Free Block at " << reinterpret_cast<uint32_t>(current) << ", Size: "
<< reinterpret_cast<uint32_t>(current->next) - reinterpret_cast<uint32_t>(current) << reinterpret_cast<uint32_t>(current->next) - reinterpret_cast<uint32_t>(current)
<< endl; << endl;
} }
current = current->next; current = current->next;
} while (reinterpret_cast<uint32_t>(current) != heap_start); } while (reinterpret_cast<uint32_t>(current) != heap_start);

View File

@ -1,40 +1,41 @@
#include "ArrayDemo.h" #include "ArrayDemo.h"
#include "lib/util/System.h"
void ArrayDemo::run() { void ArrayDemo::run() {
Container::Array<int, 10> arr1 {}; Container::Array<int, 10> arr1{};
Container::Array<int, 10> arr2 {}; Container::Array<int, 10> arr2{};
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Adding..." << endl; Util::System::out << "Adding..." << endl;
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
arr1[i] = i; arr1[i] = i;
} }
Kernel::kout << "Iterator printing arr1:" << endl; Util::System::out << "Iterator printing arr1:" << endl;
for (int i : arr1) { for (int i: arr1) {
Kernel::kout << i << " "; Util::System::out << i << " ";
} }
Kernel::kout << endl; Util::System::out << endl;
Kernel::kout << "Swapping arr1 and arr2..." << endl; Util::System::out << "Swapping arr1 and arr2..." << endl;
arr1.swap(arr2); arr1.swap(arr2);
Kernel::kout << "Iterator printing arr1:" << endl; Util::System::out << "Iterator printing arr1:" << endl;
for (int i : arr1) { for (int i: arr1) {
Kernel::kout << i << " "; Util::System::out << i << " ";
} }
Kernel::kout << endl; Util::System::out << endl;
Kernel::kout << "Iterator printing arr2:" << endl; Util::System::out << "Iterator printing arr2:" << endl;
for (int i : arr2) { for (int i: arr2) {
Kernel::kout << i << " "; Util::System::out << i << " ";
} }
Kernel::kout << endl; Util::System::out << endl;
// arr1.swap(arr3); // Not possible as type/size has to match // arr1.swap(arr3); // Not possible as type/size has to match
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -9,30 +9,31 @@
*****************************************************************************/ *****************************************************************************/
#include "HeapDemo.h" #include "HeapDemo.h"
#include "lib/util/System.h"
void HeapDemo::run() { void HeapDemo::run() {
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "HEAP_DEMO ===================================================================" << endl; Util::System::out << "HEAP_DEMO ===================================================================" << endl;
/* hier muss Code eingefuegt werden */ /* hier muss Code eingefuegt werden */
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
// Rounding to word border // Rounding to word border
Kernel::kout << "ROUNDING ====================================================================" << endl; Util::System::out << "ROUNDING ====================================================================" << endl;
void* alloc = Kernel::allocator.alloc(1); // 1 Byte void *alloc = Kernel::allocator.alloc(1); // 1 Byte
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
Kernel::allocator.free(alloc); Kernel::allocator.free(alloc);
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
// Some objects and forward/backward merging // Some objects and forward/backward merging
Kernel::kout << "SOME OBJECTS ================================================================" << endl; Util::System::out << "SOME OBJECTS ================================================================" << endl;
MyObj* a = new MyObj(5); MyObj *a = new MyObj(5);
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
MyObj* b = new MyObj(10); MyObj *b = new MyObj(10);
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
MyObj* c = new MyObj(15); MyObj *c = new MyObj(15);
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
delete b; // No merge delete b; // No merge
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
@ -48,7 +49,7 @@ void HeapDemo::run() {
// allocator.dump_free_memory(); // allocator.dump_free_memory();
// Allocate too much // Allocate too much
Kernel::kout << "TOO MUCH ====================================================================" << endl; Util::System::out << "TOO MUCH ====================================================================" << endl;
Kernel::allocator.alloc(1024 * 1024); // should fail as only 1024 * 1024 - Headersize bytes are available Kernel::allocator.alloc(1024 * 1024); // should fail as only 1024 * 1024 - Headersize bytes are available
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
@ -65,14 +66,14 @@ void HeapDemo::run() {
// allocator.dump_free_memory(); // allocator.dump_free_memory();
// Array allocation // Array allocation
Kernel::kout << "ARRAY =======================================================================" << endl; Util::System::out << "ARRAY =======================================================================" << endl;
MyObj* objs = new MyObj[1024]; MyObj *objs = new MyObj[1024];
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
delete[] objs; delete[] objs;
Kernel::allocator.dump_free_memory(); Kernel::allocator.dump_free_memory();
Kernel::kout << "HEAP_DEMO END ===============================================================" << endl; Util::System::out << "HEAP_DEMO END ===============================================================" << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -14,21 +14,21 @@ void KeyboardDemo::run() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
Kernel::kout << "Keyboard Demo: " << endl; Util::System::out << "Keyboard Demo: " << endl;
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Info: Die Keyboard Demo sperrt den Output Stream:\n" Util::System::out << "Info: Die Keyboard Demo sperrt den Output Stream:\n"
<< " Wenn die Preemption Demo laeuft wird diese also erst\n" << " Wenn die Preemption Demo laeuft wird diese also erst\n"
<< " fortfahren wenn die Keyboard Demo wieder beendet ist." << endl; << " fortfahren wenn die Keyboard Demo wieder beendet ist." << endl;
Kernel::kout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nInput: "; Util::System::out << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nInput: ";
Kernel::kout.flush(); Util::System::out.flush();
while (running) { while (running) {
Kernel::kout << listener.waitForKeyEvent(); Util::System::out << listener.waitForKeyEvent();
Kernel::kout.flush(); Util::System::out.flush();
} }
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -14,13 +14,14 @@
#include "kernel/system/Globals.h" #include "kernel/system/Globals.h"
#include "kernel/process/Thread.h" #include "kernel/process/Thread.h"
#include "kernel/event/KeyEventListener.h" #include "kernel/event/KeyEventListener.h"
#include "lib/util/System.h"
class KeyboardDemo : public Kernel::Thread { class KeyboardDemo : public Kernel::Thread {
private: private:
Kernel::KeyEventListener listener; Kernel::KeyEventListener listener;
public: public:
KeyboardDemo(const KeyboardDemo& copy) = delete; KeyboardDemo(const KeyboardDemo &copy) = delete;
KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) { KeyboardDemo() : Thread("KeyboardDemo"), listener(tid) {
Kernel::kevman.subscribe(listener); Kernel::kevman.subscribe(listener);
@ -30,10 +31,10 @@ public:
~KeyboardDemo() override { ~KeyboardDemo() override {
if (running) { if (running) {
// NOTE: If the thread was exited nicely it can unlock before destructor, // NOTE: If the thread was exited nicely it can unlock before destructor,
// but on forced kill Kernel::kout has to be unlocked in the destructor. // but on forced kill Util::System::out has to be unlocked in the destructor.
// This is bad since it could release the lock although some other // This is bad since it could release the lock although some other
// thread set it (so use nice_kill) // thread set it (so use nice_kill)
Kernel::kout.unlock(); Util::System::out.unlock();
} }
Kernel::kevman.unsubscribe(listener); Kernel::kevman.unsubscribe(listener);
} }

View File

@ -12,23 +12,23 @@
#include "VectorDemo.h" #include "VectorDemo.h"
void print_demo_menu() { void print_demo_menu() {
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Demo Menu, press number to start, k/K to kill:\n" Util::System::out << "Demo Menu, press number to start, k/K to kill:\n"
<< "1 - Text Demo\n" << "1 - Text Demo\n"
<< "2 - PCSPK Demo\n" << "2 - PCSPK Demo\n"
<< "3 - Keyboard Demo\n" << "3 - Keyboard Demo\n"
<< "4 - Heap Demo\n" << "4 - Heap Demo\n"
<< "5 - VBE Demo\n" << "5 - VBE Demo\n"
<< "6 - Paging Demo\n" << "6 - Paging Demo\n"
<< "7 - Preemption Demo\n" << "7 - Preemption Demo\n"
<< "Extra demos:\n" << "Extra demos:\n"
<< "8 - bse::vector demo\n" << "8 - bse::vector demo\n"
<< "9 - bse::array demo\n" << "9 - bse::array demo\n"
<< "0 - bse::unique_ptr demo\n" << "0 - bse::unique_ptr demo\n"
<< "! - bse::string demo\n" << "! - bse::string demo\n"
<< endl; << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
} }
void MainMenu::run() { void MainMenu::run() {
@ -41,40 +41,40 @@ void MainMenu::run() {
if ((input >= '0' && input <= '9') || input == '!') { if ((input >= '0' && input <= '9') || input == '!') {
switch (input) { switch (input) {
case '1': case '1':
running_demo = Kernel::scheduler.ready<TextDemo>(); running_demo = Kernel::scheduler.ready<TextDemo>();
break; break;
case '2': case '2':
running_demo = Kernel::scheduler.ready<PCSPKdemo>(&Device::PCSPK::aerodynamic); running_demo = Kernel::scheduler.ready<PCSPKdemo>(&Device::PCSPK::aerodynamic);
break; break;
case '3': case '3':
running_demo = Kernel::scheduler.ready<KeyboardDemo>(); running_demo = Kernel::scheduler.ready<KeyboardDemo>();
break; break;
case '4': case '4':
running_demo = Kernel::scheduler.ready<HeapDemo>(); running_demo = Kernel::scheduler.ready<HeapDemo>();
break; break;
case '5': case '5':
running_demo = Kernel::scheduler.ready<VBEdemo>(); running_demo = Kernel::scheduler.ready<VBEdemo>();
break; break;
case '6': case '6':
running_demo = Kernel::scheduler.ready<PagingDemo>(); running_demo = Kernel::scheduler.ready<PagingDemo>();
break; break;
case '7': case '7':
running_demo = Kernel::scheduler.ready<PreemptiveThreadDemo>(3); running_demo = Kernel::scheduler.ready<PreemptiveThreadDemo>(3);
break; break;
case '8': case '8':
running_demo = Kernel::scheduler.ready<VectorDemo>(); running_demo = Kernel::scheduler.ready<VectorDemo>();
break; break;
case '9': case '9':
running_demo = Kernel::scheduler.ready<ArrayDemo>(); running_demo = Kernel::scheduler.ready<ArrayDemo>();
break; break;
case '0': case '0':
running_demo = Kernel::scheduler.ready<SmartPointerDemo>(); running_demo = Kernel::scheduler.ready<SmartPointerDemo>();
break; break;
case '!': case '!':
running_demo = Kernel::scheduler.ready<StringDemo>(); running_demo = Kernel::scheduler.ready<StringDemo>();
break; break;
} }
} else if (input == 'k') { } else if (input == 'k') {
Kernel::scheduler.nice_kill(running_demo); // NOTE: If thread exits itself this will throw error Kernel::scheduler.nice_kill(running_demo); // NOTE: If thread exits itself this will throw error

View File

@ -1,16 +1,17 @@
#include "PCSPKdemo.h" #include "PCSPKdemo.h"
#include "lib/util/System.h"
void PCSPKdemo::run() { void PCSPKdemo::run() {
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Playing..." << endl; Util::System::out << "Playing..." << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
(*melody)(); // This syntax is confusing as hell (*melody)(); // This syntax is confusing as hell
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout << "Finished" << endl; Util::System::out << "Finished" << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -1,14 +1,16 @@
#include "PagingDemo.h" #include "PagingDemo.h"
#include "lib/util/System.h"
void PagingDemo::writeprotect_page() { void PagingDemo::writeprotect_page() {
Kernel::kout << "Accessing a writeprotected page triggers bluescreen,\nif you can read this it didn't work" << endl; Util::System::out << "Accessing a writeprotected page triggers bluescreen,\nif you can read this it didn't work"
<< endl;
// BlueScreen 1 // BlueScreen 1
// asm("int $3"); // asm("int $3");
// BlueScreen 2 // BlueScreen 2
log.info() << "Allocating page" << endl; log.info() << "Allocating page" << endl;
uint32_t* page = Kernel::pg_alloc_page(); uint32_t *page = Kernel::pg_alloc_page();
*page = 42; *page = 42;
log.info() << "Writeprotecting page..." << endl; log.info() << "Writeprotecting page..." << endl;
Kernel::pg_write_protect_page(page); Kernel::pg_write_protect_page(page);
@ -20,30 +22,30 @@ void PagingDemo::writeprotect_page() {
} }
void PagingDemo::notpresent_page() { void PagingDemo::notpresent_page() {
Kernel::kout << "Produces pagefault, if you can read this it didn't work" << endl; Util::System::out << "Produces pagefault, if you can read this it didn't work" << endl;
log.info() << "Allocating page" << endl; log.info() << "Allocating page" << endl;
uint32_t* page = Kernel::pg_alloc_page(); uint32_t *page = Kernel::pg_alloc_page();
*page = 42; *page = 42;
log.info() << "Marking page notpresent..." << endl; log.info() << "Marking page notpresent..." << endl;
Kernel::pg_notpresent_page(page); Kernel::pg_notpresent_page(page);
log.info() << "Accessing page" << endl; log.info() << "Accessing page" << endl;
Kernel::kout << "Page not accessible: " << *page << endl; Util::System::out << "Page not accessible: " << *page << endl;
// No free because bluescreen // No free because bluescreen
} }
void PagingDemo::run() { void PagingDemo::run() {
Kernel::kout << "Press w for writeprotect demo, n for notpresent demo" << endl; Util::System::out << "Press w for writeprotect demo, n for notpresent demo" << endl;
switch(listener.waitForKeyEvent()) { switch (listener.waitForKeyEvent()) {
case 'w': case 'w':
writeprotect_page(); writeprotect_page();
break; break;
case 'n': case 'n':
notpresent_page(); notpresent_page();
break; break;
} }
Kernel::scheduler.exit(); Kernel::scheduler.exit();

View File

@ -1,34 +1,35 @@
#include "PreemptiveThreadDemo.h" #include "PreemptiveThreadDemo.h"
#include "lib/util/System.h"
void PreemptiveLoopThread::run() { void PreemptiveLoopThread::run() {
int cnt = 0; int cnt = 0;
while (running) { while (running) {
// Basic synchronization by semaphore // Basic synchronization by semaphore
Kernel::kout.lock(); Util::System::out.lock();
// Saving + restoring Kernel::kout position doesn't help much as preemption still occurs // Saving + restoring Util::System::out position doesn't help much as preemption still occurs
CGA_Stream::setpos(55, id); CGA_Stream::setpos(55, id);
Kernel::kout << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl; Util::System::out << fillw(3) << id << fillw(0) << ": " << dec << cnt++ << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
} }
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }
void PreemptiveThreadDemo::run() { void PreemptiveThreadDemo::run() {
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Preemptive Thread Demo:" << endl; Util::System::out << "Preemptive Thread Demo:" << endl;
Kernel::kout << "Readying LoopThreads" << endl; Util::System::out << "Readying LoopThreads" << endl;
for (unsigned int i = 0; i < number_of_threads; ++i) { for (unsigned int i = 0; i < number_of_threads; ++i) {
Kernel::scheduler.ready<PreemptiveLoopThread>(i); Kernel::scheduler.ready<PreemptiveLoopThread>(i);
} }
Kernel::kout << "Exiting main thread" << endl; Util::System::out << "Exiting main thread" << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -1,11 +1,12 @@
#include "SmartPointerDemo.h" #include "SmartPointerDemo.h"
#include "kernel/process/IdleThread.h" #include "kernel/process/IdleThread.h"
#include "lib/util/System.h"
void SmartPointerDemo::run() { void SmartPointerDemo::run() {
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Output is written to log to be able to trace memory allocations/deallocations" << endl; Util::System::out << "Output is written to log to be able to trace memory allocations/deallocations" << endl;
{ {
log.info() << "Allocating new unique_ptr<int>..." << endl; log.info() << "Allocating new unique_ptr<int>..." << endl;
@ -76,7 +77,7 @@ void SmartPointerDemo::run() {
// NOTE: This wasn't working because of a missing operator[] delete in the allocator // NOTE: This wasn't working because of a missing operator[] delete in the allocator
log.info() << "Allocating unique_ptr<int>*..." << endl; log.info() << "Allocating unique_ptr<int>*..." << endl;
Memory::unique_ptr<int>* ptrptr = new Memory::unique_ptr<int>[10]; Memory::unique_ptr<int> *ptrptr = new Memory::unique_ptr<int>[10];
delete[] ptrptr; delete[] ptrptr;
log.info() << "Should be deleted by now..." << endl; log.info() << "Should be deleted by now..." << endl;
@ -95,7 +96,7 @@ void SmartPointerDemo::run() {
{ {
log.info() << "Heapallocating Array<bse::unique_ptr<int>, 10>..." << endl; log.info() << "Heapallocating Array<bse::unique_ptr<int>, 10>..." << endl;
Container::Array<Memory::unique_ptr<int>, 10>* arr = new Container::Array<Memory::unique_ptr<int>, 10>; Container::Array<Memory::unique_ptr<int>, 10> *arr = new Container::Array<Memory::unique_ptr<int>, 10>;
log.info() << "Populating slot 0..." << endl; log.info() << "Populating slot 0..." << endl;
(*arr)[0] = Memory::make_unique<int>(1); (*arr)[0] = Memory::make_unique<int>(1);
log.info() << "Moving slot 0 to slot 1..." << endl; log.info() << "Moving slot 0 to slot 1..." << endl;
@ -117,6 +118,6 @@ void SmartPointerDemo::run() {
} }
log.info() << "Should be deleted by now..." << endl; log.info() << "Should be deleted by now..." << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -1,43 +1,44 @@
#include "StringDemo.h" #include "StringDemo.h"
#include "lib/util/System.h"
void StringDemo::run() { void StringDemo::run() {
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
log.info() << "Allocating new string" << endl; log.info() << "Allocating new string" << endl;
String::string str1 = "This is a dynamically allocated string!"; String::string str1 = "This is a dynamically allocated string!";
Kernel::kout << str1 << endl; Util::System::out << str1 << endl;
log.info() << "Reassign string" << endl; log.info() << "Reassign string" << endl;
str1 = "Hello"; str1 = "Hello";
Kernel::kout << str1 << " has length " << dec << str1.size() << endl; Util::System::out << str1 << " has length " << dec << str1.size() << endl;
Kernel::kout << "Again with strlen: Hello has length " << dec << String::strlen("Hello") << endl; Util::System::out << "Again with strlen: Hello has length " << dec << String::strlen("Hello") << endl;
Kernel::kout << "Adding strings: " << str1 << " + World" << endl; Util::System::out << "Adding strings: " << str1 << " + World" << endl;
log.info() << "Adding strings" << endl; log.info() << "Adding strings" << endl;
str1 = str1 + " World"; str1 = str1 + " World";
Kernel::kout << str1 << endl; Util::System::out << str1 << endl;
Kernel::kout << "Hello += World" << endl; Util::System::out << "Hello += World" << endl;
log.info() << "Hello += World" << endl; log.info() << "Hello += World" << endl;
String::string str3 = "Hello"; String::string str3 = "Hello";
str3 += " World"; str3 += " World";
Kernel::kout << str3 << endl; Util::System::out << str3 << endl;
Kernel::kout << "Hello World *= 3" << endl; Util::System::out << "Hello World *= 3" << endl;
str3 *= 3; str3 *= 3;
Kernel::kout << str3 << endl; Util::System::out << str3 << endl;
Kernel::kout << "String iterator!" << endl; Util::System::out << "String iterator!" << endl;
for (const char c : str1) { for (const char c: str1) {
Kernel::kout << c << " "; Util::System::out << c << " ";
} }
Kernel::kout << endl; Util::System::out << endl;
log.info() << "Allocating new string" << endl; log.info() << "Allocating new string" << endl;
String::string str2 = "Hello World"; String::string str2 = "Hello World";
Kernel::kout << "str1 == str2: " << static_cast<int>(str1 == str2) << endl; Util::System::out << "str1 == str2: " << static_cast<int>(str1 == str2) << endl;
Kernel::kout << "strcmp(Hello, Hello): " << String::strcmp("Hello", "Hello") << endl; Util::System::out << "strcmp(Hello, Hello): " << String::strcmp("Hello", "Hello") << endl;
log.info() << "Reassign str2" << endl; log.info() << "Reassign str2" << endl;
str2 = "Hello"; str2 = "Hello";
@ -48,9 +49,11 @@ void StringDemo::run() {
arr[2] = 'l'; arr[2] = 'l';
arr[3] = 'l'; arr[3] = 'l';
arr[4] = 'o'; arr[4] = 'o';
Kernel::kout << "bse::array<char, 5> to bse::string: " << static_cast<String::string>(arr) << ", size: " << (String::string(arr)).size() << endl; Util::System::out << "bse::array<char, 5> to bse::string: " << static_cast<String::string>(arr) << ", size: "
Kernel::kout << "(bse::string)arr (" << static_cast<String::string>(arr) << ") == str2 (" << str2 << "): " << static_cast<int>(String::string(arr) == str2) << endl; << (String::string(arr)).size() << endl;
Util::System::out << "(bse::string)arr (" << static_cast<String::string>(arr) << ") == str2 (" << str2 << "): "
<< static_cast<int>(String::string(arr) == str2) << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -9,35 +9,36 @@
*****************************************************************************/ *****************************************************************************/
#include "TextDemo.h" #include "TextDemo.h"
#include "lib/util/System.h"
void TextDemo::run() { void TextDemo::run() {
/* Hier muess Code eingefuegt werden */ /* Hier muess Code eingefuegt werden */
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "TextDemo\n" Util::System::out << "TextDemo\n"
<< endl; << endl;
Kernel::kout << "Attribut (GREEN on WHITE): " Util::System::out << "Attribut (GREEN on WHITE): "
<< bgc(Device::CGA::WHITE) << green << "GREEN on WHITE" << endl << bgc(Device::CGA::WHITE) << green << "GREEN on WHITE" << endl
<< "Attribut (WHITE on BLACK): " << "Attribut (WHITE on BLACK): "
<< bgc(Device::CGA::BLACK) << white << "WHITE on BLACK" << endl; << bgc(Device::CGA::BLACK) << white << "WHITE on BLACK" << endl;
Kernel::kout << endl; Util::System::out << endl;
Kernel::kout << "Test der Zahlenausgabefunktion:" << endl Util::System::out << "Test der Zahlenausgabefunktion:" << endl
<< "| dec | hex | bin |" << endl << "| dec | hex | bin |" << endl
<< "+-------+-------+-------+" << endl; << "+-------+-------+-------+" << endl;
for (uint16_t num = 0; num < 17; ++num) { for (uint16_t num = 0; num < 17; ++num) {
Kernel::kout << fillw(0) << "| " << fillw(6) << dec << num Util::System::out << fillw(0) << "| " << fillw(6) << dec << num
<< fillw(0) << "| " << fillw(6) << hex << num << fillw(0) << "| " << fillw(6) << hex << num
<< fillw(0) << "| " << fillw(6) << bin << num << fillw(0) << "| " << fillw(6) << bin << num
<< fillw(0) << "|" << endl; << fillw(0) << "|" << endl;
} }
Kernel::kout << endl; Util::System::out << endl;
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

View File

@ -1,8 +1,9 @@
#include "VectorDemo.h" #include "VectorDemo.h"
#include "lib/util/System.h"
void print(OutStream& os, const Container::Vector<int>& list) { void print(OutStream &os, const Container::Vector<int> &list) {
os << "Printing List: "; os << "Printing List: ";
for (const int i : list) { for (const int i: list) {
os << i << " "; os << i << " ";
} }
os << endl; os << endl;
@ -11,9 +12,9 @@ void print(OutStream& os, const Container::Vector<int>& list) {
void VectorDemo::run() { void VectorDemo::run() {
Container::Vector<int> list; Container::Vector<int> list;
Kernel::kout.lock(); Util::System::out.lock();
Kernel::kout.clear(); Util::System::out.clear();
Kernel::kout << "Logs are written to serial to see the memory interactions" << endl; Util::System::out << "Logs are written to serial to see the memory interactions" << endl;
log.info() << "Initial list size: " << dec << list.size() << endl; log.info() << "Initial list size: " << dec << list.size() << endl;
@ -101,10 +102,10 @@ void VectorDemo::run() {
// ============================================================ // ============================================================
log.info() << "Range based for support" << endl; log.info() << "Range based for support" << endl;
for (int i : list) { for (int i: list) {
log.info() << "List contains element: " << dec << i << endl; log.info() << "List contains element: " << dec << i << endl;
} }
Kernel::kout.unlock(); Util::System::out.unlock();
Kernel::scheduler.exit(); Kernel::scheduler.exit();
} }

7
src/lib/util/System.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "System.h"
namespace Util {
CGA_Stream System::out;
}

18
src/lib/util/System.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef CHURLOS_LIB_SYSTEM_H
#define CHURLOS_LIB_SYSTEM_H
#include "lib/stream/CGA_Stream.h"
namespace Util {
class System {
public:
// TODO: Something like "CGA_Stream" shouldn't exists, the stream should not be coupled to the output device
// TODO: There should be an "in" and "error" stream
static CGA_Stream out;
};
}
#endif //CHURLOS_LIB_SYSTEM_H