DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
tpglibs::ProcessorInternalStateBufferManager< T > Class Template Reference

Manages the internal state storage buffers for a processor. More...

#include <ProcessorInternalStateBufferManager.hpp>

Collaboration diagram for tpglibs::ProcessorInternalStateBufferManager< T >:
[legend]

Public Types

using signal_t = T
 Signal type to use. Generally __m256i or std::array<int16_t, 16>;.
 

Public Member Functions

 ProcessorInternalStateBufferManager ()
 Constructor.
 
 ~ProcessorInternalStateBufferManager ()
 Destructor.
 
void write_to_active_buffer ()
 Write to the active buffer.
 
ProcessorMetricArray< signal_tswitch_buffer_and_read ()
 Read from the inactive buffer.
 
ProcessorMetricArray< std::array< int16_t, 16 > > switch_buffer_and_read_casted ()
 Read from the inactive buffer and cast to std::array<int16_t, 16>.
 
void configure_from_registry (ProcessorInternalStateNameRegistry< signal_t > *registry)
 Configure and allocate correct buffer storage given the configuration string.
 
void clear ()
 clear all buffers and deallocate memory.
 
void clear ()
 
ProcessorMetricArray< std::array< int16_t, 16 > > switch_buffer_and_read_casted ()
 
ProcessorMetricArray< std::array< int16_t, 16 > > switch_buffer_and_read_casted ()
 

Protected Member Functions

void allocate_buffers (size_t buffer_size)
 Allocate the correct size for the double buffer read and write buffers.
 
void allocate_cast_buffers (size_t)
 Allocate the correct size for the double buffer read and write buffers for the casted data.
 
void switch_active_buffer ()
 Switch the active buffer.
 
void allocate_cast_buffers (size_t n)
 

Private Attributes

std::vector< std::shared_ptr< signal_t > > m_internal_state_item_ptrs
 The vector of pointers to the internal state items.
 
ProcessorMetricArray< signal_tm_store_buffers [2] {}
 The double buffers for storing the internal state data.
 
ProcessorMetricArray< std::array< int16_t, 16 > > m_cast_store_buffers [2] {}
 The double buffers for storing the internal state data casted to std::array<int16_t, 16>.
 
std::atomic< ProcessorMetricArray< std::array< int16_t, 16 > > * > m_cast_active_buffer { &m_cast_store_buffers[0] }
 The active buffer for the casted data.
 
std::atomic< ProcessorMetricArray< signal_t > * > m_write_buffer = &m_store_buffers[0]
 The write buffer pointer (buffer writer currently uses).
 
std::atomic< ProcessorMetricArray< signal_t > * > m_read_buffer = &m_store_buffers[0]
 The read buffer pointer (buffer reader currently uses).
 
std::atomic< uint16_t > m_write_seq {0}
 The sequence number for writes (odd=writing, even=complete).
 
std::atomic< uint16_t > m_last_read_seq {0}
 The last sequence number that was read.
 
size_t m_buffer_size
 size of each buffer.
 

Detailed Description

template<typename T>
class tpglibs::ProcessorInternalStateBufferManager< T >

Manages the internal state storage buffers for a processor.

Definition at line 32 of file ProcessorInternalStateBufferManager.hpp.

Member Typedef Documentation

◆ signal_t

template<typename T >
using tpglibs::ProcessorInternalStateBufferManager< T >::signal_t = T

Signal type to use. Generally __m256i or std::array<int16_t, 16>;.

Definition at line 35 of file ProcessorInternalStateBufferManager.hpp.

Constructor & Destructor Documentation

◆ ProcessorInternalStateBufferManager()

template<typename T >
tpglibs::ProcessorInternalStateBufferManager< T >::ProcessorInternalStateBufferManager ( )

Constructor.

Definition at line 117 of file ProcessorInternalStateBufferManager.hpp.

117 {
118 }

◆ ~ProcessorInternalStateBufferManager()

Destructor.

Definition at line 121 of file ProcessorInternalStateBufferManager.hpp.

121 {
122 clear();
123 }
void clear()
clear all buffers and deallocate memory.

Member Function Documentation

◆ allocate_buffers()

template<typename T >
void tpglibs::ProcessorInternalStateBufferManager< T >::allocate_buffers ( size_t buffer_size)
protected

