Implemented more STL and page allocation for malloc.

This commit is contained in:
Patrick 2024-01-27 15:24:50 +01:00
parent edd9ee85c7
commit 193e3a19dc
13 changed files with 701 additions and 28 deletions

9
bastl/include/cfloat Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#if !defined(BAD_APPLE_OS_CFLOAT_INCLUDED)
#define BAD_APPLE_OS_CFLOAT_INCLUDED
#include <float.h>
#endif // !defined(BAD_APPLE_OS_CFLOAT_INCLUDED)

21
bastl/include/climits Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#if !defined(BAD_APPLE_OS_CLIMITS_INCLUDED)
#define BAD_APPLE_OS_CLIMITS_INCLUDED
#include <limits.h>
#if !defined(LLONG_MIN)
#define LLONG_MIN (-LLONG_MAX - 1LL)
#endif
#if !defined(LLONG_MAX)
#define LLONG_MAX __LONG_LONG_MAX__
#endif
#if !defined(ULLONG_MAX)
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
#endif
#endif // !defined(BAD_APPLE_OS_CLIMITS_INCLUDED)

9
bastl/include/cmath Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#if !defined(BAD_APPLE_OS_CMATH_INCLUDED)
#define BAD_APPLE_OS_CMATH_INCLUDED
#include <math.h>
#endif // !defined(BAD_APPLE_OS_CMATH_INCLUDED)

477
bastl/include/limits Normal file
View File

