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

146 {
147 m_ProducerIndex.store(0, std::memory_order_relaxed);
149 m_ConsumerIndex.store(0, std::memory_order_relaxed);
151 m_Data = memory_backing;
152 m_Capacity = capacity;
153 m_CapacityMask = capacity - 1;
154
155 JobAssert((m_Capacity & m_CapacityMask) == 0, "Capacity must be a power of 2.");
156 }
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 158 of file job_queue.hpp.

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

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

◆ Pop()

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

Definition at line 163 of file job_queue.hpp.

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

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

173 {
174 const size_type write_index = m_ProducerIndex.load(std::memory_order_relaxed);
175
176 if (IsFull(write_index, m_CachedConsumerIndex))
177 {
178 m_CachedConsumerIndex = m_ConsumerIndex.load(std::memory_order_acquire);
179 if (IsFull(write_index, m_CachedConsumerIndex))
180 {
181 return false;
182 }
183 }
184
185 callback(ElementAt(write_index));
186 m_ProducerIndex.store(write_index + 1, std::memory_order_release);
187
188 return true;
189 }
T * ElementAt(const size_type index) const noexcept
Definition: job_queue.hpp:224
bool IsFull(const size_type head, const size_type tail) const noexcept
Definition: job_queue.hpp:214
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 192 of file job_queue.hpp.

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

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

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

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

220 {
221 return head == tail;
222 }

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

◆ ElementAt()

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

Definition at line 224 of file job_queue.hpp.

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

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: