Mercurial > libavcodec.hg
annotate pthread.c @ 9930:32e856bd5ded libavcodec
Check for CONFIG_LIBFOO_DECODER/CONFIG_LIBFOO_ENCODER instead of just
CONFIG_LIBFOO in the external libraries section.
This is more consistent with the rest of the Makefiles, it makes clearer what
is actually implemented and should be advantageous if we implement an external
library encoder where we previously just had the decoder and vice versa.
author | diego |
---|---|
date | Tue, 07 Jul 2009 09:33:08 +0000 |
parents | 04423b2f6e0b |
children | 98501365c3aa |
rev | line source |
---|---|
1799 | 1 /* |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8333
diff
changeset
|
2 * Copyright (c) 2004 Roman Shaposhnik |
2967 | 3 * |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
4 * Many thanks to Steven M. Schultz for providing clever ideas and |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
5 * to Michael Niedermayer <michaelni@gmx.at> for writing initial |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
6 * implementation. |
1799 | 7 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
8 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
9 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * FFmpeg is free software; you can redistribute it and/or |
1799 | 11 * modify it under the terms of the GNU Lesser General Public |
12 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
13 * version 2.1 of the License, or (at your option) any later version. |
1799 | 14 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
15 * FFmpeg is distributed in the hope that it will be useful, |
1799 | 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 * Lesser General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
21 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1799 | 23 */ |
24 #include <pthread.h> | |
25 | |
26 #include "avcodec.h" | |
27 | |
8333 | 28 typedef int (action_func)(AVCodecContext *c, void *arg); |
1857 | 29 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
30 typedef struct ThreadContext { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
31 pthread_t *workers; |
8333 | 32 action_func *func; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
33 void *args; |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
34 int *rets; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
35 int rets_count; |
1857 | 36 int job_count; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
37 int job_size; |
2967 | 38 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
39 pthread_cond_t last_job_cond; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
40 pthread_cond_t current_job_cond; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
41 pthread_mutex_t current_job_lock; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
42 int current_job; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
43 int done; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
44 } ThreadContext; |
1799 | 45 |
5542
b0a566346fb1
Add attribute that forces alignment of stack to functions that need it.
ramiro
parents:
5232
diff
changeset
|
46 static void* attribute_align_arg worker(void *v) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
47 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
48 AVCodecContext *avctx = v; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
49 ThreadContext *c = avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
50 int our_job = c->job_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
51 int thread_count = avctx->thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
52 int self_id; |
1799 | 53 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
54 pthread_mutex_lock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
55 self_id = c->current_job++; |
2967 | 56 for (;;){ |
2979 | 57 while (our_job >= c->job_count) { |
58 if (c->current_job == thread_count + c->job_count) | |
59 pthread_cond_signal(&c->last_job_cond); | |
2967 | 60 |
2979 | 61 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
62 our_job = self_id; |
2967 | 63 |
2979 | 64 if (c->done) { |
65 pthread_mutex_unlock(&c->current_job_lock); | |
66 return NULL; | |
67 } | |
68 } | |
69 pthread_mutex_unlock(&c->current_job_lock); | |
2967 | 70 |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
71 c->rets[our_job%c->rets_count] = c->func(avctx, (char*)c->args + our_job*c->job_size); |
2967 | 72 |
2979 | 73 pthread_mutex_lock(&c->current_job_lock); |
74 our_job = c->current_job++; | |
1799 | 75 } |
76 } | |
77 | |
4283
d6f83e2f8804
rename always_inline to av_always_inline and move to common.h
mru
parents:
3947
diff
changeset
|
78 static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
79 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
80 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
81 pthread_mutex_unlock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
82 } |
1799 | 83 |
2967 | 84 void avcodec_thread_free(AVCodecContext *avctx) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
85 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
86 ThreadContext *c = avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
87 int i; |
2967 | 88 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
89 pthread_mutex_lock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
90 c->done = 1; |
2035
e1b69326ae36
10l fixes by ("Debabrata Banerjee" <davatar at comcast dot net>)
michael
parents:
2023
diff
changeset
|
91 pthread_cond_broadcast(&c->current_job_cond); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
92 pthread_mutex_unlock(&c->current_job_lock); |
1857 | 93 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
94 for (i=0; i<avctx->thread_count; i++) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
95 pthread_join(c->workers[i], NULL); |
1857 | 96 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
97 pthread_mutex_destroy(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
98 pthread_cond_destroy(&c->current_job_cond); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
99 pthread_cond_destroy(&c->last_job_cond); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
100 av_free(c->workers); |
5232 | 101 av_freep(&avctx->thread_opaque); |
1799 | 102 } |
103 | |
8333 | 104 int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
105 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
106 ThreadContext *c= avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
107 int dummy_ret; |
2967 | 108 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
109 if (job_count <= 0) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
110 return 0; |
2967 | 111 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
112 pthread_mutex_lock(&c->current_job_lock); |
1799 | 113 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
114 c->current_job = avctx->thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
115 c->job_count = job_count; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
116 c->job_size = job_size; |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
117 c->args = arg; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
118 c->func = func; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
119 if (ret) { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
120 c->rets = ret; |
2979 | 121 c->rets_count = job_count; |
2967 | 122 } else { |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
123 c->rets = &dummy_ret; |
2979 | 124 c->rets_count = 1; |
1799 | 125 } |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
126 pthread_cond_broadcast(&c->current_job_cond); |
1857 | 127 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
128 avcodec_thread_park_workers(c, avctx->thread_count); |
2967 | 129 |
1799 | 130 return 0; |
131 } | |
132 | |
2967 | 133 int avcodec_thread_init(AVCodecContext *avctx, int thread_count) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
134 { |
1799 | 135 int i; |
136 ThreadContext *c; | |
137 | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
138 c = av_mallocz(sizeof(ThreadContext)); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
139 if (!c) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
140 return -1; |
2967 | 141 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
142 c->workers = av_mallocz(sizeof(pthread_t)*thread_count); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
143 if (!c->workers) { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
144 av_free(c); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
145 return -1; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
146 } |
1799 | 147 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
148 avctx->thread_opaque = c; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
149 avctx->thread_count = thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
150 c->current_job = 0; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
151 c->job_count = 0; |
8129
a9734fe0811e
Making it easier to send arbitrary structures as work orders to MT workers
romansh
parents:
5542
diff
changeset
|
152 c->job_size = 0; |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
153 c->done = 0; |
2967 | 154 pthread_cond_init(&c->current_job_cond, NULL); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
155 pthread_cond_init(&c->last_job_cond, NULL); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
156 pthread_mutex_init(&c->current_job_lock, NULL); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
157 pthread_mutex_lock(&c->current_job_lock); |
2967 | 158 for (i=0; i<thread_count; i++) { |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
159 if(pthread_create(&c->workers[i], NULL, worker, avctx)) { |
2979 | 160 avctx->thread_count = i; |
161 pthread_mutex_unlock(&c->current_job_lock); | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
162 avcodec_thread_free(avctx); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
163 return -1; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
164 } |
1799 | 165 } |
2967 | 166 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
167 avcodec_thread_park_workers(c, thread_count); |
2967 | 168 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
169 avctx->execute = avcodec_thread_execute; |
1799 | 170 return 0; |
171 } |