annotate pthread.c @ 5542:b0a566346fb1 libavcodec

Add attribute that forces alignment of stack to functions that need it. Necessary for systems that don't align by default to 16 bytes, required by some SSE instructions. Requires GCC >= 4.2. Based on patch by Ga¸«³l Chardon.
author ramiro
date Mon, 13 Aug 2007 15:28:29 +0000
parents 238b95c5ffe2
children a9734fe0811e
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
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
28 typedef int (action_t)(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;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
32 action_t *func;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
33 void **args;
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;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
37
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
38 pthread_cond_t last_job_cond;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
39 pthread_cond_t current_job_cond;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
40 pthread_mutex_t current_job_lock;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
41 int current_job;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
42 int done;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
43 } ThreadContext;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
44
5542
b0a566346fb1 Add attribute that forces alignment of stack to functions that need it.
ramiro
parents: 5232
diff changeset
45 static void* attribute_align_arg worker(void *v)
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
46 {
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
47 AVCodecContext *avctx = v;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
48 ThreadContext *c = avctx->thread_opaque;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
49 int our_job = c->job_count;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
50 int thread_count = avctx->thread_count;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
51 int self_id;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
52
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
53 pthread_mutex_lock(&c->current_job_lock);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
54 self_id = c->current_job++;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
55 for (;;){
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
56 while (our_job >= c->job_count) {
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
57 if (c->current_job == thread_count + c->job_count)
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
58 pthread_cond_signal(&c->last_job_cond);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
59
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
60 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
61 our_job = self_id;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
62
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
63 if (c->done) {
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
64 pthread_mutex_unlock(&c->current_job_lock);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
65 return NULL;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
66 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
67 }
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
68 pthread_mutex_unlock(&c->current_job_lock);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
69
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
70 c->rets[our_job%c->rets_count] = c->func(avctx, c->args[our_job]);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
71
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
72 pthread_mutex_lock(&c->current_job_lock);
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
73 our_job = c->current_job++;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
74 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
75 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
76
4283
d6f83e2f8804 rename always_inline to av_always_inline and move to common.h
mru
parents: 3947
diff changeset
77 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
78 {
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
79 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
80 pthread_mutex_unlock(&c->current_job_lock);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
81 }
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
82
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
83 void avcodec_thread_free(AVCodecContext *avctx)
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
84 {
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
85 ThreadContext *c = avctx->thread_opaque;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
86 int i;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
87
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
88 pthread_mutex_lock(&c->current_job_lock);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
89 c->done = 1;
2035
e1b69326ae36 10l fixes by ("Debabrata Banerjee" <davatar at comcast dot net>)
michael
parents: 2023
diff changeset
90 pthread_cond_broadcast(&c->current_job_cond);
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
91 pthread_mutex_unlock(&c->current_job_lock);
1857
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
92
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
93 for (i=0; i<avctx->thread_count; i++)
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
94 pthread_join(c->workers[i], NULL);
1857
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
95
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
96 pthread_mutex_destroy(&c->current_job_lock);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
97 pthread_cond_destroy(&c->current_job_cond);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
98 pthread_cond_destroy(&c->last_job_cond);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
99 av_free(c->workers);
5232
238b95c5ffe2 set thread_opaque to NULL when freeing it
benoit
parents: 5215
diff changeset
100 av_freep(&avctx->thread_opaque);
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
101 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
102
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
103 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
104 {
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
105 ThreadContext *c= avctx->thread_opaque;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
106 int dummy_ret;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
107
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
108 if (job_count <= 0)
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
109 return 0;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
110
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
111 pthread_mutex_lock(&c->current_job_lock);
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
112
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
113 c->current_job = avctx->thread_count;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
114 c->job_count = job_count;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
115 c->args = arg;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
116 c->func = func;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
117 if (ret) {
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
118 c->rets = ret;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
119 c->rets_count = job_count;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
120 } else {
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
121 c->rets = &dummy_ret;
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
122 c->rets_count = 1;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
123 }
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
124 pthread_cond_broadcast(&c->current_job_cond);
1857
00a6bfc81010 count > thread_count for execute()
michael
parents: 1822
diff changeset
125
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
126 avcodec_thread_park_workers(c, avctx->thread_count);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
127
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
128 return 0;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
129 }
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
130
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
131 int avcodec_thread_init(AVCodecContext *avctx, int thread_count)
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
132 {
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
133 int i;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
134 ThreadContext *c;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
135
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
136 c = av_mallocz(sizeof(ThreadContext));
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
137 if (!c)
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
138 return -1;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
139
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
140 c->workers = av_mallocz(sizeof(pthread_t)*thread_count);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
141 if (!c->workers) {
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
142 av_free(c);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
143 return -1;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
144 }
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
145
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
146 avctx->thread_opaque = c;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
147 avctx->thread_count = thread_count;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
148 c->current_job = 0;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
149 c->job_count = 0;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
150 c->done = 0;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
151 pthread_cond_init(&c->current_job_cond, NULL);
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
152 pthread_cond_init(&c->last_job_cond, NULL);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
153 pthread_mutex_init(&c->current_job_lock, NULL);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
154 pthread_mutex_lock(&c->current_job_lock);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
155 for (i=0; i<thread_count; i++) {
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
156 if(pthread_create(&c->workers[i], NULL, worker, avctx)) {
2979
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
157 avctx->thread_count = i;
bfabfdf9ce55 COSMETICS: tabs --> spaces, some prettyprinting
diego
parents: 2967
diff changeset
158 pthread_mutex_unlock(&c->current_job_lock);
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
159 avcodec_thread_free(avctx);
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
160 return -1;
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
161 }
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
162 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
163
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
164 avcodec_thread_park_workers(c, thread_count);
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2035
diff changeset
165
2023
50e92cec1b84 * reimplementation using mutexes and condition variables.
romansh
parents: 1857
diff changeset
166 avctx->execute = avcodec_thread_execute;
1799
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
167 return 0;
95612d423fde multithreaded/SMP motion estimation
michael
parents:
diff changeset
168 }