From 820201caa803e78c461e05128b87f4d7b24247a7 Mon Sep 17 00:00:00 2001 From: James Zern Date: Wed, 16 Oct 2013 16:10:27 +0200 Subject: [PATCH] vp9_thread: add vp9_worker_execute() cherry-picked from: commit 988b70844e03efcfcc075a9bc25d846670494f36 Author: Pascal Massimino Date: Fri Aug 2 11:15:16 2013 -0700 add WebPWorkerExecute() for convenient bypass This is mainly for re-using the worker structs without using the thread. Change-Id: I8e1be29e53874ef425b15c192fb68036b4c0a359 Original source: http://git.chromium.org/webm/libwebp.git 100644 blob c0d318aee628fdf9ba4876451a28aa978f1066b8 src/utils/thread.c 100644 blob c2b92c9fe353f8e514f78922f3d237204a9cbc66 src/utils/thread.h Change-Id: I13fe92b1e94062bb99fdeeb7cb0b4b0575d27793 --- test/vp9_thread_test.cc | 22 +++++++++++++++++----- vp9/decoder/vp9_thread.c | 15 +++++++++------ vp9/decoder/vp9_thread.h | 5 +++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/test/vp9_thread_test.cc b/test/vp9_thread_test.cc index 41d22dd3a..4fec46ad4 100644 --- a/test/vp9_thread_test.cc +++ b/test/vp9_thread_test.cc @@ -18,7 +18,7 @@ namespace { -class VP9WorkerThreadTest : public ::testing::Test { +class VP9WorkerThreadTest : public ::testing::TestWithParam { protected: virtual ~VP9WorkerThreadTest() {} virtual void SetUp() { @@ -38,7 +38,7 @@ int ThreadHook(void* data, void* return_value) { return *reinterpret_cast(return_value); } -TEST_F(VP9WorkerThreadTest, HookSuccess) { +TEST_P(VP9WorkerThreadTest, HookSuccess) { EXPECT_TRUE(vp9_worker_sync(&worker_)); // should be a no-op. for (int i = 0; i < 2; ++i) { @@ -50,7 +50,12 @@ TEST_F(VP9WorkerThreadTest, HookSuccess) { worker_.data1 = &hook_data; worker_.data2 = &return_value; - vp9_worker_launch(&worker_); + const bool synchronous = GetParam(); + if (synchronous) { + vp9_worker_execute(&worker_); + } else { + vp9_worker_launch(&worker_); + } EXPECT_TRUE(vp9_worker_sync(&worker_)); EXPECT_FALSE(worker_.had_error); EXPECT_EQ(5, hook_data); @@ -59,7 +64,7 @@ TEST_F(VP9WorkerThreadTest, HookSuccess) { } } -TEST_F(VP9WorkerThreadTest, HookFailure) { +TEST_P(VP9WorkerThreadTest, HookFailure) { EXPECT_TRUE(vp9_worker_reset(&worker_)); int hook_data = 0; @@ -68,7 +73,12 @@ TEST_F(VP9WorkerThreadTest, HookFailure) { worker_.data1 = &hook_data; worker_.data2 = &return_value; - vp9_worker_launch(&worker_); + const bool synchronous = GetParam(); + if (synchronous) { + vp9_worker_execute(&worker_); + } else { + vp9_worker_launch(&worker_); + } EXPECT_FALSE(vp9_worker_sync(&worker_)); EXPECT_TRUE(worker_.had_error); @@ -106,4 +116,6 @@ TEST(VP9DecodeMTTest, MTDecode) { EXPECT_STREQ("b35a1b707b28e82be025d960aba039bc", md5.Get()); } +INSTANTIATE_TEST_CASE_P(Synchronous, VP9WorkerThreadTest, ::testing::Bool()); + } // namespace diff --git a/vp9/decoder/vp9_thread.c b/vp9/decoder/vp9_thread.c index 5442ddfa1..d953e72b3 100644 --- a/vp9/decoder/vp9_thread.c +++ b/vp9/decoder/vp9_thread.c @@ -145,9 +145,7 @@ static THREADFN thread_loop(void *ptr) { // thread loop pthread_cond_wait(&worker->condition_, &worker->mutex_); } if (worker->status_ == WORK) { - if (worker->hook) { - worker->had_error |= !worker->hook(worker->data1, worker->data2); - } + vp9_worker_execute(worker); worker->status_ = OK; } else if (worker->status_ == NOT_OK) { // finish the worker done = 1; @@ -178,7 +176,7 @@ static void change_state(VP9Worker* const worker, pthread_mutex_unlock(&worker->mutex_); } -#endif +#endif // CONFIG_MULTITHREAD //------------------------------------------------------------------------------ @@ -218,12 +216,17 @@ int vp9_worker_reset(VP9Worker* const worker) { return ok; } +void vp9_worker_execute(VP9Worker* const worker) { + if (worker->hook != NULL) { + worker->had_error |= !worker->hook(worker->data1, worker->data2); + } +} + void vp9_worker_launch(VP9Worker* const worker) { #if CONFIG_MULTITHREAD change_state(worker, WORK); #else - if (worker->hook) - worker->had_error |= !worker->hook(worker->data1, worker->data2); + vp9_worker_execute(worker); #endif } diff --git a/vp9/decoder/vp9_thread.h b/vp9/decoder/vp9_thread.h index e5e6f606b..a624f3c2a 100644 --- a/vp9/decoder/vp9_thread.h +++ b/vp9/decoder/vp9_thread.h @@ -80,6 +80,11 @@ int vp9_worker_sync(VP9Worker* const worker); // hook/data1/data2 can be changed at any time before calling this function, // but not be changed afterward until the next call to vp9_worker_sync(). void vp9_worker_launch(VP9Worker* const worker); +// This function is similar to vp9_worker_launch() except that it calls the +// hook directly instead of using a thread. Convenient to bypass the thread +// mechanism while still using the VP9Worker structs. vp9_worker_sync() must +// still be called afterward (for error reporting). +void vp9_worker_execute(VP9Worker* const worker); // Kill the thread and terminate the object. To use the object again, one // must call vp9_worker_reset() again. void vp9_worker_end(VP9Worker* const worker); -- 2.40.0