Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: third_party/libwebp/utils/thread.c

Issue 1546003002: libwebp: update to 0.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 'defines' exists Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 Google Inc. All Rights Reserved. 1 // Copyright 2011 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 // Author: Skal (pascal.massimino@gmail.com) 12 // Author: Skal (pascal.massimino@gmail.com)
13 13
14 #include <assert.h> 14 #include <assert.h>
15 #include <string.h> // for memset() 15 #include <string.h> // for memset()
16 #include "./thread.h" 16 #include "./thread.h"
17 #include "./utils.h" 17 #include "./utils.h"
18 18
19 #ifdef WEBP_USE_THREAD 19 #ifdef WEBP_USE_THREAD
20 20
21 #if defined(_WIN32) 21 #if defined(_WIN32)
22 22
23 #include <windows.h> 23 #include <windows.h>
24 typedef HANDLE pthread_t; 24 typedef HANDLE pthread_t;
25 typedef CRITICAL_SECTION pthread_mutex_t; 25 typedef CRITICAL_SECTION pthread_mutex_t;
26
27 #if _WIN32_WINNT >= 0x0600 // Windows Vista / Server 2008 or greater
28 #define USE_WINDOWS_CONDITION_VARIABLE
29 typedef CONDITION_VARIABLE pthread_cond_t;
30 #else
26 typedef struct { 31 typedef struct {
27 HANDLE waiting_sem_; 32 HANDLE waiting_sem_;
28 HANDLE received_sem_; 33 HANDLE received_sem_;
29 HANDLE signal_event_; 34 HANDLE signal_event_;
30 } pthread_cond_t; 35 } pthread_cond_t;
36 #endif // _WIN32_WINNT >= 0x600
37
38 #ifndef WINAPI_FAMILY_PARTITION
39 #define WINAPI_PARTITION_DESKTOP 1
40 #define WINAPI_FAMILY_PARTITION(x) x
41 #endif
42
43 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
44 #define USE_CREATE_THREAD
45 #endif
31 46
32 #else // !_WIN32 47 #else // !_WIN32
33 48
34 #include <pthread.h> 49 #include <pthread.h>
35 50
36 #endif // _WIN32 51 #endif // _WIN32
37 52
38 struct WebPWorkerImpl { 53 struct WebPWorkerImpl {
39 pthread_mutex_t mutex_; 54 pthread_mutex_t mutex_;
40 pthread_cond_t condition_; 55 pthread_cond_t condition_;
41 pthread_t thread_; 56 pthread_t thread_;
42 }; 57 };
43 58
44 #if defined(_WIN32) 59 #if defined(_WIN32)
45 60
46 //------------------------------------------------------------------------------ 61 //------------------------------------------------------------------------------
47 // simplistic pthread emulation layer 62 // simplistic pthread emulation layer
48 63
49 #include <process.h> 64 #include <process.h>
50 65
51 // _beginthreadex requires __stdcall 66 // _beginthreadex requires __stdcall
52 #define THREADFN unsigned int __stdcall 67 #define THREADFN unsigned int __stdcall
53 #define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val) 68 #define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val)
54 69
70 #if _WIN32_WINNT >= 0x0501 // Windows XP or greater
71 #define WaitForSingleObject(obj, timeout) \
72 WaitForSingleObjectEx(obj, timeout, FALSE /*bAlertable*/)
73 #endif
74
55 static int pthread_create(pthread_t* const thread, const void* attr, 75 static int pthread_create(pthread_t* const thread, const void* attr,
56 unsigned int (__stdcall *start)(void*), void* arg) { 76 unsigned int (__stdcall *start)(void*), void* arg) {
57 (void)attr; 77 (void)attr;
78 #ifdef USE_CREATE_THREAD
79 *thread = CreateThread(NULL, /* lpThreadAttributes */
80 0, /* dwStackSize */
81 start,
82 arg,
83 0, /* dwStackSize */
84 NULL); /* lpThreadId */
85 #else
58 *thread = (pthread_t)_beginthreadex(NULL, /* void *security */ 86 *thread = (pthread_t)_beginthreadex(NULL, /* void *security */
59 0, /* unsigned stack_size */ 87 0, /* unsigned stack_size */
60 start, 88 start,
61 arg, 89 arg,
62 0, /* unsigned initflag */ 90 0, /* unsigned initflag */
63 NULL); /* unsigned *thrdaddr */ 91 NULL); /* unsigned *thrdaddr */
92 #endif
64 if (*thread == NULL) return 1; 93 if (*thread == NULL) return 1;
65 SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); 94 SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL);
66 return 0; 95 return 0;
67 } 96 }
68 97
69 static int pthread_join(pthread_t thread, void** value_ptr) { 98 static int pthread_join(pthread_t thread, void** value_ptr) {
70 (void)value_ptr; 99 (void)value_ptr;
71 return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 || 100 return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 ||
72 CloseHandle(thread) == 0); 101 CloseHandle(thread) == 0);
73 } 102 }
74 103
75 // Mutex 104 // Mutex
76 static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) { 105 static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) {
77 (void)mutexattr; 106 (void)mutexattr;
107 #if _WIN32_WINNT >= 0x0600 // Windows Vista / Server 2008 or greater
108 InitializeCriticalSectionEx(mutex, 0 /*dwSpinCount*/, 0 /*Flags*/);
109 #else
78 InitializeCriticalSection(mutex); 110 InitializeCriticalSection(mutex);
111 #endif
79 return 0; 112 return 0;
80 } 113 }
81 114
82 static int pthread_mutex_lock(pthread_mutex_t* const mutex) { 115 static int pthread_mutex_lock(pthread_mutex_t* const mutex) {
83 EnterCriticalSection(mutex); 116 EnterCriticalSection(mutex);
84 return 0; 117 return 0;
85 } 118 }
86 119
87 static int pthread_mutex_unlock(pthread_mutex_t* const mutex) { 120 static int pthread_mutex_unlock(pthread_mutex_t* const mutex) {
88 LeaveCriticalSection(mutex); 121 LeaveCriticalSection(mutex);
89 return 0; 122 return 0;
90 } 123 }
91 124
92 static int pthread_mutex_destroy(pthread_mutex_t* const mutex) { 125 static int pthread_mutex_destroy(pthread_mutex_t* const mutex) {
93 DeleteCriticalSection(mutex); 126 DeleteCriticalSection(mutex);
94 return 0; 127 return 0;
95 } 128 }
96 129
97 // Condition 130 // Condition
98 static int pthread_cond_destroy(pthread_cond_t* const condition) { 131 static int pthread_cond_destroy(pthread_cond_t* const condition) {
99 int ok = 1; 132 int ok = 1;
133 #ifdef USE_WINDOWS_CONDITION_VARIABLE
134 (void)condition;
135 #else
100 ok &= (CloseHandle(condition->waiting_sem_) != 0); 136 ok &= (CloseHandle(condition->waiting_sem_) != 0);
101 ok &= (CloseHandle(condition->received_sem_) != 0); 137 ok &= (CloseHandle(condition->received_sem_) != 0);
102 ok &= (CloseHandle(condition->signal_event_) != 0); 138 ok &= (CloseHandle(condition->signal_event_) != 0);
139 #endif
103 return !ok; 140 return !ok;
104 } 141 }
105 142
106 static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) { 143 static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) {
107 (void)cond_attr; 144 (void)cond_attr;
145 #ifdef USE_WINDOWS_CONDITION_VARIABLE
146 InitializeConditionVariable(condition);
147 #else
108 condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL); 148 condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
109 condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL); 149 condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL);
110 condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL); 150 condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
111 if (condition->waiting_sem_ == NULL || 151 if (condition->waiting_sem_ == NULL ||
112 condition->received_sem_ == NULL || 152 condition->received_sem_ == NULL ||
113 condition->signal_event_ == NULL) { 153 condition->signal_event_ == NULL) {
114 pthread_cond_destroy(condition); 154 pthread_cond_destroy(condition);
115 return 1; 155 return 1;
116 } 156 }
157 #endif
117 return 0; 158 return 0;
118 } 159 }
119 160
120 static int pthread_cond_signal(pthread_cond_t* const condition) { 161 static int pthread_cond_signal(pthread_cond_t* const condition) {
121 int ok = 1; 162 int ok = 1;
163 #ifdef USE_WINDOWS_CONDITION_VARIABLE
164 WakeConditionVariable(condition);
165 #else
122 if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) { 166 if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) {
123 // a thread is waiting in pthread_cond_wait: allow it to be notified 167 // a thread is waiting in pthread_cond_wait: allow it to be notified
124 ok = SetEvent(condition->signal_event_); 168 ok = SetEvent(condition->signal_event_);
125 // wait until the event is consumed so the signaler cannot consume 169 // wait until the event is consumed so the signaler cannot consume
126 // the event via its own pthread_cond_wait. 170 // the event via its own pthread_cond_wait.
127 ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) != 171 ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) !=
128 WAIT_OBJECT_0); 172 WAIT_OBJECT_0);
129 } 173 }
174 #endif
130 return !ok; 175 return !ok;
131 } 176 }
132 177
133 static int pthread_cond_wait(pthread_cond_t* const condition, 178 static int pthread_cond_wait(pthread_cond_t* const condition,
134 pthread_mutex_t* const mutex) { 179 pthread_mutex_t* const mutex) {
135 int ok; 180 int ok;
181 #ifdef USE_WINDOWS_CONDITION_VARIABLE
182 ok = SleepConditionVariableCS(condition, mutex, INFINITE);
183 #else
136 // note that there is a consumer available so the signal isn't dropped in 184 // note that there is a consumer available so the signal isn't dropped in
137 // pthread_cond_signal 185 // pthread_cond_signal
138 if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) 186 if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL))
139 return 1; 187 return 1;
140 // now unlock the mutex so pthread_cond_signal may be issued 188 // now unlock the mutex so pthread_cond_signal may be issued
141 pthread_mutex_unlock(mutex); 189 pthread_mutex_unlock(mutex);
142 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == 190 ok = (WaitForSingleObject(condition->signal_event_, INFINITE) ==
143 WAIT_OBJECT_0); 191 WAIT_OBJECT_0);
144 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); 192 ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL);
145 pthread_mutex_lock(mutex); 193 pthread_mutex_lock(mutex);
194 #endif
146 return !ok; 195 return !ok;
147 } 196 }
148 197
149 #else // !_WIN32 198 #else // !_WIN32
150 # define THREADFN void* 199 # define THREADFN void*
151 # define THREAD_RETURN(val) val 200 # define THREAD_RETURN(val) val
152 #endif // _WIN32 201 #endif // _WIN32
153 202
154 //------------------------------------------------------------------------------ 203 //------------------------------------------------------------------------------
155 204
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 } 349 }
301 g_worker_interface = *winterface; 350 g_worker_interface = *winterface;
302 return 1; 351 return 1;
303 } 352 }
304 353
305 const WebPWorkerInterface* WebPGetWorkerInterface(void) { 354 const WebPWorkerInterface* WebPGetWorkerInterface(void) {
306 return &g_worker_interface; 355 return &g_worker_interface;
307 } 356 }
308 357
309 //------------------------------------------------------------------------------ 358 //------------------------------------------------------------------------------
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698