summaryrefslogtreecommitdiff
path: root/euler
diff options
context:
space:
mode:
Diffstat (limited to 'euler')
-rw-r--r--euler/include/euler/syscall.hpp33
-rw-r--r--euler/include/list3
-rw-r--r--euler/include/mutex4
-rw-r--r--euler/include/std/allocator.hpp2
-rw-r--r--euler/include/std/fwd/allocator.hpp6
-rw-r--r--euler/include/std/fwd/string.hpp5
-rw-r--r--euler/include/std/fwd/vector.hpp8
-rw-r--r--euler/include/std/list.hpp157
-rw-r--r--euler/include/std/mutex.hpp40
-rw-r--r--euler/include/std/string.hpp7
-rw-r--r--euler/include/std/unique_lock.hpp53
-rw-r--r--euler/include/std/vector.hpp4
-rw-r--r--euler/source/entry.cpp2
-rw-r--r--euler/source/std/cstdio.cpp1
-rw-r--r--euler/source/std/string.cpp6
-rw-r--r--euler/source/stream.cpp1
-rw-r--r--euler/source/syscall.cpp13
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);
+
+ }
+
}