40 # include <sys/timeb.h>
42 #elif defined(__APPLE__)
43 # include <sys/sysctl.h>
44 # include <sys/types.h>
46 # include <sys/time.h>
51 # include <tbb/spin_mutex.h>
57 #if defined(__APPLE__) && defined(_OPENMP) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) && \
59 # define USE_APPLE_OMP_FIX
62 #ifdef USE_APPLE_OMP_FIX
64 extern pthread_key_t gomp_tls_key;
65 static void *thread_tls_data;
125 static pthread_mutex_t
_fftw_lock = PTHREAD_MUTEX_INITIALIZER;
133 #define RE_MAX_THREAD BLENDER_MAX_THREADS
137 void *(*do_thread)(
void *);
163 if (threadbase !=
nullptr && tot > 0) {
173 for (
a = 0;
a < tot;
a++) {
183 #ifdef USE_APPLE_OMP_FIX
187 thread_tls_data = pthread_getspecific(gomp_tls_key);
225 #ifdef USE_APPLE_OMP_FIX
228 pthread_setspecific(gomp_tls_key, thread_tls_data);
236 return pthread_equal(pthread_self(),
mainid);
249 printf(
"ERROR: could not insert thread slot\n");
256 pthread_join(tslot->pthread,
nullptr);
257 tslot->callerdata =
nullptr;
268 if (counter == index && tslot->avail == 0) {
269 pthread_join(tslot->pthread,
nullptr);
270 tslot->callerdata =
nullptr;
281 if (tslot->avail == 0) {
282 pthread_join(tslot->pthread,
nullptr);
283 tslot->callerdata =
nullptr;
299 if (tslot->avail == 0) {
300 pthread_join(tslot->pthread,
nullptr);
323 GetSystemInfo(&info);
324 t = (int)info.dwNumberOfProcessors;
333 sysctl(mib, 2, &
t, &
len,
nullptr, 0);
335 t = (int)sysconf(_SC_NPROCESSORS_ONLN);
398 pthread_mutex_init(
mutex,
nullptr);
403 pthread_mutex_lock(
mutex);
408 pthread_mutex_unlock(
mutex);
413 return (pthread_mutex_trylock(
mutex) == 0);
418 pthread_mutex_destroy(
mutex);
437 static tbb::spin_mutex *tbb_spin_mutex_cast(
SpinLock *
spin)
439 static_assert(
sizeof(
SpinLock) >=
sizeof(tbb::spin_mutex),
440 "SpinLock must match tbb::spin_mutex");
441 static_assert(
alignof(
SpinLock) %
alignof(tbb::spin_mutex) == 0,
442 "SpinLock must be aligned same as tbb::spin_mutex");
443 return reinterpret_cast<tbb::spin_mutex *
>(
spin);
450 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
451 new (spin_mutex) tbb::spin_mutex();
452 #elif defined(__APPLE__)
454 #elif defined(_MSC_VER)
457 pthread_spin_init(
spin, 0);
464 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
466 #elif defined(__APPLE__)
468 #elif defined(_MSC_VER)
469 while (InterlockedExchangeAcquire(
spin, 1)) {
476 pthread_spin_lock(
spin);
483 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
484 spin_mutex->unlock();
485 #elif defined(__APPLE__)
487 #elif defined(_MSC_VER)
491 pthread_spin_unlock(
spin);
498 tbb::spin_mutex *spin_mutex = tbb_spin_mutex_cast(
spin);
499 spin_mutex->~spin_mutex();
500 #elif defined(__APPLE__)
502 #elif defined(_MSC_VER)
505 pthread_spin_destroy(
spin);
513 pthread_rwlock_init(
mutex,
nullptr);
519 pthread_rwlock_rdlock(
mutex);
522 pthread_rwlock_wrlock(
mutex);
528 pthread_rwlock_unlock(
mutex);
533 pthread_rwlock_destroy(
mutex);
563 pthread_cond_init(&ticket->
cond,
nullptr);
564 pthread_mutex_init(&ticket->
mutex,
nullptr);
571 pthread_mutex_destroy(&ticket->
mutex);
572 pthread_cond_destroy(&ticket->
cond);
578 unsigned int queue_me;
580 pthread_mutex_lock(&ticket->
mutex);
584 pthread_cond_wait(&ticket->
cond, &ticket->
mutex);
587 pthread_mutex_unlock(&ticket->
mutex);
592 pthread_mutex_lock(&ticket->
mutex);
594 pthread_cond_broadcast(&ticket->
cond);
595 pthread_mutex_unlock(&ticket->
mutex);
604 pthread_cond_init(cond,
nullptr);
609 pthread_cond_wait(cond,
mutex);
619 pthread_cond_signal(cond);
624 pthread_cond_broadcast(cond);
629 pthread_cond_destroy(cond);
682 void *work =
nullptr;
714 usec = now.millitm * 1000;
719 gettimeofday(&now,
nullptr);
726 div_result = ldiv(ms, 1000);
727 timeout->tv_sec = sec + div_result.quot;
729 x = usec + (div_result.rem * 1000);
736 timeout->tv_nsec =
x * 1000;
742 void *work =
nullptr;
743 struct timespec timeout;
821 static bool check_is_threadripper2_alike_topology(
void)
827 static bool is_threadripper2 =
false;
829 return is_threadripper2;
833 if (cpu_brand ==
nullptr) {
836 if (strstr(cpu_brand,
"Threadripper")) {
845 if (strstr(cpu_brand,
"2990WX") || strstr(cpu_brand,
"2950X")) {
846 is_threadripper2 =
true;
855 if (strstr(cpu_brand,
"EPYC")) {
857 is_threadripper2 =
true;
860 return is_threadripper2;
863 static void threadripper_put_process_on_fast_node(
void)
883 static void threadripper_put_thread_on_fast_node(
void)
912 if (check_is_threadripper2_alike_topology()) {
913 threadripper_put_process_on_fast_node();
922 if (check_is_threadripper2_alike_topology()) {
923 threadripper_put_thread_on_fast_node();
void BLI_gsqueue_free(GSQueue *queue)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
GSQueue * BLI_gsqueue_new(const size_t elem_size)
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
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)
char * BLI_cpu_brand_string(void)
pthread_spinlock_t SpinLock
pthread_rwlock_t ThreadRWMutex
pthread_cond_t ThreadCondition
pthread_mutex_t ThreadMutex
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
Platform independent time functions.
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)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ThreadQueue * queue
all scheduled work for the cpu
bool numaAPI_RunProcessOnNode(int node)
NUMAAPI_Result numaAPI_Initialize(void)
bool numaAPI_RunThreadOnNode(int node)
pthread_cond_t finish_cond
void *(* do_thread)(void *)
void BLI_condition_notify_all(ThreadCondition *cond)
static bool is_numa_available
static int num_threads_override
bool BLI_mutex_trylock(ThreadMutex *mutex)
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
void BLI_thread_queue_push(ThreadQueue *queue, void *work)
void BLI_thread_unlock(int type)
void BLI_ticket_mutex_unlock(TicketMutex *ticket)
static pthread_mutex_t _image_lock
void BLI_mutex_end(ThreadMutex *mutex)
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)
void BLI_threadapi_init(void)
void BLI_thread_put_process_on_fast_node(void)
void BLI_thread_put_thread_on_fast_node(void)
void BLI_threadpool_remove(ListBase *threadbase, void *callerdata)
static pthread_mutex_t _view3d_lock
void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex)
static unsigned int thread_levels
int BLI_threadpool_available_thread_index(ListBase *threadbase)
void * BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
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)
int BLI_system_thread_count(void)
void BLI_thread_queue_free(ThreadQueue *queue)
int BLI_system_num_threads_override_get(void)
void BLI_threadapi_exit(void)
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)
static void * tslot_thread_start(void *tslot_p)
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)
ThreadMutex * BLI_mutex_alloc(void)
int BLI_thread_is_main(void)
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)
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
static void wait_timeout(struct timespec *timeout, int ms)
ThreadRWMutex * BLI_rw_mutex_alloc(void)
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_thread_queue_pop(ThreadQueue *queue)
void BLI_spin_lock(SpinLock *spin)
void BLI_rw_mutex_free(ThreadRWMutex *mutex)
ThreadQueue * BLI_thread_queue_init(void)
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
void BLI_spin_end(SpinLock *spin)
TicketMutex * BLI_ticket_mutex_alloc(void)
int BLI_thread_queue_len(ThreadQueue *queue)
static ThreadMutex * global_mutex_from_type(const int type)
double PIL_check_seconds_timer(void)