@ -0,0 +1,477 @@
#pragma once
#if !defined(BAD_APPLE_OS_LIMITS_INCLUDED)
#define BAD_APPLE_OS_LIMITS_INCLUDED
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdint>
namespace std
{
namespace detail
{
inline constexpr double LOG10_2 = 0.3010299956639812;
}
enum float_round_style
{
round_indeterminate = -1,
round_toward_zero = 0,
round_to_nearest = 1,
round_toward_infinity = 2,
round_toward_neg_infinity = 3
};
template<typename T>
class numeric_limits
{
public:
static constexpr bool is_specialized = false;
static constexpr bool is_signed = false;
static constexpr bool is_integer = false;
static constexpr bool is_exact = false;
static constexpr bool has_infinity = false;
static constexpr bool has_quiet_NaN = false;
static constexpr bool has_signaling_NaN = false;
static constexpr float_round_style round_style = round_toward_zero;
static constexpr bool is_iec559 = false;
static constexpr bool is_bounded = false;
static constexpr bool is_modulo = false;
static constexpr int digits = 0;
static constexpr int digits10 = 0;
static constexpr int max_digits10 = 0;
static constexpr int radix = 0;
static constexpr int min_exponent = 0;
static constexpr int min_exponent10 = 0;
static constexpr int max_exponent = 0;
static constexpr int max_exponent10 = 0;
static constexpr bool traps = false;
static constexpr bool tinyness_before = false;
static constexpr T min() noexcept { return T(); }
static constexpr T lowest() noexcept { return T(); }
static constexpr T max() noexcept { return T(); }
static constexpr T epsilon() noexcept { return T(); }
static constexpr T round_error() noexcept { return T(); }
static constexpr T infinity() noexcept { return T(); }
static constexpr T quiet_NaN() noexcept { return T(); }
static constexpr T signaling_NaN() noexcept { return T(); }
static constexpr T denorm_min() noexcept { return T(); }
};
template<>
class numeric_limits<bool>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr int digits = 1;
static constexpr int radix = 2;
static constexpr bool min() noexcept { return false; }
static constexpr bool lowest() noexcept { return false; }
static constexpr bool max() noexcept { return true; }
};
template<>
class numeric_limits<char>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = (CHAR_MIN < 0);
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = (CHAR_BIT - is_signed);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr char min() noexcept { return CHAR_MIN; }
static constexpr char lowest() noexcept { return CHAR_MIN; }
static constexpr char max() noexcept { return CHAR_MAX; }
};
template<>
class numeric_limits<signed char>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = (CHAR_BIT - 1);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr signed char min() noexcept { return SCHAR_MIN; }
static constexpr signed char lowest() noexcept { return SCHAR_MIN; }
static constexpr signed char max() noexcept { return SCHAR_MAX; }
};
template<>
class numeric_limits<unsigned char>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr unsigned char min() noexcept { return 0; }
static constexpr unsigned char lowest() noexcept { return 0; }
static constexpr unsigned char max() noexcept { return UCHAR_MAX; }
};
template<>
class numeric_limits<wchar_t>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = (WCHAR_MIN < 0);
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(wchar_t) - is_signed;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr wchar_t min() noexcept { return WCHAR_MIN; }
static constexpr wchar_t lowest() noexcept { return WCHAR_MIN; }
static constexpr wchar_t max() noexcept { return WCHAR_MAX; }
};
template<>
class numeric_limits<char8_t>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr char8_t min() noexcept { return 0; }
static constexpr char8_t lowest() noexcept { return 0; }
static constexpr char8_t max() noexcept { return UCHAR_MAX; }
};
template<>
class numeric_limits<char16_t>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(char16_t);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr char16_t min() noexcept { return 0; }
static constexpr char16_t lowest() noexcept { return 0; }
static constexpr char16_t max() noexcept { return UINT_LEAST16_MAX; }
};
template<>
class numeric_limits<char32_t>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(char32_t);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr char32_t min() noexcept { return 0; }
static constexpr char32_t lowest() noexcept { return 0; }
static constexpr char32_t max() noexcept { return UINT_LEAST32_MAX; }
};
template<>
class numeric_limits<short>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(short) - 1;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr short min() noexcept { return SHRT_MIN; }
static constexpr short lowest() noexcept { return SHRT_MIN; }
static constexpr short max() noexcept { return SHRT_MAX; }
};
template<>
class numeric_limits<unsigned short>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(short);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr unsigned short min() noexcept { return 0; }
static constexpr unsigned short lowest() noexcept { return 0; }
static constexpr unsigned short max() noexcept { return USHRT_MAX; }
};
template<>
class numeric_limits<int>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(int) - 1;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr int min() noexcept { return INT_MIN; }
static constexpr int lowest() noexcept { return INT_MIN; }
static constexpr int max() noexcept { return INT_MAX; }
};
template<>
class numeric_limits<unsigned int>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(int);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr unsigned int min() noexcept { return 0; }
static constexpr unsigned int lowest() noexcept { return 0; }
static constexpr unsigned int max() noexcept { return UINT_MAX; }
};
template<>
class numeric_limits<long>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(long) - 1;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr long min() noexcept { return LONG_MIN; }
static constexpr long lowest() noexcept { return LONG_MIN; }
static constexpr long max() noexcept { return LONG_MAX; }
};
template<>
class numeric_limits<unsigned long>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(long);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr unsigned long min() noexcept { return 0; }
static constexpr unsigned long lowest() noexcept { return 0; }
static constexpr unsigned long max() noexcept { return ULONG_MAX; }
};
template<>
class numeric_limits<long long>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(long long) - 1;
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr long long min() noexcept { return LLONG_MIN; }
static constexpr long long lowest() noexcept { return LLONG_MIN; }
static constexpr long long max() noexcept { return LLONG_MAX; }
};
template<>
class numeric_limits<unsigned long long>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = false;
static constexpr bool is_integer = true;
static constexpr bool is_exact = true;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = true;
static constexpr int digits = CHAR_BIT * sizeof(long long);
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
static constexpr int radix = 2;
static constexpr bool traps = true;
static constexpr unsigned long long min() noexcept { return 0; }
static constexpr unsigned long long lowest() noexcept { return 0; }
static constexpr unsigned long long max() noexcept { return ULLONG_MAX; }
};
template<>
class numeric_limits<float>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool has_infinity = true;
static constexpr bool has_quiet_NaN = true;
static constexpr bool has_signaling_NaN = true;
static constexpr float_round_style round_style = round_to_nearest;
static constexpr bool is_iec559 = true;
static constexpr bool is_bounded = true;
static constexpr int digits = FLT_MANT_DIG;
static constexpr int digits10 = FLT_DIG;
static constexpr int max_digits10 = FLT_DECIMAL_DIG;
static constexpr int radix = FLT_RADIX;
static constexpr int min_exponent = FLT_MIN_EXP;
static constexpr int min_exponent10 = FLT_MIN_10_EXP;
static constexpr int max_exponent = FLT_MAX_EXP;
static constexpr int max_exponent10 = FLT_MAX_10_EXP;
static constexpr float min() noexcept { return FLT_MIN; }
static constexpr float lowest() noexcept { return -FLT_MAX; }
static constexpr float max() noexcept { return FLT_MAX; }
static constexpr float epsilon() noexcept { return FLT_EPSILON; }
static constexpr float round_error() noexcept { return 0.5f; }
static constexpr float infinity() noexcept { return HUGE_VALF; }
static constexpr float quiet_NaN() noexcept { return FLT_QNAN; }
static constexpr float signaling_NaN() noexcept { return FLT_SNAN; }
static constexpr float denorm_min() noexcept { return FLT_TRUE_MIN; }
};
template<>
class numeric_limits<double>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool has_infinity = true;
static constexpr bool has_quiet_NaN = true;
static constexpr bool has_signaling_NaN = true;
static constexpr float_round_style round_style = round_to_nearest;
static constexpr bool is_iec559 = true;
static constexpr bool is_bounded = true;
static constexpr int digits = DBL_MANT_DIG;
static constexpr int digits10 = DBL_DIG;
static constexpr int max_digits10 = DBL_DECIMAL_DIG;
static constexpr int radix = FLT_RADIX;
static constexpr int min_exponent = DBL_MIN_EXP;
static constexpr int min_exponent10 = DBL_MIN_10_EXP;
static constexpr int max_exponent = DBL_MAX_EXP;
static constexpr int max_exponent10 = DBL_MAX_10_EXP;
static constexpr double min() noexcept { return DBL_MIN; }
static constexpr double lowest() noexcept { return -DBL_MAX; }
static constexpr double max() noexcept { return DBL_MAX; }
static constexpr double epsilon() noexcept { return DBL_EPSILON; }
static constexpr double round_error() noexcept { return 0.5; }
static constexpr double infinity() noexcept { return HUGE_VAL; }
static constexpr double quiet_NaN() noexcept { return DBL_QNAN; }
static constexpr double signaling_NaN() noexcept { return DBL_SNAN; }
static constexpr double denorm_min() noexcept { return DBL_TRUE_MIN; }
};
template<>
class numeric_limits<long double>
{
public:
static constexpr bool is_specialized = true;
static constexpr bool is_signed = true;
static constexpr bool has_infinity = true;
static constexpr bool has_quiet_NaN = true;
static constexpr bool has_signaling_NaN = true;
static constexpr float_round_style round_style = round_to_nearest;
static constexpr bool is_iec559 = true;
static constexpr bool is_bounded = true;
static constexpr int digits = LDBL_MANT_DIG;
static constexpr int digits10 = LDBL_DIG;
static constexpr int max_digits10 = LDBL_DECIMAL_DIG;
static constexpr int radix = FLT_RADIX;
static constexpr int min_exponent = LDBL_MIN_EXP;
static constexpr int min_exponent10 = LDBL_MIN_10_EXP;
static constexpr int max_exponent = LDBL_MAX_EXP;
static constexpr int max_exponent10 = LDBL_MAX_10_EXP;
static constexpr long double min() noexcept { return LDBL_MIN; }
static constexpr long double lowest() noexcept { return -LDBL_MAX; }
static constexpr long double max() noexcept { return LDBL_MAX; }
static constexpr long double epsilon() noexcept { return LDBL_EPSILON; }
static constexpr long double round_error() noexcept { return 0.5l; }
static constexpr long double infinity() noexcept { return HUGE_VALL; }
static constexpr long double quiet_NaN() noexcept { return LDBL_QNAN; }
static constexpr long double signaling_NaN() noexcept { return LDBL_SNAN; }
static constexpr long double denorm_min() noexcept { return LDBL_TRUE_MIN; }
};
}
#endif // !defined(BAD_APPLE_OS_LIMITS_INCLUDED)

