Loading libs/hwui/tests/unit/CommonPoolTests.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -136,3 +136,47 @@ TEST(CommonPool, fullQueue) { f.get(); } } class ObjectTracker { static std::atomic_int sGlobalCount; public: ObjectTracker() { sGlobalCount++; } ObjectTracker(const ObjectTracker&) { sGlobalCount++; } ObjectTracker(ObjectTracker&&) { sGlobalCount++; } ~ObjectTracker() { sGlobalCount--; } static int count() { return sGlobalCount.load(); } }; std::atomic_int ObjectTracker::sGlobalCount{0}; TEST(CommonPool, asyncLifecycleCheck) { ASSERT_EQ(0, ObjectTracker::count()); { ObjectTracker obj; ASSERT_EQ(1, ObjectTracker::count()); EXPECT_LT(1, CommonPool::async([obj] { return ObjectTracker::count(); }).get()); } CommonPool::waitForIdle(); ASSERT_EQ(0, ObjectTracker::count()); } TEST(CommonPool, syncLifecycleCheck) { ASSERT_EQ(0, ObjectTracker::count()); { ObjectTracker obj; ASSERT_EQ(1, ObjectTracker::count()); EXPECT_LT(1, CommonPool::runSync([obj] { return ObjectTracker::count(); })); } CommonPool::waitForIdle(); ASSERT_EQ(0, ObjectTracker::count()); } No newline at end of file libs/hwui/thread/CommonPool.cpp +19 −2 Original line number Diff line number Diff line Loading @@ -49,9 +49,13 @@ CommonPool::CommonPool() { } } void CommonPool::post(Task&& task) { CommonPool& CommonPool::instance() { static CommonPool pool; pool.enqueue(std::move(task)); return pool; } void CommonPool::post(Task&& task) { instance().enqueue(std::move(task)); } void CommonPool::enqueue(Task&& task) { Loading Loading @@ -86,5 +90,18 @@ void CommonPool::workerLoop() { } } void CommonPool::waitForIdle() { instance().doWaitForIdle(); } void CommonPool::doWaitForIdle() { std::unique_lock lock(mLock); while (mWaitingThreads != THREAD_COUNT) { lock.unlock(); usleep(100); lock.lock(); } } } // namespace uirenderer } // namespace android No newline at end of file libs/hwui/thread/CommonPool.h +10 −2 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -95,11 +97,17 @@ public: return task.get_future().get(); }; // For testing purposes only, blocks until all worker threads are parked. static void waitForIdle(); private: static CommonPool& instance(); CommonPool(); ~CommonPool() {} void enqueue(Task&&); void doWaitForIdle(); void workerLoop(); Loading Loading
libs/hwui/tests/unit/CommonPoolTests.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -136,3 +136,47 @@ TEST(CommonPool, fullQueue) { f.get(); } } class ObjectTracker { static std::atomic_int sGlobalCount; public: ObjectTracker() { sGlobalCount++; } ObjectTracker(const ObjectTracker&) { sGlobalCount++; } ObjectTracker(ObjectTracker&&) { sGlobalCount++; } ~ObjectTracker() { sGlobalCount--; } static int count() { return sGlobalCount.load(); } }; std::atomic_int ObjectTracker::sGlobalCount{0}; TEST(CommonPool, asyncLifecycleCheck) { ASSERT_EQ(0, ObjectTracker::count()); { ObjectTracker obj; ASSERT_EQ(1, ObjectTracker::count()); EXPECT_LT(1, CommonPool::async([obj] { return ObjectTracker::count(); }).get()); } CommonPool::waitForIdle(); ASSERT_EQ(0, ObjectTracker::count()); } TEST(CommonPool, syncLifecycleCheck) { ASSERT_EQ(0, ObjectTracker::count()); { ObjectTracker obj; ASSERT_EQ(1, ObjectTracker::count()); EXPECT_LT(1, CommonPool::runSync([obj] { return ObjectTracker::count(); })); } CommonPool::waitForIdle(); ASSERT_EQ(0, ObjectTracker::count()); } No newline at end of file
libs/hwui/thread/CommonPool.cpp +19 −2 Original line number Diff line number Diff line Loading @@ -49,9 +49,13 @@ CommonPool::CommonPool() { } } void CommonPool::post(Task&& task) { CommonPool& CommonPool::instance() { static CommonPool pool; pool.enqueue(std::move(task)); return pool; } void CommonPool::post(Task&& task) { instance().enqueue(std::move(task)); } void CommonPool::enqueue(Task&& task) { Loading Loading @@ -86,5 +90,18 @@ void CommonPool::workerLoop() { } } void CommonPool::waitForIdle() { instance().doWaitForIdle(); } void CommonPool::doWaitForIdle() { std::unique_lock lock(mLock); while (mWaitingThreads != THREAD_COUNT) { lock.unlock(); usleep(100); lock.lock(); } } } // namespace uirenderer } // namespace android No newline at end of file
libs/hwui/thread/CommonPool.h +10 −2 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -95,11 +97,17 @@ public: return task.get_future().get(); }; // For testing purposes only, blocks until all worker threads are parked. static void waitForIdle(); private: static CommonPool& instance(); CommonPool(); ~CommonPool() {} void enqueue(Task&&); void doWaitForIdle(); void workerLoop(); Loading