diff options
author | 2019-04-04 15:49:40 -0700 | |
---|---|---|
committer | 2019-04-04 16:05:10 -0700 | |
commit | 5ff61f32a78dca0c722c8ac2685874a26190ceed (patch) | |
tree | f795a2a4c2d8c4386a0be6840e0f0f96ad020c25 | |
parent | dd07ae579c291a2b6ffe09bd576fd908eb9e5ddd (diff) |
Fix lifecycle issue in CommonPool
Destroy things more faster
Fixes: 129250875
Test: hwui_unit_tests
Change-Id: I7e060fcb61f5321dd9e68a3ee4a01868033b3fc3
-rw-r--r-- | libs/hwui/tests/unit/CommonPoolTests.cpp | 123 | ||||
-rw-r--r-- | libs/hwui/thread/CommonPool.h | 6 |
2 files changed, 127 insertions, 2 deletions
diff --git a/libs/hwui/tests/unit/CommonPoolTests.cpp b/libs/hwui/tests/unit/CommonPoolTests.cpp index c564ed632786..9c885ef0e29f 100644 --- a/libs/hwui/tests/unit/CommonPoolTests.cpp +++ b/libs/hwui/tests/unit/CommonPoolTests.cpp @@ -135,4 +135,127 @@ TEST(CommonPool, fullQueue) { for (auto& f : futures) { f.get(); } +} + +struct DestructorObserver { + DestructorObserver(int* destroyCount) : mDestroyCount(destroyCount) {} + DestructorObserver(const DestructorObserver& other) : mDestroyCount(other.mDestroyCount) {} + DestructorObserver(DestructorObserver&& other) { + mDestroyCount = other.mDestroyCount; + other.mDestroyCount = nullptr; + } + ~DestructorObserver() { + if (mDestroyCount) { + (*mDestroyCount)++; + } + } + DestructorObserver& operator=(DestructorObserver&& other) { + mDestroyCount = other.mDestroyCount; + other.mDestroyCount = nullptr; + return *this; + } + int* mDestroyCount; +}; + +struct CopyObserver { + CopyObserver(int* copyCount) : mCopyCount(copyCount) {} + CopyObserver(CopyObserver&& other) = default; + CopyObserver& operator=(CopyObserver&& other) = default; + + CopyObserver(const CopyObserver& other) { + mCopyCount = other.mCopyCount; + if (mCopyCount) { + (*mCopyCount)++; + } + } + + CopyObserver& operator=(const CopyObserver& other) { + mCopyCount = other.mCopyCount; + if (mCopyCount) { + (*mCopyCount)++; + } + return *this; + } + + int* mCopyCount; +}; + +TEST(CommonPool, asyncLifecycleCheck) { + std::vector<std::future<void>> mFrameFences; + int destroyCount = 0; + int runCount = 0; + { + DestructorObserver observer{&destroyCount}; + auto func = [observer = std::move(observer), count = &runCount]() { + if (observer.mDestroyCount) { + (*count)++; + } + }; + mFrameFences.push_back(CommonPool::async(std::move(func))); + } + for (auto& fence : mFrameFences) { + EXPECT_TRUE(fence.valid()); + fence.get(); + EXPECT_FALSE(fence.valid()); + } + mFrameFences.clear(); + EXPECT_EQ(1, runCount); + EXPECT_EQ(1, destroyCount); +} + +TEST(CommonPool, asyncCopyCheck) { + std::vector<std::future<void>> mFrameFences; + int copyCount = 0; + int runCount = 0; + { + CopyObserver observer{©Count}; + auto func = [observer = std::move(observer), count = &runCount]() { + if (observer.mCopyCount) { + (*count)++; + } + }; + mFrameFences.push_back(CommonPool::async(std::move(func))); + } + for (auto& fence : mFrameFences) { + EXPECT_TRUE(fence.valid()); + fence.get(); + EXPECT_FALSE(fence.valid()); + } + mFrameFences.clear(); + EXPECT_EQ(1, runCount); + // We expect std::move all the way + EXPECT_EQ(0, copyCount); +} + +TEST(CommonPool, syncLifecycleCheck) { + int destroyCount = 0; + int runCount = 0; + { + DestructorObserver observer{&destroyCount}; + auto func = [observer = std::move(observer), count = &runCount]() { + if (observer.mDestroyCount) { + (*count)++; + } + }; + CommonPool::runSync(std::move(func)); + } + EXPECT_EQ(1, runCount); + EXPECT_EQ(1, destroyCount); +} + +TEST(CommonPool, syncCopyCheck) { + int copyCount = 0; + int runCount = 0; + { + CopyObserver observer{©Count}; + auto func = [observer = std::move(observer), count = &runCount]() { + if (observer.mCopyCount) { + (*count)++; + } + }; + CommonPool::runSync(std::move(func)); + } + EXPECT_EQ(1, runCount); + // We expect std::move all the way + EXPECT_EQ(0, copyCount); }
\ No newline at end of file diff --git a/libs/hwui/thread/CommonPool.h b/libs/hwui/thread/CommonPool.h index aef2990d6343..51628259d2a8 100644 --- a/libs/hwui/thread/CommonPool.h +++ b/libs/hwui/thread/CommonPool.h @@ -57,11 +57,13 @@ public: mHead = newHead; } - constexpr T&& pop() { + constexpr T pop() { LOG_ALWAYS_FATAL_IF(mTail == mHead, "empty"); int index = mTail; mTail = (mTail + 1) % SIZE; - return std::move(mBuffer[index]); + T ret = std::move(mBuffer[index]); + mBuffer[index] = nullptr; + return ret; } private: |