View File

@ -5,9 +5,42 @@
#define BAD_APPLE_OS_MEMORY_HPP_INCLUDED
#include <cstddef>
#include <cstring>
#include <limits>
#include <new>
#include <type_traits>
namespace std
{
template<typename T>
struct allocator
{
using value_type = T;
using size_type = std::size_t;
using propagate_on_container_move_assignment = true_type;
constexpr allocator() noexcept = default;
constexpr allocator(const allocator&) noexcept = default;
template<typename U>
constexpr allocator(const allocator<U>&) noexcept {}
[[nodiscard]] constexpr T* allocate(size_t n)
{
if (numeric_limits<size_t>::max() / sizeof(T) < n)
{
__ba_throw bad_array_new_length();
}
return static_cast<T*>(::operator new(n * sizeof(T))); // TODO: alignment for bigger types
}
constexpr void deallocate(T* p, size_t n)
{
(void) n;
::operator delete(p); // TODO: bigger alignments
}
};
constexpr void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space) noexcept
{
if (space < size) {

View File

@ -7,7 +7,7 @@
namespace std
{
class bad_alloc : public std::exception
class bad_alloc : public exception
{
public:
bad_alloc() noexcept = default;
@ -15,6 +15,11 @@ public:
const char * what() const noexcept override;
};
class bad_array_new_length : public bad_alloc
{
};
}
inline void* operator new(std::size_t, void* placement) noexcept

View File

@ -4,7 +4,7 @@
#if !defined(BAD_APPLE_OS_STDEXCEPT_INCLUDED)
#define BAD_APPLE_OS_STDEXCEPT_INCLUDED
#include "exception"
#include <exception>
namespace std
{

View File

@ -86,6 +86,24 @@ struct type_identity
template<typename T>
using type_identity_t = type_identity<T>::type;
template<typename T, T v>
struct integral_constant
{
using value_type = T;
using type = integral_constant<T, v>;
static constexpr T value = v;
constexpr operator value_type() const noexcept { return v; }
constexpr value_type operator()() const noexcept { return v; }
};
template<bool B>
using bool_constant = integral_constant<bool, B>;
using true_type = integral_constant<bool, true>;
using false_type = integral_constant<bool, false>;
}
#endif // !defined(BAD_APPLE_OS_TYPE_TRAITS_INCLUDED)

View File

@ -6,13 +6,14 @@
#include <algorithm>
#include <cstddef>
#include <memory>
#include <new>
#include <stdexcept>
#include <utility>
namespace std
{
template<typename T, typename TAlloc = void> // TODO: allocator
template<typename T, typename Allocator = allocator<T>>
class vector
{
public:
@ -29,9 +30,10 @@ private:
T* _elements = nullptr;
size_type _size = 0;
size_type _capacity = 0;
Allocator _allocator = {};
public:
constexpr vector() noexcept = default;
constexpr vector(const vector& other) noexcept
constexpr vector(const vector& other) noexcept : _allocator(other._allocator)
{
resize(other.size());
for (size_type idx = 0; idx < size(); ++idx)
@ -42,16 +44,22 @@ public:
constexpr vector(vector&& other) noexcept
: _elements(exchange(other._elements, nullptr)),
_size(exchange(other._size, 0)),
_capacity(exchange(other._capacity, 0))
_capacity(exchange(other._capacity, 0)),
_allocator(exchange(other._allocator, {}))
{
}
constexpr explicit vector(size_type count, const value_type& value = value_type())
constexpr explicit vector(const Allocator& allocator) noexcept : _allocator(allocator) {}
constexpr explicit vector(size_type count, const value_type& value = value_type(), const Allocator& allocator = {}) : _allocator(allocator)
{
resize(count, value);
}
constexpr ~vector() noexcept
{
delete _elements;
for (size_type idx = 0; idx < size(); ++idx)
{
_elements[idx].~T();
}
_allocator.deallocate(_elements, _capacity);
}
constexpr vector& operator=(const vector& other)
{
@ -302,7 +310,7 @@ private:
if (capacity() == newCapacity) {
return;
}
T* newElements = static_cast<T*>(malloc(newCapacity * sizeof(T)));
T* newElements = _allocator.allocate(newCapacity * sizeof(T));
if (newElements == nullptr)
{
__ba_throw bad_alloc();
@ -312,7 +320,7 @@ private:
::new (&newElements[idx]) T(move(_elements[idx]));
_elements[idx].~T();
}
free(_elements);
_allocator.deallocate(_elements, _capacity);
_elements = newElements;
_capacity = newCapacity;
}

View File

@ -0,0 +1,43 @@
#pragma once
#if !defined(BAD_APPLE_OS_MATH_H_INCLUDED)
#define BAD_APPLE_OS_MATH_H_INCLUDED
#if !defined(HUGE_VALF)
#define HUGE_VALF (__builtin_inff())
#endif
#if !defined(FLT_QNAN)
#define FLT_QNAN (__builtin_nanf(""))
#endif
#if !defined(FLT_SNAN)
#define FLT_SNAN (__builtin_nansf(""))
#endif
#if !defined(HUGE_VAL)
#define HUGE_VAL (__builtin_inf())
#endif
#if !defined(DBL_QNAN)
#define DBL_QNAN (__builtin_nan(""))
#endif
#if !defined(DBL_SNAN)
#define DBL_SNAN (__builtin_nans(""))
#endif
#if !defined(HUGE_VALL)
#define HUGE_VALL (__builtin_infl())
#endif
#if !defined(LDBL_QNAN)
#define LDBL_QNAN (__builtin_nanl(""))
#endif
#if !defined(LDBL_SNAN)
#define LDBL_SNAN (__builtin_nansl(""))
#endif
#endif // !defined(BAD_APPLE_OS_MATH_H_INCLUDED)

View File

@ -40,8 +40,8 @@ enum class MemoryType
struct MemoryRange
{
std::uint64_t pageBase;
std::uint64_t numPages;
std::uint64_t pageBase = 0;
std::uint64_t numPages = 0;
MemoryType type = MemoryType::USABLE;
MemoryRange& operator=(const MemoryRange&) noexcept = default;
@ -51,11 +51,31 @@ struct MemoryRange
}
};
struct AllocatePagesOptions
{
std::size_t numPages = 1;
bool bigPages = false;
};
struct PageRange
{
std::uint64_t mBase = 0;
std::uint64_t numPages = 0;
explicit operator bool() const noexcept { return numPages > 0; }
bool operator!() const noexcept { return numPages == 0; }
[[nodiscard]] std::span<std::uint8_t> getMemory() const noexcept
{
std::uint8_t* basePtr = std::bit_cast<std::uint8_t*>(mBase << 12);
return {basePtr, basePtr + (numPages * 512)};
}
};
[[nodiscard]] bool setupPaging(std::span<const MemoryRange> memoryRanges) noexcept;
[[nodiscard]] const char* memoryTypeName(MemoryType type) noexcept;
[[nodiscard]] void* allocatePages(unsigned numConsecutive) noexcept;
[[nodiscard]] inline void* allocatePage() noexcept { return allocatePages(1); }
[[nodiscard]] PageRange allocatePages(const AllocatePagesOptions& options = {}) noexcept;
void setupIdentityPaging(std::uint64_t page) noexcept;
void setupIdentityPaging2M(std::uint64_t page) noexcept;
@ -69,10 +89,16 @@ inline void identityMapRegion(void* start, std::size_t bytes) noexcept
}
template<typename T = void>
inline T* pageToPointer(std::uint64_t page) noexcept
[[nodiscard]] inline T* pageToPointer(std::uint64_t page) noexcept
{
return std::bit_cast<T*>(page << 12);
}
[[nodiscard]] inline std::size_t bytesToPages(std::size_t bytes, bool bigPages = false) noexcept
{
const std::size_t pageBytes = bigPages ? (2 << 20) : 4096;
return (bytes + pageBytes - 1) / pageBytes;
}
}
void __ba_initInitialHeap() noexcept;

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include <stddef.h>
#include "os/memory.hpp"
#include "os/tty.hpp"
namespace
@ -33,18 +34,6 @@ void __ba_initInitialHeap() noexcept
gNextBlock->nextBlock = nullptr;
}
void __ba_registerAllocatableMemory(void* memory, size_t size) noexcept
{
if (size < sizeof(max_align_t))
{
return;
}
MallocBlock* newBlock = static_cast<MallocBlock*>(memory);
newBlock->nextBlock = gNextBlock;
newBlock->elements = size / sizeof(max_align_t);
gNextBlock = newBlock;
}
extern "C"
{
void abort()
@ -94,9 +83,23 @@ void* malloc(size_t size) noexcept
prevBlock = block;
}
baos::PageRange pages = baos::allocatePages({
.numPages = std::max(1ul, baos::bytesToPages(size, /* bigPages = */ true)),
.bigPages = true
});
if (!pages) {
return nullptr;
}
std::span<std::uint8_t> memory = pages.getMemory();
MallocBlock* newBlock = std::bit_cast<MallocBlock*>(memory.begin());
newBlock->nextBlock = gNextBlock;
newBlock->elements = memory.size();
gNextBlock = newBlock;
return malloc(size);
}
void free(void* memory) noexcept
{
if (memory == nullptr)

View File

@ -188,7 +188,7 @@ bool allocateIdentityMappedPages(std::size_t numPages, std::size_t pageAlignment
if (!allocateMemoryRange(numPages, pageAlignment, page)) {
return false;
}
setupIdentityPaging2M(page);
setupIdentityPaging(page, page + numPages);
outPage = page;
return true;
}
@ -272,6 +272,27 @@ const char* memoryTypeName(MemoryType type) noexcept
return "<INVALID>";
}
PageRange allocatePages(const AllocatePagesOptions& options) noexcept
{
if (options.numPages == 0) {
return {};
}
std::uint64_t page = 0;
const std::uint64_t numPages = options.numPages * (options.bigPages ? BIG_PAGE_SIZE : 1);
if (!allocateIdentityMappedPages(
/* numPages = */ numPages,
/* pageAlignment = */ options.bigPages ? BIG_PAGE_ALIGNMENT : 1,
/* outPage = */ page
))
{
return {};
}
return {
.mBase = page,
.numPages = numPages
};
}
void setupIdentityPaging(std::uint64_t page) noexcept
{
PageTableEntry& pageTableEntry = getOrCreatePage(page);