diff --git a/src/ofdm/ofdm_demodulator.h b/src/ofdm/ofdm_demodulator.h index fd3c76a..9635ada 100644 --- a/src/ofdm/ofdm_demodulator.h +++ b/src/ofdm/ofdm_demodulator.h @@ -13,10 +13,10 @@ #include "./circular_buffer.h" #include "utility/observable.h" #include "utility/span.h" -#include "utility/joint_allocate.h" +#include "utility/aligned_allocator.hpp" #include "viterbi_config.h" -typedef struct fftwf_plan_s* fftwf_plan; \ +struct fftwf_plan_s; class OFDM_Demod_Pipeline; class OFDM_Demod_Coordinator; @@ -72,8 +72,8 @@ class OFDM_Demod bool m_is_null_end_found; float m_signal_l1_average; // fft - fftwf_plan m_fft_plan; - fftwf_plan m_ifft_plan; + fftwf_plan_s* m_fft_plan; + fftwf_plan_s* m_ifft_plan; // threads std::unique_ptr m_coordinator; std::vector> m_pipelines; @@ -82,7 +82,7 @@ class OFDM_Demod // callback for when ofdm is completed Observable> m_obs_on_ofdm_frame; // Joint memory allocation block - AlignedVector m_joint_data_block; + std::vector> m_joint_data_block; // 1. pipeline reader double buffer OFDM_Frame_Buffer> m_active_buffer; OFDM_Frame_Buffer> m_inactive_buffer; diff --git a/src/utility/aligned_allocator.hpp b/src/utility/aligned_allocator.hpp new file mode 100644 index 0000000..4b8f47b --- /dev/null +++ b/src/utility/aligned_allocator.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include + +// C++17 aligned allocator +// Sources: https://en.cppreference.com/w/cpp/named_req/Allocator +// https://en.cppreference.com/w/cpp/memory/allocator_traits +// https://en.cppreference.com/w/cpp/memory/new/operator_new +template +class AlignedAllocator +{ +public: + using value_type = T; + using is_always_equal = std::false_type; + using propagate_on_container_copy_assignment = std::false_type; // do not copy allocator when copying object + using propagate_on_container_move_assignment = std::true_type; // move allocator when moving object + using propagate_on_container_swap = std::true_type; + template + struct rebind { + using other = AlignedAllocator; + }; + static constexpr size_t default_alignment = (sizeof(std::size_t) > sizeof(T)) ? sizeof(std::size_t) : sizeof(T); +private: + std::size_t m_alignment; +public: + explicit AlignedAllocator(std::size_t alignment=default_alignment): m_alignment(alignment) {} + [[nodiscard]] T* allocate(std::size_t length) { + return reinterpret_cast(operator new(length*sizeof(T), std::align_val_t(m_alignment))); + } + void deallocate(T* const ptr, std::size_t /*length*/) const { + assert(reinterpret_cast(ptr) % m_alignment == 0); + operator delete(ptr, std::align_val_t(m_alignment)); + } + bool operator==(const AlignedAllocator& other) const noexcept { + return m_alignment == other.m_alignment; + } + bool operator!=(const AlignedAllocator& other) const noexcept { + return m_alignment != other.m_alignment; + } + // cast between types + inline size_t get_alignment() const { return m_alignment; } + template + explicit AlignedAllocator(const AlignedAllocator& other): m_alignment(other.get_alignment()) {} + template + operator AlignedAllocator() const { return AlignedAllocator(m_alignment); } +}; diff --git a/src/utility/aligned_vector.h b/src/utility/aligned_vector.h deleted file mode 100644 index 666a320..0000000 --- a/src/utility/aligned_vector.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -// Wrap aligned allocator and deallocator calls in a RAII class -template -class AlignedVector -{ -private: - T* m_buf; - size_t m_len; - size_t m_align; -public: - explicit AlignedVector(const size_t len=0, const size_t align=32) { - // Cannot align to zero bytes - assert(align != 0u); - m_len = len; - m_align = align; - m_buf = NULL; - const size_t total_bytes = m_len*sizeof(T); - if (m_len > 0) { - m_buf = reinterpret_cast(operator new[](total_bytes, std::align_val_t(m_align))); - } - } - - ~AlignedVector() { - if (m_buf != NULL) { - operator delete[](m_buf, std::align_val_t(m_align)); - } - m_len = 0; - m_align = 0; - m_buf = NULL; - } - - AlignedVector(const AlignedVector& other) { - m_len = other.size(); - m_align = other.alignment(); - m_buf = NULL; - - const size_t total_bytes = m_len*sizeof(T); - if (m_len > 0) { - m_buf = reinterpret_cast(operator new[](total_bytes, std::align_val_t(m_align))); - std::memcpy(m_buf, other.data(), total_bytes); - } - }; - - AlignedVector& operator=(const AlignedVector& other) { - if (this == &other) { - return *this; - } - - if (m_buf != NULL) { - operator delete[](m_buf, std::align_val_t(m_align)); - } - - m_len = other.size(); - m_align = other.alignment(); - m_buf = NULL; - - const size_t total_bytes = m_len*sizeof(T); - if (m_len > 0) { - m_buf = reinterpret_cast(operator new[](total_bytes, std::align_val_t(m_align))); - std::memcpy(m_buf, other.data(), total_bytes); - } - - return *this; - } - - AlignedVector(AlignedVector&& other) { - m_len = other.m_len; - m_align = other.m_align; - m_buf = other.m_buf; - - other.m_len = 0; - other.m_align = 0; - other.m_buf = NULL; - } - - AlignedVector& operator=(AlignedVector&& other) { - if (this == &other) { - return *this; - } - - if (m_buf != NULL) { - operator delete[](m_buf, std::align_val_t(m_align)); - } - - m_len = other.m_len; - m_align = other.m_align; - m_buf = other.m_buf; - - other.m_len = 0; - other.m_align = 0; - other.m_buf = NULL; - - return *this; - }; - - inline - T& operator[](size_t index) { - return m_buf[index]; - } - - inline - const T& operator[](size_t index) const { - return m_buf[index]; - } - - auto begin() const { return m_buf; } - auto end() const { return &m_buf[m_len]; } - auto size() const { return m_len; } - auto data() const { return m_buf; } - auto alignment() const { return m_align; } -}; \ No newline at end of file diff --git a/src/utility/joint_allocate.h b/src/utility/joint_allocate.h index 3553d01..5141441 100644 --- a/src/utility/joint_allocate.h +++ b/src/utility/joint_allocate.h @@ -3,8 +3,9 @@ #include #include #include -#include "span.h" -#include "aligned_vector.h" +#include +#include "./span.h" +#include "./aligned_allocator.hpp" // Define the specification for each buffer inside the joint block struct BufferParameters { @@ -15,12 +16,12 @@ struct BufferParameters { : length(_length), alignment(_alignment) {} }; -static AlignedVector AllocateJoint(size_t curr_size, size_t align_size) { - return AlignedVector(curr_size, align_size); +static std::vector> AllocateJoint(size_t curr_size, size_t align_size) { + return std::vector>(curr_size, AlignedAllocator(align_size)); } template -static AlignedVector AllocateJoint(size_t curr_joint_size, size_t joint_alignment, tcb::span& buf, BufferParameters params, Ts&& ... args) { +static std::vector> AllocateJoint(size_t curr_joint_size, size_t joint_alignment, tcb::span& buf, BufferParameters params, Ts&& ... args) { // create padding so that next buffer has its alignment const auto align_elem_size = params.alignment ? params.alignment : sizeof(T); const size_t padded_joint_size = ((curr_joint_size+align_elem_size-1) / align_elem_size) * align_elem_size; @@ -46,6 +47,6 @@ static AlignedVector AllocateJoint(size_t curr_joint_size, size_t joint // Recursive template for creating a jointly allocated block template -static AlignedVector AllocateJoint(tcb::span& buf, BufferParameters params, Ts&& ... args) { +static std::vector> AllocateJoint(tcb::span& buf, BufferParameters params, Ts&& ... args) { return AllocateJoint(0, 1, buf, params, args...); } \ No newline at end of file