History

avcodec/pthread_slice: Don't reinitialise initialised mutex

It results in undefined behaviour. Instead initialize the mutexes and condition variables once during init (and check these initializations). Also combine the corresponding mutex and condition variable into one structure so that one can allocate their array jointly.

Andreas Rheinhardt committed 4 years ago

Commit 804bf891 parent 26e7d7b4 files · +63 −33Browse files

Unified · Split

4 files
  1. libavcodec/hevcdec.c +5 −2
  2. libavcodec/pthread_slice.c +52 −31
  3. libavcodec/thread.h +1 −0
  4. libavcodec/utils.c +5 −0
libavcodec/hevcdec.c+5−2
@@ -3803,9 +3803,12 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) · 3802 unmodified lines
38033803 HEVCContext *s = avctx->priv_data;
38043804 int ret;
38053805
3806− if(avctx->active_thread_type & FF_THREAD_SLICE)
3806+ if (avctx->active_thread_type & FF_THREAD_SLICE) {
38073807 s->threads_number = avctx->thread_count;
3808− else
3808+ ret = ff_slice_thread_init_progress(avctx);
3809+ if (ret < 0)
3810+ return ret;
3811+ } else
38093812 s->threads_number = 1;
38103813
38113814 if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1)
libavcodec/pthread_slice.c+52−31
@@ -41,6 +41,11 @@ typedef int (action_func)(AVCodecContext *c, void *arg); · 40 unmodified lines
4141 typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
4242 typedef int (main_func)(AVCodecContext *c);
4343
44+typedef struct Progress {
45+ pthread_cond_t cond;
46+ pthread_mutex_t mutex;
47+} Progress;
48+
4449 typedef struct SliceThreadContext {
4550 AVSliceThread *thread;
4651 action_func *func;
@@ -53,8 +58,7 @@ typedef struct SliceThreadContext { · 6 unmodified lines
5358 int *entries;
5459 int entries_count;
5560 int thread_count;
56− pthread_cond_t *progress_cond;
57− pthread_mutex_t *progress_mutex;
61+ Progress *progress;
5862 } SliceThreadContext;
5963
6064 static void main_function(void *priv) {
@@ -83,13 +87,13 @@ void ff_slice_thread_free(AVCodecContext *avctx) · 22 unmodified lines
8387 avpriv_slicethread_free(&c->thread);
8488
8589 for (i = 0; i < c->thread_count; i++) {
86− pthread_mutex_destroy(&c->progress_mutex[i]);
87− pthread_cond_destroy(&c->progress_cond[i]);
90+ Progress *const progress = &c->progress[i];
91+ pthread_mutex_destroy(&progress->mutex);
92+ pthread_cond_destroy(&progress->cond);
8893 }
8994
9095 av_freep(&c->entries);
91− av_freep(&c->progress_mutex);
92− av_freep(&c->progress_cond);
96+ av_freep(&c->progress);
9397 av_freep(&avctx->internal->thread_ctx);
9498 }
9599
@@ -172,65 +176,82 @@ int ff_slice_thread_init(AVCodecContext *avctx) · 76 unmodified lines
172176 return 0;
173177 }
174178
179+int av_cold ff_slice_thread_init_progress(AVCodecContext *avctx)
180+{
181+ SliceThreadContext *const p = avctx->internal->thread_ctx;
182+ int err, i = 0, thread_count = avctx->thread_count;
183+
184+ p->progress = av_calloc(thread_count, sizeof(*p->progress));
185+ if (!p->progress) {
186+ err = AVERROR(ENOMEM);
187+ goto fail;
188+ }
189+
190+ for (; i < thread_count; i++) {
191+ Progress *const progress = &p->progress[i];
192+ err = pthread_mutex_init(&progress->mutex, NULL);
193+ if (err) {
194+ err = AVERROR(err);
195+ goto fail;
196+ }
197+ err = pthread_cond_init (&progress->cond, NULL);
198+ if (err) {
199+ err = AVERROR(err);
200+ pthread_mutex_destroy(&progress->mutex);
201+ goto fail;
202+ }
203+ }
204+ err = 0;
205+fail:
206+ p->thread_count = i;
207+ return err;
208+}
209+
175210 void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
176211 {
177212 SliceThreadContext *p = avctx->internal->thread_ctx;
213+ Progress *const progress = &p->progress[thread];
178214 int *entries = p->entries;
179215
180− pthread_mutex_lock(&p->progress_mutex[thread]);
216+ pthread_mutex_lock(&progress->mutex);
181217 entries[field] +=n;
182− pthread_cond_signal(&p->progress_cond[thread]);
183− pthread_mutex_unlock(&p->progress_mutex[thread]);
218+ pthread_cond_signal(&progress->cond);
219+ pthread_mutex_unlock(&progress->mutex);
184220 }
185221
186222 void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)
187223 {
188224 SliceThreadContext *p = avctx->internal->thread_ctx;
225+ Progress *progress;
189226 int *entries = p->entries;
190227
191228 if (!entries || !field) return;
192229
193230 thread = thread ? thread - 1 : p->thread_count - 1;
231+ progress = &p->progress[thread];
194232
195− pthread_mutex_lock(&p->progress_mutex[thread]);
233+ pthread_mutex_lock(&progress->mutex);
196234 while ((entries[field - 1] - entries[field]) < shift){
197− pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]);
235+ pthread_cond_wait(&progress->cond, &progress->mutex);
198236 }
199− pthread_mutex_unlock(&p->progress_mutex[thread]);
237+ pthread_mutex_unlock(&progress->mutex);
200238 }
201239
202240 int ff_alloc_entries(AVCodecContext *avctx, int count)
203241 {
204− int i;
205−
206242 if (avctx->active_thread_type & FF_THREAD_SLICE) {
207243 SliceThreadContext *p = avctx->internal->thread_ctx;
208244
209245 if (p->entries) {
210− av_assert0(p->thread_count == avctx->thread_count);
211246 av_freep(&p->entries);
212247 }
213248
214− p->thread_count = avctx->thread_count;
215249 p->entries = av_calloc(count, sizeof(*p->entries));
216−
217− if (!p->progress_mutex) {
218− p->progress_mutex = av_malloc_array(p->thread_count, sizeof(pthread_mutex_t));
219− p->progress_cond = av_malloc_array(p->thread_count, sizeof(pthread_cond_t));
220− }
221−
222− if (!p->entries || !p->progress_mutex || !p->progress_cond) {
223− av_freep(&p->entries);
224− av_freep(&p->progress_mutex);
225− av_freep(&p->progress_cond);
250+ if (!p->entries) {
251+ p->entries_count = 0;
226252 return AVERROR(ENOMEM);
227253 }
228254 p->entries_count = count;
229−
230− for (i = 0; i < p->thread_count; i++) {
231− pthread_mutex_init(&p->progress_mutex[i], NULL);
232− pthread_cond_init(&p->progress_cond[i], NULL);
233− }
234255 }
235256
236257 return 0;
libavcodec/thread.h+1−0
@@ -106,6 +106,7 @@ int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, · 105 unmodified lines
106106 void ff_thread_free(AVCodecContext *s);
107107 int ff_alloc_entries(AVCodecContext *avctx, int count);
108108 void ff_reset_entries(AVCodecContext *avctx);
109+int ff_slice_thread_init_progress(AVCodecContext *avctx);
109110 void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n);
110111 void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift);
111112
libavcodec/utils.c+5−0
@@ -958,6 +958,11 @@ int ff_thread_can_start_frame(AVCodecContext *avctx) · 957 unmodified lines
958958 return 1;
959959 }
960960
961+int ff_slice_thread_init_progress(AVCodecContext *avctx)
962+{
963+ return 0;
964+}
965+
961966 int ff_alloc_entries(AVCodecContext *avctx, int count)
962967 {
963968 return 0;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t