From be691582ee12613278af24cb5a824eeb357f6324 Mon Sep 17 00:00:00 2001 From: Benji Dial Date: Mon, 29 Jul 2024 11:27:22 -0400 Subject: some work on compositor --- euler/include/euler/syscall.hpp | 33 +++++++- euler/include/list | 3 + euler/include/mutex | 4 + euler/include/std/allocator.hpp | 2 + euler/include/std/fwd/allocator.hpp | 6 ++ euler/include/std/fwd/string.hpp | 5 ++ euler/include/std/fwd/vector.hpp | 8 ++ euler/include/std/list.hpp | 157 ++++++++++++++++++++++++++++++++++++ euler/include/std/mutex.hpp | 40 +++++++++ euler/include/std/string.hpp | 7 +- euler/include/std/unique_lock.hpp | 53 ++++++++++++ euler/include/std/vector.hpp | 4 +- euler/source/entry.cpp | 2 + euler/source/std/cstdio.cpp | 1 + euler/source/std/string.cpp | 6 +- euler/source/stream.cpp | 1 + euler/source/syscall.cpp | 13 +++ 17 files changed, 336 insertions(+), 9 deletions(-) create mode 100644 euler/include/list create mode 100644 euler/include/mutex create mode 100644 euler/include/std/fwd/allocator.hpp create mode 100644 euler/include/std/fwd/string.hpp create mode 100644 euler/include/std/fwd/vector.hpp create mode 100644 euler/include/std/list.hpp create mode 100644 euler/include/std/mutex.hpp create mode 100644 euler/include/std/unique_lock.hpp (limited to 'euler') diff --git a/euler/include/euler/syscall.hpp b/euler/include/euler/syscall.hpp index 64456ae..4a3daa4 100644 --- a/euler/include/euler/syscall.hpp +++ b/euler/include/euler/syscall.hpp @@ -1,11 +1,11 @@ #pragma once +#include +#include #include #include #include #include -#include -#include namespace euler::syscall { @@ -124,6 +124,30 @@ namespace euler::syscall { //entry_point must not return void start_thread(void (*entry_point)(uint64_t), uint64_t arg); + //entry_point must not return + template + void start_thread(void (*entry_point)(obj_t *), obj_t *arg) { + start_thread((void (*)(uint64_t))entry_point, (uint64_t)arg); + } + + //entry_point must not return + template + void start_thread(void (*entry_point)(const obj_t *), const obj_t *arg) { + start_thread((void (*)(uint64_t))entry_point, (uint64_t)arg); + } + + //entry_point must not return + template + void start_thread(void (*entry_point)(obj_t &), obj_t &arg) { + start_thread((void (*)(uint64_t))entry_point, (uint64_t)&arg); + } + + //entry_point must not return + template + void start_thread(void (*entry_point)(const obj_t &), const obj_t &arg) { + start_thread((void (*)(uint64_t))entry_point, (uint64_t)&arg); + } + //entry_point must not return void start_thread(void (*entry_point)()); @@ -133,4 +157,9 @@ namespace euler::syscall { std::optional try_get_environment_variable( const std::string &name); + void set_thread_name(const std::string &name); + } + +#include +#include diff --git a/euler/include/list b/euler/include/list new file mode 100644 index 0000000..51eb3ba --- /dev/null +++ b/euler/include/list @@ -0,0 +1,3 @@ +#pragma once + +#include diff --git a/euler/include/mutex b/euler/include/mutex new file mode 100644 index 0000000..7a03381 --- /dev/null +++ b/euler/include/mutex @@ -0,0 +1,4 @@ +#pragma once + +#include +#include diff --git a/euler/include/std/allocator.hpp b/euler/include/std/allocator.hpp index 32ba005..e76feb9 100644 --- a/euler/include/std/allocator.hpp +++ b/euler/include/std/allocator.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include namespace std { diff --git a/euler/include/std/fwd/allocator.hpp b/euler/include/std/fwd/allocator.hpp new file mode 100644 index 0000000..18e14a8 --- /dev/null +++ b/euler/include/std/fwd/allocator.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace std { + template + struct allocator; +} diff --git a/euler/include/std/fwd/string.hpp b/euler/include/std/fwd/string.hpp new file mode 100644 index 0000000..5e46abf --- /dev/null +++ b/euler/include/std/fwd/string.hpp @@ -0,0 +1,5 @@ +#pragma once + +namespace std { + class string; +} diff --git a/euler/include/std/fwd/vector.hpp b/euler/include/std/fwd/vector.hpp new file mode 100644 index 0000000..fd8fe15 --- /dev/null +++ b/euler/include/std/fwd/vector.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace std { + template > + class vector; +} diff --git a/euler/include/std/list.hpp b/euler/include/std/list.hpp new file mode 100644 index 0000000..77eaaec --- /dev/null +++ b/euler/include/std/list.hpp @@ -0,0 +1,157 @@ +#pragma once + +#include + +namespace std { + + template > + class list { + + public: + struct node { + T value; + node *prev; + node *next; + }; + + template + struct generic_iterator { + + node *the_node; + + bool operator ==(const generic_iterator &other) { + return the_node == other.the_node; + } + + bool operator !=(const generic_iterator &other) { + return the_node != other.the_node; + } + + V &operator *() { + return the_node->value; + } + + V *operator ->() { + return &the_node->value; + } + + generic_iterator &operator ++() { + the_node = the_node->next; + return *this; + } + + }; + + using iterator = generic_iterator; + using const_iterator = generic_iterator; + + private: + node *first_node; + node *last_node; + size_t count; + + public: + void push_back(const T &value) { + node *n = new node { .value = value, + .prev = last_node, .next = 0 }; + if (last_node) last_node->next = n; + else first_node = n; + last_node = n; + ++count; + } + + void push_back(T &&value) { + node *n = new node { + .value = std::move(value), + .prev = last_node, .next = 0 }; + if (last_node) last_node->next = n; + else first_node = n; + last_node = n; + ++count; + } + + iterator erase(iterator pos) { + --count; + auto *n = pos.the_node; + auto *r = n->next; + if (n->prev) n->prev->next = n->next; + else first_node = n->next; + if (n->next) n->next->prev = n->prev; + else last_node = n->prev; + delete n; + return iterator { .the_node = r }; + } + + iterator begin() const noexcept { + return iterator { .the_node = first_node }; + } + + iterator end() const noexcept { + return iterator { .the_node = 0 }; + } + + size_t remove(const T &value) { + size_t removed = 0; + auto it = begin(); + while (it != end()) + if (*it == value) { + it = erase(it); + ++removed; + } + else + ++it; + count -= removed; + return removed; + } + + list() : first_node(0), last_node(0), count(0) {} + + list(const list &other) : first_node(0), last_node(0), count(0) { + for (node *n = other.first_node; n; n = n->next) + push_back(n->value); + } + + list(list &&other) : first_node(other.first_node), + last_node(other.last_node), count(other.count) { + other.first_node = 0; + other.last_node = 0; + other.count = 0; + } + + void clear() { + + if (count == 0) return; + + for (node *n = first_node->next; n; n = n->next) + delete n->prev; + delete last_node; + + first_node = 0; + last_node = 0; + count = 0; + + } + + ~list() { + clear(); + } + + list &operator =(const list &other) { + clear(); + for (node *n = other.first_node; n; n = n->next) + push_back(n->value); + } + + list &operator =(list &&other) { + clear(); + first_node = other.first_node; + last_node = other.last_node; + count = other.count; + other.first_node = 0; + other.last_node = 0; + other.count = 0; + } + + }; + +} diff --git a/euler/include/std/mutex.hpp b/euler/include/std/mutex.hpp new file mode 100644 index 0000000..0a27877 --- /dev/null +++ b/euler/include/std/mutex.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace std { + + class mutex { + + euler::syscall::stream_handle in_handle; + euler::syscall::stream_handle out_handle; + + public: + inline mutex() noexcept { + euler::syscall::create_private_socket(in_handle, out_handle); + uint8_t byte = 0; + euler::syscall::write_to_stream(in_handle, 1, &byte); + } + + mutex(const mutex &) = delete; + + inline ~mutex() { + euler::syscall::close_stream(in_handle); + euler::syscall::close_stream(out_handle); + } + + mutex &operator =(const mutex &) = delete; + + inline void lock() { + uint8_t byte; + euler::syscall::read_from_stream(out_handle, 1, &byte); + } + + inline void unlock() { + uint8_t byte = 0; + euler::syscall::write_to_stream(in_handle, 1, &byte); + } + + }; + +} diff --git a/euler/include/std/string.hpp b/euler/include/std/string.hpp index 7ccdbc2..505ee69 100644 --- a/euler/include/std/string.hpp +++ b/euler/include/std/string.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -16,9 +18,7 @@ namespace std { : characters(other.characters) {} constexpr string(string &&other) noexcept - : characters(std::move(other.characters)) { - other.characters.push_back('\0'); - } + : characters(std::move(other.characters)) {} constexpr string(const char *s) { size_t count = 0; @@ -38,7 +38,6 @@ namespace std { constexpr string &operator =(string &&str) noexcept { characters = std::move(str.characters); - str.characters.push_back('\0'); return *this; } diff --git a/euler/include/std/unique_lock.hpp b/euler/include/std/unique_lock.hpp new file mode 100644 index 0000000..14b3645 --- /dev/null +++ b/euler/include/std/unique_lock.hpp @@ -0,0 +1,53 @@ +#pragma once + +namespace std { + + template + class unique_lock { + + Mutex *the_mutex; + bool has_locked; + + public: + inline unique_lock() noexcept : the_mutex(0) {} + + unique_lock(const unique_lock &other) = delete; + + inline unique_lock(unique_lock &&other) noexcept + : the_mutex(other.the_mutex), has_locked(other.has_locked) { + other.the_mutex = 0; + } + + inline explicit unique_lock(Mutex &m) + : the_mutex(&m), has_locked(true) { + the_mutex->lock(); + } + + inline ~unique_lock() { + if (the_mutex && has_locked) + the_mutex->unlock(); + } + + unique_lock &operator =(const unique_lock &other) = delete; + + inline unique_lock &operator =(unique_lock &&other) { + if (the_mutex && has_locked) + the_mutex->unlock(); + the_mutex = other.the_mutex; + has_locked = other.has_locked; + other.the_mutex = 0; + } + + inline void lock() { + the_mutex->lock(); + has_locked = true; + } + + inline void unlock() { + the_mutex->unlock(); + has_locked = false; + } + + }; + +} diff --git a/euler/include/std/vector.hpp b/euler/include/std/vector.hpp index a1ac21d..1c35d9d 100644 --- a/euler/include/std/vector.hpp +++ b/euler/include/std/vector.hpp @@ -1,10 +1,12 @@ #pragma once +#include + #include namespace std { - template > + template class vector { public: diff --git a/euler/source/entry.cpp b/euler/source/entry.cpp index e79209c..ab721f1 100644 --- a/euler/source/entry.cpp +++ b/euler/source/entry.cpp @@ -6,6 +6,8 @@ int main(int argc, char **argv); extern "C" [[noreturn]] void _start() { + //TODO: call static initializers + auto argc_raw = euler::syscall::try_get_environment_variable("ARGC"); int argc = argc_raw.has_value() ? std::stoi(argc_raw.value()) : 0; diff --git a/euler/source/std/cstdio.cpp b/euler/source/std/cstdio.cpp index 8c12a7c..485efc3 100644 --- a/euler/source/std/cstdio.cpp +++ b/euler/source/std/cstdio.cpp @@ -1,4 +1,5 @@ #include +#include extern "C" FILE *fopen(const char *filename, const char *mode) { diff --git a/euler/source/std/string.cpp b/euler/source/std/string.cpp index 31c47a5..ae397b1 100644 --- a/euler/source/std/string.cpp +++ b/euler/source/std/string.cpp @@ -44,6 +44,7 @@ namespace std { value = value * base + c - 'A' + 10; else break; + ++i; } if (pos != 0) @@ -75,10 +76,11 @@ namespace std { } std::string operator +(std::string &&lhs, std::string &&rhs) { + size_t og_lhs_s = lhs.size(); std::string s = std::move(lhs); - s.resize(lhs.size() + rhs.size()); + s.resize(og_lhs_s + rhs.size()); for (size_t i = 0; i < rhs.size(); ++i) - s[lhs.size() + i] = rhs[i]; + s[og_lhs_s + i] = rhs[i]; rhs.clear(); return s; } diff --git a/euler/source/stream.cpp b/euler/source/stream.cpp index faf2907..da973ba 100644 --- a/euler/source/stream.cpp +++ b/euler/source/stream.cpp @@ -1,4 +1,5 @@ #include +#include #include namespace euler { diff --git a/euler/source/syscall.cpp b/euler/source/syscall.cpp index b3ed3a8..0d30c4a 100644 --- a/euler/source/syscall.cpp +++ b/euler/source/syscall.cpp @@ -1,4 +1,6 @@ #include +#include +#include extern "C" void __euler_do_syscall( uint64_t &rax, uint64_t &rdi, uint64_t &rsi, uint64_t &rdx); @@ -394,4 +396,15 @@ namespace euler::syscall { } + void set_thread_name(const std::string &name) { + + uint64_t rax = 24; + uint64_t rdi = (uint64_t)name.data(); + uint64_t rsi = name.size(); + uint64_t rdx; + + __euler_do_syscall(rax, rdi, rsi, rdx); + + } + } -- cgit v1.2.3