diff options
Diffstat (limited to 'euler')
-rw-r--r-- | euler/include/euler/syscall.hpp | 33 | ||||
-rw-r--r-- | euler/include/list | 3 | ||||
-rw-r--r-- | euler/include/mutex | 4 | ||||
-rw-r--r-- | euler/include/std/allocator.hpp | 2 | ||||
-rw-r--r-- | euler/include/std/fwd/allocator.hpp | 6 | ||||
-rw-r--r-- | euler/include/std/fwd/string.hpp | 5 | ||||
-rw-r--r-- | euler/include/std/fwd/vector.hpp | 8 | ||||
-rw-r--r-- | euler/include/std/list.hpp | 157 | ||||
-rw-r--r-- | euler/include/std/mutex.hpp | 40 | ||||
-rw-r--r-- | euler/include/std/string.hpp | 7 | ||||
-rw-r--r-- | euler/include/std/unique_lock.hpp | 53 | ||||
-rw-r--r-- | euler/include/std/vector.hpp | 4 | ||||
-rw-r--r-- | euler/source/entry.cpp | 2 | ||||
-rw-r--r-- | euler/source/std/cstdio.cpp | 1 | ||||
-rw-r--r-- | euler/source/std/string.cpp | 6 | ||||
-rw-r--r-- | euler/source/stream.cpp | 1 | ||||
-rw-r--r-- | euler/source/syscall.cpp | 13 |
17 files changed, 336 insertions, 9 deletions
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 <std/fwd/string.hpp> +#include <std/fwd/vector.hpp> #include <optional> #include <cstdint> #include <utility> #include <variant> -#include <string> -#include <vector> namespace euler::syscall { @@ -125,6 +125,30 @@ namespace euler::syscall { void start_thread(void (*entry_point)(uint64_t), uint64_t arg); //entry_point must not return + template <class obj_t> + 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 <class obj_t> + 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 <class obj_t> + 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 <class obj_t> + 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)()); //return value is number of bytes cleared @@ -133,4 +157,9 @@ namespace euler::syscall { std::optional<std::string> try_get_environment_variable( const std::string &name); + void set_thread_name(const std::string &name); + } + +#include <string> +#include <vector> 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 <std/list.hpp> 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 <std/unique_lock.hpp> +#include <std/mutex.hpp> 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 <std/fwd/allocator.hpp> + #include <euler/heap.hpp> 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 <class T> + 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 <std/fwd/allocator.hpp> + +namespace std { + template <class T, class Allocator = std::allocator<T>> + 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 <memory> + +namespace std { + + template <class T, class Allocator = std::allocator<T>> + class list { + + public: + struct node { + T value; + node *prev; + node *next; + }; + + template <class V> + 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<T>; + using const_iterator = generic_iterator<const T>; + + 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 <euler/syscall.hpp> + +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 <std/fwd/string.hpp> + #include <cstddef> #include <vector> @@ -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 Mutex> + 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 <std/fwd/vector.hpp> + #include <memory> namespace std { - template <class T, class Allocator = std::allocator<T>> + template <class T, class Allocator> 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 <cstdio> +#include <string> 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 <euler/stream.hpp> +#include <algorithm> #include <cstring> 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 <euler/syscall.hpp> +#include <string> +#include <vector> 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); + + } + } |