Mercurial > libavcodec.hg
comparison pthread.c @ 2967:ef2149182f1c libavcodec
COSMETICS: Remove all trailing whitespace.
| author | diego |
|---|---|
| date | Sat, 17 Dec 2005 18:14:38 +0000 |
| parents | e1b69326ae36 |
| children | bfabfdf9ce55 |
comparison
equal
deleted
inserted
replaced
| 2966:564788471dd4 | 2967:ef2149182f1c |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2004 Roman Shaposhnik. | 2 * Copyright (c) 2004 Roman Shaposhnik. |
| 3 * | 3 * |
| 4 * Many thanks to Steven M. Schultz for providing clever ideas and | 4 * Many thanks to Steven M. Schultz for providing clever ideas and |
| 5 * to Michael Niedermayer <michaelni@gmx.at> for writing initial | 5 * to Michael Niedermayer <michaelni@gmx.at> for writing initial |
| 6 * implementation. | 6 * implementation. |
| 7 * | 7 * |
| 8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
| 32 action_t *func; | 32 action_t *func; |
| 33 void **args; | 33 void **args; |
| 34 int *rets; | 34 int *rets; |
| 35 int rets_count; | 35 int rets_count; |
| 36 int job_count; | 36 int job_count; |
| 37 | 37 |
| 38 pthread_cond_t last_job_cond; | 38 pthread_cond_t last_job_cond; |
| 39 pthread_cond_t current_job_cond; | 39 pthread_cond_t current_job_cond; |
| 40 pthread_mutex_t current_job_lock; | 40 pthread_mutex_t current_job_lock; |
| 41 int current_job; | 41 int current_job; |
| 42 int done; | 42 int done; |
| 43 } ThreadContext; | 43 } ThreadContext; |
| 44 | 44 |
| 45 static void* worker(void *v) | 45 static void* worker(void *v) |
| 46 { | 46 { |
| 47 AVCodecContext *avctx = v; | 47 AVCodecContext *avctx = v; |
| 48 ThreadContext *c = avctx->thread_opaque; | 48 ThreadContext *c = avctx->thread_opaque; |
| 49 int our_job = c->job_count; | 49 int our_job = c->job_count; |
| 50 int thread_count = avctx->thread_count; | 50 int thread_count = avctx->thread_count; |
| 51 int self_id; | 51 int self_id; |
| 52 | 52 |
| 53 pthread_mutex_lock(&c->current_job_lock); | 53 pthread_mutex_lock(&c->current_job_lock); |
| 54 self_id = c->current_job++; | 54 self_id = c->current_job++; |
| 55 for (;;){ | 55 for (;;){ |
| 56 while (our_job >= c->job_count) { | 56 while (our_job >= c->job_count) { |
| 57 if (c->current_job == thread_count + c->job_count) | 57 if (c->current_job == thread_count + c->job_count) |
| 58 pthread_cond_signal(&c->last_job_cond); | 58 pthread_cond_signal(&c->last_job_cond); |
| 59 | 59 |
| 60 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); | 60 pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); |
| 61 our_job = self_id; | 61 our_job = self_id; |
| 62 | 62 |
| 63 if (c->done) { | 63 if (c->done) { |
| 64 pthread_mutex_unlock(&c->current_job_lock); | 64 pthread_mutex_unlock(&c->current_job_lock); |
| 65 return NULL; | 65 return NULL; |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 pthread_mutex_unlock(&c->current_job_lock); | 68 pthread_mutex_unlock(&c->current_job_lock); |
| 69 | 69 |
| 70 c->rets[our_job%c->rets_count] = c->func(avctx, c->args[our_job]); | 70 c->rets[our_job%c->rets_count] = c->func(avctx, c->args[our_job]); |
| 71 | 71 |
| 72 pthread_mutex_lock(&c->current_job_lock); | 72 pthread_mutex_lock(&c->current_job_lock); |
| 73 our_job = c->current_job++; | 73 our_job = c->current_job++; |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 78 { | 78 { |
| 79 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); | 79 pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); |
| 80 pthread_mutex_unlock(&c->current_job_lock); | 80 pthread_mutex_unlock(&c->current_job_lock); |
| 81 } | 81 } |
| 82 | 82 |
| 83 void avcodec_thread_free(AVCodecContext *avctx) | 83 void avcodec_thread_free(AVCodecContext *avctx) |
| 84 { | 84 { |
| 85 ThreadContext *c = avctx->thread_opaque; | 85 ThreadContext *c = avctx->thread_opaque; |
| 86 int i; | 86 int i; |
| 87 | 87 |
| 88 pthread_mutex_lock(&c->current_job_lock); | 88 pthread_mutex_lock(&c->current_job_lock); |
| 89 c->done = 1; | 89 c->done = 1; |
| 90 pthread_cond_broadcast(&c->current_job_cond); | 90 pthread_cond_broadcast(&c->current_job_cond); |
| 91 pthread_mutex_unlock(&c->current_job_lock); | 91 pthread_mutex_unlock(&c->current_job_lock); |
| 92 | 92 |
| 98 pthread_cond_destroy(&c->last_job_cond); | 98 pthread_cond_destroy(&c->last_job_cond); |
| 99 av_free(c->workers); | 99 av_free(c->workers); |
| 100 av_free(c); | 100 av_free(c); |
| 101 } | 101 } |
| 102 | 102 |
| 103 int avcodec_thread_execute(AVCodecContext *avctx, action_t* func, void **arg, int *ret, int job_count) | 103 int avcodec_thread_execute(AVCodecContext *avctx, action_t* func, void **arg, int *ret, int job_count) |
| 104 { | 104 { |
| 105 ThreadContext *c= avctx->thread_opaque; | 105 ThreadContext *c= avctx->thread_opaque; |
| 106 int dummy_ret; | 106 int dummy_ret; |
| 107 | 107 |
| 108 if (job_count <= 0) | 108 if (job_count <= 0) |
| 109 return 0; | 109 return 0; |
| 110 | 110 |
| 111 pthread_mutex_lock(&c->current_job_lock); | 111 pthread_mutex_lock(&c->current_job_lock); |
| 112 | 112 |
| 113 c->current_job = avctx->thread_count; | 113 c->current_job = avctx->thread_count; |
| 114 c->job_count = job_count; | 114 c->job_count = job_count; |
| 115 c->args = arg; | 115 c->args = arg; |
| 116 c->func = func; | 116 c->func = func; |
| 117 if (ret) { | 117 if (ret) { |
| 118 c->rets = ret; | 118 c->rets = ret; |
| 119 c->rets_count = job_count; | 119 c->rets_count = job_count; |
| 120 } else { | 120 } else { |
| 121 c->rets = &dummy_ret; | 121 c->rets = &dummy_ret; |
| 122 c->rets_count = 1; | 122 c->rets_count = 1; |
| 123 } | 123 } |
| 124 pthread_cond_broadcast(&c->current_job_cond); | 124 pthread_cond_broadcast(&c->current_job_cond); |
| 125 | 125 |
| 126 avcodec_thread_park_workers(c, avctx->thread_count); | 126 avcodec_thread_park_workers(c, avctx->thread_count); |
| 127 | 127 |
| 128 return 0; | 128 return 0; |
| 129 } | 129 } |
| 130 | 130 |
| 131 int avcodec_thread_init(AVCodecContext *avctx, int thread_count) | 131 int avcodec_thread_init(AVCodecContext *avctx, int thread_count) |
| 132 { | 132 { |
| 133 int i; | 133 int i; |
| 134 ThreadContext *c; | 134 ThreadContext *c; |
| 135 | 135 |
| 136 c = av_mallocz(sizeof(ThreadContext)); | 136 c = av_mallocz(sizeof(ThreadContext)); |
| 137 if (!c) | 137 if (!c) |
| 138 return -1; | 138 return -1; |
| 139 | 139 |
| 140 c->workers = av_mallocz(sizeof(pthread_t)*thread_count); | 140 c->workers = av_mallocz(sizeof(pthread_t)*thread_count); |
| 141 if (!c->workers) { | 141 if (!c->workers) { |
| 142 av_free(c); | 142 av_free(c); |
| 143 return -1; | 143 return -1; |
| 144 } | 144 } |
| 146 avctx->thread_opaque = c; | 146 avctx->thread_opaque = c; |
| 147 avctx->thread_count = thread_count; | 147 avctx->thread_count = thread_count; |
| 148 c->current_job = 0; | 148 c->current_job = 0; |
| 149 c->job_count = 0; | 149 c->job_count = 0; |
| 150 c->done = 0; | 150 c->done = 0; |
| 151 pthread_cond_init(&c->current_job_cond, NULL); | 151 pthread_cond_init(&c->current_job_cond, NULL); |
| 152 pthread_cond_init(&c->last_job_cond, NULL); | 152 pthread_cond_init(&c->last_job_cond, NULL); |
| 153 pthread_mutex_init(&c->current_job_lock, NULL); | 153 pthread_mutex_init(&c->current_job_lock, NULL); |
| 154 pthread_mutex_lock(&c->current_job_lock); | 154 pthread_mutex_lock(&c->current_job_lock); |
| 155 for (i=0; i<thread_count; i++) { | 155 for (i=0; i<thread_count; i++) { |
| 156 if(pthread_create(&c->workers[i], NULL, worker, avctx)) { | 156 if(pthread_create(&c->workers[i], NULL, worker, avctx)) { |
| 157 avctx->thread_count = i; | 157 avctx->thread_count = i; |
| 158 pthread_mutex_unlock(&c->current_job_lock); | 158 pthread_mutex_unlock(&c->current_job_lock); |
| 159 avcodec_thread_free(avctx); | 159 avcodec_thread_free(avctx); |
| 160 return -1; | 160 return -1; |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 | 163 |
| 164 avcodec_thread_park_workers(c, thread_count); | 164 avcodec_thread_park_workers(c, thread_count); |
| 165 | 165 |
| 166 avctx->execute = avcodec_thread_execute; | 166 avctx->execute = avcodec_thread_execute; |
| 167 return 0; | 167 return 0; |
| 168 } | 168 } |
