Skip to content

Commit 9f8f5c3

Browse files
committed
replace system-specific mutex and condition-variable implementation with c++ std-library classes (#480)
1 parent d9fea9d commit 9f8f5c3

File tree

4 files changed

+67
-123
lines changed

4 files changed

+67
-123
lines changed

libde265/image.cc

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,6 @@ de265_image::de265_image()
227227
nThreadsBlocked = 0;
228228
nThreadsFinished = 0;
229229
nThreadsTotal = 0;
230-
231-
de265_mutex_init(&mutex);
232-
de265_cond_init(&finished_cond);
233230
}
234231

235232

@@ -489,9 +486,6 @@ de265_image::~de265_image()
489486
if (ctb_progress) {
490487
delete[] ctb_progress;
491488
}
492-
493-
de265_cond_destroy(&finished_cond);
494-
de265_mutex_destroy(&mutex);
495489
}
496490

497491

@@ -685,59 +679,55 @@ void de265_image::exchange_pixel_data_with(de265_image& b)
685679

686680
void de265_image::thread_start(int nThreads)
687681
{
688-
de265_mutex_lock(&mutex);
682+
std::unique_lock<std::mutex> lock(mutex);
689683

690684
//printf("nThreads before: %d %d\n",nThreadsQueued, nThreadsTotal);
691685

692686
nThreadsQueued += nThreads;
693687
nThreadsTotal += nThreads;
694688

695689
//printf("nThreads after: %d %d\n",nThreadsQueued, nThreadsTotal);
696-
697-
de265_mutex_unlock(&mutex);
698690
}
699691

700692
void de265_image::thread_run(const thread_task* task)
701693
{
694+
std::unique_lock<std::mutex> lock(mutex);
695+
702696
//printf("run thread %s\n", task->name().c_str());
703697

704-
de265_mutex_lock(&mutex);
705698
nThreadsQueued--;
706699
nThreadsRunning++;
707-
de265_mutex_unlock(&mutex);
708700
}
709701

710702
void de265_image::thread_blocks()
711703
{
712-
de265_mutex_lock(&mutex);
704+
std::unique_lock<std::mutex> lock(mutex);
705+
713706
nThreadsRunning--;
714707
nThreadsBlocked++;
715-
de265_mutex_unlock(&mutex);
716708
}
717709

718710
void de265_image::thread_unblocks()
719711
{
720-
de265_mutex_lock(&mutex);
712+
std::unique_lock<std::mutex> lock(mutex);
713+
721714
nThreadsBlocked--;
722715
nThreadsRunning++;
723-
de265_mutex_unlock(&mutex);
724716
}
725717

726718
void de265_image::thread_finishes(const thread_task* task)
727719
{
728720
//printf("finish thread %s\n", task->name().c_str());
729721

730-
de265_mutex_lock(&mutex);
722+
std::unique_lock<std::mutex> lock(mutex);
731723

732724
nThreadsRunning--;
733725
nThreadsFinished++;
734726
assert(nThreadsRunning >= 0);
735727

736728
if (nThreadsFinished==nThreadsTotal) {
737-
de265_cond_broadcast(&finished_cond, &mutex);
729+
finished_cond.notify_all();
738730
}
739-
740-
de265_mutex_unlock(&mutex);
741731
}
742732

743733
void de265_image::wait_for_progress(thread_task* task, int ctbx,int ctby, int progress)
@@ -772,11 +762,11 @@ void de265_image::wait_for_progress(thread_task* task, int ctbAddrRS, int progre
772762

773763
void de265_image::wait_for_completion()
774764
{
775-
de265_mutex_lock(&mutex);
765+
std::unique_lock<std::mutex> lock(mutex);
766+
776767
while (nThreadsFinished!=nThreadsTotal) {
777-
de265_cond_wait(&finished_cond, &mutex);
768+
finished_cond.wait(lock);
778769
}
779-
de265_mutex_unlock(&mutex);
780770
}
781771

782772
bool de265_image::debug_is_completed() const

libde265/image.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ struct de265_image {
471471
int nThreadsTotal;
472472

473473
// ALIGNED_8(de265_sync_int tasks_pending); // number of tasks pending to complete decoding
474-
de265_mutex mutex;
475-
de265_cond finished_cond;
474+
std::mutex mutex;
475+
std::condition_variable finished_cond;
476476

477477
public:
478478

libde265/threads.cc

Lines changed: 43 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,6 @@
4141
int de265_thread_create(de265_thread* t, void *(*start_routine) (void *), void *arg) { return pthread_create(t,NULL,start_routine,arg); }
4242
void de265_thread_join(de265_thread t) { pthread_join(t,NULL); }
4343
void de265_thread_destroy(de265_thread* t) { }
44-
void de265_mutex_init(de265_mutex* m) { pthread_mutex_init(m,NULL); }
45-
void de265_mutex_destroy(de265_mutex* m) { pthread_mutex_destroy(m); }
46-
void de265_mutex_lock(de265_mutex* m) { pthread_mutex_lock(m); }
47-
void de265_mutex_unlock(de265_mutex* m) { pthread_mutex_unlock(m); }
48-
void de265_cond_init(de265_cond* c) { pthread_cond_init(c,NULL); }
49-
void de265_cond_destroy(de265_cond* c) { pthread_cond_destroy(c); }
50-
void de265_cond_broadcast(de265_cond* c,de265_mutex* m) { pthread_cond_broadcast(c); }
51-
void de265_cond_wait(de265_cond* c,de265_mutex* m) { pthread_cond_wait(c,m); }
52-
void de265_cond_signal(de265_cond* c) { pthread_cond_signal(c); }
5344
#else // _WIN32
5445

5546
#define THREAD_RESULT_TYPE DWORD
@@ -66,37 +57,16 @@ int de265_thread_create(de265_thread* t, LPTHREAD_START_ROUTINE start_routine,
6657
}
6758
void de265_thread_join(de265_thread t) { WaitForSingleObject(t, INFINITE); }
6859
void de265_thread_destroy(de265_thread* t) { CloseHandle(*t); *t = NULL; }
69-
void de265_mutex_init(de265_mutex* m) { *m = CreateMutex(NULL, FALSE, NULL); }
70-
void de265_mutex_destroy(de265_mutex* m) { CloseHandle(*m); }
71-
void de265_mutex_lock(de265_mutex* m) { WaitForSingleObject(*m, INFINITE); }
72-
void de265_mutex_unlock(de265_mutex* m) { ReleaseMutex(*m); }
73-
void de265_cond_init(de265_cond* c) { win32_cond_init(c); }
74-
void de265_cond_destroy(de265_cond* c) { win32_cond_destroy(c); }
75-
void de265_cond_broadcast(de265_cond* c,de265_mutex* m)
76-
{
77-
de265_mutex_lock(m);
78-
win32_cond_broadcast(c);
79-
de265_mutex_unlock(m);
80-
}
81-
void de265_cond_wait(de265_cond* c,de265_mutex* m) { win32_cond_wait(c,m); }
82-
void de265_cond_signal(de265_cond* c) { win32_cond_signal(c); }
8360
#endif // _WIN32
8461

8562

86-
87-
8863
de265_progress_lock::de265_progress_lock()
8964
{
9065
mProgress = 0;
91-
92-
de265_mutex_init(&mutex);
93-
de265_cond_init(&cond);
9466
}
9567

9668
de265_progress_lock::~de265_progress_lock()
9769
{
98-
de265_mutex_destroy(&mutex);
99-
de265_cond_destroy(&cond);
10070
}
10171

10272
void de265_progress_lock::wait_for_progress(int progress)
@@ -105,34 +75,29 @@ void de265_progress_lock::wait_for_progress(int progress)
10575
return;
10676
}
10777

108-
de265_mutex_lock(&mutex);
78+
std::unique_lock<std::mutex> lock(mutex);
10979
while (mProgress < progress) {
110-
de265_cond_wait(&cond, &mutex);
80+
cond.wait(lock);
11181
}
112-
de265_mutex_unlock(&mutex);
11382
}
11483

11584
void de265_progress_lock::set_progress(int progress)
11685
{
117-
de265_mutex_lock(&mutex);
86+
std::unique_lock<std::mutex> lock(mutex);
11887

11988
if (progress>mProgress) {
12089
mProgress = progress;
12190

122-
de265_cond_broadcast(&cond, &mutex);
91+
cond.notify_all();
12392
}
124-
125-
de265_mutex_unlock(&mutex);
12693
}
12794

12895
void de265_progress_lock::increase_progress(int progress)
12996
{
130-
de265_mutex_lock(&mutex);
97+
std::unique_lock<std::mutex> lock(mutex);
13198

13299
mProgress += progress;
133-
de265_cond_broadcast(&cond, &mutex);
134-
135-
de265_mutex_unlock(&mutex);
100+
cond.notify_all();
136101
}
137102

138103
int de265_progress_lock::get_progress() const
@@ -191,54 +156,54 @@ static THREAD_RESULT_TYPE THREAD_CALLING_CONVENTION worker_thread(THREAD_PARAM_T
191156
thread_pool* pool = (thread_pool*)pool_ptr;
192157

193158

194-
de265_mutex_lock(&pool->mutex);
195-
196159
while(true) {
197160

198-
// wait until we can pick a task or until the pool has been stopped
161+
thread_task* task = nullptr;
199162

200-
for (;;) {
201-
// end waiting if thread-pool has been stopped or we have a task to execute
163+
{
164+
std::unique_lock<std::mutex> lock(pool->mutex);
202165

203-
if (pool->stopped || pool->tasks.size()>0) {
204-
break;
205-
}
166+
// wait until we can pick a task or until the pool has been stopped
206167

207-
//printf("going idle\n");
208-
de265_cond_wait(&pool->cond_var, &pool->mutex);
209-
}
168+
for (;;) {
169+
// end waiting if thread-pool has been stopped or we have a task to execute
210170

211-
// if the pool was shut down, end the execution
171+
if (pool->stopped || pool->tasks.size()>0) {
172+
break;
173+
}
212174

213-
if (pool->stopped) {
214-
de265_mutex_unlock(&pool->mutex);
215-
return (THREAD_RESULT_TYPE)0;
216-
}
175+
//printf("going idle\n");
176+
pool->cond_var.wait(lock);
177+
}
217178

179+
// if the pool was shut down, end the execution
218180

219-
// get a task
181+
if (pool->stopped) {
182+
return (THREAD_RESULT_TYPE)0;
183+
}
220184

221-
thread_task* task = pool->tasks.front();
222-
pool->tasks.pop_front();
223185

224-
pool->num_threads_working++;
186+
// get a task
225187

226-
//printblks(pool);
188+
task = pool->tasks.front();
189+
pool->tasks.pop_front();
227190

228-
de265_mutex_unlock(&pool->mutex);
191+
pool->num_threads_working++;
229192

193+
//printblks(pool);
194+
}
230195

231196
// execute the task
232197

233198
task->work();
234199

235200
// end processing and check if this was the last task to be processed
236201

237-
de265_mutex_lock(&pool->mutex);
202+
// TODO: the num_threads_working can probably be an atomic integer
203+
std::unique_lock<std::mutex> lock(pool->mutex);
238204

239205
pool->num_threads_working--;
240206
}
241-
de265_mutex_unlock(&pool->mutex);
242207

243208
return (THREAD_RESULT_TYPE)0;
244209
}
@@ -257,13 +222,12 @@ de265_error start_thread_pool(thread_pool* pool, int num_threads)
257222

258223
pool->num_threads = 0; // will be increased below
259224

260-
de265_mutex_init(&pool->mutex);
261-
de265_cond_init(&pool->cond_var);
225+
{
226+
std::unique_lock<std::mutex> lock(pool->mutex);
262227

263-
de265_mutex_lock(&pool->mutex);
264-
pool->num_threads_working = 0;
265-
pool->stopped = false;
266-
de265_mutex_unlock(&pool->mutex);
228+
pool->num_threads_working = 0;
229+
pool->stopped = false;
230+
}
267231

268232
// start worker threads
269233

@@ -283,32 +247,30 @@ de265_error start_thread_pool(thread_pool* pool, int num_threads)
283247

284248
void stop_thread_pool(thread_pool* pool)
285249
{
286-
de265_mutex_lock(&pool->mutex);
287-
pool->stopped = true;
288-
de265_mutex_unlock(&pool->mutex);
250+
{
251+
std::unique_lock<std::mutex> lock(pool->mutex);
252+
pool->stopped = true;
253+
}
289254

290-
de265_cond_broadcast(&pool->cond_var, &pool->mutex);
255+
pool->cond_var.notify_all();
291256

292257
for (int i=0;i<pool->num_threads;i++) {
293258
de265_thread_join(pool->thread[i]);
294259
de265_thread_destroy(&pool->thread[i]);
295260
}
296-
297-
de265_mutex_destroy(&pool->mutex);
298-
de265_cond_destroy(&pool->cond_var);
299261
}
300262

301263

302264
void add_task(thread_pool* pool, thread_task* task)
303265
{
304-
de265_mutex_lock(&pool->mutex);
266+
std::unique_lock<std::mutex> lock(pool->mutex);
267+
305268
if (!pool->stopped) {
306269

307270
pool->tasks.push_back(task);
308271

309272
// wake up one thread
310273

311-
de265_cond_signal(&pool->cond_var);
274+
pool->cond_var.notify_one();
312275
}
313-
de265_mutex_unlock(&pool->mutex);
314276
}

0 commit comments

Comments
 (0)