void BLI_task_pool_free(TaskPool *pool) { BLI_task_pool_stop(pool); BLI_mutex_end(&pool->num_mutex); BLI_condition_end(&pool->num_cond); BLI_mutex_end(&pool->user_mutex); /* Free local memory pool, those pointers are lost forever. */ if (pool->task_mempool == &pool->task_mempool_local) { for (int i = 0; i < pool->task_mempool_local.num_tasks; i++) { MEM_freeN(pool->task_mempool_local.tasks[i]); } } #ifdef DEBUG_STATS printf("Thread ID Allocated Reused Discarded\n"); for (int i = 0; i < pool->scheduler->num_threads + 1; ++i) { printf("%02d %05d %05d %05d\n", i, pool->mempool_stats[i].num_alloc, pool->mempool_stats[i].num_reuse, pool->mempool_stats[i].num_discard); } MEM_freeN(pool->mempool_stats); #endif MEM_freeN(pool); BLI_end_threaded_malloc(); }
void BLI_task_pool_free(TaskPool *pool) { BLI_task_pool_stop(pool); BLI_mutex_end(&pool->num_mutex); BLI_condition_end(&pool->num_cond); BLI_mutex_end(&pool->user_mutex); MEM_freeN(pool); BLI_end_threaded_malloc(); }
void BLI_task_scheduler_free(TaskScheduler *scheduler) { Task *task; /* stop all waiting threads */ BLI_mutex_lock(&scheduler->queue_mutex); scheduler->do_exit = true; BLI_condition_notify_all(&scheduler->queue_cond); BLI_mutex_unlock(&scheduler->queue_mutex); /* delete threads */ if (scheduler->threads) { int i; for (i = 0; i < scheduler->num_threads; i++) { if (pthread_join(scheduler->threads[i], NULL) != 0) fprintf(stderr, "TaskScheduler failed to join thread %d/%d\n", i, scheduler->num_threads); } MEM_freeN(scheduler->threads); } /* Delete task thread data */ if (scheduler->task_threads) { MEM_freeN(scheduler->task_threads); } /* Delete task memory pool */ if (scheduler->task_mempool) { for (int i = 0; i <= scheduler->num_threads; ++i) { for (int j = 0; j < scheduler->task_mempool[i].num_tasks; ++j) { MEM_freeN(scheduler->task_mempool[i].tasks[j]); } } MEM_freeN(scheduler->task_mempool); } /* delete leftover tasks */ for (task = scheduler->queue.first; task; task = task->next) { task_data_free(task, 0); } BLI_freelistN(&scheduler->queue); /* delete mutex/condition */ BLI_mutex_end(&scheduler->queue_mutex); BLI_condition_end(&scheduler->queue_cond); MEM_freeN(scheduler); }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; if (oglrender->is_animation) { BLI_task_pool_work_and_wait(oglrender->task_pool); BLI_task_pool_free(oglrender->task_pool); /* Depending on various things we might or might not use global scheduler. */ if (oglrender->task_scheduler != NULL) { BLI_task_scheduler_free(oglrender->task_scheduler); } BLI_spin_end(&oglrender->reports_lock); } BLI_mutex_end(&oglrender->task_mutex); BLI_condition_end(&oglrender->task_condition); #ifdef DEBUG_TIME printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start); #endif if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); if (oglrender->is_sequencer) { MEM_freeN(oglrender->seq_data.ibufs_arr); } oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }