diff options
Diffstat (limited to 'libs/hwui/tests/unit/ThreadBaseTests.cpp')
-rw-r--r-- | libs/hwui/tests/unit/ThreadBaseTests.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/libs/hwui/tests/unit/ThreadBaseTests.cpp b/libs/hwui/tests/unit/ThreadBaseTests.cpp new file mode 100644 index 000000000000..1168ff211202 --- /dev/null +++ b/libs/hwui/tests/unit/ThreadBaseTests.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include "thread/ThreadBase.h" +#include "utils/TimeUtils.h" + +#include <chrono> +#include "unistd.h" + +using namespace android; +using namespace android::uirenderer; + +static ThreadBase& thread() { + class TestThread : public ThreadBase, public virtual RefBase {}; + static sp<TestThread> thread = []() -> auto { + sp<TestThread> ret{new TestThread}; + ret->start("TestThread"); + return ret; + } + (); + return *thread; +} + +static WorkQueue& queue() { + return thread().queue(); +} + +TEST(ThreadBase, post) { + std::atomic_bool ran(false); + queue().post([&ran]() { ran = true; }); + for (int i = 0; !ran && i < 1000; i++) { + usleep(1); + } + ASSERT_TRUE(ran) << "Failed to flip atomic after 1 second"; +} + +TEST(ThreadBase, postDelay) { + using clock = WorkQueue::clock; + + std::promise<nsecs_t> ranAtPromise; + auto queuedAt = clock::now(); + queue().postDelayed(100_us, [&]() { ranAtPromise.set_value(clock::now()); }); + auto ranAt = ranAtPromise.get_future().get(); + auto ranAfter = ranAt - queuedAt; + ASSERT_TRUE(ranAfter > 90_us) << "Ran after " << ns2us(ranAfter) << "us <= 90us"; +} + +TEST(ThreadBase, runSync) { + pid_t thisTid = gettid(); + pid_t otherTid = thisTid; + + auto result = queue().runSync([&otherTid]() -> auto { + otherTid = gettid(); + return 42; + }); + + ASSERT_EQ(42, result); + ASSERT_NE(thisTid, otherTid); +} + +TEST(ThreadBase, async) { + pid_t thisTid = gettid(); + pid_t thisPid = getpid(); + + auto otherTid = queue().async([]() -> auto { return gettid(); }); + auto otherPid = queue().async([]() -> auto { return getpid(); }); + auto result = queue().async([]() -> auto { return 42; }); + + ASSERT_NE(thisTid, otherTid.get()); + ASSERT_EQ(thisPid, otherPid.get()); + ASSERT_EQ(42, result.get()); +} + +TEST(ThreadBase, lifecyclePerf) { + struct EventCount { + std::atomic_int construct{0}; + std::atomic_int destruct{0}; + std::atomic_int copy{0}; + std::atomic_int move{0}; + }; + + struct Counter { + Counter(EventCount* count) : mCount(count) { mCount->construct++; } + + Counter(const Counter& other) : mCount(other.mCount) { + if (mCount) mCount->copy++; + } + + Counter(Counter&& other) : mCount(other.mCount) { + other.mCount = nullptr; + if (mCount) mCount->move++; + } + + Counter& operator=(const Counter& other) { + mCount = other.mCount; + if (mCount) mCount->copy++; + return *this; + } + + Counter& operator=(Counter&& other) { + mCount = other.mCount; + other.mCount = nullptr; + if (mCount) mCount->move++; + return *this; + } + + ~Counter() { + if (mCount) mCount->destruct++; + } + + EventCount* mCount; + }; + + EventCount count; + { + Counter counter{&count}; + queue().runSync([c = std::move(counter)](){}); + } + ASSERT_EQ(1, count.construct.load()); + ASSERT_EQ(1, count.destruct.load()); + ASSERT_EQ(0, count.copy.load()); + ASSERT_LE(1, count.move.load()); +} + +int lifecycleTestHelper(const sp<VirtualLightRefBase>& test) { + return queue().runSync([t = test]()->int { return t->getStrongCount(); }); +} + +TEST(ThreadBase, lifecycle) { + sp<VirtualLightRefBase> dummyObject{new VirtualLightRefBase}; + ASSERT_EQ(1, dummyObject->getStrongCount()); + ASSERT_EQ(2, queue().runSync([dummyObject]() -> int { return dummyObject->getStrongCount(); })); + ASSERT_EQ(1, dummyObject->getStrongCount()); + ASSERT_EQ(2, lifecycleTestHelper(dummyObject)); + ASSERT_EQ(1, dummyObject->getStrongCount()); +}
\ No newline at end of file |