Blender V5.0
threads.cc File Reference
#include <algorithm>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_threads.h"
#include "BLI_time.h"
#include "BLI_utildefines.h"
#include <sys/time.h>
#include <unistd.h>
#include "atomic_ops.h"

Go to the source code of this file.

Classes

struct  ThreadSlot
struct  TicketMutex
struct  ThreadQueueWork
struct  ThreadQueue

Macros

#define RE_MAX_THREAD   BLENDER_MAX_THREADS

Functions

void BLI_threadapi_init ()
void BLI_threadapi_exit ()
void BLI_threadpool_init (ListBase *threadbase, void *(*do_thread)(void *), int tot)
int BLI_available_threads (ListBase *threadbase)
int BLI_threadpool_available_thread_index (ListBase *threadbase)
static void * tslot_thread_start (void *tslot_p)
int BLI_thread_is_main ()
void BLI_threadpool_insert (ListBase *threadbase, void *callerdata)
void BLI_threadpool_remove (ListBase *threadbase, void *callerdata)
void BLI_threadpool_remove_index (ListBase *threadbase, int index)
void BLI_threadpool_clear (ListBase *threadbase)
void BLI_threadpool_end (ListBase *threadbase)
int BLI_system_thread_count ()
void BLI_system_num_threads_override_set (int num)
int BLI_system_num_threads_override_get ()
static ThreadMutexglobal_mutex_from_type (const int type)
void BLI_thread_lock (int type)
void BLI_thread_unlock (int type)
void BLI_mutex_init (ThreadMutex *mutex)
void BLI_mutex_lock (ThreadMutex *mutex)
void BLI_mutex_unlock (ThreadMutex *mutex)
bool BLI_mutex_trylock (ThreadMutex *mutex)
void BLI_mutex_end (ThreadMutex *mutex)
ThreadMutexBLI_mutex_alloc ()
void BLI_mutex_free (ThreadMutex *mutex)
void BLI_spin_init (SpinLock *spin)
void BLI_spin_lock (SpinLock *spin)
void BLI_spin_unlock (SpinLock *spin)
void BLI_spin_end (SpinLock *spin)
void BLI_rw_mutex_init (ThreadRWMutex *mutex)
void BLI_rw_mutex_lock (ThreadRWMutex *mutex, int mode)
void BLI_rw_mutex_unlock (ThreadRWMutex *mutex)
void BLI_rw_mutex_end (ThreadRWMutex *mutex)
ThreadRWMutexBLI_rw_mutex_alloc ()
void BLI_rw_mutex_free (ThreadRWMutex *mutex)
TicketMutexBLI_ticket_mutex_alloc ()
void BLI_ticket_mutex_free (TicketMutex *ticket)
static bool ticket_mutex_lock (TicketMutex *ticket, const bool check_recursive)
void BLI_ticket_mutex_lock (TicketMutex *ticket)
bool BLI_ticket_mutex_lock_check_recursive (TicketMutex *ticket)
void BLI_ticket_mutex_unlock (TicketMutex *ticket)
void BLI_condition_init (ThreadCondition *cond)
void BLI_condition_wait (ThreadCondition *cond, ThreadMutex *mutex)
void BLI_condition_wait_global_mutex (ThreadCondition *cond, const int type)
void BLI_condition_notify_one (ThreadCondition *cond)
void BLI_condition_notify_all (ThreadCondition *cond)
void BLI_condition_end (ThreadCondition *cond)
ThreadQueueBLI_thread_queue_init ()
void BLI_thread_queue_free (ThreadQueue *queue)
uint64_t BLI_thread_queue_push (ThreadQueue *queue, void *work, ThreadQueueWorkPriority priority)
static void check_finalization (ThreadQueue *queue)
void BLI_thread_queue_cancel_work (ThreadQueue *queue, uint64_t work_id)
void * BLI_thread_queue_pop (ThreadQueue *queue)
static void wait_timeout (timespec *timeout, int ms)
void * BLI_thread_queue_pop_timeout (ThreadQueue *queue, int ms)
int BLI_thread_queue_len (ThreadQueue *queue)
bool BLI_thread_queue_is_empty (ThreadQueue *queue)
void BLI_thread_queue_nowait (ThreadQueue *queue)
void BLI_thread_queue_wait_finish (ThreadQueue *queue)

Variables

static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _image_draw_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t _view3d_lock = PTHREAD_MUTEX_INITIALIZER
static pthread_t mainid
static uint thread_levels = 0
static int threads_override_num = 0

Macro Definition Documentation

◆ RE_MAX_THREAD

#define RE_MAX_THREAD   BLENDER_MAX_THREADS

Definition at line 104 of file threads.cc.

Referenced by BLI_system_thread_count(), and BLI_threadpool_init().

Function Documentation

◆ BLI_available_threads()

int BLI_available_threads ( struct ListBase * threadbase)

Amount of available threads.

Definition at line 146 of file threads.cc.

References LISTBASE_FOREACH.

Referenced by ZstdWriteWrap::write().

◆ BLI_condition_end()

void BLI_condition_end ( ThreadCondition * cond)

◆ BLI_condition_init()

◆ BLI_condition_notify_all()

void BLI_condition_notify_all ( ThreadCondition * cond)

Definition at line 595 of file threads.cc.

Referenced by IMB_thumb_path_unlock().

◆ BLI_condition_notify_one()

◆ BLI_condition_wait()

void BLI_condition_wait ( ThreadCondition * cond,
ThreadMutex * mutex )

Definition at line 580 of file threads.cc.

References mutex.

Referenced by blender::ed::vse::preview_startjob(), and blender::seq::seq_prefetch_do_suspend().

◆ BLI_condition_wait_global_mutex()

void BLI_condition_wait_global_mutex ( ThreadCondition * cond,
const int type )

Definition at line 585 of file threads.cc.

References global_mutex_from_type().

Referenced by IMB_thumb_path_lock().

◆ BLI_mutex_alloc()

ThreadMutex * BLI_mutex_alloc ( void )

Definition at line 365 of file threads.cc.

References BLI_mutex_init(), MEM_callocN(), and mutex.

Referenced by blender::ed::vse::sequencer_preview_add_sound().

◆ BLI_mutex_end()

◆ BLI_mutex_free()

void BLI_mutex_free ( ThreadMutex * mutex)

Definition at line 372 of file threads.cc.

References BLI_mutex_end(), MEM_freeN(), and mutex.

Referenced by blender::ed::vse::free_preview_job().

◆ BLI_mutex_init()

◆ BLI_mutex_lock()

◆ BLI_mutex_trylock()

bool BLI_mutex_trylock ( ThreadMutex * mutex)

Definition at line 355 of file threads.cc.

References mutex.

◆ BLI_mutex_unlock()

◆ BLI_rw_mutex_alloc()

ThreadRWMutex * BLI_rw_mutex_alloc ( void )

◆ BLI_rw_mutex_end()

void BLI_rw_mutex_end ( ThreadRWMutex * mutex)

Definition at line 482 of file threads.cc.

References mutex.

Referenced by BLI_rw_mutex_free(), and BaseRender::~BaseRender().

◆ BLI_rw_mutex_free()

void BLI_rw_mutex_free ( ThreadRWMutex * mutex)

Definition at line 494 of file threads.cc.

References BLI_rw_mutex_end(), MEM_freeN(), and mutex.

Referenced by fluid_modifier_freeDomain().

◆ BLI_rw_mutex_init()

void BLI_rw_mutex_init ( ThreadRWMutex * mutex)

Definition at line 462 of file threads.cc.

References mutex.

Referenced by BLI_rw_mutex_alloc().

◆ BLI_rw_mutex_lock()

◆ BLI_rw_mutex_unlock()

◆ BLI_spin_end()

◆ BLI_spin_init()

◆ BLI_spin_lock()

◆ BLI_spin_unlock()

◆ BLI_system_num_threads_override_get()

int BLI_system_num_threads_override_get ( void )

Definition at line 294 of file threads.cc.

References threads_override_num.

Referenced by BKE_render_num_threads(), BLI_task_scheduler_init(), and OIIO_init().

◆ BLI_system_num_threads_override_set()

void BLI_system_num_threads_override_set ( int num)

Definition at line 289 of file threads.cc.

References num, and threads_override_num.

Referenced by arg_handle_threads_set().

◆ BLI_system_thread_count()

◆ BLI_thread_is_main()

int BLI_thread_is_main ( void )

Definition at line 179 of file threads.cc.

References mainid.

Referenced by blender::gpu::GPUSecondaryContext::activate(), BKE_icon_geom_ensure(), BKE_icon_geom_from_file(), BKE_icon_geom_from_memory(), BKE_icon_get(), BKE_icon_gplayer_color_ensure(), BKE_icon_id_delete(), BKE_icon_id_ensure(), BKE_icons_free(), BKE_icons_init(), BKE_image_free_gputextures(), BKE_image_free_unused_gpu_textures(), BKE_previewimg_cached_ensure(), BKE_previewimg_cached_get(), BKE_previewimg_cached_release(), BKE_previewimg_cached_thumbnail_read(), BLI_change_working_dir(), BLT_translate(), BPY_context_update(), ctx_data_get(), ctx_wm_python_context_get(), blender::gpu::VKDevice::debug_print(), ContextShared::disable(), blender::draw::DebugDraw::display_to_view(), DRW_blender_gpu_render_context_enable(), DRW_gpu_context_activate(), DRW_gpu_context_destroy(), DRW_gpu_context_release(), DRW_system_gpu_render_context_enable(), ED_preview_ensure_dbase(), ED_render_id_flush_update(), ED_render_scene_update(), engine_depsgraph_free(), RenderDisplay::ensure_system_gpu_context(), blender::render::Compositor::execute(), GPU_batch_preset_sphere(), GPU_batch_preset_sphere_wire(), blender::gpu::GPUSecondaryContext::GPUSecondaryContext(), icon_gplayer_color_ensure_create_icon(), icon_id_ensure_create_icon(), image_init_after_load(), blender::eevee::LightBake::LightBake(), RE_engine_gpu_context_create(), RE_FreeUnusedGPUResources(), blender::gpu::VKBackend::render_end(), blender::eevee::LightBake::update(), wm_file_write(), wm_job_end(), wm_surface_reset_drawable(), WM_system_gpu_context_create(), wm_window_events_process(), wm_window_reset_drawable(), blender::render::Compositor::~Compositor(), blender::gpu::GPUSecondaryContext::~GPUSecondaryContext(), blender::eevee::LightBake::~LightBake(), and RenderDisplay::~RenderDisplay().

◆ BLI_thread_lock()

◆ BLI_thread_queue_cancel_work()

void BLI_thread_queue_cancel_work ( ThreadQueue * queue,
uint64_t work_id )

Remove the corresponding work from the queue.

Definition at line 684 of file threads.cc.

References check_finalization(), ThreadQueue::mutex, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, and ThreadQueue::queue_normal_priority.

◆ BLI_thread_queue_free()

void BLI_thread_queue_free ( ThreadQueue * queue)

Deallocate the ThreadQueue. Assumes no one is using the queue anymore.

Definition at line 635 of file threads.cc.

References ThreadQueue::finish_cond, ThreadQueue::mutex, and ThreadQueue::push_cond.

Referenced by filelist_cache_previews_free(), PreviewLoadJob::~PreviewLoadJob(), and TaskPool::~TaskPool().

◆ BLI_thread_queue_init()

ThreadQueue * BLI_thread_queue_init ( void )

◆ BLI_thread_queue_is_empty()

bool BLI_thread_queue_is_empty ( ThreadQueue * queue)
Returns
true if there are no pending works in the queue.

Definition at line 839 of file threads.cc.

References ThreadQueue::mutex, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, and ThreadQueue::queue_normal_priority.

Referenced by filelist_cache_previews_update().

◆ BLI_thread_queue_len()

int BLI_thread_queue_len ( ThreadQueue * queue)
Returns
the total amount of pending works still in the queue.

Definition at line 827 of file threads.cc.

References ThreadQueue::mutex, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, ThreadQueue::queue_normal_priority, and size().

◆ BLI_thread_queue_nowait()

void BLI_thread_queue_nowait ( ThreadQueue * queue)

After calling this function, BLI_thread_queue_pop and BLI_thread_queue_pop_timeout won't block the calling thread even when the queue is empty.

Definition at line 851 of file threads.cc.

References ThreadQueue::mutex, ThreadQueue::nowait, and ThreadQueue::push_cond.

Referenced by filelist_cache_previews_free().

◆ BLI_thread_queue_pop()

void * BLI_thread_queue_pop ( ThreadQueue * queue)

Pop the oldest, highest priority work from the queue. Blocks the calling thread unless BLI_thread_queue_nowait has been called for this queue.

Returns
nullptr if nowait has been set and the queue is empty. Otherwise returns a work pointer.

Definition at line 712 of file threads.cc.

References check_finalization(), ThreadQueue::mutex, ThreadQueue::nowait, ThreadQueue::push_cond, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, ThreadQueue::queue_normal_priority, and ThreadQueueWork::work.

Referenced by filelist_cache_previews_update().

◆ BLI_thread_queue_pop_timeout()

void * BLI_thread_queue_pop_timeout ( ThreadQueue * queue,
int ms )

Try to pop the oldest, highest priority work from the queue. Blocks the calling thread unless BLI_thread_queue_nowait has been called for this queue.

Returns
nullptr if time runs out, or if nowait has been set and the queue is empty. Otherwise returns a work pointer.

Definition at line 782 of file threads.cc.

References BLI_time_now_seconds(), check_finalization(), ThreadQueue::mutex, ThreadQueue::nowait, ThreadQueue::push_cond, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, ThreadQueue::queue_normal_priority, wait_timeout(), and ThreadQueueWork::work.

Referenced by filelist_cache_previews_clear(), blender::gpu::VKDevice::render_graph_new(), and blender::gpu::VKDevice::submission_runner().

◆ BLI_thread_queue_push()

uint64_t BLI_thread_queue_push ( ThreadQueue * queue,
void * work,
ThreadQueueWorkPriority priority )

Push one work pointer to the queue. Higher priority works always take priority over lower priority ones, regardless of their insertion order. Works within the same priority follow FIFO order.

Returns
a unique work_id that can be used later for canceling the work before it's popped out from the queue.

Definition at line 645 of file threads.cc.

References BLI_assert, BLI_THREAD_QUEUE_WORK_PRIORITY_HIGH, BLI_THREAD_QUEUE_WORK_PRIORITY_LOW, BLI_THREAD_QUEUE_WORK_PRIORITY_NORMAL, ThreadQueue::current_id, ThreadQueueWork::id, ThreadQueue::mutex, ThreadQueue::push_cond, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, ThreadQueue::queue_normal_priority, and ThreadQueueWork::work.

Referenced by blender::gpu::VKDevice::context_unregister(), filelist_cache_preview_runf(), filelist_cache_previews_push(), PreviewLoadJob::push_load_request(), blender::gpu::VKDevice::render_graph_submit(), and blender::gpu::VKDevice::submission_runner().

◆ BLI_thread_queue_wait_finish()

void BLI_thread_queue_wait_finish ( ThreadQueue * queue)

Blocks the calling thread until the queue is empty.

Definition at line 862 of file threads.cc.

References ThreadQueue::finish_cond, ThreadQueue::mutex, ThreadQueue::queue_high_priority, ThreadQueue::queue_low_priority, and ThreadQueue::queue_normal_priority.

◆ BLI_thread_unlock()

◆ BLI_threadapi_exit()

void BLI_threadapi_exit ( void )

◆ BLI_threadapi_init()

void BLI_threadapi_init ( void )

◆ BLI_threadpool_available_thread_index()

int BLI_threadpool_available_thread_index ( struct ListBase * threadbase)

Returns thread number, for sample patterns or threadsafe tables.

Definition at line 159 of file threads.cc.

References LISTBASE_FOREACH.

◆ BLI_threadpool_clear()

void BLI_threadpool_clear ( ListBase * threadbase)

Definition at line 223 of file threads.cc.

References LISTBASE_FOREACH.

◆ BLI_threadpool_end()

◆ BLI_threadpool_init()

void BLI_threadpool_init ( struct ListBase * threadbase,
void *(* do_thread )(void *),
int tot )
Parameters
totWhen 0 only initializes malloc mutex in a safe way (see sequence.c) problem otherwise: scene render will kill of the mutex!

Definition at line 121 of file threads.cc.

References atomic_fetch_and_add_u(), ThreadSlot::avail, BLI_addtail(), BLI_listbase_clear(), ThreadSlot::do_thread, MEM_callocN(), RE_MAX_THREAD, and thread_levels.

Referenced by ZstdWriteWrap::open(), sb_cf_threads_run(), sb_sfesf_threads_run(), blender::seq::seq_prefetch_start_ex(), TaskPool::TaskPool(), and WM_jobs_start().

◆ BLI_threadpool_insert()

void BLI_threadpool_insert ( ListBase * threadbase,
void * callerdata )

◆ BLI_threadpool_remove()

void BLI_threadpool_remove ( ListBase * threadbase,
void * callerdata )

◆ BLI_threadpool_remove_index()

void BLI_threadpool_remove_index ( ListBase * threadbase,
int index )

Definition at line 208 of file threads.cc.

References LISTBASE_FOREACH.

◆ BLI_ticket_mutex_alloc()

TicketMutex * BLI_ticket_mutex_alloc ( void )

◆ BLI_ticket_mutex_free()

void BLI_ticket_mutex_free ( TicketMutex * ticket)

◆ BLI_ticket_mutex_lock()

void BLI_ticket_mutex_lock ( TicketMutex * ticket)

◆ BLI_ticket_mutex_lock_check_recursive()

bool BLI_ticket_mutex_lock_check_recursive ( TicketMutex * ticket)

Definition at line 557 of file threads.cc.

References ticket_mutex_lock().

Referenced by DRW_lock_start(), and DRW_submission_start().

◆ BLI_ticket_mutex_unlock()

◆ check_finalization()

void check_finalization ( ThreadQueue * queue)
static

◆ global_mutex_from_type()

◆ ticket_mutex_lock()

bool ticket_mutex_lock ( TicketMutex * ticket,
const bool check_recursive )
static

◆ tslot_thread_start()

void * tslot_thread_start ( void * tslot_p)
static

Definition at line 173 of file threads.cc.

References ThreadSlot::callerdata, and ThreadSlot::do_thread.

Referenced by BLI_threadpool_insert().

◆ wait_timeout()

void wait_timeout ( timespec * timeout,
int ms )
static

Definition at line 747 of file threads.cc.

References x.

Referenced by BLI_thread_queue_pop_timeout().

Variable Documentation

◆ _colormanage_lock

pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 96 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _custom1_lock

pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 93 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _fftw_lock

pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 97 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _image_draw_lock

pthread_mutex_t _image_draw_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 91 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _image_lock

pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER
static

Basic Thread Control API

Many thread cases have an X amount of jobs, and only an Y amount of threads are useful (typically amount of CPU's)

This code can be used to start a maximum amount of 'thread slots', which then can be filled in a loop with an idle timer.

A sample loop can look like this (pseudo c);

int max_threads = 2;
int cont = 1;
BLI_threadpool_init(&lb, do_something_func, max_threads);
while (cont) {
if (BLI_available_threads(&lb) && !(escape loop event)) {
// get new job (data pointer)
// tag job 'processed
}
// Find if a job is ready, this the do_something_func() should write in job somewhere.
cont = 0;
for (go over all jobs)
if (job is ready) {
if (job was not removed) {
}
}
else cont = 1;
}
// Conditions to exit loop.
if (if escape loop event) {
if (BLI_available_threadslots(&lb) == max_threads) {
break;
}
}
}
void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata)
Definition threads.cc:197
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
Definition threads.cc:121
void BLI_threadpool_end(struct ListBase *threadbase)
Definition threads.cc:234
int BLI_available_threads(struct ListBase *threadbase)
Definition threads.cc:146
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
Definition threads.cc:184
void BLI_time_sleep_ms(int ms)
Definition time.cc:133
bool all(VecOp< bool, D >) RET

Definition at line 90 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _movieclip_lock

pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 95 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _nodes_lock

pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 94 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _view3d_lock

pthread_mutex_t _view3d_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 98 of file threads.cc.

Referenced by global_mutex_from_type().

◆ _viewer_lock

pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 92 of file threads.cc.

Referenced by global_mutex_from_type().

◆ mainid

pthread_t mainid
static

Definition at line 99 of file threads.cc.

Referenced by BLI_thread_is_main(), and BLI_threadapi_init().

◆ thread_levels

uint thread_levels = 0
static

Definition at line 100 of file threads.cc.

Referenced by BLI_threadpool_init().

◆ threads_override_num

int threads_override_num = 0
static