Mercurial > libavcodec.hg
annotate pthread.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | c8c591fe26f8 |
children | d6f83e2f8804 |
rev | line source |
---|---|
1799 | 1 /* |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
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 */ | |
25 #include <pthread.h> | |
26 | |
27 #include "avcodec.h" | |
28 #include "common.h" | |
29 | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
30 typedef int (action_t)(AVCodecContext *c, void *arg); |
1857 | 31 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
32 typedef struct ThreadContext { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
33 pthread_t *workers; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
34 action_t *func; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
35 void **args; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
36 int *rets; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
37 int rets_count; |
1857 | 38 int job_count; |
2967 | 39 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
40 pthread_cond_t last_job_cond; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
41 pthread_cond_t current_job_cond; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
42 pthread_mutex_t current_job_lock; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
43 int current_job; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
44 int done; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
45 } ThreadContext; |
1799 | 46 |
2967 | 47 static void* worker(void *v) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
48 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
49 AVCodecContext *avctx = v; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
50 ThreadContext *c = avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
51 int our_job = c->job_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
52 int thread_count = avctx->thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
53 int self_id; |
1799 | 54 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
55 pthread_mutex_lock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
56 self_id = c->current_job++; |
2967 | 57 for (;;){ |
2979 | 58 while (our_job >= c->job_count) { |
59 if (c->current_job == thread_count + c->job_count) | |
60 pthread_cond_signal(&c->last_job_cond); | |
2967 | 61 |
2979 | 62 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
63 our_job = self_id; |
2967 | 64 |
2979 | 65 if (c->done) { |
66 pthread_mutex_unlock(&c->current_job_lock); | |
67 return NULL; | |
68 } | |
69 } | |
70 pthread_mutex_unlock(&c->current_job_lock); | |
2967 | 71 |
2979 | 72 c->rets[our_job%c->rets_count] = c->func(avctx, c->args[our_job]); |
2967 | 73 |
2979 | 74 pthread_mutex_lock(&c->current_job_lock); |
75 our_job = c->current_job++; | |
1799 | 76 } |
77 } | |
78 | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
79 static always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
80 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
81 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
82 pthread_mutex_unlock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
83 } |
1799 | 84 |
2967 | 85 void avcodec_thread_free(AVCodecContext *avctx) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
86 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
87 ThreadContext *c = avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
88 int i; |
2967 | 89 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
90 pthread_mutex_lock(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
91 c->done = 1; |
2035
e1b69326ae36
10l fixes by ("Debabrata Banerjee" <davatar at comcast dot net>)
michael
parents:
2023
diff
changeset
|
92 pthread_cond_broadcast(&c->current_job_cond); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
93 pthread_mutex_unlock(&c->current_job_lock); |
1857 | 94 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
95 for (i=0; i<avctx->thread_count; i++) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
96 pthread_join(c->workers[i], NULL); |
1857 | 97 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
98 pthread_mutex_destroy(&c->current_job_lock); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
99 pthread_cond_destroy(&c->current_job_cond); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
100 pthread_cond_destroy(&c->last_job_cond); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
101 av_free(c->workers); |
2035
e1b69326ae36
10l fixes by ("Debabrata Banerjee" <davatar at comcast dot net>)
michael
parents:
2023
diff
changeset
|
102 av_free(c); |
1799 | 103 } |
104 | |
2967 | 105 int avcodec_thread_execute(AVCodecContext *avctx, action_t* func, void **arg, int *ret, int job_count) |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
106 { |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
107 ThreadContext *c= avctx->thread_opaque; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
108 int dummy_ret; |
2967 | 109 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
110 if (job_count <= 0) |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
111 return 0; |
2967 | 112 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
113 pthread_mutex_lock(&c->current_job_lock); |
1799 | 114 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
115 c->current_job = avctx->thread_count; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
116 c->job_count = job_count; |
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; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
152 c->done = 0; |
2967 | 153 pthread_cond_init(&c->current_job_cond, NULL); |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
154 pthread_cond_init(&c->last_job_cond, NULL); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
155 pthread_mutex_init(&c->current_job_lock, NULL); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
156 pthread_mutex_lock(&c->current_job_lock); |
2967 | 157 for (i=0; i<thread_count; i++) { |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
158 if(pthread_create(&c->workers[i], NULL, worker, avctx)) { |
2979 | 159 avctx->thread_count = i; |
160 pthread_mutex_unlock(&c->current_job_lock); | |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
161 avcodec_thread_free(avctx); |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
162 return -1; |
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
163 } |
1799 | 164 } |
2967 | 165 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
166 avcodec_thread_park_workers(c, thread_count); |
2967 | 167 |
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
168 avctx->execute = avcodec_thread_execute; |
1799 | 169 return 0; |
170 } |