BluFedora Job System v1.0.0
This is a C++ job system library for use in game engines.
job::internal Namespace Reference

Classes

struct  PrivateCtx
 

Typedefs

using JobFn = void(*)(const PrivateCtx &ctx)
 

Functions

void AssertHandler (const bool condition, const char *const filename, const int line_number, const char *const msg)
 
void DispatchImpl (const char *const name, Counter *const counter, const QueueMode queue, const JobFn func, const std::size_t user_data_size, const std::size_t user_data_alignment, const void *const user_data, void(*InitUserData)(void *const user_data, const void *const in_user_data)) noexcept
 

Typedef Documentation

◆ JobFn

using job::internal::JobFn = typedef void (*)(const PrivateCtx& ctx)

Definition at line 234 of file job_api.hpp.

Function Documentation

◆ AssertHandler()

void job::internal::AssertHandler ( const bool  condition,
const char *const  filename,
const int  line_number,
const char *const  msg 
)

◆ DispatchImpl()

void job::internal::DispatchImpl ( const char *const  name,
Counter *const  counter,
const QueueMode  queue,
const JobFn  func,
const std::size_t  user_data_size,
const std::size_t  user_data_alignment,
const void *const  user_data,
void(*)(void *const user_data, const void *const in_user_data)  InitUserData 
)
noexcept

Definition at line 947 of file job_system.cpp.

955{
956 const WorkerID worker_id = worker::GetCurrentID();
957 job::ThreadLocalState* const worker = system::GetWorker(worker_id);
958 const std::uint32_t max_tasks_per_worker = g_JobSystem->num_tasks_per_worker;
959
960 // Try to ensure some tasks are free to allocate.
961 {
962 if (worker->num_allocated_tasks == max_tasks_per_worker)
963 {
964 worker::GarbageCollectAllocatedTasks(worker);
965
966 if (worker->num_allocated_tasks == max_tasks_per_worker)
967 {
968 // While we cannot allocate do some work.
969 system::WakeUpAllWorkers();
970
971 while (worker->num_allocated_tasks == max_tasks_per_worker)
972 {
973 worker::TryRunTask(worker);
974 worker::GarbageCollectAllocatedTasks(worker);
975 }
976 }
977 }
978 }
979
980 Task* const task = task_pool::AllocateTask(&worker->task_allocator, name, func, counter);
981 const TaskHandle task_hdl = task_pool::TaskToIndex(worker->task_allocator, task);
982 const job::TaskPtr task_ptr = {worker_id, task_pool::TaskToIndex(worker->task_allocator, task)};
983
984 // Copy user data
985 {
986 const Byte* const user_data_end = task->user_data + sizeof(task->user_data);
987 Byte* const aligned_ptr = static_cast<Byte*>(AlignPointer(task->user_data, user_data_alignment));
988 const Byte* const aligned_ptr_end = aligned_ptr + user_data_size;
989 const std::ptrdiff_t alignment_offset = aligned_ptr - task->user_data;
990
991 JobAssert(aligned_ptr_end <= user_data_end, "Userdata could not be stored in task.");
992 JobAssert(alignment_offset <= std::uint8_t(-1), "Alignment delta too large.");
993
994 InitUserData(aligned_ptr, user_data);
995 task->userdata_align = static_cast<std::uint8_t>(alignment_offset);
996 }
997
998 worker->allocated_tasks[worker->num_allocated_tasks++] = task_hdl;
999
1000 const WorkerID num_workers = NumWorkers();
1001
1002 // If we only have one thread running using the worker queue is invalid.
1003 switch ((num_workers == 1u) ? QueueMode::Default : queue)
1004 {
1005 case QueueMode::Default:
1006 {
1007 task::SubmitQPushHelper(task_ptr, worker, &worker->normal_queue);
1008 break;
1009 }
1010 case QueueMode::WorkerOnly:
1011 {
1012 task::SubmitQPushHelper(task_ptr, worker, &worker->worker_queue);
1013 break;
1014 }
1015 default:
1016#if defined(__GNUC__) // GCC, Clang, ICC
1017 __builtin_unreachable();
1018#elif defined(_MSC_VER) // MSVC
1019 __assume(false);
1020#endif
1021 break;
1022 }
1023
1024 const std::int32_t num_pending_jobs = g_JobSystem->num_available_jobs.fetch_add(1, std::memory_order_relaxed);
1025
1026 if (num_pending_jobs >= num_workers)
1027 {
1028 system::WakeUpAllWorkers();
1029 }
1030 else
1031 {
1032 system::WakeUpOneWorker();
1033 }
1034}
#define JobAssert(expr, msg)
Definition: job_api.hpp:32
static job::JobSystemContext * g_JobSystem
Definition: job_system.cpp:207
std::uint16_t WorkerID
The id type of each worker thread.
Definition: job_api.hpp:39
std::uint32_t num_tasks_per_worker
Definition: job_system.cpp:189
std::uint16_t NumWorkers() noexcept
Returns the number of workers created by the system. This function can be called by any thread concur...
Definition: job_system.cpp:863
unsigned char Byte
Definition: job_system.cpp:84
std::uint16_t TaskHandle
Definition: job_system.cpp:79
std::atomic_uint32_t num_available_jobs
Definition: job_system.cpp:201

References job::Default, g_JobSystem, JobAssert, job::JobSystemContext::num_available_jobs, job::JobSystemContext::num_tasks_per_worker, job::NumWorkers(), and job::WorkerOnly.

Referenced by job::Dispatch().