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
3803 HEVCContext *s = avctx->priv_data;3803 HEVCContext *s = avctx->priv_data;
3804 int ret;3804 int ret;
3805 3805
3806 if(avctx->active_thread_type & FF_THREAD_SLICE)3806 if (avctx->active_thread_type & FF_THREAD_SLICE) {
3807 s->threads_number = avctx->thread_count;3807 s->threads_number = avctx->thread_count;
3808 else3808 ret = ff_slice_thread_init_progress(avctx);
3809 if (ret < 0)
3810 return ret;
3811 } else
3809 s->threads_number = 1;3812 s->threads_number = 1;
3810 3813
3811 if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1)3814 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
41typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);41typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
42typedef int (main_func)(AVCodecContext *c);42typedef int (main_func)(AVCodecContext *c);
43 43
44typedef struct Progress {
45 pthread_cond_t cond;
46 pthread_mutex_t mutex;
47} Progress;
48
44typedef struct SliceThreadContext {49typedef struct SliceThreadContext {
45 AVSliceThread *thread;50 AVSliceThread *thread;
46 action_func *func;51 action_func *func;
@@ -53,8 +58,7 @@ typedef struct SliceThreadContext { · 6 unmodified lines
53 int *entries;58 int *entries;
54 int entries_count;59 int entries_count;
55 int thread_count;60 int thread_count;
56 pthread_cond_t *progress_cond;61 Progress *progress;
57 pthread_mutex_t *progress_mutex;
58} SliceThreadContext;62} SliceThreadContext;
59 63
60static void main_function(void *priv) {64static void main_function(void *priv) {
@@ -83,13 +87,13 @@ void ff_slice_thread_free(AVCodecContext *avctx) · 22 unmodified lines
83 avpriv_slicethread_free(&c->thread);87 avpriv_slicethread_free(&c->thread);
84 88
85 for (i = 0; i < c->thread_count; i++) {89 for (i = 0; i < c->thread_count; i++) {
86 pthread_mutex_destroy(&c->progress_mutex[i]);90 Progress *const progress = &c->progress[i];
87 pthread_cond_destroy(&c->progress_cond[i]);91 pthread_mutex_destroy(&progress->mutex);
92 pthread_cond_destroy(&progress->cond);
88 }93 }
89 94
90 av_freep(&c->entries);95 av_freep(&c->entries);
91 av_freep(&c->progress_mutex);96 av_freep(&c->progress);
92 av_freep(&c->progress_cond);
93 av_freep(&avctx->internal->thread_ctx);97 av_freep(&avctx->internal->thread_ctx);
94}98}
95 99
@@ -172,65 +176,82 @@ int ff_slice_thread_init(AVCodecContext *avctx) · 76 unmodified lines
172 return 0;176 return 0;
173}177}
174 178
179int 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;
205fail:
206 p->thread_count = i;
207 return err;
208}
209
175void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)210void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
176{211{
177 SliceThreadContext *p = avctx->internal->thread_ctx;212 SliceThreadContext *p = avctx->internal->thread_ctx;
213 Progress *const progress = &p->progress[thread];
178 int *entries = p->entries;214 int *entries = p->entries;
179 215
180 pthread_mutex_lock(&p->progress_mutex[thread]);216 pthread_mutex_lock(&progress->mutex);
181 entries[field] +=n;217 entries[field] +=n;
182 pthread_cond_signal(&p->progress_cond[thread]);218 pthread_cond_signal(&progress->cond);
183 pthread_mutex_unlock(&p->progress_mutex[thread]);219 pthread_mutex_unlock(&progress->mutex);
184}220}
185 221
186void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)222void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)
187{223{
188 SliceThreadContext *p = avctx->internal->thread_ctx;224 SliceThreadContext *p = avctx->internal->thread_ctx;
225 Progress *progress;
189 int *entries = p->entries;226 int *entries = p->entries;
190 227
191 if (!entries || !field) return;228 if (!entries || !field) return;
192 229
193 thread = thread ? thread - 1 : p->thread_count - 1;230 thread = thread ? thread - 1 : p->thread_count - 1;
231 progress = &p->progress[thread];
194 232
195 pthread_mutex_lock(&p->progress_mutex[thread]);233 pthread_mutex_lock(&progress->mutex);
196 while ((entries[field - 1] - entries[field]) < shift){234 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);
198 }236 }
199 pthread_mutex_unlock(&p->progress_mutex[thread]);237 pthread_mutex_unlock(&progress->mutex);
200}238}
201 239
202int ff_alloc_entries(AVCodecContext *avctx, int count)240int ff_alloc_entries(AVCodecContext *avctx, int count)
203{241{
204 int i;
205
206 if (avctx->active_thread_type & FF_THREAD_SLICE) {242 if (avctx->active_thread_type & FF_THREAD_SLICE) {
207 SliceThreadContext *p = avctx->internal->thread_ctx;243 SliceThreadContext *p = avctx->internal->thread_ctx;
208 244
209 if (p->entries) {245 if (p->entries) {
210 av_assert0(p->thread_count == avctx->thread_count);
211 av_freep(&p->entries);246 av_freep(&p->entries);
212 }247 }
213 248
214 p->thread_count = avctx->thread_count;
215 p->entries = av_calloc(count, sizeof(*p->entries));249 p->entries = av_calloc(count, sizeof(*p->entries));
216 250 if (!p->entries) {
217 if (!p->progress_mutex) {251 p->entries_count = 0;
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);
226 return AVERROR(ENOMEM);252 return AVERROR(ENOMEM);
227 }253 }
228 p->entries_count = count;254 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 }
234 }255 }
235 256
236 return 0;257 return 0;
libavcodec/thread.h+1−0
@@ -106,6 +106,7 @@ int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, · 105 unmodified lines
106void ff_thread_free(AVCodecContext *s);106void ff_thread_free(AVCodecContext *s);
107int ff_alloc_entries(AVCodecContext *avctx, int count);107int ff_alloc_entries(AVCodecContext *avctx, int count);
108void ff_reset_entries(AVCodecContext *avctx);108void ff_reset_entries(AVCodecContext *avctx);
109int ff_slice_thread_init_progress(AVCodecContext *avctx);
109void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n);110void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n);
110void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift);111void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift);
111 112
libavcodec/utils.c+5−0
@@ -958,6 +958,11 @@ int ff_thread_can_start_frame(AVCodecContext *avctx) · 957 unmodified lines
958 return 1;958 return 1;
959}959}
960 960
961int ff_slice_thread_init_progress(AVCodecContext *avctx)
962{
963 return 0;
964}
965
961int ff_alloc_entries(AVCodecContext *avctx, int count)966int ff_alloc_entries(AVCodecContext *avctx, int count)
962{967{
963 return 0;968 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