Update kernel

This commit is contained in:
EnderIce2
2024-01-19 06:47:42 +02:00
parent fd15592608
commit 96daa43d38
282 changed files with 25486 additions and 15700 deletions

View File

@ -53,14 +53,54 @@ namespace std
}
template <class InputIt, class T>
InputIt find(InputIt first, InputIt last, const T &value)
constexpr InputIt find(InputIt first, InputIt last, const T &value)
{
while (first != last)
{
for (; first != last; ++first)
if (*first == value)
return first;
++first;
}
return last;
}
template <class InputIt, class UnaryPredicate>
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first)
if (p(*first))
return first;
return last;
}
template <class InputIt, class UnaryPredicate>
constexpr InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate q)
{
for (; first != last; ++first)
if (!q(*first))
return first;
return last;
}
template <class ForwardIt, class T>
ForwardIt remove(ForwardIt first, ForwardIt last, const T &value)
{
first = std::find(first, last, value);
if (first != last)
for (ForwardIt i = first; ++i != last;)
if (!(*i == value))
*first++ = std::move(*i);
return first;
}
template <class ForwardIt, class UnaryPredicate>
ForwardIt remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
first = std::find_if(first, last, p);
if (first != last)
for (ForwardIt i = first; ++i != last;)
if (!p(*i))
*first++ = std::move(*i);
return first;
}
}

View File

