annotate pthread.c @ 8520:a0164882aa38 libavcodec

Generic metadata API. avi is updated as example. No version bump, the API still might change slightly ... No update to ffmpeg.c as requested by aurel.
author michael
date Sun, 04 Jan 2009 18:48:37 +0000
parents 09aafff47bc0
children 04423b2f6e0b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
1 /*
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
2 * Copyright (c) 2004 Roman Shaposhnik.
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
11 * modify it under the terms of the GNU Lesser General Public
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
18 * Lesser General Public License for more details.
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
19 *
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
23 */
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
24 #include <pthread.h>
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
25
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
26 #include "avcodec.h"
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
27
8333
09aafff47bc0 Avoid invasion of POSIX-reserved _t namespace.
diego
parents: 8129
diff changeset
28 typedef int (action_func)(AVCodecContext *c, void *arg);
1857
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
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
09aafff47bc0 Avoid invasion of POSIX-reserved _t namespace.
diego
parents: 8129
diff changeset
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
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
56 for (;;){
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
57 while (our_job >= c->job_count) {
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
58 if (c->current_job == thread_count + c->job_count)
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
59 pthread_cond_signal(&c->last_job_cond);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
60
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
63
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
64 if (c->done) {
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
65 pthread_mutex_unlock(&c->current_job_lock);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
66 return NULL;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
67 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
68 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
69 pthread_mutex_unlock(&c->current_job_lock);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
72
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
73 pthread_mutex_lock(&c->current_job_lock);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
74 our_job = c->current_job++;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
75 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
76 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
83
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
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
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
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
238b95c5ffe2 set thread_opaque to NULL when freeing it
benoit
parents: 5215
diff changeset
101 av_freep(&avctx->thread_opaque);
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
102 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
103
8333
09aafff47bc0 Avoid invasion of POSIX-reserved _t namespace.
diego
parents: 8129
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
111
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
112 pthread_mutex_lock(&c->current_job_lock);
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
121 c->rets_count = job_count;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
122 } else {
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
123 c->rets = &dummy_ret;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
124 c->rets_count = 1;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
125 }
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
126 pthread_cond_broadcast(&c->current_job_cond);
1857
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
127
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
128 avcodec_thread_park_workers(c, avctx->thread_count);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
129
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
130 return 0;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
131 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
132
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
135 int i;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
136 ThreadContext *c;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
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
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
160 avctx->thread_count = i;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
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
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
165 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
166
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
167 avcodec_thread_park_workers(c, thread_count);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
168
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
169 avctx->execute = avcodec_thread_execute;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
170 return 0;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
171 }