1f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck/* 2f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * Copyright (C) 2017 The Android Open Source Project 3f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * 4f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * you may not use this file except in compliance with the License. 6f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * You may obtain a copy of the License at 7f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * 8f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * http://www.apache.org/licenses/LICENSE-2.0 9f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * 10f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * Unless required by applicable law or agreed to in writing, software 11f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * distributed under the License is distributed on an "AS IS" BASIS, 12f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * See the License for the specific language governing permissions and 14f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck * limitations under the License. 15f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck */ 16f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 17f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include <gtest/gtest.h> 18f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 19f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include "thread/ThreadBase.h" 20f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include "utils/TimeUtils.h" 21f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 22f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include <chrono> 23f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck#include "unistd.h" 24f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 25f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckusing namespace android; 26f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckusing namespace android::uirenderer; 27f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 28f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckstatic ThreadBase& thread() { 29f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck class TestThread : public ThreadBase, public virtual RefBase {}; 30f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck static sp<TestThread> thread = []() -> auto { 31f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck sp<TestThread> ret{new TestThread}; 32f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ret->start("TestThread"); 33f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck return ret; 341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck } 351bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck (); 36f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck return *thread; 37f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 38f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 39f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckstatic WorkQueue& queue() { 40f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck return thread().queue(); 41f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 42f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 43f8441e65526cd1721f1ad77dad21b1a1e2743d76John ReckTEST(ThreadBase, post) { 44f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck std::atomic_bool ran(false); 451bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck queue().post([&ran]() { ran = true; }); 46f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck for (int i = 0; !ran && i < 1000; i++) { 47f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck usleep(1); 48f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 49f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_TRUE(ran) << "Failed to flip atomic after 1 second"; 50f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 51f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 52f8441e65526cd1721f1ad77dad21b1a1e2743d76John ReckTEST(ThreadBase, postDelay) { 53f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck using clock = WorkQueue::clock; 54f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 55f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck std::promise<nsecs_t> ranAtPromise; 56f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck auto queuedAt = clock::now(); 571bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck queue().postDelayed(100_us, [&]() { ranAtPromise.set_value(clock::now()); }); 58f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck auto ranAt = ranAtPromise.get_future().get(); 59f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck auto ranAfter = ranAt - queuedAt; 60f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_TRUE(ranAfter > 90_us) << "Ran after " << ns2us(ranAfter) << "us <= 90us"; 61f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 62f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 63f8441e65526cd1721f1ad77dad21b1a1e2743d76John ReckTEST(ThreadBase, runSync) { 64f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck pid_t thisTid = gettid(); 65f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck pid_t otherTid = thisTid; 66f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 67f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck auto result = queue().runSync([&otherTid]() -> auto { 68f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck otherTid = gettid(); 69f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck return 42; 70f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck }); 71f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 72f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(42, result); 73f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_NE(thisTid, otherTid); 74f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 75f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 76f8441e65526cd1721f1ad77dad21b1a1e2743d76John ReckTEST(ThreadBase, async) { 77f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck pid_t thisTid = gettid(); 78f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck pid_t thisPid = getpid(); 79f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 801bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck auto otherTid = queue().async([]() -> auto { return gettid(); }); 811bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck auto otherPid = queue().async([]() -> auto { return getpid(); }); 821bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck auto result = queue().async([]() -> auto { return 42; }); 83f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 84f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_NE(thisTid, otherTid.get()); 85f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(thisPid, otherPid.get()); 86f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(42, result.get()); 87f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 88f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 89f8441e65526cd1721f1ad77dad21b1a1e2743d76John ReckTEST(ThreadBase, lifecyclePerf) { 90f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck struct EventCount { 91f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck std::atomic_int construct{0}; 92f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck std::atomic_int destruct{0}; 93f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck std::atomic_int copy{0}; 94f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck std::atomic_int move{0}; 95f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck }; 96f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 97f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck struct Counter { 981bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck Counter(EventCount* count) : mCount(count) { mCount->construct++; } 99f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 100f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck Counter(const Counter& other) : mCount(other.mCount) { 101f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck if (mCount) mCount->copy++; 102f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 103f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 104f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck Counter(Counter&& other) : mCount(other.mCount) { 105f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck other.mCount = nullptr; 106f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck if (mCount) mCount->move++; 107f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 108f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 109f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck Counter& operator=(const Counter& other) { 110f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck mCount = other.mCount; 111f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck if (mCount) mCount->copy++; 112f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck return *this; 113f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 114f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 115f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck Counter& operator=(Counter&& other) { 116f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck mCount = other.mCount; 117f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck other.mCount = nullptr; 118f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck if (mCount) mCount->move++; 119f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck return *this; 120f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 121f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 122f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ~Counter() { 123f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck if (mCount) mCount->destruct++; 124f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 125f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 126f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck EventCount* mCount; 127f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck }; 128f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 129f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck EventCount count; 130f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck { 131f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck Counter counter{&count}; 132f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck queue().runSync([c = std::move(counter)](){}); 133f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck } 134f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(1, count.construct.load()); 135f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(1, count.destruct.load()); 136f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(0, count.copy.load()); 137f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_LE(1, count.move.load()); 138f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 139f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 140f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reckint lifecycleTestHelper(const sp<VirtualLightRefBase>& test) { 1411bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck return queue().runSync([t = test]()->int { return t->getStrongCount(); }); 142f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck} 143f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck 144f8441e65526cd1721f1ad77dad21b1a1e2743d76John ReckTEST(ThreadBase, lifecycle) { 145f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck sp<VirtualLightRefBase> dummyObject{new VirtualLightRefBase}; 146f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(1, dummyObject->getStrongCount()); 1471bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck ASSERT_EQ(2, queue().runSync([dummyObject]() -> int { return dummyObject->getStrongCount(); })); 148f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(1, dummyObject->getStrongCount()); 149f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(2, lifecycleTestHelper(dummyObject)); 150f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck ASSERT_EQ(1, dummyObject->getStrongCount()); 151f8441e65526cd1721f1ad77dad21b1a1e2743d76John Reck}