@ -20,27 +20,24 @@
#include <debug.h>
#define assert(x) \
do \
{ \
if (!(x)) \
{ \
error("Assertion failed! [%s] [%s:%s:%d]", \
#x, __FILE__, __FUNCTION__, __LINE__); \
int3; \
while (true) \
; \
} \
#define assert(x) \
do \
{ \
if (__builtin_expect(!!(!(x)), 0)) \
{ \
error("Assertion failed! [%s]", #x); \
int3; \
__builtin_unreachable(); \
} \
} while (0)
#define assert_allow_continue(x) \
do \
{ \
if (!(x)) \
{ \
error("Assertion failed! [%s] [%s:%s:%d]", \
#x, __FILE__, __FUNCTION__, __LINE__); \
} \
#define assert_allow_continue(x) \
do \
{ \
if (__builtin_expect(!!(!(x)), 0)) \
{ \
error("Assertion failed! [%s]", #x); \
} \
} while (0)
#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)

View File

@ -68,12 +68,12 @@ namespace std
*/
enum class memory_order : int
{
relaxed,
consume,
acquire,
release,
acq_rel,
seq_cst
relaxed = __ATOMIC_RELAXED,
consume = __ATOMIC_CONSUME,
acquire = __ATOMIC_ACQUIRE,
release = __ATOMIC_RELEASE,
acq_rel = __ATOMIC_ACQ_REL,
seq_cst = __ATOMIC_SEQ_CST
};
/**
@ -172,7 +172,7 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable
*/
T load(memory_order order = memory_order::seq_cst) const
inline __always_inline T load(memory_order order = memory_order::seq_cst) const
{
return builtin_atomic_n(load)(&this->value,
static_cast<int>(order));
@ -181,7 +181,7 @@ namespace std
/**
* @copydoc load()
*/
T load(memory_order order = memory_order::seq_cst) const volatile
inline __always_inline T load(memory_order order = memory_order::seq_cst) const volatile
{
return builtin_atomic_n(load)(&this->value,
static_cast<int>(order));
@ -196,7 +196,7 @@ namespace std
* @param desired The value to store
* @param order Memory order constraint to use
*/
void store(T desired, memory_order order = memory_order::seq_cst)
inline __always_inline void store(T desired, memory_order order = memory_order::seq_cst)
{
builtin_atomic_n(store)(&this->value, desired,
static_cast<int>(order));
@ -205,8 +205,8 @@ namespace std
/**
* @copydoc store()
*/
void store(T desired,
memory_order order = memory_order::seq_cst) volatile
inline __always_inline void store(T desired,
memory_order order = memory_order::seq_cst) volatile
{
builtin_atomic_n(store)(&this->value, desired,
static_cast<int>(order));
@ -219,7 +219,7 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the exchange
*/
T exchange(T desired, memory_order order = memory_order::seq_cst)
inline __always_inline T exchange(T desired, memory_order order = memory_order::seq_cst)
{
return builtin_atomic_n(exchange)(&this->value, desired,
static_cast<int>(order));
@ -228,8 +228,8 @@ namespace std
/**
* @copydoc exchange()
*/
T exchange(T desired,
memory_order order = memory_order::seq_cst) volatile
inline __always_inline T exchange(T desired,
memory_order order = memory_order::seq_cst) volatile
{
return builtin_atomic_n(exchange)(&this->value, desired,
static_cast<int>(order));
@ -244,9 +244,9 @@ namespace std
* @param failure Memory order constraint to use if the exchange fails
* @return True if the exchange succeeded, false otherwise
*/
bool compare_exchange_weak(T &expected, T desired,
memory_order success,
memory_order failure)
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
memory_order success,
memory_order failure)
{
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
desired, false, success,
@ -256,9 +256,9 @@ namespace std
/**
* @copydoc compare_exchange_weak()
*/
bool compare_exchange_weak(T &expected, T desired,
memory_order success,
memory_order failure) volatile
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
memory_order success,
memory_order failure) volatile
{
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
desired, false, success,
@ -273,9 +273,9 @@ namespace std
* @param order Memory order constraint to use
* @return True if the exchange succeeded, false otherwise
*/
bool compare_exchange_weak(T &expected, T desired,
memory_order order =
memory_order_seq_cst)
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
desired, false, order,
@ -285,9 +285,9 @@ namespace std
/**
* @copydoc compare_exchange_weak()
*/
bool compare_exchange_weak(T &expected, T desired,
memory_order order =
memory_order_seq_cst) volatile
inline __always_inline bool compare_exchange_weak(T &expected, T desired,
memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(compare_exchange_weak)(&this->value, &expected,
desired, false, order,
@ -303,9 +303,9 @@ namespace std
* @param failure Memory order constraint to use if the exchange fails
* @return True if the exchange succeeded, false otherwise
*/
bool compare_exchange_strong(T &expected, T desired,
memory_order success,
memory_order failure)
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
memory_order success,
memory_order failure)
{
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
desired, true, success,
@ -315,9 +315,9 @@ namespace std
/**
* @copydoc compare_exchange_strong()
*/
bool compare_exchange_strong(T &expected, T desired,
memory_order success,
memory_order failure) volatile
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
memory_order success,
memory_order failure) volatile
{
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
desired, true, success,
@ -332,9 +332,9 @@ namespace std
* @param order Memory order constraint to use
* @return True if the exchange succeeded, false otherwise
*/
bool compare_exchange_strong(T &expected, T desired,
memory_order order =
memory_order_seq_cst)
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
desired, true, order,
@ -344,9 +344,9 @@ namespace std
/**
* @copydoc compare_exchange_strong()
*/
bool compare_exchange_strong(T &expected, T desired,
memory_order order =
memory_order_seq_cst) volatile
inline __always_inline bool compare_exchange_strong(T &expected, T desired,
memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(compare_exchange_strong)(&this->value, &expected,
desired, true, order,
@ -360,8 +360,8 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the addition
*/
T fetch_add(T arg, memory_order order =
memory_order_seq_cst)
inline __always_inline T fetch_add(T arg, memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(fetch_add)(&this->value, arg,
static_cast<int>(order));
@ -370,8 +370,8 @@ namespace std
/**
* @copydoc fetch_add()
*/
T fetch_add(T arg, memory_order order =
memory_order_seq_cst) volatile
inline __always_inline T fetch_add(T arg, memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(fetch_add)(&this->value, arg,
static_cast<int>(order));
@ -384,8 +384,8 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the subtraction
*/
T fetch_sub(T arg, memory_order order =
memory_order_seq_cst)
inline __always_inline T fetch_sub(T arg, memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(fetch_sub)(&this->value, arg,
static_cast<int>(order));
@ -394,8 +394,8 @@ namespace std
/**
* @copydoc fetch_sub()
*/
T fetch_sub(T arg, memory_order order =
memory_order_seq_cst) volatile
inline __always_inline T fetch_sub(T arg, memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(fetch_sub)(&this->value, arg,
static_cast<int>(order));
@ -408,8 +408,8 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the AND
*/
T fetch_and(T arg, memory_order order =
memory_order_seq_cst)
inline __always_inline T fetch_and(T arg, memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(fetch_and)(&this->value, arg,
static_cast<int>(order));
@ -418,8 +418,8 @@ namespace std
/**
* @copydoc fetch_and()
*/
T fetch_and(T arg, memory_order order =
memory_order_seq_cst) volatile
inline __always_inline T fetch_and(T arg, memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(fetch_and)(&this->value, arg,
static_cast<int>(order));
@ -432,8 +432,8 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the OR
*/
T fetch_or(T arg, memory_order order =
memory_order_seq_cst)
inline __always_inline T fetch_or(T arg, memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(fetch_or)(&this->value, arg,
static_cast<int>(order));
@ -442,8 +442,8 @@ namespace std
/**
* @copydoc fetch_or()
*/
T fetch_or(T arg, memory_order order =
memory_order_seq_cst) volatile
inline __always_inline T fetch_or(T arg, memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(fetch_or)(&this->value, arg,
static_cast<int>(order));
@ -456,8 +456,8 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the XOR
*/
T fetch_xor(T arg, memory_order order =
memory_order_seq_cst)
inline __always_inline T fetch_xor(T arg, memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(fetch_xor)(&this->value, arg,
static_cast<int>(order));
@ -466,8 +466,8 @@ namespace std
/**
* @copydoc fetch_xor()
*/
T fetch_xor(T arg, memory_order order =
memory_order_seq_cst) volatile
inline __always_inline T fetch_xor(T arg, memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(fetch_xor)(&this->value, arg,
static_cast<int>(order));
@ -480,8 +480,8 @@ namespace std
* @param order Memory order constraint to use
* @return The value of the atomic variable before the NAND
*/
T fetch_nand(T arg, memory_order order =
memory_order_seq_cst)
inline __always_inline T fetch_nand(T arg, memory_order order =
memory_order_seq_cst)
{
return builtin_atomic(fetch_nand)(&this->value, arg,
static_cast<int>(order));
@ -490,8 +490,8 @@ namespace std
/**
* @copydoc fetch_nand()
*/
T fetch_nand(T arg, memory_order order =
memory_order_seq_cst) volatile
inline __always_inline T fetch_nand(T arg, memory_order order =
memory_order_seq_cst) volatile
{
return builtin_atomic(fetch_nand)(&this->value, arg,
static_cast<int>(order));

19
include_std/cassert Normal file
View File

@ -0,0 +1,19 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <assert.h>

View File

@ -405,7 +405,17 @@
/** State not recoverable */
#define ENOTRECOVERABLE 131
extern int *__errno_location(void) __attribute__((const));
#include <types.h>
EXTERNC int *__errno_location(void) __attribute__((const));
#define errno (*__errno_location())
#ifdef __cplusplus
extern "C"
{
#endif
const char *strerror(int errnum);
#ifdef __cplusplus
}
#endif
#endif // !_ERRNO_H

View File

@ -19,12 +19,43 @@
namespace std
{
template <typename T>
struct equal_to
{
bool operator()(const T &lhs, const T &rhs) const
{
return lhs == rhs;
}
};
template <typename T>
struct equal_to
{
bool operator()(const T &lhs, const T &rhs) const
{
return lhs == rhs;
}
};
template <typename Key>
struct hash
{
size_t operator()(const Key &key) const
{
#if defined(a64)
static_assert(sizeof(uintptr_t) == sizeof(uint64_t));
const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull;
const uint64_t FNV_PRIME = 1099511628211ull;
#elif defined(a32)
static_assert(sizeof(uintptr_t) == sizeof(uint32_t));
const uint32_t FNV_OFFSET_BASIS = 2166136261u;
const uint32_t FNV_PRIME = 16777619u;
#else
#error "Unsupported architecture"
#endif
const uint8_t *data = reinterpret_cast<const uint8_t *>(&key);
const size_t size = sizeof(Key);
uintptr_t hash = FNV_OFFSET_BASIS;
for (size_t i = 0; i < size; ++i)
{
hash ^= static_cast<uintptr_t>(data[i]);
hash *= FNV_PRIME;
}
return static_cast<size_t>(hash);
}
};
}

View File

@ -18,6 +18,8 @@
#pragma once
#include <types.h>
#include <assert.h>
#include <lock.hpp>
namespace std
{
@ -25,75 +27,77 @@ namespace std
class list
{
private:
struct lNode
NewLock(lock);
struct node
{
T value;
lNode *prev;
lNode *next;
node *prev;
node *next;
lNode(const T &v, lNode *p = nullptr, lNode *n = nullptr)
node(const T &v, node *p = nullptr, node *n = nullptr)
: value(v), prev(p), next(n) {}
};
lNode *head;
lNode *tail;
size_t size;
node *head = nullptr;
node *tail = nullptr;
std::atomic_size_t lSize = 0;
public:
list() : head(nullptr), tail(nullptr), size(0) {}
list() {}
~list() { clear(); }
list(const list &other) : head(nullptr), tail(nullptr), size(0) { *this = other; }
list(const list &other) { *this = other; }
void push_back(const T &value)
{
lNode *new_node = new lNode(value, tail, nullptr);
SmartLock(this->lock);
node *nNode = new node(value, tail);
if (empty())
{
head = tail = new_node;
}
head = tail = nNode;
else
{
tail->next = new_node;
tail = new_node;
tail->next = nNode;
tail = nNode;
}
++size;
++lSize;
}
void pop_back()
{
SmartLock(this->lock);
if (unlikely(empty()))
{
assert(!"list is empty");
}
else if (head == tail)
{
delete tail;
head = tail = nullptr;
--size;
--lSize;
}
else
{
lNode *old_tail = tail;
node *oldTail = tail;
tail = tail->prev;
tail->next = nullptr;
delete old_tail;
--size;
delete oldTail;
--lSize;
}
}
void push_front(const T &value)
{
lNode *new_node = new lNode(value, nullptr, head);
SmartLock(this->lock);
node *nNode = new node(value, nullptr, head);
if (empty())
{
head = tail = new_node;
}
head = tail = nNode;
else
{
head->prev = new_node;
head = new_node;
head->prev = nNode;
head = nNode;
}
++size;
++lSize;
}
void pop_front()
@ -105,21 +109,84 @@ namespace std
if (head == tail)
{
SmartLock(this->lock);
delete head;
head = tail = nullptr;
--size;
--lSize;
}
else
{
lNode *old_head = head;
SmartLock(this->lock);
node *old_head = head;
head = head->next;
head->prev = nullptr;
delete old_head;
--size;
--lSize;
}
}
bool empty() const { return size == 0; }
template <class... Args>
void emplace_back(Args &&...args)
{
assert(sizeof...(args) > 0);
SmartLock(this->lock);
node *nNode = new node(T(std::forward<Args>(args)...), tail);
if (this->empty())
head = tail = nNode;
else
{
tail->next = nNode;
tail = nNode;
}
++lSize;
}
template <class... Args>
void emplace_front(Args &&...args)
{
assert(sizeof...(args) > 0);
SmartLock(this->lock);
node *nNode = new node(T(std::forward<Args>(args)...), nullptr, head);
if (this->empty())
head = tail = nNode;
else
{
head->prev = nNode;
head = nNode;
}
++lSize;
}
T &front()
{
SmartLock(this->lock);
return head->value;
}
const T &front() const
{
SmartLock(this->lock);
return head->value;
}
T &back()
{
SmartLock(this->lock);
return tail->value;
}
const T &back() const
{
SmartLock(this->lock);
return tail->value;
}
bool empty() const { return lSize.load() == 0; }
size_t size() const { return lSize; }
void clear()
{
@ -127,39 +194,179 @@ namespace std
pop_back();
}
list &operator=(const list &other)
void merge(list &other)
{
if (this != &other)
if (this == &other)
return;
while (other.empty() == false)
{
clear();
for (const T &value : other)
T &fr = other.front();
push_back(fr);
other.pop_front();
}
}
void remove(const T &value)
{
SmartLock(this->lock);
node *p = head;
while (p != nullptr)
{
if (p->value == value)
{
push_back(value);
if (p->prev)
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
if (p == head)
head = p->next;
if (p == tail)
tail = p->prev;
delete p;
--lSize;
return;
}
p = p->next;
}
}
template <class UnaryPredicate>
void remove_if(UnaryPredicate p)
{
SmartLock(this->lock);
node *n = head;
while (n != nullptr)
{
if (p(n->value))
{
if (n->prev)
n->prev->next = n->next;
if (n->next)
n->next->prev = n->prev;
if (n == head)
head = n->next;
if (n == tail)
tail = n->prev;
delete n;
--lSize;
return;
}
n = n->next;
}
}
void reverse()
{
if (empty())
return;
SmartLock(this->lock);
node *p = head;
while (p != nullptr)
{
node *tmp = p->next;
p->next = p->prev;
p->prev = tmp;
p = tmp;
}
node *tmp = head;
head = tail;
tail = tmp;
}
void sort()
{
if (empty())
return;
SmartLock(this->lock);
bool swapped = true;
while (swapped)
{
swapped = false;
node *p = head;
while (p->next != nullptr)
{
if (p->value > p->next->value)
{
T tmp = p->value;
p->value = p->next->value;
p->next->value = tmp;
swapped = true;
}
p = p->next;
}
}
}
template <class Compare>
void sort(Compare comp)
{
if (empty())
return;
SmartLock(this->lock);
bool swapped = true;
while (swapped)
{
swapped = false;
node *p = head;
while (p->next != nullptr)
{
if (comp(p->value, p->next->value))
{
T tmp = p->value;
p->value = p->next->value;
p->next->value = tmp;
swapped = true;
}
p = p->next;
}
}
}
/* Non-STL function */
T &operator[](size_t Index)
{
SmartLock(this->lock);
node *p = head;
for (size_t i = 0; i < Index; ++i)
p = p->next;
return p->value;
}
list &operator=(const list &other)
{
if (this == &other)
return *this;
for (const T &value : other)
push_back(value);
return *this;
}
class iterator
{
private:
lNode *node;
node *_node;
friend class list;
public:
iterator(lNode *p = nullptr) : node(p) {}
T &operator*() const { return node->value; }
T *operator->() const { return &node->value; }
iterator(node *p = nullptr) : _node(p) {}
T &operator*() const { return _node->value; }
T *operator->() const { return &_node->value; }
iterator &operator++()
{
node = node->next;
_node = _node->next;
return *this;
}
iterator &operator--()
{
node = node->prev;
_node = _node->prev;
return *this;
}
@ -177,12 +384,14 @@ namespace std
return tmp;
}
bool operator==(const iterator &rhs) const { return node == rhs.node; }
bool operator!=(const iterator &rhs) const { return node != rhs.node; }
bool operator==(const iterator &rhs) const { return _node == rhs._node; }
bool operator!=(const iterator &rhs) const { return _node != rhs._node; }
};
iterator begin() { return iterator(head); }
iterator end() { return iterator(nullptr); }
const iterator begin() const { return iterator(head); }
const iterator end() const { return iterator(nullptr); }
iterator insert(iterator pos, const T &value)
{
@ -198,24 +407,46 @@ namespace std
}
else
{
lNode *p = pos.node;
lNode *new_node = new lNode(value, p->prev, p);
p->prev->next = new_node;
p->prev = new_node;
++size;
return iterator(new_node);
SmartLock(this->lock);
node *p = pos.node;
node *nNode = new node(value, p->prev, p);
p->prev->next = nNode;
p->prev = nNode;
++lSize;
return iterator(nNode);
}
}
iterator erase(iterator pos)
{
lNode *p = pos.node;
iterator next(p->next);
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
--size;
return next;
if (pos == end())
return end();
else if (pos == begin())
{
pop_front();
return begin();
}
else
{
SmartLock(this->lock);
node *p = pos._node;
if (p->prev)
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
if (head == p)
head = p->next;
if (tail == p)
tail = p->prev;
iterator ret(p->next);
delete p;
--lSize;
return ret;
}
}
};
}

View File

@ -15,7 +15,4 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _SCHED_H
#define _SCHED_H
#endif // !_SCHED_H
#pragma once

View File

@ -1,50 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_STD_FUNCTIONAL_H__
#define __FENNIX_KERNEL_STD_FUNCTIONAL_H__
#include <types.h>
#include <assert.h>
namespace std
{
template <typename Key>
struct hash
{
size_t operator()(const Key &key) const
{
static_assert(sizeof(size_t) == sizeof(uint64_t)); // size_t and uint64_t must have the same size
const uint64_t fnv_offset_basis = 14695981039346656037ull;
const uint64_t fnv_prime = 1099511628211ull;
const uint8_t *data = reinterpret_cast<const uint8_t *>(&key);
const size_t size = sizeof(Key);
uint64_t ret = fnv_offset_basis;
for (size_t i = 0; i < size; ++i)
{
ret ^= static_cast<uint64_t>(data[i]);
ret *= fnv_prime;
}
return static_cast<size_t>(ret);
}
};
}
#endif // !__FENNIX_KERNEL_STD_FUNCTIONAL_H__

View File

@ -250,15 +250,6 @@ namespace std
}
};
template <typename T>
using remove_reference_t = typename remove_reference<T>::type;
template <typename T>
T &&forward(remove_reference_t<T> &t) { return static_cast<T &&>(t); };
template <typename T>
T &&forward(remove_reference_t<T> &&t) { return static_cast<T &&>(t); };
template <typename T, typename... Args>
shared_ptr<T> make_shared(Args &&...args)
{

View File

@ -1,131 +0,0 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_STD_UNORDERED_MAP_H__
#define __FENNIX_KERNEL_STD_UNORDERED_MAP_H__
#include <types.h>
#include <std/functional.hpp>
#include <std/utility.hpp>
#include <vector>
#include <list>
namespace std
{
template <typename key_type, typename value_type>
class unordered_map
{
public:
typedef std::pair<key_type, value_type> key_value_pair;
typedef std::list<key_value_pair> bucket;
typedef typename std::vector<bucket>::iterator iterator;
typedef typename std::vector<bucket>::const_iterator const_iterator;
private:
static const size_t DEFAULT_NUM_BUCKETS = 10;
std::vector<bucket> bkts;
size_t hash(const key_type &key) const
{
std::hash<key_type> hash_function;
return hash_function(key) % this->bkts.size();
}
public:
unordered_map() : bkts(DEFAULT_NUM_BUCKETS) {}
unordered_map(size_t num_buckets) : bkts(num_buckets) {}
void insert(const key_value_pair &pair)
{
size_t bucket_index = hash(pair.first);
bucket &bkt = this->bkts[bucket_index];
for (auto it = bkt.begin(); it != bkt.end(); ++it)
{
if (it->first == pair.first)
{
it->second = pair.second;
return;
}
}
bkt.push_back(pair);
}
bool contains(const key_type &key) const
{
size_t bucket_index = hash(key);
const bucket &bkt = this->bkts[bucket_index];
for (auto it = bkt.begin(); it != bkt.end(); ++it)
{
if (it->first == key)
{
return true;
}
}
return false;
}
iterator find(const key_type &k)
{
size_t bucket_index = hash(k);
bucket &bkt = this->bkts[bucket_index];
for (auto it = bkt.begin(); it != bkt.end(); ++it)
{
if (it->first == k)
return it;
}
return bkt.end();
}
const_iterator find(const key_type &k) const
{
size_t bucket_index = hash(k);
const bucket &bkt = this->bkts[bucket_index];
for (auto it = bkt.begin(); it != bkt.end(); ++it)
{
if (it->first == k)
return it;
}
return bkt.end();
}
iterator end() { return this->bkts.end(); }
size_t size() const
{
size_t count = 0;
foreach (const auto &bkt in this->bkts)
count += bkt.size();
return count;
}
value_type &operator[](const key_type &key)
{
size_t bucket_index = hash(key);
bucket &bkt = this->bkts[bucket_index];
for (auto it = bkt.begin(); it != bkt.end(); ++it)
{
if (it->first == key)
return it->second;
}
bkt.emplace_back(key, value_type());
return bkt.back().second;
}
};
}
#endif // !__FENNIX_KERNEL_STD_UNORDERED_MAP_H__

88
include_std/stdatomic.h Normal file
View File

@ -0,0 +1,88 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
typedef enum
{
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST
} memory_order;
#define atomic_store_explicit(object, desired, order) \
__atomic_store_n(object, desired, order)
#define atomic_store(object, desired) \
__atomic_store_n(object, desired, __ATOMIC_SEQ_CST)
#define atomic_load_explicit(object, order) \
__atomic_load_n(object, order)
#define atomic_load(object) \
__atomic_load_n(object, __ATOMIC_SEQ_CST)
#define atomic_exchange_explicit(object, desired, order) \
__atomic_exchange_n(object, desired, order)
#define atomic_exchange(object, desired) \
__atomic_exchange_n(object, desired, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
__atomic_compare_exchange_n(object, expected, desired, 0, success, failure)
#define atomic_compare_exchange_strong(object, expected, desired) \
__atomic_compare_exchange_n(object, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
__atomic_compare_exchange_n(object, expected, desired, 1, success, failure)
#define atomic_compare_exchange_weak(object, expected, desired) \
__atomic_compare_exchange_n(object, expected, desired, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_fetch_add(object, operand) \
__atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_add_explicit(object, operand, order) \
__atomic_fetch_add(object, operand, order)
#define atomic_fetch_sub(object, operand) \
__atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_sub_explicit(object, operand, order) \
__atomic_fetch_sub(object, operand, order)
#define atomic_fetch_or(object, operand) \
__atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_or_explicit(object, operand, order) \
__atomic_fetch_or(object, operand, order)
#define atomic_fetch_xor(object, operand) \
__atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_xor_explicit(object, operand, order) \
__atomic_fetch_xor(object, operand, order)
#define atomic_fetch_and(object, operand) \
__atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_and_explicit(object, operand, order) \
__atomic_fetch_and(object, operand, order)

View File

@ -113,14 +113,14 @@ namespace std
delete[] this->Data, this->Data = nullptr;
}
size_t length() const
size_t length()
{
v_strdbg("%#lx: String length: %d",
this, this->Length);
return this->Length;
}
size_t capacity() const
size_t capacity()
{
v_strdbg("%#lx: String capacity: %d",
this, this->Capacity);
@ -174,14 +174,14 @@ namespace std
this, this->Data, this->Data, this->Length, this->Capacity);
}
bool empty() const
bool empty()
{
strdbg("%#lx: String empty: %d",
this, this->Length == 0);
return this->Length == 0;
}
size_t size() const
size_t size()
{
strdbg("%#lx: String size: %d",
this, this->Length);
@ -530,7 +530,7 @@ namespace std
return *this;
}
/* warning: implicitly-declared constexpr String::String(const String&) is deprecated [-Wdeprecated-copy] */
/* warning: implicitly-declared 'constexpr String::String(const String&)' is deprecated [-Wdeprecated-copy] */
string &operator=(const string &Other) = default;
// string &operator=(const string &Other)

View File

@ -18,4 +18,6 @@
#ifndef _STRING_H
#define _STRING_H
#include <convert.h>
#endif // !_STRING_H

45
include_std/sys/mman.h Normal file
View File

@ -0,0 +1,45 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <types.h>
/* stubs */
#ifndef MAP_PRIVATE
#define MAP_PRIVATE 0x0
#endif
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS 0x0
#endif
#ifndef PROT_READ
#define PROT_READ 0x0
#endif
#ifndef PROT_WRITE
#define PROT_WRITE 0x0
#endif
#ifndef MAP_FAILED
#define MAP_FAILED 0x0
#endif
#ifndef POSIX_MADV_DONTNEED
#define POSIX_MADV_DONTNEED 0x0
#endif

View File

@ -15,7 +15,15 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef _SYS_TIME_H
#define _SYS_TIME_H
#ifndef _TIME_H
#define _TIME_H
#endif // !_SYS_TIME_H
#include <types.h>
struct timespec
{
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#endif // !_TIME_H

View File

@ -18,4 +18,9 @@
#ifndef _UNISTD_H
#define _UNISTD_H
#include <types.h>
#define _SC_PAGESIZE 30
#define _SC_PAGE_SIZE _SC_PAGESIZE
#endif // !_UNISTD_H

282
include_std/unordered_map Normal file
View File

@ -0,0 +1,282 @@
/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <lock.hpp>
#include <utility>
#include <vector>
#include <list>
#define DEBUG_UMAP_MESSAGES 1
#ifdef DEBUG_UMAP_MESSAGES
#define umDebug(m, ...) debug("%#lx: " m, this, ##__VA_ARGS__)
#else
#define umDebug(m, ...)
#endif
namespace std
{
template <typename Key, typename T>
class unordered_map
{
public:
typedef std::pair<Key, T> pair_t;
typedef std::list<pair_t> bucket_t;
private:
NewLock(lock);
std::vector<bucket_t> Buckets;
size_t hash(const Key &key) const
{
size_t ret = std::hash<Key>()(key) % this->Buckets.size();
// debug("Hashed %#lx to %d", key, ret);
return ret;
}
public:
unordered_map()
: Buckets(16)
{
umDebug("Created unordered_map with 16 buckets (default)");
}
unordered_map(size_t num)
: Buckets(num)
{
umDebug("Created unordered_map with %d buckets", num);
}
~unordered_map()
{
umDebug("Destroyed unordered_map");
}
void insert(const pair_t &p)
{
SmartLock(this->lock);
size_t bucketIndex = hash(p.first) % Buckets.size();
auto &bucket = Buckets[bucketIndex];
for (auto &element : bucket)
{
if (element.first == p.first)
{
element.second = p.second;
return;
}
}
bucket.push_back(p);
}
void erase(const Key &key)
{
SmartLock(this->lock);
size_t bucketIndex = hash(key) % Buckets.size();
auto &bucket = Buckets[bucketIndex];
bucket.remove_if([key](const pair_t &element)
{ return element.first == key; });
}
void clear()
{
SmartLock(this->lock);
for (auto &bucket : Buckets)
{
bucket.clear();
}
}
bool contains(const Key &key)
{
SmartLock(this->lock);
size_t bucketIndex = hash(key) % Buckets.size();
const auto &bucket = Buckets[bucketIndex];
for (const auto &element : bucket)
{
if (element.first == key)
return true;
}
return false;
}
size_t size()
{
SmartLock(this->lock);
size_t count = 0;
for (const auto &bucket : Buckets)
{
count += bucket.size();
}
return count;
}
bool empty() { return size() == 0; }
T &operator[](const Key &key)
{
SmartLock(this->lock);
size_t bucketIndex = hash(key) % Buckets.size();
auto &bucket = Buckets[bucketIndex];
for (auto &element : bucket)
{
if (element.first == key)
return element.second;
}
bucket.emplace_back(key, T{});
return bucket.back().second;
}
class iterator
{
private:
using BucketIterator = typename std::list<pair_t>::iterator;
size_t bucketIndex;
BucketIterator bucketIterator;
std::vector<std::list<pair_t>> *buckets;
public:
size_t GetBucketIndex() const { return bucketIndex; }
BucketIterator &GetBucketIterator() const { return bucketIterator; }
iterator(size_t index,
BucketIterator it,
std::vector<std::list<pair_t>> *buckets)
: bucketIndex(index),
bucketIterator(it),
buckets(buckets) {}
iterator &operator++()
{
++bucketIterator;
while (bucketIndex < buckets->size() &&
bucketIterator == (*buckets)[bucketIndex].end())
{
++bucketIndex;
if (bucketIndex < buckets->size())
{
bucketIterator = (*buckets)[bucketIndex].begin();
}
}
return *this;
}
bool operator!=(const iterator &other) const
{
return bucketIndex != other.bucketIndex ||
bucketIterator != other.bucketIterator;
}
pair_t &operator*()
{
return *bucketIterator;
}
pair_t *operator->()
{
return &(*bucketIterator);
}
operator bool() const
{
return bucketIndex < buckets->size();
}
};
iterator find(const Key &key)
{
SmartLock(this->lock);
size_t bucketIndex = hash(key) % Buckets.size();
auto &bucket = Buckets[bucketIndex];
auto it = std::find_if(bucket.begin(), bucket.end(),
[key](const pair_t &element)
{ return element.first == key; });
if (it != bucket.end())
{
return iterator(bucketIndex,
it,
&Buckets);
}
return end();
}
iterator begin()
{
SmartLock(this->lock);
for (size_t i = 0; i < Buckets.size(); ++i)
{
if (!Buckets[i].empty())
{
return iterator(i,
Buckets[i].begin(),
&Buckets);
}
}
return end();
}
iterator end()
{
return iterator(Buckets.size(),
Buckets.back().end(),
&Buckets);
}
iterator insert(iterator pos, const pair_t &p)
{
SmartLock(this->lock);
size_t bucketIndex = hash(p.first) % Buckets.size();
auto &bucket = Buckets[bucketIndex];
auto itr = std::find_if(bucket.begin(), bucket.end(),
[p](const pair_t &element)
{ return element.first == p.first; });
if (itr != bucket.end())
return end();
return iterator(bucketIndex,
bucket.insert(pos.bucketIterator, p),
&Buckets);
}
iterator erase(iterator pos)
{
SmartLock(this->lock);
size_t bucketIndex = pos.GetBucketIndex();
auto &bucket = Buckets[bucketIndex];
return iterator(bucketIndex,
bucket.erase(pos.GetBucketIterator()),
&Buckets);
}
};
}

View File

@ -26,4 +26,29 @@ namespace std
{
return static_cast<typename std::remove_reference<T>::type &&>(arg);
}
template <typename T1, typename T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1 &x, const T2 &y) : first(x), second(y) {}
};
template <typename T1, typename T2>
pair<T1, T2> make_pair(T1 x, T2 y)
{
return pair<T1, T2>(x, y);
}
template <class T>
T &&forward(typename std::remove_reference<T>::type &arg)
{
return static_cast<T &&>(arg);
}
}

View File

@ -15,25 +15,20 @@
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_STD_UTILITY_H__
#define __FENNIX_KERNEL_STD_UTILITY_H__
#ifndef __FENNIX_KERNEL_UTSNAME_H__
#define __FENNIX_KERNEL_UTSNAME_H__
#include <types.h>
namespace std
#define _UTSNAME_LENGTH 65
struct utsname
{
template <typename T1, typename T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
char sysname[_UTSNAME_LENGTH];
char nodename[_UTSNAME_LENGTH];
char release[_UTSNAME_LENGTH];
char version[_UTSNAME_LENGTH];
char machine[_UTSNAME_LENGTH];
};
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1 &x, const T2 &y) : first(x), second(y) {}
};
}
#endif // !__FENNIX_KERNEL_STD_UTILITY_H__
#endif // !__FENNIX_KERNEL_UTSNAME_H__

View File

@ -23,13 +23,14 @@
#include <functional>
#include <algorithm>
#include <assert.h>
#include <lock.hpp>
#include <cstring>
#include <utility>
// #define DEBUG_VECTOR_MESSAGES 1
#ifdef DEBUG_VECTOR_MESSAGES
#define vDebug(m, ...) debug(m, ##__VA_ARGS__)
#define vDebug(m, ...) debug("%#lx: " m, this, ##__VA_ARGS__)
#else
#define vDebug(m, ...)
#endif
@ -40,22 +41,23 @@ namespace std
class vector
{
private:
size_t VectorSize = 0;
size_t VectorCapacity = 0;
NewLock(lock);
std::atomic_size_t VectorSize = 0;
std::atomic_size_t VectorCapacity = 0;
T *VectorBuffer = nullptr;
public:
typedef T *iterator;
typedef const T *const_iterator;
vector() { vDebug("%#lx: ( empty init )", this); }
vector() { vDebug("( empty init )"); }
vector(size_t Size)
: VectorSize(Size),
VectorCapacity(Size),
VectorBuffer(new T[Size])
{
vDebug("%#lx: ( init w/size: %lld )", this, Size);
vDebug("( init w/size: %lld )", Size);
}
vector(size_t Size, const T &Initial)
@ -63,34 +65,40 @@ namespace std
VectorCapacity(Size),
VectorBuffer(new T[Size])
{
vDebug("%#lx: ( init w/size: %lld, initial vector: %llx )", this,
vDebug("( init w/size: %lld, initial vector: %llx )",
Size, Initial);
assert(Size > 0);
SmartLock(this->lock);
for (size_t i = 0; i < Size; i++)
VectorBuffer[i] = Initial;
}
vector(const vector<T> &v)
: VectorSize(v.VectorSize),
VectorCapacity(v.VectorCapacity),
: VectorSize(v.VectorSize.load()),
VectorCapacity(v.VectorCapacity.load()),
VectorBuffer(nullptr)
{
vDebug("%#lx: ( vector copy: %#lx )", this, &v);
vDebug("( vector copy: %#lx )", &v);
if (!v.VectorBuffer || VectorSize <= 0)
if (!v.VectorBuffer || VectorSize.load() <= 0)
return;
VectorBuffer = new T[VectorSize];
std::copy(v.VectorBuffer, v.VectorBuffer + VectorSize, VectorBuffer);
SmartLock(this->lock);
VectorBuffer = new T[VectorSize.load()];
std::copy(v.VectorBuffer, v.VectorBuffer + VectorSize.load(), VectorBuffer);
}
~vector()
{
vDebug("%#lx: ( deinit )", this);
vDebug("( deinit )");
VectorSize.store(0);
VectorCapacity.store(0);
SmartLock(this->lock);
VectorSize = 0;
VectorCapacity = 0;
if (VectorBuffer != nullptr)
{
delete[] VectorBuffer;
@ -100,8 +108,8 @@ namespace std
void erase(iterator Position)
{
vDebug("%#lx: Erasing element at position %lld (v. size: %lld)", this,
Position - this->VectorBuffer, this->VectorSize);
vDebug("Erasing element at position %lld (v. size: %lld)",
Position - this->VectorBuffer, this->VectorSize.load());
if (Position == this->end())
{
@ -112,24 +120,25 @@ namespace std
assert(Position <= this->end());
assert(Position >= this->VectorBuffer);
assert(Position < this->VectorBuffer + this->VectorSize);
assert(Position < this->VectorBuffer + this->VectorSize.load());
SmartLock(this->lock);
size_t index = Position - this->VectorBuffer;
if (std::is_trivially_copyable<T>::value)
{
this->VectorBuffer[index] = T();
vDebug("%#lx: %#lx is trivially copyable", this,
vDebug("%#lx is trivially copyable",
&this->VectorBuffer[index]);
}
else
{
this->VectorBuffer[index].~T();
vDebug("%#lx: %#lx is not trivially copyable", this,
vDebug("%#lx is not trivially copyable",
&this->VectorBuffer[index]);
}
for (size_t i = index; i < this->VectorSize - 1; ++i)
for (size_t i = index; i < this->VectorSize.load() - 1; ++i)
{
this->VectorBuffer[i] = std::move(this->VectorBuffer[i + 1]);
}
@ -138,7 +147,9 @@ namespace std
T &next(size_t Position)
{
if (Position + 1 < this->VectorSize)
SmartLock(this->lock);
if (Position + 1 < this->VectorSize.load())
return this->VectorBuffer[Position + 1];
warn("%#lx: next( %lld ) is null (requested by %#lx)", this,
@ -149,6 +160,8 @@ namespace std
T &prev(size_t Position)
{
SmartLock(this->lock);
if (Position > 0)
return this->VectorBuffer[Position - 1];
@ -160,11 +173,13 @@ namespace std
T &next(const T &Value)
{
for (size_t i = 0; i < this->VectorSize; i++)
SmartLock(this->lock);
for (size_t i = 0; i < this->VectorSize.load(); i++)
{
if (std::equal_to<T>()(this->VectorBuffer[i], Value))
{
if (i + 1 < this->VectorSize)
if (i + 1 < this->VectorSize.load())
return this->VectorBuffer[i + 1];
else
break;
@ -179,7 +194,9 @@ namespace std
T &prev(const T &Value)
{
for (size_t i = 0; i < this->VectorSize; i++)
SmartLock(this->lock);
for (size_t i = 0; i < this->VectorSize.load(); i++)
{
if (std::equal_to<T>()(this->VectorBuffer[i], Value))
{
@ -198,25 +215,44 @@ namespace std
void push_back(const T &Value)
{
vDebug("%#lx: push_back( %#lx )", this, Value);
vDebug("push_back( %#lx )", Value);
if (this->VectorSize >= this->VectorCapacity)
if (this->VectorSize.load() >= this->VectorCapacity.load())
{
size_t newCapacity = this->VectorCapacity == 0
size_t newCapacity = this->VectorCapacity.load() == 0
? 1
: this->VectorCapacity * 2;
: this->VectorCapacity.load() * 2;
reserve(newCapacity);
}
SmartLock(this->lock);
this->VectorBuffer[this->VectorSize++] = Value;
}
template <class... Args>
void emplace_back(Args &&...args)
{
vDebug("emplace_back( %#lx )", args...);
if (this->VectorSize.load() >= this->VectorCapacity.load())
{
size_t newCapacity = this->VectorCapacity.load() == 0
? 1
: this->VectorCapacity.load() * 2;
reserve(newCapacity);
}
SmartLock(this->lock);
this->VectorBuffer[this->VectorSize++] = T(std::forward<Args>(args)...);
}
void reverse()
{
if (this->VectorSize <= 1)
if (this->VectorSize.load() <= 1)
return;
for (size_t i = 0, j = this->VectorSize - 1; i < j; i++, j--)
SmartLock(this->lock);
for (size_t i = 0, j = this->VectorSize.load() - 1; i < j; i++, j--)
{
T &elem1 = this->VectorBuffer[i];
T &elem2 = this->VectorBuffer[j];
@ -226,31 +262,35 @@ namespace std
void reserve(size_t Capacity)
{
assert(!(Capacity <= VectorCapacity));
assert(!(Capacity <= VectorCapacity.load()));
SmartLock(this->lock);
T *NewBuffer = new T[Capacity];
size_t Size = std::min(Capacity, this->VectorSize);
size_t Size = std::min(Capacity, this->VectorSize.load());
for (size_t i = 0; i < Size; i++)
NewBuffer[i] = std::move(this->VectorBuffer[i]);
vDebug("%#lx: reserve( %lld )->Buffer:~%#lx", this,
vDebug("reserve( %lld )->Buffer:~%#lx",
Capacity, this->VectorBuffer);
delete[] this->VectorBuffer;
this->VectorBuffer = NewBuffer;
this->VectorCapacity = Capacity;
this->VectorCapacity.store(Capacity);
}
void resize(size_t Size)
{
reserve(Size);
this->VectorSize = Size;
this->VectorSize.store(Size);
}
void clear()
{
this->VectorCapacity = 0;
this->VectorSize = 0;
this->VectorCapacity.store(0);
this->VectorSize.store(0);
SmartLock(this->lock);
if (VectorBuffer != nullptr)
{
delete[] this->VectorBuffer;
@ -260,7 +300,8 @@ namespace std
T &operator[](size_t Index)
{
if (Index >= this->VectorSize || !this->VectorBuffer)
SmartLock(this->lock);
if (Index >= this->VectorSize.load() || !this->VectorBuffer)
{
warn("%#lx: operator[]( %lld ) is null (requested by %#lx)", this,
Index, __builtin_return_address(0));
@ -273,33 +314,71 @@ namespace std
vector<T> &operator=(const vector<T> &v)
{
SmartLock(this->lock);
if (this == &v)
return *this;
delete[] this->VectorBuffer;
this->VectorSize = v.VectorSize;
this->VectorCapacity = v.VectorCapacity;
this->VectorSize.store(v.VectorSize.load());
this->VectorCapacity.store(v.VectorCapacity.load());
vDebug("%#lx: operator=( <vector> )->Size:%lld", this,
this->VectorSize);
vDebug("operator=( <vector> )->Size:%lld",
this->VectorSize.load());
this->VectorBuffer = new T[this->VectorSize];
for (size_t i = 0; i < this->VectorSize; i++)
this->VectorBuffer = new T[this->VectorSize.load()];
for (size_t i = 0; i < this->VectorSize.load(); i++)
this->VectorBuffer[i] = v.VectorBuffer[i];
return *this;
}
void pop_back() { this->VectorSize--; }
T &front() { return this->VectorBuffer[0]; }
T &back() { return this->VectorBuffer[this->VectorSize - 1]; }
T *data() { return this->VectorBuffer; }
bool empty() const { return this->VectorSize == 0; }
size_t capacity() const { return this->VectorCapacity; }
size_t size() const { return this->VectorSize; }
iterator begin() { return this->VectorBuffer; }
iterator end() { return this->VectorBuffer + size(); }
const_iterator begin() const { return this->VectorBuffer; }
const_iterator end() const { return this->VectorBuffer + size(); }
T &front()
{
SmartLock(this->lock);
return this->VectorBuffer[0];
}
T &back()
{
SmartLock(this->lock);
return this->VectorBuffer[this->VectorSize.load() - 1];
}
T *data()
{
SmartLock(this->lock);
return this->VectorBuffer;
}
bool empty() const { return this->VectorSize.load() == 0; }
size_t capacity() const { return this->VectorCapacity.load(); }
size_t size() const { return this->VectorSize.load(); }
iterator begin()
{
SmartLock(this->lock);
return this->VectorBuffer;
}
iterator end()
{
SmartLock(this->lock);
return this->VectorBuffer + size();
}
const_iterator begin() const
{
SmartLock(this->lock);
return this->VectorBuffer;
}
const_iterator end() const
{
SmartLock(this->lock);
return this->VectorBuffer + size();
}
};
}