1f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Copyright 2013 Google Inc. All Rights Reserved. 2f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// 3f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Use of this source code is governed by a BSD-style license 4f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// that can be found in the COPYING file in the root of the source 5f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// tree. An additional intellectual property rights grant can be found 6f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// in the file PATENTS. All contributing project authors may 7f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// be found in the AUTHORS file in the root of the source tree. 8f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// ----------------------------------------------------------------------------- 9f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// 10f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Multi-threaded worker 11f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// 12f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Original source: 13f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// http://git.chromium.org/webm/libwebp.git 14f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// 100644 blob 13a61a4c84194c3374080cbf03d881d3cd6af40d src/utils/thread.h 15f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 16f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 17f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#ifndef VP9_DECODER_VP9_THREAD_H_ 18f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#define VP9_DECODER_VP9_THREAD_H_ 19f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 205ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include "./vpx_config.h" 21f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 22f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#if defined(__cplusplus) || defined(c_plusplus) 23f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangextern "C" { 24f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#endif 25f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 26f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#if CONFIG_MULTITHREAD 27f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 28f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#if defined(_WIN32) 29f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 305ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <windows.h> // NOLINT 31f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef HANDLE pthread_t; 32f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef CRITICAL_SECTION pthread_mutex_t; 33f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef struct { 34f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang HANDLE waiting_sem_; 35f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang HANDLE received_sem_; 36f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang HANDLE signal_event_; 37f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang} pthread_cond_t; 38f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 39f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#else 40f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 415ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#include <pthread.h> // NOLINT 42f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 43f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#endif /* _WIN32 */ 44f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#endif /* CONFIG_MULTITHREAD */ 45f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 46f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// State of the worker thread object 47f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef enum { 48f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang NOT_OK = 0, // object is unusable 49f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang OK, // ready to work 50f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang WORK // busy finishing the current task 51f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang} VP9WorkerStatus; 52f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 53f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Function to be called by the worker thread. Takes two opaque pointers as 54f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// arguments (data1 and data2), and should return false in case of error. 55f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef int (*VP9WorkerHook)(void*, void*); 56f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 57f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Synchronize object used to launch job in the worker thread 58f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangtypedef struct { 59f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#if CONFIG_MULTITHREAD 60f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang pthread_mutex_t mutex_; 61f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang pthread_cond_t condition_; 62f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang pthread_t thread_; 63f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#endif 64f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang VP9WorkerStatus status_; 65f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang VP9WorkerHook hook; // hook to call 66f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang void* data1; // first argument passed to 'hook' 67f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang void* data2; // second argument passed to 'hook' 68f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang int had_error; // return value of the last call to 'hook' 69f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang} VP9Worker; 70f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 71f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Must be called first, before any other method. 72f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangvoid vp9_worker_init(VP9Worker* const worker); 73f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Must be called to initialize the object and spawn the thread. Re-entrant. 74f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Will potentially launch the thread. Returns false in case of error. 75f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangint vp9_worker_reset(VP9Worker* const worker); 76f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Makes sure the previous work is finished. Returns true if worker->had_error 77f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// was not set and no error condition was triggered by the working thread. 78f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangint vp9_worker_sync(VP9Worker* const worker); 79f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Triggers the thread to call hook() with data1 and data2 argument. These 80f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// hook/data1/data2 can be changed at any time before calling this function, 81f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// but not be changed afterward until the next call to vp9_worker_sync(). 82f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangvoid vp9_worker_launch(VP9Worker* const worker); 835ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// This function is similar to vp9_worker_launch() except that it calls the 845ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// hook directly instead of using a thread. Convenient to bypass the thread 855ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// mechanism while still using the VP9Worker structs. vp9_worker_sync() must 865ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang// still be called afterward (for error reporting). 875ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuangvoid vp9_worker_execute(VP9Worker* const worker); 88f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// Kill the thread and terminate the object. To use the object again, one 89f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang// must call vp9_worker_reset() again. 90f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuangvoid vp9_worker_end(VP9Worker* const worker); 91f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 92f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang//------------------------------------------------------------------------------ 93f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 94f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#if defined(__cplusplus) || defined(c_plusplus) 95f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang} // extern "C" 96f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang#endif 97f3bed9137f66ef693bd406e43b17e9a1114f1e14hkuang 985ae7ac49f08a179e4f054d99fcfc9dce78d26e58hkuang#endif // VP9_DECODER_VP9_THREAD_H_ 99