Commit 820201ca authored by James Zern's avatar James Zern

vp9_thread: add vp9_worker_execute()

cherry-picked from:
commit 988b70844e03efcfcc075a9bc25d846670494f36
Author: Pascal Massimino <pascal.massimino@gmail.com>
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
parent 7fd2561d
......@@ -18,7 +18,7 @@
namespace {
class VP9WorkerThreadTest : public ::testing::Test {
class VP9WorkerThreadTest : public ::testing::TestWithParam<bool> {
protected:
virtual ~VP9WorkerThreadTest() {}
virtual void SetUp() {
......@@ -38,7 +38,7 @@ int ThreadHook(void* data, void* return_value) {
return *reinterpret_cast<int*>(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
......@@ -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
}
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment