OLD | NEW |
1 // Copyright 2013 Google Inc. All Rights Reserved. | 1 // Copyright 2013 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Use of this source code is governed by a BSD-style license | 3 // Use of this source code is governed by a BSD-style license |
4 // that can be found in the COPYING file in the root of the source | 4 // that can be found in the COPYING file in the root of the source |
5 // tree. An additional intellectual property rights grant can be found | 5 // tree. An additional intellectual property rights grant can be found |
6 // in the file PATENTS. All contributing project authors may | 6 // in the file PATENTS. All contributing project authors may |
7 // be found in the AUTHORS file in the root of the source tree. | 7 // be found in the AUTHORS file in the root of the source tree. |
8 // ----------------------------------------------------------------------------- | 8 // ----------------------------------------------------------------------------- |
9 // | 9 // |
10 // Multi-threaded worker | 10 // Multi-threaded worker |
11 // | 11 // |
12 // Original source: | 12 // Original source: |
13 // http://git.chromium.org/webm/libwebp.git | 13 // http://git.chromium.org/webm/libwebp.git |
14 // 100644 blob 13a61a4c84194c3374080cbf03d881d3cd6af40d src/utils/thread.h | 14 // 100644 blob 13a61a4c84194c3374080cbf03d881d3cd6af40d src/utils/thread.h |
15 | 15 |
16 | 16 |
17 #ifndef VP9_DECODER_VP9_THREAD_H_ | 17 #ifndef VP9_DECODER_VP9_THREAD_H_ |
18 #define VP9_DECODER_VP9_THREAD_H_ | 18 #define VP9_DECODER_VP9_THREAD_H_ |
19 | 19 |
20 #include "./vpx_config.h" | 20 #include "./vpx_config.h" |
21 | 21 |
22 #ifdef __cplusplus | 22 #ifdef __cplusplus |
23 extern "C" { | 23 extern "C" { |
24 #endif | 24 #endif |
25 | 25 |
26 #if CONFIG_MULTITHREAD | 26 #if CONFIG_MULTITHREAD |
27 | 27 |
28 #if defined(_WIN32) | 28 #if defined(_WIN32) |
29 | 29 #include <errno.h> // NOLINT |
| 30 #include <process.h> // NOLINT |
30 #include <windows.h> // NOLINT | 31 #include <windows.h> // NOLINT |
31 typedef HANDLE pthread_t; | 32 typedef HANDLE pthread_t; |
32 typedef CRITICAL_SECTION pthread_mutex_t; | 33 typedef CRITICAL_SECTION pthread_mutex_t; |
33 typedef struct { | 34 typedef struct { |
34 HANDLE waiting_sem_; | 35 HANDLE waiting_sem_; |
35 HANDLE received_sem_; | 36 HANDLE received_sem_; |
36 HANDLE signal_event_; | 37 HANDLE signal_event_; |
37 } pthread_cond_t; | 38 } pthread_cond_t; |
38 | 39 |
39 #else | 40 //------------------------------------------------------------------------------ |
| 41 // simplistic pthread emulation layer |
40 | 42 |
| 43 // _beginthreadex requires __stdcall |
| 44 #define THREADFN unsigned int __stdcall |
| 45 #define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val) |
| 46 |
| 47 static INLINE int pthread_create(pthread_t* const thread, const void* attr, |
| 48 unsigned int (__stdcall *start)(void*), |
| 49 void* arg) { |
| 50 (void)attr; |
| 51 *thread = (pthread_t)_beginthreadex(NULL, /* void *security */ |
| 52 0, /* unsigned stack_size */ |
| 53 start, |
| 54 arg, |
| 55 0, /* unsigned initflag */ |
| 56 NULL); /* unsigned *thrdaddr */ |
| 57 if (*thread == NULL) return 1; |
| 58 SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); |
| 59 return 0; |
| 60 } |
| 61 |
| 62 static INLINE int pthread_join(pthread_t thread, void** value_ptr) { |
| 63 (void)value_ptr; |
| 64 return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 || |
| 65 CloseHandle(thread) == 0); |
| 66 } |
| 67 |
| 68 // Mutex |
| 69 static INLINE int pthread_mutex_init(pthread_mutex_t *const mutex, |
| 70 void* mutexattr) { |
| 71 (void)mutexattr; |
| 72 InitializeCriticalSection(mutex); |
| 73 return 0; |
| 74 } |
| 75 |
| 76 static INLINE int pthread_mutex_trylock(pthread_mutex_t *const mutex) { |
| 77 return TryEnterCriticalSection(mutex) ? 0 : EBUSY; |
| 78 } |
| 79 |
| 80 static INLINE int pthread_mutex_lock(pthread_mutex_t *const mutex) { |
| 81 EnterCriticalSection(mutex); |
| 82 return 0; |
| 83 } |
| 84 |
| 85 static INLINE int pthread_mutex_unlock(pthread_mutex_t *const mutex) { |
| 86 LeaveCriticalSection(mutex); |
| 87 return 0; |
| 88 } |
| 89 |
| 90 static INLINE int pthread_mutex_destroy(pthread_mutex_t *const mutex) { |
| 91 DeleteCriticalSection(mutex); |
| 92 return 0; |
| 93 } |
| 94 |
| 95 // Condition |
| 96 static INLINE int pthread_cond_destroy(pthread_cond_t *const condition) { |
| 97 int ok = 1; |
| 98 ok &= (CloseHandle(condition->waiting_sem_) != 0); |
| 99 ok &= (CloseHandle(condition->received_sem_) != 0); |
| 100 ok &= (CloseHandle(condition->signal_event_) != 0); |
| 101 return !ok; |
| 102 } |
| 103 |
| 104 static INLINE int pthread_cond_init(pthread_cond_t *const condition, |
| 105 void* cond_attr) { |
| 106 (void)cond_attr; |
| 107 condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL); |
| 108 condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL); |
| 109 condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL); |
| 110 if (condition->waiting_sem_ == NULL || |
| 111 condition->received_sem_ == NULL || |
| 112 condition->signal_event_ == NULL) { |
| 113 pthread_cond_destroy(condition); |
| 114 return 1; |
| 115 } |
| 116 return 0; |
| 117 } |
| 118 |
| 119 static INLINE int pthread_cond_signal(pthread_cond_t *const condition) { |
| 120 int ok = 1; |
| 121 if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) { |
| 122 // a thread is waiting in pthread_cond_wait: allow it to be notified |
| 123 ok = SetEvent(condition->signal_event_); |
| 124 // wait until the event is consumed so the signaler cannot consume |
| 125 // the event via its own pthread_cond_wait. |
| 126 ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) != |
| 127 WAIT_OBJECT_0); |
| 128 } |
| 129 return !ok; |
| 130 } |
| 131 |
| 132 static INLINE int pthread_cond_wait(pthread_cond_t *const condition, |
| 133 pthread_mutex_t *const mutex) { |
| 134 int ok; |
| 135 // note that there is a consumer available so the signal isn't dropped in |
| 136 // pthread_cond_signal |
| 137 if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) |
| 138 return 1; |
| 139 // now unlock the mutex so pthread_cond_signal may be issued |
| 140 pthread_mutex_unlock(mutex); |
| 141 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == |
| 142 WAIT_OBJECT_0); |
| 143 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); |
| 144 pthread_mutex_lock(mutex); |
| 145 return !ok; |
| 146 } |
| 147 #else // _WIN32 |
41 #include <pthread.h> // NOLINT | 148 #include <pthread.h> // NOLINT |
| 149 # define THREADFN void* |
| 150 # define THREAD_RETURN(val) val |
| 151 #endif |
42 | 152 |
43 #endif /* _WIN32 */ | 153 #endif // CONFIG_MULTITHREAD |
44 #endif /* CONFIG_MULTITHREAD */ | |
45 | 154 |
46 // State of the worker thread object | 155 // State of the worker thread object |
47 typedef enum { | 156 typedef enum { |
48 NOT_OK = 0, // object is unusable | 157 NOT_OK = 0, // object is unusable |
49 OK, // ready to work | 158 OK, // ready to work |
50 WORK // busy finishing the current task | 159 WORK // busy finishing the current task |
51 } VP9WorkerStatus; | 160 } VP9WorkerStatus; |
52 | 161 |
53 // Function to be called by the worker thread. Takes two opaque pointers as | 162 // Function to be called by the worker thread. Takes two opaque pointers as |
54 // arguments (data1 and data2), and should return false in case of error. | 163 // arguments (data1 and data2), and should return false in case of error. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 // must call vp9_worker_reset() again. | 198 // must call vp9_worker_reset() again. |
90 void vp9_worker_end(VP9Worker* const worker); | 199 void vp9_worker_end(VP9Worker* const worker); |
91 | 200 |
92 //------------------------------------------------------------------------------ | 201 //------------------------------------------------------------------------------ |
93 | 202 |
94 #ifdef __cplusplus | 203 #ifdef __cplusplus |
95 } // extern "C" | 204 } // extern "C" |
96 #endif | 205 #endif |
97 | 206 |
98 #endif // VP9_DECODER_VP9_THREAD_H_ | 207 #endif // VP9_DECODER_VP9_THREAD_H_ |
OLD | NEW |