Mercurial > libavcodec.hg
annotate pthread.c @ 3198:6b9f0c4fbdbe libavcodec
First part of a series of speed-enchancing patches.
This one sets up a snow.h and makes snow use the dsputil function pointer
framework to access the three functions that will be implemented in asm
in the other parts of the patchset.
Patch by Robert Edele < yartrebo AH earthlink POIS net>
Original thread:
Subject: [Ffmpeg-devel] [PATCH] Snow mmx+sse2 asm optimizations
Date: Sun, 05 Feb 2006 12:47:14 -0500
| author | gpoirier |
|---|---|
| date | Thu, 16 Mar 2006 19:18:18 +0000 |
| parents | 0b546eab515d |
| children | c8c591fe26f8 |
| 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 * |
| 8 * This library is free software; you can redistribute it and/or | |
| 9 * modify it under the terms of the GNU Lesser General Public | |
| 10 * License as published by the Free Software Foundation; either | |
| 11 * version 2 of the License, or (at your option) any later version. | |
| 12 * | |
| 13 * This library is distributed in the hope that it will be useful, | |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 16 * Lesser General Public License for more details. | |
| 17 * | |
| 18 * You should have received a copy of the GNU Lesser General Public | |
| 19 * License along with this library; if not, write to the Free Software | |
|
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 1799 | 21 * |
| 22 */ | |
| 23 #include <pthread.h> | |
| 24 | |
| 25 #include "avcodec.h" | |
| 26 #include "common.h" | |
| 27 | |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
28 typedef int (action_t)(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; |
|
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 | 36 int job_count; |
| 2967 | 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 | 44 |
| 2967 | 45 static void* 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 | 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 | 55 for (;;){ |
| 2979 | 56 while (our_job >= c->job_count) { |
| 57 if (c->current_job == thread_count + c->job_count) | |
| 58 pthread_cond_signal(&c->last_job_cond); | |
| 2967 | 59 |
| 2979 | 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 | 62 |
| 2979 | 63 if (c->done) { |
| 64 pthread_mutex_unlock(&c->current_job_lock); | |
| 65 return NULL; | |
| 66 } | |
| 67 } | |
| 68 pthread_mutex_unlock(&c->current_job_lock); | |
| 2967 | 69 |
| 2979 | 70 c->rets[our_job%c->rets_count] = c->func(avctx, c->args[our_job]); |
| 2967 | 71 |
| 2979 | 72 pthread_mutex_lock(&c->current_job_lock); |
| 73 our_job = c->current_job++; | |
| 1799 | 74 } |
| 75 } | |
| 76 | |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
77 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
|
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 | 82 |
| 2967 | 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 | 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 | 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 | 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); |
|
2035
e1b69326ae36
10l fixes by ("Debabrata Banerjee" <davatar at comcast dot net>)
michael
parents:
2023
diff
changeset
|
100 av_free(c); |
| 1799 | 101 } |
| 102 | |
| 2967 | 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 | 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 | 110 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
111 pthread_mutex_lock(&c->current_job_lock); |
| 1799 | 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 | 119 c->rets_count = job_count; |
| 2967 | 120 } else { |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
121 c->rets = &dummy_ret; |
| 2979 | 122 c->rets_count = 1; |
| 1799 | 123 } |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
124 pthread_cond_broadcast(&c->current_job_cond); |
| 1857 | 125 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
126 avcodec_thread_park_workers(c, avctx->thread_count); |
| 2967 | 127 |
| 1799 | 128 return 0; |
| 129 } | |
| 130 | |
| 2967 | 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 | 133 int i; |
| 134 ThreadContext *c; | |
| 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 | 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 | 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 | 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 | 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 | 157 avctx->thread_count = i; |
| 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 | 162 } |
| 2967 | 163 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
164 avcodec_thread_park_workers(c, thread_count); |
| 2967 | 165 |
|
2023
50e92cec1b84
* reimplementation using mutexes and condition variables.
romansh
parents:
1857
diff
changeset
|
166 avctx->execute = avcodec_thread_execute; |
| 1799 | 167 return 0; |
| 168 } |
