BluFedora Job System v1.0.0
This is a C++ job system library for use in game engines.
Job::SPSCQueue< T > Class Template Reference

#include <job_queue.hpp>

Public Types

using size_type = std::size_t
 
using atomic_size_type = std::atomic< size_type >
 

Public Member Functions

 SPSCQueue ()=default
 
 ~SPSCQueue ()=default
 
void Initialize (T *const memory_backing, const size_type capacity) noexcept
 
bool Push (const T &value)
 
bool Pop (T *const out_value)
 
template<typename CallbackFn >
bool PushLazy (CallbackFn &&callback)
 
template<typename CallbackFn >
bool PopLazy (CallbackFn &&callback)
 

Private Member Functions

bool IsFull (const size_type head, const size_type tail) const noexcept
 
T * ElementAt (const size_type index) const noexcept
 

Static Private Member Functions

static bool IsEmpty (const size_type head, const size_type tail) noexcept
 

Private Attributes

atomic_size_type m_ProducerIndex
 
unsigned char m_Padding0 [k_FalseSharingPadSize - sizeof(m_ProducerIndex)]
 
size_type m_CachedConsumerIndex
 
unsigned char m_Padding1 [k_FalseSharingPadSize - sizeof(m_CachedConsumerIndex)]
 
atomic_size_type m_ConsumerIndex
 
unsigned char m_Padding2 [k_FalseSharingPadSize - sizeof(m_ConsumerIndex)]
 
size_type m_CachedProducerIndex
 
unsigned char m_Padding3 [k_FalseSharingPadSize - sizeof(m_CachedProducerIndex)]
 
T * m_Data
 
size_type m_Capacity
 
size_type m_CapacityMask
 
unsigned char m_Padding4 [k_FalseSharingPadSize - sizeof(m_Data) - sizeof(m_Capacity) - sizeof(m_CapacityMask)]
 

Detailed Description

template<typename T>
class Job::SPSCQueue< T >

Definition at line 111 of file job_queue.hpp.

Member Typedef Documentation

◆ size_type

template<typename T >
using Job::SPSCQueue< T >::size_type = std::size_t

Definition at line 114 of file job_queue.hpp.

◆ atomic_size_type

template<typename T >
using Job::SPSCQueue< T >::atomic_size_type = std::atomic<size_type>

Definition at line 115 of file job_queue.hpp.

Constructor & Destructor Documentation

◆ SPSCQueue()

template<typename T >
Job::SPSCQueue< T >::SPSCQueue ( )
default

◆ ~SPSCQueue()

template<typename T >
Job::SPSCQueue< T >::~SPSCQueue ( )
default

Member Function Documentation

◆ Initialize()

template<typename T >
void Job::SPSCQueue< T >::Initialize ( T *const  memory_backing,
const size_type  capacity 
)
inlinenoexcept

Definition at line 146 of file job_queue.hpp.

147 {
148 m_ProducerIndex.store(0, std::memory_order_relaxed);
150 m_ConsumerIndex.store(0, std::memory_order_relaxed);
152 m_Data = memory_backing;
153 m_Capacity = capacity;
154 m_CapacityMask = capacity - 1;
155
156 JobAssert((m_Capacity & m_CapacityMask) == 0, "Capacity must be a power of 2.");
157 }
atomic_size_type m_ConsumerIndex
Definition: job_queue.hpp:127
size_type m_Capacity
Definition: job_queue.hpp:135
size_type m_CachedProducerIndex
Definition: job_queue.hpp:129
size_type m_CachedConsumerIndex
Definition: job_queue.hpp:122
atomic_size_type m_ProducerIndex
Definition: job_queue.hpp:120
size_type m_CapacityMask
Definition: job_queue.hpp:136
#define JobAssert(expr, msg)
Definition: job_assert.hpp:27

References JobAssert, Job::SPSCQueue< T >::m_CachedConsumerIndex, Job::SPSCQueue< T >::m_CachedProducerIndex, Job::SPSCQueue< T >::m_Capacity, Job::SPSCQueue< T >::m_CapacityMask, Job::SPSCQueue< T >::m_ConsumerIndex, Job::SPSCQueue< T >::m_Data, and Job::SPSCQueue< T >::m_ProducerIndex.

◆ Push()

template<typename T >
bool Job::SPSCQueue< T >::Push ( const T &  value)
inline

Definition at line 159 of file job_queue.hpp.

160 {
161 return PushLazy([&value](T* const destination) { ::new (destination) T(value); });
162 }
bool PushLazy(CallbackFn &&callback)
Definition: job_queue.hpp:173

References Job::SPSCQueue< T >::PushLazy().

◆ Pop()

template<typename T >
bool Job::SPSCQueue< T >::Pop ( T *const  out_value)
inline

Definition at line 164 of file job_queue.hpp.

165 {
166 JobAssert(out_value != nullptr, "`out_value` cannot be a nullptr.");
167
168 return PopLazy([out_value](T&& value) { *out_value = std::move(value); });
169 }
bool PopLazy(CallbackFn &&callback)
Definition: job_queue.hpp:193

References JobAssert, and Job::SPSCQueue< T >::PopLazy().

◆ PushLazy()

template<typename T >
template<typename CallbackFn >
bool Job::SPSCQueue< T >::PushLazy ( CallbackFn &&  callback)
inline

Definition at line 173 of file job_queue.hpp.

174 {
175 const size_type write_index = m_ProducerIndex.load(std::memory_order_relaxed);
176
177 if (IsFull(write_index, m_CachedConsumerIndex))
178 {
179 m_CachedConsumerIndex = m_ConsumerIndex.load(std::memory_order_acquire);
180 if (IsFull(write_index, m_CachedConsumerIndex))
181 {
182 return false;
183 }
184 }
185
186 callback(ElementAt(write_index));
187 m_ProducerIndex.store(write_index + 1, std::memory_order_release);
188
189 return true;
190 }
T * ElementAt(const size_type index) const noexcept
Definition: job_queue.hpp:225
bool IsFull(const size_type head, const size_type tail) const noexcept
Definition: job_queue.hpp:215
std::size_t size_type
Definition: job_queue.hpp:114

References Job::SPSCQueue< T >::ElementAt(), Job::SPSCQueue< T >::IsFull(), Job::SPSCQueue< T >::m_CachedConsumerIndex, Job::SPSCQueue< T >::m_ConsumerIndex, and Job::SPSCQueue< T >::m_ProducerIndex.

Referenced by Job::SPSCQueue< T >::Push().

◆ PopLazy()

template<typename T >
template<typename CallbackFn >
bool Job::SPSCQueue< T >::PopLazy ( CallbackFn &&  callback)
inline

Definition at line 193 of file job_queue.hpp.

194 {
195 const size_type read_index = m_ConsumerIndex.load(std::memory_order_relaxed);
196
197 if (IsEmpty(m_CachedProducerIndex, read_index))
198 {
199 m_CachedProducerIndex = m_ProducerIndex.load(std::memory_order_acquire);
200 if (IsEmpty(m_CachedProducerIndex, read_index))
201 {
202 return false;
203 }
204 }
205
206 T* const element = ElementAt(read_index);
207 callback(std::move(*element));
208 element->~T();
209 m_ConsumerIndex.fetch_add(1, std::memory_order_release);
210
211 return true;
212 }
static bool IsEmpty(const size_type head, const size_type tail) noexcept
Definition: job_queue.hpp:220

References Job::SPSCQueue< T >::ElementAt(), Job::SPSCQueue< T >::IsEmpty(), Job::SPSCQueue< T >::m_CachedProducerIndex, Job::SPSCQueue< T >::m_ConsumerIndex, and Job::SPSCQueue< T >::m_ProducerIndex.

Referenced by Job::SPSCQueue< T >::Pop().

◆ IsFull()

template<typename T >
bool Job::SPSCQueue< T >::IsFull ( const size_type  head,
const size_type  tail 
) const
inlineprivatenoexcept

Definition at line 215 of file job_queue.hpp.

216 {
217 return ((head + 1) & m_CapacityMask) == tail;
218 }

References Job::SPSCQueue< T >::m_CapacityMask.

Referenced by Job::SPSCQueue< T >::PushLazy().

◆ IsEmpty()

template<typename T >
static bool Job::SPSCQueue< T >::IsEmpty ( const size_type  head,
const size_type  tail 
)
inlinestaticprivatenoexcept

Definition at line 220 of file job_queue.hpp.

221 {
222 return head == tail;
223 }

Referenced by Job::SPSCQueue< T >::PopLazy().

◆ ElementAt()

template<typename T >
T * Job::SPSCQueue< T >::ElementAt ( const size_type  index) const
inlineprivatenoexcept

Definition at line 225 of file job_queue.hpp.

226 {
227 return m_Data + (index & m_CapacityMask);
228 }

References Job::SPSCQueue< T >::m_CapacityMask, and Job::SPSCQueue< T >::m_Data.

Referenced by Job::SPSCQueue< T >::PopLazy(), and Job::SPSCQueue< T >::PushLazy().

Member Data Documentation

◆ m_ProducerIndex

template<typename T >
atomic_size_type Job::SPSCQueue< T >::m_ProducerIndex
private

◆ m_Padding0

template<typename T >
unsigned char Job::SPSCQueue< T >::m_Padding0[k_FalseSharingPadSize - sizeof(m_ProducerIndex)]
private

Definition at line 121 of file job_queue.hpp.

◆ m_CachedConsumerIndex

template<typename T >
size_type Job::SPSCQueue< T >::m_CachedConsumerIndex
private

◆ m_Padding1

template<typename T >
unsigned char Job::SPSCQueue< T >::m_Padding1[k_FalseSharingPadSize - sizeof(m_CachedConsumerIndex)]
private

Definition at line 123 of file job_queue.hpp.

◆ m_ConsumerIndex

template<typename T >
atomic_size_type Job::SPSCQueue< T >::m_ConsumerIndex
private

◆ m_Padding2

template<typename T >
unsigned char Job::SPSCQueue< T >::m_Padding2[k_FalseSharingPadSize - sizeof(m_ConsumerIndex)]
private

Definition at line 128 of file job_queue.hpp.

◆ m_CachedProducerIndex

template<typename T >
size_type Job::SPSCQueue< T >::m_CachedProducerIndex
private

Definition at line 129 of file job_queue.hpp.

Referenced by Job::SPSCQueue< T >::Initialize(), and Job::SPSCQueue< T >::PopLazy().

◆ m_Padding3

template<typename T >
unsigned char Job::SPSCQueue< T >::m_Padding3[k_FalseSharingPadSize - sizeof(m_CachedProducerIndex)]
private

Definition at line 130 of file job_queue.hpp.

◆ m_Data

template<typename T >
T* Job::SPSCQueue< T >::m_Data
private

◆ m_Capacity

template<typename T >
size_type Job::SPSCQueue< T >::m_Capacity
private

Definition at line 135 of file job_queue.hpp.

Referenced by Job::SPSCQueue< T >::Initialize().

◆ m_CapacityMask

template<typename T >
size_type Job::SPSCQueue< T >::m_CapacityMask
private

◆ m_Padding4

template<typename T >
unsigned char Job::SPSCQueue< T >::m_Padding4[k_FalseSharingPadSize - sizeof(m_Data) - sizeof(m_Capacity) - sizeof(m_CapacityMask)]
private

Definition at line 137 of file job_queue.hpp.


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