BluFedora Job System v1.0.0
This is a C++ job system library for use in game engines.
|
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... | |
Task * | Job::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... | |
API for a multi-threading job system.
References: [https://blog.molecular-matters.com/2015/08/24/job-system-2-0-lock-free-work-stealing-part-1-basics/] [https://manu343726.github.io/2017-03-13-lock-free-job-stealing-task-system-with-modern-c/] [https://github.com/cdwfs/cds_job/blob/master/cds_job.h] [https://github.com/cyshi/logbook/blob/master/src/common/work_stealing_queue.h] [https://fabiensanglard.net/doom3_bfg/threading.php] [https://gdcvault.com/play/1022186/Parallelizing-the-Naughty-Dog-Engine]
Definition in file job_api.hpp.
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. |
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. |