Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenlib/intern/threads.c
| Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| #ifdef USE_APPLE_OMP_FIX | #ifdef USE_APPLE_OMP_FIX | ||||
| /* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */ | /* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */ | ||||
| extern pthread_key_t gomp_tls_key; | extern pthread_key_t gomp_tls_key; | ||||
| static void *thread_tls_data; | static void *thread_tls_data; | ||||
| #endif | #endif | ||||
| /* We're using one global task scheduler for all kind of tasks. */ | |||||
| static TaskScheduler *task_scheduler = NULL; | |||||
| /* ********** basic thread control API ************ | /* ********** basic thread control API ************ | ||||
| * | * | ||||
| * Many thread cases have an X amount of jobs, and only an Y amount of | * Many thread cases have an X amount of jobs, and only an Y amount of | ||||
| * threads are useful (typically amount of cpus) | * threads are useful (typically amount of cpus) | ||||
| * | * | ||||
| * This code can be used to start a maximum amount of 'thread slots', which | * 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. | * then can be filled in a loop with an idle timer. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | void BLI_threadapi_init(void) | ||||
| BLI_spin_init(&_malloc_lock); | BLI_spin_init(&_malloc_lock); | ||||
| if (numaAPI_Initialize() == NUMAAPI_SUCCESS) { | if (numaAPI_Initialize() == NUMAAPI_SUCCESS) { | ||||
| is_numa_available = true; | is_numa_available = true; | ||||
| } | } | ||||
| } | } | ||||
| void BLI_threadapi_exit(void) | void BLI_threadapi_exit(void) | ||||
| { | { | ||||
| if (task_scheduler) { | |||||
| BLI_task_scheduler_free(task_scheduler); | |||||
| task_scheduler = NULL; | |||||
| } | |||||
| BLI_spin_end(&_malloc_lock); | BLI_spin_end(&_malloc_lock); | ||||
| } | } | ||||
| TaskScheduler *BLI_task_scheduler_get(void) | |||||
| { | |||||
| if (task_scheduler == NULL) { | |||||
| int tot_thread = BLI_system_thread_count(); | |||||
| /* Do a lazy initialization, so it happens after | |||||
| * command line arguments parsing | |||||
| */ | |||||
| task_scheduler = BLI_task_scheduler_create(tot_thread); | |||||
| } | |||||
| return task_scheduler; | |||||
| } | |||||
| /* tot = 0 only initializes malloc mutex in a safe way (see sequence.c) | /* tot = 0 only initializes malloc mutex in a safe way (see sequence.c) | ||||
| * problem otherwise: scene render will kill of the mutex! | * problem otherwise: scene render will kill of the mutex! | ||||
| */ | */ | ||||
| void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot) | void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot) | ||||
| { | { | ||||
| int a; | int a; | ||||
| ▲ Show 20 Lines • Show All 645 Lines • ▼ Show 20 Lines | |||||
| /* ************************************************ */ | /* ************************************************ */ | ||||
| void BLI_threaded_malloc_begin(void) | void BLI_threaded_malloc_begin(void) | ||||
| { | { | ||||
| unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1); | unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1); | ||||
| if (level == 0) { | if (level == 0) { | ||||
| MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); | MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); | ||||
| /* There is a little chance that two threads will need to access to a | |||||
| * scheduler which was not yet created from main thread. which could | |||||
| * cause scheduler created multiple times. | |||||
| */ | |||||
| BLI_task_scheduler_get(); | |||||
| } | } | ||||
| } | } | ||||
| void BLI_threaded_malloc_end(void) | void BLI_threaded_malloc_end(void) | ||||
| { | { | ||||
| unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1); | unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1); | ||||
| if (level == 0) { | if (level == 0) { | ||||
| MEM_set_lock_callback(NULL, NULL); | MEM_set_lock_callback(NULL, NULL); | ||||
| ▲ Show 20 Lines • Show All 112 Lines • Show Last 20 Lines | |||||