diff --git a/include/blt/profiling/profiler_v2.h b/include/blt/profiling/profiler_v2.h new file mode 100644 index 0000000..ce49c95 --- /dev/null +++ b/include/blt/profiling/profiler_v2.h @@ -0,0 +1,52 @@ +#pragma once +/* + * Created by Brett on 20/09/23. + * Licensed under GNU General Public License V3.0 + * See LICENSE file for license detail + */ + +#ifndef BLT_PROFILER_V2_H +#define BLT_PROFILER_V2_H + +#include +#include +#include +#include + +namespace blt +{ + // 32 bit currently not supported + typedef std::int64_t pf_time_t; + + struct interval_t + { + pf_time_t start = 0; + pf_time_t end = 0; + pf_time_t total = 0; + pf_time_t count = 0; + }; + + struct profile_t + { + std::vector intervals; + }; + + void startInterval(interval_t& interval); + + void endInterval(profile_t& profiler, interval_t& interval); + + void printProfile(const profile_t& profiler); + + void writeProfile(std::ifstream& stream, const profile_t& profiler); + + namespace _internal + { + void startInterval(const std::string& profile_name, const std::string& interval_name); + void endInterval(const std::string& profile_name, const std::string& interval_name); + void printProfile(const std::string& profile_name); + void writeProfile(const std::string& profile_name); + } + +} + +#endif //BLT_PROFILER_V2_H diff --git a/include/blt/std/memory.h b/include/blt/std/memory.h index a12d189..1c1fcb8 100755 --- a/include/blt/std/memory.h +++ b/include/blt/std/memory.h @@ -9,51 +9,72 @@ #include #include +#include +#include +#include "queue.h" -namespace blt { +namespace blt +{ template - struct ptr_iterator { + struct ptr_iterator + { public: using iterator_category = std::random_access_iterator_tag; - using difference_type = std::ptrdiff_t; - using value_type = V; - using pointer = value_type*; - using reference = value_type&; + using difference_type = std::ptrdiff_t; + using value_type = V; + using pointer = value_type*; + using reference = value_type&; - explicit ptr_iterator(V* v): _v(v) {} + explicit ptr_iterator(V* v): _v(v) + {} - reference operator*() const { return *_v; } - pointer operator->() { return _v; } - ptr_iterator& operator++() { + reference operator*() const + { return *_v; } + + pointer operator->() + { return _v; } + + ptr_iterator& operator++() + { _v++; return *this; } - ptr_iterator& operator--() { + + ptr_iterator& operator--() + { _v--; return *this; } - ptr_iterator operator++(int){ + + ptr_iterator operator++(int) + { auto tmp = *this; ++(*this); return tmp; } - ptr_iterator operator--(int){ + + ptr_iterator operator--(int) + { auto tmp = *this; --(*this); return tmp; } - friend bool operator==(const ptr_iterator& a, const ptr_iterator& b) { + + friend bool operator==(const ptr_iterator& a, const ptr_iterator& b) + { return a._v == b._v; } - friend bool operator!=(const ptr_iterator& a, const ptr_iterator& b) { + + friend bool operator!=(const ptr_iterator& a, const ptr_iterator& b) + { return a._v != b._v; } private: V* _v; }; - + /** * Creates an encapsulation of a T array which will be automatically deleted when this object goes out of scope. * This is a simple buffer meant to be used only inside of a function and not moved around, with a few minor exceptions. @@ -62,18 +83,21 @@ namespace blt { * @tparam T type that is stored in buffer eg char */ template - struct scoped_buffer { + struct scoped_buffer + { private: T* _buffer; size_t _size; public: - explicit scoped_buffer(size_t size): _size(size) { + explicit scoped_buffer(size_t size): _size(size) + { _buffer = new T[size]; } scoped_buffer(const scoped_buffer& copy) = delete; - scoped_buffer(scoped_buffer&& move) noexcept { + scoped_buffer(scoped_buffer&& move) noexcept + { _buffer = move._buffer; _size = move.size(); move._buffer = nullptr; @@ -81,7 +105,8 @@ namespace blt { scoped_buffer operator=(scoped_buffer& copyAssignment) = delete; - scoped_buffer& operator=(scoped_buffer&& moveAssignment) noexcept { + scoped_buffer& operator=(scoped_buffer&& moveAssignment) noexcept + { _buffer = moveAssignment._buffer; _size = moveAssignment.size(); moveAssignment._buffer = nullptr; @@ -89,64 +114,82 @@ namespace blt { return *this; } - inline T& operator[](unsigned long index) { + inline T& operator[](unsigned long index) + { return _buffer[index]; } - inline const T& operator[](unsigned long index) const { + inline const T& operator[](unsigned long index) const + { return _buffer[index]; } - inline T* operator*(){ + inline T* operator*() + { return _buffer; } - [[nodiscard]] inline size_t size() const { + [[nodiscard]] inline size_t size() const + { return _size; } - inline T* ptr(){ + inline T* ptr() + { return _buffer; } - ptr_iterator begin(){ + ptr_iterator begin() + { return ptr_iterator{_buffer}; } - ptr_iterator end(){ + ptr_iterator end() + { return ptr_iterator{&_buffer[_size]}; } - ~scoped_buffer() { + ~scoped_buffer() + { delete[] _buffer; } }; template - struct nullptr_initializer { + struct nullptr_initializer + { private: T* m_ptr = nullptr; public: nullptr_initializer() = default; - explicit nullptr_initializer(T* ptr): m_ptr(ptr) {} - nullptr_initializer(const nullptr_initializer& ptr): m_ptr(ptr.m_ptr) {} - nullptr_initializer(nullptr_initializer&& ptr) noexcept : m_ptr(ptr.m_ptr) {} - nullptr_initializer& operator=(const nullptr_initializer& ptr){ + explicit nullptr_initializer(T* ptr): m_ptr(ptr) + {} + + nullptr_initializer(const nullptr_initializer& ptr): m_ptr(ptr.m_ptr) + {} + + nullptr_initializer(nullptr_initializer&& ptr) noexcept: m_ptr(ptr.m_ptr) + {} + + nullptr_initializer& operator=(const nullptr_initializer& ptr) + { if (&ptr == this) return *this; this->m_ptr = ptr.m_ptr; return *this; } - nullptr_initializer& operator=(nullptr_initializer&& ptr) noexcept { + nullptr_initializer& operator=(nullptr_initializer&& ptr) noexcept + { if (&ptr == this) return *this; this->m_ptr = ptr.m_ptr; return *this; } - inline T* operator->(){ + inline T* operator->() + { return m_ptr; } @@ -160,44 +203,141 @@ namespace blt { * @tparam V associated value */ template - class enum_storage { + class enum_storage + { private: - V* _values; - size_t _size = 0; + V* m_values; + size_t m_size = 0; public: - enum_storage(std::initializer_list> init){ + enum_storage(std::initializer_list> init) + { for (auto& i : init) - _size = std::max((size_t)i.first, _size); - _values = new V[_size]; + m_size = std::max((size_t) i.first, m_size); + m_values = new V[m_size]; for (auto& v : init) - _values[(size_t)v.first] = v.second; + m_values[(size_t) v.first] = v.second; } - inline V& operator[](size_t index){ - return _values[index]; + inline V& operator[](size_t index) + { + return m_values[index]; } - inline const V& operator[](size_t index) const { - return _values[index]; + inline const V& operator[](size_t index) const + { + return m_values[index]; } - [[nodiscard]] inline size_t size() const { - return _size; + [[nodiscard]] inline size_t size() const + { + return m_size; } - ptr_iterator begin(){ - return ptr_iterator{_values}; + ptr_iterator begin() + { + return ptr_iterator{m_values}; } - ptr_iterator end(){ - return ptr_iterator{&_values[_size]}; + ptr_iterator end() + { + return ptr_iterator{&m_values[m_size]}; } - ~enum_storage(){ - delete[] _values; + ~enum_storage() + { + delete[] m_values; } }; + template + class area_allocator + { + public: + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef void* void_pointer; + typedef const void* const_void_pointer; + private: + struct pointer_view + { + const_pointer p; + size_t n; + }; + + void expand() + { + size_t new_size = m_size * 2; + T* data = new T[new_size]; + if constexpr (std::is_trivially_copyable_v) + std::memcpy(data, m_data, m_size); + else if constexpr (std::is_move_assignable_v) + { + for (size_t i = 0; i < m_size; i++) + data[i] = std::move(m_data[i]); + } else if constexpr (std::is_move_constructible_v) + { + // is this bad? probably + for (size_t i = 0; i < m_size; i++) + data[i] = T(std::move(m_data)); + } else if constexpr (std::is_copy_assignable_v) + { + for (size_t i = 0; i < m_size; i++) + data[i] = m_data[i]; + } else + { + static_assert("Unable to use this type with this allocator!"); + } + delete[] m_data; + m_data = data; + m_size = new_size; + } + + void realign() + { + + } + + public: + area_allocator() + { + m_data = new T[m_size]; + } + + [[nodiscard]] pointer* allocate(size_t n) + { + if (m_last + n > m_size) + expand(); + pointer loc = &m_data[m_last]; + m_last += n; + return loc; + } + + void deallocate(pointer* p, size_t n) noexcept + { + deallocated_blocks.push({p, n}); + m_deallocated += n; + // TODO: magic number + if (static_cast(m_deallocated) / static_cast(m_last) > 0.25) + realign(); + } + + ~area_allocator() + { + delete[] m_data; + } + + private: + // current size of the data + size_t m_size = 1; + // last allocated location + size_t m_last = 0; + // how many values have been deallocated + size_t m_deallocated = 0; + T* m_data = nullptr; + blt::flat_queue deallocated_blocks; + }; + } #endif //BLT_TESTS_MEMORY_H diff --git a/src/blt/profiling/profiler_v2.cpp b/src/blt/profiling/profiler_v2.cpp new file mode 100644 index 0000000..72616a4 --- /dev/null +++ b/src/blt/profiling/profiler_v2.cpp @@ -0,0 +1,11 @@ +/* + * Created by Brett on 20/09/23. + * Licensed under GNU General Public License V3.0 + * See LICENSE file for license detail + */ +#include + +namespace blt +{ + +} \ No newline at end of file