BluFedora Job System v1.0.0
This is a C++ job system library for use in game engines.
job_api.hpp File Reference

API for a multi-threading job system. More...

#include "job_assert.hpp"
#include "job_init_token.hpp"
#include <cstdint>
#include <new>
#include <utility>

Go to the source code of this file.

Classes

struct  Job::JobSystemCreateOptions
 The runtime configuration for the Job System. More...
 
struct  Job::JobSystemMemoryRequirements
 The memory requirements for a given configuration JobSystemCreateOptions. More...
 
struct  Job::TaskData
 A buffer for user-data you can write to, maybe large enough to store task data inline. More...
 
struct  Job::Splitter
 

Namespaces

namespace  Job
 
namespace  Job::detail
 

Typedefs

using Job::WorkerID = std::uint16_t
 The id type of each worker thread. More...
 
using Job::TaskFn = void(*)(Task *)
 The signature of the type of function for a single Task. More...
 

Enumerations

enum class  Job::QueueType : std::uint8_t { Job::NORMAL = 0 , Job::MAIN = 1 , Job::WORKER = 2 }
 Determines which threads the task will be allowed to run on. More...
 

Functions

QueueType Job::detail::taskQType (const Task *task) noexcept
 
void * Job::detail::taskGetPrivateUserData (Task *const task, const std::size_t alignment) noexcept
 
void * Job::detail::taskReservePrivateUserData (Task *const task, const std::size_t num_bytes, const std::size_t alignment) noexcept
 
bool Job::detail::mainQueueTryRunTask (void) noexcept
 
std::size_t Job::NumSystemThreads () noexcept
 Makes some system calls to grab the number threads / processors on the device. This function can be called by any thread concurrently. More...
 
InitializationToken Job::Initialize (const JobSystemMemoryRequirements &memory_requirements={}, void *const memory=nullptr) noexcept
 Sets up the Job system and creates all the worker threads. The thread that calls 'Job::Initialize' is considered the main thread. More...
 
void Job::SetupUserThread ()
 Must be called in the callstack of the thread to be setup. More...
 
const char * Job::ProcessorArchitectureName () noexcept
 An implementation defined name for the CPU architecture of the device. This function can be called by any thread concurrently. More...
 
std::uint16_t Job::NumWorkers () noexcept
 Returns the number of workers created by the system. This function can be called by any thread concurrently. More...
 
WorkerID Job::CurrentWorker () noexcept
 The current id of the current thread. This function can be called by any thread concurrently. More...
 
bool Job::IsMainThread () noexcept
 Allows for querying if we are currently executing in the main thread. More...
 
void Job::Shutdown () noexcept
 This will deallocate any memory used by the system and shutdown any threads created by 'bfJob::initialize'. More...
 
TaskJob::TaskMake (const TaskFn function, Task *const parent=nullptr) noexcept
 Creates a new Task that should be later submitted by calling 'TaskSubmit'. More...
 
TaskData Job::TaskGetData (Task *const task, const std::size_t alignment) noexcept
 Returns you the user-data buffer you way write to get data into your TaskFn. More...
 
void Job::TaskAddContinuation (Task *const self, Task *const continuation, const QueueType queue=QueueType::NORMAL) noexcept
 A 'continuation' is a task that will be added to a queue after the 'self' Task has finished running. More...
 
template<typename T >
T * Job::TaskDataAs (Task *const task) noexcept
 Grabs the user-data pointer as the T you specified. No safety is guaranteed, this is just a dumb cast. More...
 
template<typename T , typename... Args>
void Job::TaskEmplaceData (Task *const task, Args &&... args)
 Calls the constructor of T on the user-data buffer. More...
 
template<typename T >
void Job::TaskSetData (Task *const task, const T &data)
 Copies 'data' into the user-data buffer by calling the T copy constructor. More...
 
template<typename T >
void Job::TaskDestructData (Task *const task)
 Helper for calling destructor on the task's user data. More...
 
template<typename Closure >
Task * Job::TaskMake (Closure &&function, Task *const parent=nullptr)
 Creates a new task making a copy of the closure. More...
 
void Job::TaskIncRef (Task *const task) noexcept
 Increments the task's ref count preventing it from being garbage collected. More...
 
void Job::TaskDecRef (Task *const task) noexcept
 Decrements the task's ref count allow it to be garbage collected. More...
 
bool Job::TaskIsDone (const Task *const task) noexcept
 Returns the done status of the task. More...
 
template<typename ConditionFn >
void Job::TickMainQueue (ConditionFn &&condition) noexcept
 Runs tasks from the main queue as long as there are tasks available and condition returns true. More...
 
void Job::TickMainQueue () noexcept
 Runs tasks from the main queue until it is empty. More...
 
void Job::TaskSubmit (Task *const self, const QueueType queue=QueueType::NORMAL) noexcept
 Submits the task to the specified queue. More...
 
void Job::WaitOnTask (const Task *const task) noexcept
 Waits until the specified task is done executing. This function will block but do work while being blocked so there is no wasted time. More...
 
void Job::TaskSubmitAndWait (Task *const self, const QueueType queue=QueueType::NORMAL) noexcept
 Same as calling taskSubmit followed by waitOnTask. More...
 
void Job::PauseProcessor () noexcept
 CPU pause instruction to indicate when you are in a spin wait loop. More...
 
void Job::YieldTimeSlice () noexcept
 Asks the OS to yield this threads execution to another thread on the current cpu core. More...
 
template<typename F , typename S >
Task * Job::ParallelFor (const std::size_t start, const std::size_t count, S &&splitter, F &&fn, Task *parent=nullptr)
 Parallel for algorithm, splits the work up recursively splitting based on the splitter passed in. More...
 
template<typename Splitter , typename Reducer >
Task * Job::ParallelReduce (const std::size_t start, const std::size_t count, Splitter &&splitter, Reducer &&reduce, Task *parent=nullptr)
 
template<typename T , typename F , typename S >
Task * Job::ParallelFor (T *const data, const std::size_t count, S &&splitter, F &&fn, Task *parent=nullptr)
 Parallel for algorithm, splits the work up recursively splitting based on the splitter passed in. This version is a helper for array data. More...
 
template<typename... F>
Task * Job::ParallelInvoke (Task *const parent, F &&... fns)
 Invokes each passed in function object in parallel. More...
 

Detailed Description


Class Documentation

◆ Job::JobSystemCreateOptions

struct Job::JobSystemCreateOptions

The runtime configuration for the Job System.

Definition at line 85 of file job_api.hpp.

Class Members
uint8_t num_user_threads The number of threads not owned by this system but wants access to the Job API (The thread must call Job::SetupUserThread).
uint8_t num_threads Use 0 to indicate using the number of cores available on the system.
uint16_t main_queue_size Number of tasks in the job system's QueueType::MAIN queue. (Must be power of two)
uint16_t normal_queue_size Number of tasks in each worker's QueueType::NORMAL queue. (Must be power of two)
uint16_t worker_queue_size Number of tasks in each worker's QueueType::WORKER queue. (Must be power of two)
uint64_t job_steal_rng_seed The RNG for work queue stealing will be seeded with this value.

◆ Job::TaskData

struct Job::TaskData

A buffer for user-data you can write to, maybe large enough to store task data inline.

If you store non trivial data remember to manually call it's destructor at the end of the task function.

If you call 'TaskEmplaceData' or 'TaskSetData' and need to update the data once more be sure to destruct the previous contents correctly if the data stored in the buffer is non trivial.

Definition at line 203 of file job_api.hpp.

Class Members
void * ptr The start of the buffer you may write to.
size_t size The size of the buffer.