24# include <sys/timeb.h>
26#elif defined(__APPLE__)
27# include <sys/sysctl.h>
28# include <sys/types.h>
35# include <tbb/spin_mutex.h>
90static pthread_mutex_t
_image_lock = PTHREAD_MUTEX_INITIALIZER;
94static pthread_mutex_t
_nodes_lock = PTHREAD_MUTEX_INITIALIZER;
97static pthread_mutex_t
_fftw_lock = PTHREAD_MUTEX_INITIALIZER;
104#define RE_MAX_THREAD BLENDER_MAX_THREADS
108 void *(*do_thread)(
void *);
125 if (threadbase !=
nullptr && tot > 0) {
135 for (a = 0; a < tot; a++) {
181 return pthread_equal(pthread_self(),
mainid);
189 tslot->callerdata = callerdata;
194 printf(
"ERROR: could not insert thread slot\n");
200 if (tslot->callerdata == callerdata) {
201 pthread_join(tslot->pthread,
nullptr);
202 tslot->callerdata =
nullptr;
213 if (counter == index && tslot->avail == 0) {
214 pthread_join(tslot->pthread,
nullptr);
215 tslot->callerdata =
nullptr;
226 if (tslot->avail == 0) {
227 pthread_join(tslot->pthread,
nullptr);
228 tslot->callerdata =
nullptr;
244 if (tslot->avail == 0) {
245 pthread_join(tslot->pthread,
nullptr);
267 GetSystemInfo(&info);
268 t =
int(info.dwNumberOfProcessors);
277 sysctl(mib, 2, &t, &
len,
nullptr, 0);
279 t =
int(sysconf(_SC_NPROCESSORS_ONLN));
342 pthread_mutex_init(
mutex,
nullptr);
347 pthread_mutex_lock(
mutex);
352 pthread_mutex_unlock(
mutex);
357 return (pthread_mutex_trylock(
mutex) == 0);
362 pthread_mutex_destroy(
mutex);
381static tbb::spin_mutex *tbb_spin_mutex_cast(
SpinLock *
spin)
383 static_assert(
sizeof(
SpinLock) >=
sizeof(tbb::spin_mutex),
384 "SpinLock must match tbb::spin_mutex");
385 static_assert(
alignof(
SpinLock) %
alignof(tbb::spin_mutex) == 0,
386 "SpinLock must be aligned same as tbb::spin_mutex");
387 return reinterpret_cast<tbb::spin_mutex *
>(
spin);
394 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
395 new (spin_mutex) tbb::spin_mutex();
396#elif defined(__APPLE__)
398#elif defined(_MSC_VER)
401 pthread_spin_init(
spin, 0);
408 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
410#elif defined(__APPLE__)
412#elif defined(_MSC_VER)
413# if defined(_M_ARM64)
415 static_assert(
sizeof(long) ==
sizeof(
SpinLock));
416 while (InterlockedExchangeAcquire((
volatile long *)
spin, 1)) {
418 while (InterlockedExchangeAcquire(
spin, 1)) {
426 pthread_spin_lock(
spin);
433 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
434 spin_mutex->unlock();
435#elif defined(__APPLE__)
437#elif defined(_MSC_VER)
441 pthread_spin_unlock(
spin);
448 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
449 spin_mutex->~spin_mutex();
450#elif defined(__APPLE__)
452#elif defined(_MSC_VER)
456 pthread_spin_destroy(
spin);
464 pthread_rwlock_init(
mutex,
nullptr);
470 pthread_rwlock_rdlock(
mutex);
473 pthread_rwlock_wrlock(
mutex);
479 pthread_rwlock_unlock(
mutex);
484 pthread_rwlock_destroy(
mutex);
516 pthread_cond_init(&ticket->
cond,
nullptr);
517 pthread_mutex_init(&ticket->
mutex,
nullptr);
524 pthread_mutex_destroy(&ticket->
mutex);
525 pthread_cond_destroy(&ticket->
cond);
533 pthread_mutex_lock(&ticket->
mutex);
536 if (check_recursive && ticket->
has_owner && pthread_equal(pthread_self(), ticket->
owner)) {
537 pthread_mutex_unlock(&ticket->
mutex);
544 pthread_cond_wait(&ticket->
cond, &ticket->
mutex);
547 ticket->
owner = pthread_self();
550 pthread_mutex_unlock(&ticket->
mutex);
566 pthread_mutex_lock(&ticket->
mutex);
569 pthread_cond_broadcast(&ticket->
cond);
570 pthread_mutex_unlock(&ticket->
mutex);
579 pthread_cond_init(cond,
nullptr);
584 pthread_cond_wait(cond,
mutex);
594 pthread_cond_signal(cond);
599 pthread_cond_broadcast(cond);
604 pthread_cond_destroy(cond);
625 pthread_mutex_init(&queue->mutex,
nullptr);
626 pthread_cond_init(&queue->push_cond,
nullptr);
627 pthread_cond_init(&queue->finish_cond,
nullptr);
635 pthread_cond_destroy(&queue->finish_cond);
636 pthread_cond_destroy(&queue->push_cond);
637 pthread_mutex_destroy(&queue->mutex);
646 pthread_mutex_lock(&queue->mutex);
651 pthread_cond_signal(&queue->push_cond);
652 pthread_mutex_unlock(&queue->mutex);
657 void *work =
nullptr;
660 pthread_mutex_lock(&queue->mutex);
662 pthread_cond_wait(&queue->push_cond, &queue->mutex);
670 pthread_cond_broadcast(&queue->finish_cond);
674 pthread_mutex_unlock(&queue->mutex);
689 usec = now.millitm * 1000;
694 gettimeofday(&now,
nullptr);
701 div_result = ldiv(ms, 1000);
702 timeout->tv_sec = sec + div_result.quot;
704 x = usec + (div_result.rem * 1000);
711 timeout->tv_nsec = x * 1000;
717 void *work =
nullptr;
724 pthread_mutex_lock(&queue->mutex);
726 if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
739 pthread_cond_broadcast(&queue->finish_cond);
743 pthread_mutex_unlock(&queue->mutex);
752 pthread_mutex_lock(&queue->mutex);
754 pthread_mutex_unlock(&queue->mutex);
763 pthread_mutex_lock(&queue->mutex);
765 pthread_mutex_unlock(&queue->mutex);
772 pthread_mutex_lock(&queue->mutex);
777 pthread_cond_broadcast(&queue->push_cond);
778 pthread_mutex_unlock(&queue->mutex);
784 pthread_mutex_lock(&queue->mutex);
787 pthread_cond_wait(&queue->finish_cond, &queue->mutex);
790 pthread_mutex_unlock(&queue->mutex);
#define BLI_assert_unreachable()
void BLI_gsqueue_free(GSQueue *queue)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
GSQueue * BLI_gsqueue_new(size_t elem_size)
bool BLI_gsqueue_is_empty(const GSQueue *queue)
size_t BLI_gsqueue_len(const GSQueue *queue)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
pthread_spinlock_t SpinLock
pthread_rwlock_t ThreadRWMutex
pthread_cond_t ThreadCondition
pthread_mutex_t ThreadMutex
Platform independent time functions.
double BLI_time_now_seconds(void)
Read Guarded memory(de)allocation.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE unsigned int atomic_fetch_and_add_u(unsigned int *p, unsigned int x)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
pthread_cond_t finish_cond
void *(* do_thread)(void *)
void BLI_condition_notify_all(ThreadCondition *cond)
bool BLI_mutex_trylock(ThreadMutex *mutex)
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
void BLI_thread_queue_push(ThreadQueue *queue, void *work)
void BLI_threadapi_init()
void * BLI_thread_queue_pop(ThreadQueue *queue)
void BLI_thread_unlock(int type)
void BLI_ticket_mutex_unlock(TicketMutex *ticket)
ThreadRWMutex * BLI_rw_mutex_alloc()
static pthread_mutex_t _image_lock
void BLI_mutex_end(ThreadMutex *mutex)
static void * tslot_thread_start(void *tslot_p)
void BLI_threadapi_exit()
void BLI_mutex_free(ThreadMutex *mutex)
static pthread_mutex_t _custom1_lock
void BLI_threadpool_clear(ListBase *threadbase)
void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot)
void BLI_thread_lock(int type)
bool BLI_ticket_mutex_lock_check_recursive(TicketMutex *ticket)
void BLI_threadpool_remove(ListBase *threadbase, void *callerdata)
TicketMutex * BLI_ticket_mutex_alloc()
static pthread_mutex_t _view3d_lock
void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex)
int BLI_system_num_threads_override_get()
static int threads_override_num
int BLI_threadpool_available_thread_index(ListBase *threadbase)
static void wait_timeout(timespec *timeout, int ms)
static bool ticket_mutex_lock(TicketMutex *ticket, const bool check_recursive)
void BLI_mutex_init(ThreadMutex *mutex)
static pthread_mutex_t _viewer_lock
void BLI_system_num_threads_override_set(int num)
void BLI_condition_end(ThreadCondition *cond)
static ThreadMutex * global_mutex_from_type(const int type)
void BLI_thread_queue_free(ThreadQueue *queue)
static uint thread_levels
ThreadQueue * BLI_thread_queue_init()
static pthread_mutex_t _colormanage_lock
static pthread_mutex_t _fftw_lock
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
void BLI_ticket_mutex_lock(TicketMutex *ticket)
void BLI_condition_notify_one(ThreadCondition *cond)
bool BLI_thread_queue_is_empty(ThreadQueue *queue)
void BLI_ticket_mutex_free(TicketMutex *ticket)
void BLI_condition_wait_global_mutex(ThreadCondition *cond, const int type)
static pthread_mutex_t _image_draw_lock
void BLI_threadpool_end(ListBase *threadbase)
void BLI_condition_init(ThreadCondition *cond)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_thread_queue_nowait(ThreadQueue *queue)
int BLI_system_thread_count()
void BLI_thread_queue_wait_finish(ThreadQueue *queue)
void BLI_mutex_unlock(ThreadMutex *mutex)
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
static pthread_mutex_t _nodes_lock
void BLI_threadpool_insert(ListBase *threadbase, void *callerdata)
static pthread_mutex_t _movieclip_lock
void BLI_spin_init(SpinLock *spin)
void BLI_spin_unlock(SpinLock *spin)
void BLI_threadpool_remove_index(ListBase *threadbase, int index)
int BLI_available_threads(ListBase *threadbase)
void BLI_spin_lock(SpinLock *spin)
void BLI_rw_mutex_free(ThreadRWMutex *mutex)
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
void BLI_spin_end(SpinLock *spin)
ThreadMutex * BLI_mutex_alloc()
void * BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
int BLI_thread_queue_len(ThreadQueue *queue)