summaryrefslogtreecommitdiff
path: root/euler/include
diff options
context:
space:
mode:
Diffstat (limited to 'euler/include')
-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
12 files changed, 315 insertions, 7 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: