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 110 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 113 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 114 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 144 of file job_queue.hpp.

145 {
146 m_ProducerIndex.store(0, std::memory_order_relaxed);
148 m_ConsumerIndex.store(0, std::memory_order_relaxed);
150 m_Data = memory_backing;
151 m_Capacity = capacity;
152 m_CapacityMask = capacity - 1;
153
154 JobAssert((m_Capacity & m_CapacityMask) == 0, "Capacity must be a power of 2.");
155 }
size_type m_CachedProducerIndex
Definition: job_queue.hpp:128
size_type m_Capacity
Definition: job_queue.hpp:134
size_type m_CachedConsumerIndex
Definition: job_queue.hpp:121
size_type m_CapacityMask
Definition: job_queue.hpp:135
atomic_size_type m_ConsumerIndex
Definition: job_queue.hpp:126
atomic_size_type m_ProducerIndex
Definition: job_queue.hpp:119
#define JobAssert(expr, msg)
Definition: job_api.hpp:32

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 157 of file job_queue.hpp.

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

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

◆ Pop()

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

Definition at line 162 of file job_queue.hpp.

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

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 170 of file job_queue.hpp.

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

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 190 of file job_queue.hpp.

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

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 212 of file job_queue.hpp.

213 {
214 return ((head + 1) & m_CapacityMask) == tail;
215 }

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 217 of file job_queue.hpp.

218 {
219 return head == tail;
220 }

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

◆ ElementAt()

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

Definition at line 222 of file job_queue.hpp.

223 {
224 return m_Data + (index & m_CapacityMask);
225 }

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 120 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 122 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 127 of file job_queue.hpp.

◆ m_CachedProducerIndex

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

Definition at line 128 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 129 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 134 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 136 of file job_queue.hpp.


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