From 70d1b407d6d0124520b2527eb6c5598c31dee85f Mon Sep 17 00:00:00 2001 From: Solra Bizna Date: Fri, 6 Oct 2017 16:37:37 -0600 Subject: [PATCH] Use a different condition variable for each mutex. Fixes OSX hang and Linux screen corruption, both when more than 2 hardware threads are used. Thanks to @ndryden for helping get to the bottom of this one. --- src/fx.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fx.cc b/src/fx.cc index dade9d4..1c64f7b 100644 --- a/src/fx.cc +++ b/src/fx.cc @@ -21,13 +21,13 @@ namespace { static Worker* worker_threads; static unsigned int thread_count; static SDL_threadID main_thread; - static SDL_cond* go_cond; SDL_mutex* lock; + SDL_cond* cond; int body() { SDL_LockMutex(lock); while(true) { while(task == nullptr) { - SDL_CondWait(go_cond, lock); + SDL_CondWait(cond, lock); } task(start, stop); task = nullptr; @@ -41,8 +41,8 @@ namespace { public: Worker() { static unsigned int num_workers_so_far = 0; - if(go_cond == nullptr) go_cond = SDL_CreateCond(); - assert(go_cond); + cond = SDL_CreateCond(); + assert(cond); lock = SDL_CreateMutex(); assert(lock); std::ostringstream str; @@ -78,11 +78,12 @@ namespace { worker_threads[i].start = start; worker_threads[i].stop = stop; SDL_UnlockMutex(worker_threads[i].lock); + SDL_CondBroadcast(worker_threads[i].cond); start = stop; } } - SDL_CondBroadcast(go_cond); if(start != big_stop) task(start, big_stop); + // wait for each worker to complete before continuing for(unsigned int i = 0; i < thread_count-1; ++i) { SDL_LockMutex(worker_threads[i].lock); SDL_UnlockMutex(worker_threads[i].lock); @@ -101,7 +102,6 @@ namespace { Worker* Worker::worker_threads; unsigned int Worker::thread_count = 0; SDL_threadID Worker::main_thread; - SDL_cond* Worker::go_cond; } void FX::init(unsigned int init_thread_count) {