Allocate the correct size for the double buffer read and write buffers.

Parameters
buffer_sizeThe size of the buffer.

Definition at line 143 of file ProcessorInternalStateBufferManager.hpp.

143 {
144 for (auto& buf : m_store_buffers) {
145 buf.m_size = buffer_size;
146 buf.m_data = static_cast<T*>(
147 _mm_malloc(buf.m_size * sizeof(T), alignof(T))
148 );
149 }
150 }
ProcessorMetricArray< signal_t > m_store_buffers[2]
The double buffers for storing the internal state data.

◆ allocate_cast_buffers() [1/2]

void tpglibs::ProcessorInternalStateBufferManager< __m256i >::allocate_cast_buffers ( size_t n)
inlineprotected

Definition at line 240 of file ProcessorInternalStateBufferManager.hpp.

240 {
241 for (auto& buf : m_cast_store_buffers) {
242 buf.m_size = n;
243 buf.m_data = static_cast<std::array<int16_t,16>*>(
244 _mm_malloc(n * sizeof(std::array<int16_t,16>), 32)
245 );
246 }
247 m_cast_active_buffer.store(&m_cast_store_buffers[0], std::memory_order_release);
248 }
ProcessorMetricArray< std::array< int16_t, 16 > > m_cast_store_buffers[2]
The double buffers for storing the internal state data casted to std::array<int16_t,...
std::atomic< ProcessorMetricArray< std::array< int16_t, 16 > > * > m_cast_active_buffer
The active buffer for the casted data.

◆ allocate_cast_buffers() [2/2]

template<typename T >
void tpglibs::ProcessorInternalStateBufferManager< T >::allocate_cast_buffers ( size_t )
inlineprotected

Allocate the correct size for the double buffer read and write buffers for the casted data.

Parameters
buffer_sizeThe size of the buffer.

Definition at line 81 of file ProcessorInternalStateBufferManager.hpp.

81{}; // Do nothing for the generic template

◆ clear() [1/2]

template<typename T >
void tpglibs::ProcessorInternalStateBufferManager< T >::clear ( )
inline

clear all buffers and deallocate memory.

Definition at line 65 of file ProcessorInternalStateBufferManager.hpp.

65 {
66 for (auto& buf : m_store_buffers) { _mm_free(buf.m_data); }
67 }

◆ clear() [2/2]

void tpglibs::ProcessorInternalStateBufferManager< __m256i >::clear ( )
inline

Definition at line 206 of file ProcessorInternalStateBufferManager.hpp.

206 {
207 // free double buffer for temp values
208 for (auto& buf : m_store_buffers) { _mm_free(buf.m_data); }
209 // free double buffer for casted values
210 for (auto& buf : m_cast_store_buffers) { _mm_free(buf.m_data); }
211 }

◆ configure_from_registry()

template<typename T >
void tpglibs::ProcessorInternalStateBufferManager< T >::configure_from_registry ( ProcessorInternalStateNameRegistry< signal_t > * registry)

Configure and allocate correct buffer storage given the configuration string.

Parameters
registryThe registry object of internal state names.

Definition at line 126 of file ProcessorInternalStateBufferManager.hpp.

126 {
127 // obtain the number of internal state items
128 auto num_items = registry->get_number_of_requested_internal_states();
129 allocate_buffers(num_items);
130 allocate_cast_buffers(num_items);
131 // Writer starts with buffer 0, reader starts with buffer 1 (they must be different!)
132 m_write_buffer.store(&m_store_buffers[0], std::memory_order_release);
133 m_read_buffer.store(&m_store_buffers[1], std::memory_order_release);
134 m_cast_active_buffer.store(&m_cast_store_buffers[0], std::memory_order_release);
135 // reset sequence counters
136 m_write_seq.store(0, std::memory_order_release);
137 m_last_read_seq.store(0, std::memory_order_release);
138 // obtain the pointers to the internal state items
139 m_internal_state_item_ptrs = registry->get_all_requested_internal_state_item_ptrs();
140 }
std::atomic< ProcessorMetricArray< signal_t > * > m_write_buffer
The write buffer pointer (buffer writer currently uses).
std::atomic< uint16_t > m_last_read_seq
The last sequence number that was read.
std::atomic< uint16_t > m_write_seq
The sequence number for writes (odd=writing, even=complete).
std::vector< std::shared_ptr< signal_t > > m_internal_state_item_ptrs
The vector of pointers to the internal state items.
void allocate_cast_buffers(size_t)
Allocate the correct size for the double buffer read and write buffers for the casted data.
std::atomic< ProcessorMetricArray< signal_t > * > m_read_buffer
The read buffer pointer (buffer reader currently uses).
void allocate_buffers(size_t buffer_size)
Allocate the correct size for the double buffer read and write buffers.

◆ switch_active_buffer()

template<typename T >
void tpglibs::ProcessorInternalStateBufferManager< T >::switch_active_buffer ( )
protected

Switch the active buffer.

◆ switch_buffer_and_read()

template<typename T >
ProcessorMetricArray< typename ProcessorInternalStateBufferManager< T >::signal_t > tpglibs::ProcessorInternalStateBufferManager< T >::switch_buffer_and_read ( )

Read from the inactive buffer.

Returns
The data read from the inactive buffer.

Definition at line 175 of file ProcessorInternalStateBufferManager.hpp.

175 {
176 // Wait until no write is in progress
177 uint16_t current_write_seq;
178 do {
179 current_write_seq = m_write_seq.load(std::memory_order_acquire);
180 } while (current_write_seq & 1); // spin if writer is mid-write (odd seq number)
181
182 // Check if there's new data since last read
183 uint16_t last_read = m_last_read_seq.load(std::memory_order_acquire);
184
185 if (current_write_seq != last_read && current_write_seq > 0) {
186 // New data available - swap the buffers between reader and writer
187 auto current_read = m_read_buffer.load(std::memory_order_acquire);
188 auto current_write = m_write_buffer.load(std::memory_order_acquire);
189
190 // Swap: reader gets what writer just finished, writer gets what reader was using
191 m_read_buffer.store(current_write, std::memory_order_release);
192 m_write_buffer.store(current_read, std::memory_order_release);
193
194 // Update last read sequence
195 m_last_read_seq.store(current_write_seq, std::memory_order_release);
196 }
197
198 // Return data from read buffer
199 auto read_ptr = m_read_buffer.load(std::memory_order_acquire);
200 return *read_ptr;
201 }

◆ switch_buffer_and_read_casted() [1/3]

template<typename T >
ProcessorMetricArray< std::array< int16_t, 16 > > tpglibs::ProcessorInternalStateBufferManager< T >::switch_buffer_and_read_casted ( )

Read from the inactive buffer and cast to std::array<int16_t, 16>.

◆ switch_buffer_and_read_casted() [2/3]

ProcessorMetricArray< std::array< int16_t, 16 > > tpglibs::ProcessorInternalStateBufferManager< __m256i >::switch_buffer_and_read_casted ( )
inline

Definition at line 215 of file ProcessorInternalStateBufferManager.hpp.

215 {
216 // First, get the raw data using switch_buffer_and_read
217 auto raw_data = switch_buffer_and_read();
218
219 auto* cast_free = m_cast_active_buffer.load(std::memory_order_acquire);
220
221 // Cast each __m256i to std::array<int16_t, 16>
222 for (size_t i = 0; i < raw_data.m_size; ++i) {
223 // Cast and save to cast buffer
224 _mm256_store_si256(
225 reinterpret_cast<__m256i*>(cast_free->m_data[i].data()),
226 raw_data.m_data[i]
227 );
228 }
229
230 // Flip the active cast buffer
231
232 auto* next = (cast_free == &m_cast_store_buffers[0]) ? &m_cast_store_buffers[1] : &m_cast_store_buffers[0];
233 m_cast_active_buffer.store(next, std::memory_order_release);
234
235 return *cast_free;
236 }
ProcessorMetricArray< signal_t > switch_buffer_and_read()
Read from the inactive buffer.

◆ switch_buffer_and_read_casted() [3/3]

ProcessorMetricArray< std::array< int16_t, 16 > > tpglibs::ProcessorInternalStateBufferManager< std::array< int16_t, 16 > >::switch_buffer_and_read_casted ( )
inline

Definition at line 252 of file ProcessorInternalStateBufferManager.hpp.

252 {
253 // First, get the raw data using switch_buffer_and_read
254 auto raw_data = switch_buffer_and_read();
255
256 // For std::array<int16_t, 16>, the cast is trivial - just return the data as-is
257 return raw_data;
258 }

◆ write_to_active_buffer()

template<typename T >
void tpglibs::ProcessorInternalStateBufferManager< T >::write_to_active_buffer ( )

Write to the active buffer.

Parameters
dataThe data to write.

Definition at line 153 of file ProcessorInternalStateBufferManager.hpp.

153 {
154 // Increment seq to indicate write start (becomes odd)
155 m_write_seq.fetch_add(1, std::memory_order_release);
156
157 auto write_ptr = m_write_buffer.load(std::memory_order_acquire);
158
159 // Write to write buffer
160 for (size_t i = 0; i < m_internal_state_item_ptrs.size(); i++) {
161 // Check for nullptr before dereferencing (handles invalid state names)
162 if (m_internal_state_item_ptrs[i] != nullptr) {
163 write_ptr->m_data[i] = *m_internal_state_item_ptrs[i];
164 } else {
165 // If pointer is null, write a zeroed value
166 write_ptr->m_data[i] = T{};
167 }
168 }
169
170 // Increment seq to indicate write complete (becomes even)
171 m_write_seq.fetch_add(1, std::memory_order_release);
172 }

Member Data Documentation

◆ m_buffer_size

template<typename T >
size_t tpglibs::ProcessorInternalStateBufferManager< T >::m_buffer_size
private

size of each buffer.

Definition at line 112 of file ProcessorInternalStateBufferManager.hpp.

◆ m_cast_active_buffer

template<typename T >
std::atomic<ProcessorMetricArray<std::array<int16_t,16> >*> tpglibs::ProcessorInternalStateBufferManager< T >::m_cast_active_buffer { &m_cast_store_buffers[0] }
private

The active buffer for the casted data.

Definition at line 97 of file ProcessorInternalStateBufferManager.hpp.

◆ m_cast_store_buffers

template<typename T >
ProcessorMetricArray<std::array<int16_t,16> > tpglibs::ProcessorInternalStateBufferManager< T >::m_cast_store_buffers[2] {}
private

The double buffers for storing the internal state data casted to std::array<int16_t, 16>.

Definition at line 94 of file ProcessorInternalStateBufferManager.hpp.

94{};

◆ m_internal_state_item_ptrs

template<typename T >
std::vector<std::shared_ptr<signal_t> > tpglibs::ProcessorInternalStateBufferManager< T >::m_internal_state_item_ptrs
private

The vector of pointers to the internal state items.

Definition at line 88 of file ProcessorInternalStateBufferManager.hpp.

◆ m_last_read_seq

template<typename T >
std::atomic<uint16_t> tpglibs::ProcessorInternalStateBufferManager< T >::m_last_read_seq {0}
private

The last sequence number that was read.

Definition at line 109 of file ProcessorInternalStateBufferManager.hpp.

109{0};

◆ m_read_buffer

template<typename T >
std::atomic<ProcessorMetricArray<signal_t>*> tpglibs::ProcessorInternalStateBufferManager< T >::m_read_buffer = &m_store_buffers[0]
private

The read buffer pointer (buffer reader currently uses).

Definition at line 103 of file ProcessorInternalStateBufferManager.hpp.

◆ m_store_buffers

template<typename T >
ProcessorMetricArray<signal_t> tpglibs::ProcessorInternalStateBufferManager< T >::m_store_buffers[2] {}
private

The double buffers for storing the internal state data.

Definition at line 91 of file ProcessorInternalStateBufferManager.hpp.

91{};

◆ m_write_buffer

template<typename T >
std::atomic<ProcessorMetricArray<signal_t>*> tpglibs::ProcessorInternalStateBufferManager< T >::m_write_buffer = &m_store_buffers[0]
private

The write buffer pointer (buffer writer currently uses).

Definition at line 100 of file ProcessorInternalStateBufferManager.hpp.

◆ m_write_seq

template<typename T >
std::atomic<uint16_t> tpglibs::ProcessorInternalStateBufferManager< T >::m_write_seq {0}
private

The sequence number for writes (odd=writing, even=complete).

Definition at line 106 of file ProcessorInternalStateBufferManager.hpp.

106{0};

The documentation for this class was generated from the following file: