diff options
Diffstat (limited to 'drivers/webpold/utils/thread.c')
-rw-r--r-- | drivers/webpold/utils/thread.c | 247 |
1 files changed, 0 insertions, 247 deletions
diff --git a/drivers/webpold/utils/thread.c b/drivers/webpold/utils/thread.c deleted file mode 100644 index ce89cf9dc7..0000000000 --- a/drivers/webpold/utils/thread.c +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2011 Google Inc. All Rights Reserved. -// -// This code is licensed under the same terms as WebM: -// Software License Agreement: http://www.webmproject.org/license/software/ -// Additional IP Rights Grant: http://www.webmproject.org/license/additional/ -// ----------------------------------------------------------------------------- -// -// Multi-threaded worker -// -// Author: Skal (pascal.massimino@gmail.com) - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <assert.h> -#include <string.h> // for memset() -#include "./thread.h" - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#ifdef WEBP_USE_THREAD - -#if defined(_WIN32) - -//------------------------------------------------------------------------------ -// simplistic pthread emulation layer - -#include <process.h> - -// _beginthreadex requires __stdcall -#define THREADFN unsigned int __stdcall -#define THREAD_RETURN(val) (unsigned int)((DWORD_PTR)val) - -static int pthread_create(pthread_t* const thread, const void* attr, - unsigned int (__stdcall *start)(void*), void* arg) { - (void)attr; - *thread = (pthread_t)_beginthreadex(NULL, /* void *security */ - 0, /* unsigned stack_size */ - start, - arg, - 0, /* unsigned initflag */ - NULL); /* unsigned *thrdaddr */ - if (*thread == NULL) return 1; - SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); - return 0; -} - -static int pthread_join(pthread_t thread, void** value_ptr) { - (void)value_ptr; - return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 || - CloseHandle(thread) == 0); -} - -// Mutex -static int pthread_mutex_init(pthread_mutex_t* const mutex, void* mutexattr) { - (void)mutexattr; - InitializeCriticalSection(mutex); - return 0; -} - -static int pthread_mutex_lock(pthread_mutex_t* const mutex) { - EnterCriticalSection(mutex); - return 0; -} - -static int pthread_mutex_unlock(pthread_mutex_t* const mutex) { - LeaveCriticalSection(mutex); - return 0; -} - -static int pthread_mutex_destroy(pthread_mutex_t* const mutex) { - DeleteCriticalSection(mutex); - return 0; -} - -// Condition -static int pthread_cond_destroy(pthread_cond_t* const condition) { - int ok = 1; - ok &= (CloseHandle(condition->waiting_sem_) != 0); - ok &= (CloseHandle(condition->received_sem_) != 0); - ok &= (CloseHandle(condition->signal_event_) != 0); - return !ok; -} - -static int pthread_cond_init(pthread_cond_t* const condition, void* cond_attr) { - (void)cond_attr; - condition->waiting_sem_ = CreateSemaphore(NULL, 0, 1, NULL); - condition->received_sem_ = CreateSemaphore(NULL, 0, 1, NULL); - condition->signal_event_ = CreateEvent(NULL, FALSE, FALSE, NULL); - if (condition->waiting_sem_ == NULL || - condition->received_sem_ == NULL || - condition->signal_event_ == NULL) { - pthread_cond_destroy(condition); - return 1; - } - return 0; -} - -static int pthread_cond_signal(pthread_cond_t* const condition) { - int ok = 1; - if (WaitForSingleObject(condition->waiting_sem_, 0) == WAIT_OBJECT_0) { - // a thread is waiting in pthread_cond_wait: allow it to be notified - ok = SetEvent(condition->signal_event_); - // wait until the event is consumed so the signaler cannot consume - // the event via its own pthread_cond_wait. - ok &= (WaitForSingleObject(condition->received_sem_, INFINITE) != - WAIT_OBJECT_0); - } - return !ok; -} - -static int pthread_cond_wait(pthread_cond_t* const condition, - pthread_mutex_t* const mutex) { - int ok; - // note that there is a consumer available so the signal isn't dropped in - // pthread_cond_signal - if (!ReleaseSemaphore(condition->waiting_sem_, 1, NULL)) - return 1; - // now unlock the mutex so pthread_cond_signal may be issued - pthread_mutex_unlock(mutex); - ok = (WaitForSingleObject(condition->signal_event_, INFINITE) == - WAIT_OBJECT_0); - ok &= ReleaseSemaphore(condition->received_sem_, 1, NULL); - pthread_mutex_lock(mutex); - return !ok; -} - -#else // _WIN32 -# define THREADFN void* -# define THREAD_RETURN(val) val -#endif - -//------------------------------------------------------------------------------ - -static THREADFN WebPWorkerThreadLoop(void *ptr) { // thread loop - WebPWorker* const worker = (WebPWorker*)ptr; - int done = 0; - while (!done) { - pthread_mutex_lock(&worker->mutex_); - while (worker->status_ == OK) { // wait in idling mode - pthread_cond_wait(&worker->condition_, &worker->mutex_); - } - if (worker->status_ == WORK) { - if (worker->hook) { - worker->had_error |= !worker->hook(worker->data1, worker->data2); - } - worker->status_ = OK; - } else if (worker->status_ == NOT_OK) { // finish the worker - done = 1; - } - // signal to the main thread that we're done (for Sync()) - pthread_cond_signal(&worker->condition_); - pthread_mutex_unlock(&worker->mutex_); - } - return THREAD_RETURN(NULL); // Thread is finished -} - -// main thread state control -static void WebPWorkerChangeState(WebPWorker* const worker, - WebPWorkerStatus new_status) { - // no-op when attempting to change state on a thread that didn't come up - if (worker->status_ < OK) return; - - pthread_mutex_lock(&worker->mutex_); - // wait for the worker to finish - while (worker->status_ != OK) { - pthread_cond_wait(&worker->condition_, &worker->mutex_); - } - // assign new status and release the working thread if needed - if (new_status != OK) { - worker->status_ = new_status; - pthread_cond_signal(&worker->condition_); - } - pthread_mutex_unlock(&worker->mutex_); -} - -#endif - -//------------------------------------------------------------------------------ - -void WebPWorkerInit(WebPWorker* const worker) { - memset(worker, 0, sizeof(*worker)); - worker->status_ = NOT_OK; -} - -int WebPWorkerSync(WebPWorker* const worker) { -#ifdef WEBP_USE_THREAD - WebPWorkerChangeState(worker, OK); -#endif - assert(worker->status_ <= OK); - return !worker->had_error; -} - -int WebPWorkerReset(WebPWorker* const worker) { - int ok = 1; - worker->had_error = 0; - if (worker->status_ < OK) { -#ifdef WEBP_USE_THREAD - if (pthread_mutex_init(&worker->mutex_, NULL) || - pthread_cond_init(&worker->condition_, NULL)) { - return 0; - } - pthread_mutex_lock(&worker->mutex_); - ok = !pthread_create(&worker->thread_, NULL, WebPWorkerThreadLoop, worker); - if (ok) worker->status_ = OK; - pthread_mutex_unlock(&worker->mutex_); -#else - worker->status_ = OK; -#endif - } else if (worker->status_ > OK) { - ok = WebPWorkerSync(worker); - } - assert(!ok || (worker->status_ == OK)); - return ok; -} - -void WebPWorkerLaunch(WebPWorker* const worker) { -#ifdef WEBP_USE_THREAD - WebPWorkerChangeState(worker, WORK); -#else - if (worker->hook) - worker->had_error |= !worker->hook(worker->data1, worker->data2); -#endif -} - -void WebPWorkerEnd(WebPWorker* const worker) { - if (worker->status_ >= OK) { -#ifdef WEBP_USE_THREAD - WebPWorkerChangeState(worker, NOT_OK); - pthread_join(worker->thread_, NULL); - pthread_mutex_destroy(&worker->mutex_); - pthread_cond_destroy(&worker->condition_); -#else - worker->status_ = NOT_OK; -#endif - } - assert(worker->status_ == NOT_OK); -} - -//------------------------------------------------------------------------------ - -#if defined(__cplusplus) || defined(c_plusplus) -} // extern "C" -#endif |