| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/debug/activity_tracker.h" | 5 #include "base/debug/activity_tracker.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 }; | 38 }; |
| 39 | 39 |
| 40 } // namespace | 40 } // namespace |
| 41 | 41 |
| 42 | 42 |
| 43 class ActivityTrackerTest : public testing::Test { | 43 class ActivityTrackerTest : public testing::Test { |
| 44 public: | 44 public: |
| 45 const int kMemorySize = 1 << 10; // 1MiB | 45 const int kMemorySize = 1 << 10; // 1MiB |
| 46 const int kStackSize = 1 << 10; // 1KiB | 46 const int kStackSize = 1 << 10; // 1KiB |
| 47 | 47 |
| 48 using Activity = ThreadActivityTracker::Activity; | |
| 49 using ActivityData = ThreadActivityTracker::ActivityData; | |
| 50 | |
| 51 ActivityTrackerTest() {} | 48 ActivityTrackerTest() {} |
| 52 | 49 |
| 53 ~ActivityTrackerTest() override { | 50 ~ActivityTrackerTest() override { |
| 54 GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get(); | 51 GlobalActivityTracker* global_tracker = GlobalActivityTracker::Get(); |
| 55 if (global_tracker) { | 52 if (global_tracker) { |
| 56 global_tracker->ReleaseTrackerForCurrentThreadForTesting(); | 53 global_tracker->ReleaseTrackerForCurrentThreadForTesting(); |
| 57 delete global_tracker; | 54 delete global_tracker; |
| 58 } | 55 } |
| 59 } | 56 } |
| 60 | 57 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 77 return 0; | 74 return 0; |
| 78 return global_tracker->available_memories_count_.load( | 75 return global_tracker->available_memories_count_.load( |
| 79 std::memory_order_relaxed); | 76 std::memory_order_relaxed); |
| 80 } | 77 } |
| 81 | 78 |
| 82 static void DoNothing() {} | 79 static void DoNothing() {} |
| 83 }; | 80 }; |
| 84 | 81 |
| 85 TEST_F(ActivityTrackerTest, PushPopTest) { | 82 TEST_F(ActivityTrackerTest, PushPopTest) { |
| 86 std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker(); | 83 std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker(); |
| 87 ThreadActivityTracker::ActivitySnapshot snapshot; | 84 ActivitySnapshot snapshot; |
| 88 | 85 |
| 89 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 86 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 90 ASSERT_EQ(0U, snapshot.activity_stack_depth); | 87 ASSERT_EQ(0U, snapshot.activity_stack_depth); |
| 91 ASSERT_EQ(0U, snapshot.activity_stack.size()); | 88 ASSERT_EQ(0U, snapshot.activity_stack.size()); |
| 92 | 89 |
| 93 char origin1; | 90 char origin1; |
| 94 tracker->PushActivity(&origin1, ThreadActivityTracker::ACT_TASK, | 91 tracker->PushActivity(&origin1, Activity::ACT_TASK, |
| 95 ActivityData::ForTask(11)); | 92 ActivityData::ForTask(11)); |
| 96 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 93 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 97 ASSERT_EQ(1U, snapshot.activity_stack_depth); | 94 ASSERT_EQ(1U, snapshot.activity_stack_depth); |
| 98 ASSERT_EQ(1U, snapshot.activity_stack.size()); | 95 ASSERT_EQ(1U, snapshot.activity_stack.size()); |
| 99 EXPECT_NE(0, snapshot.activity_stack[0].time_internal); | 96 EXPECT_NE(0, snapshot.activity_stack[0].time_internal); |
| 100 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, | 97 EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); |
| 101 snapshot.activity_stack[0].activity_type); | |
| 102 EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1), | 98 EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1), |
| 103 snapshot.activity_stack[0].origin_address); | 99 snapshot.activity_stack[0].origin_address); |
| 104 EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id); | 100 EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id); |
| 105 | 101 |
| 106 char origin2; | 102 char origin2; |
| 107 char lock2; | 103 char lock2; |
| 108 tracker->PushActivity(&origin2, ThreadActivityTracker::ACT_LOCK, | 104 tracker->PushActivity(&origin2, Activity::ACT_LOCK, |
| 109 ActivityData::ForLock(&lock2)); | 105 ActivityData::ForLock(&lock2)); |
| 110 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 106 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 111 ASSERT_EQ(2U, snapshot.activity_stack_depth); | 107 ASSERT_EQ(2U, snapshot.activity_stack_depth); |
| 112 ASSERT_EQ(2U, snapshot.activity_stack.size()); | 108 ASSERT_EQ(2U, snapshot.activity_stack.size()); |
| 113 EXPECT_LE(snapshot.activity_stack[0].time_internal, | 109 EXPECT_LE(snapshot.activity_stack[0].time_internal, |
| 114 snapshot.activity_stack[1].time_internal); | 110 snapshot.activity_stack[1].time_internal); |
| 115 EXPECT_EQ(ThreadActivityTracker::ACT_LOCK, | 111 EXPECT_EQ(Activity::ACT_LOCK, snapshot.activity_stack[1].activity_type); |
| 116 snapshot.activity_stack[1].activity_type); | |
| 117 EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin2), | 112 EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin2), |
| 118 snapshot.activity_stack[1].origin_address); | 113 snapshot.activity_stack[1].origin_address); |
| 119 EXPECT_EQ(reinterpret_cast<uintptr_t>(&lock2), | 114 EXPECT_EQ(reinterpret_cast<uintptr_t>(&lock2), |
| 120 snapshot.activity_stack[1].data.lock.lock_address); | 115 snapshot.activity_stack[1].data.lock.lock_address); |
| 121 | 116 |
| 122 tracker->PopActivity(); | 117 tracker->PopActivity(); |
| 123 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 118 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 124 ASSERT_EQ(1U, snapshot.activity_stack_depth); | 119 ASSERT_EQ(1U, snapshot.activity_stack_depth); |
| 125 ASSERT_EQ(1U, snapshot.activity_stack.size()); | 120 ASSERT_EQ(1U, snapshot.activity_stack.size()); |
| 126 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, | 121 EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); |
| 127 snapshot.activity_stack[0].activity_type); | |
| 128 EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1), | 122 EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1), |
| 129 snapshot.activity_stack[0].origin_address); | 123 snapshot.activity_stack[0].origin_address); |
| 130 EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id); | 124 EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id); |
| 131 | 125 |
| 132 tracker->PopActivity(); | 126 tracker->PopActivity(); |
| 133 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 127 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 134 ASSERT_EQ(0U, snapshot.activity_stack_depth); | 128 ASSERT_EQ(0U, snapshot.activity_stack_depth); |
| 135 ASSERT_EQ(0U, snapshot.activity_stack.size()); | 129 ASSERT_EQ(0U, snapshot.activity_stack.size()); |
| 136 } | 130 } |
| 137 | 131 |
| 138 TEST_F(ActivityTrackerTest, ScopedTaskTest) { | 132 TEST_F(ActivityTrackerTest, ScopedTaskTest) { |
| 139 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); | 133 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
| 140 | 134 |
| 141 ThreadActivityTracker* tracker = | 135 ThreadActivityTracker* tracker = |
| 142 GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); | 136 GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); |
| 143 ThreadActivityTracker::ActivitySnapshot snapshot; | 137 ActivitySnapshot snapshot; |
| 144 | 138 |
| 145 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 139 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 146 ASSERT_EQ(0U, snapshot.activity_stack_depth); | 140 ASSERT_EQ(0U, snapshot.activity_stack_depth); |
| 147 ASSERT_EQ(0U, snapshot.activity_stack.size()); | 141 ASSERT_EQ(0U, snapshot.activity_stack.size()); |
| 148 | 142 |
| 149 { | 143 { |
| 150 PendingTask task1(FROM_HERE, base::Bind(&DoNothing)); | 144 PendingTask task1(FROM_HERE, base::Bind(&DoNothing)); |
| 151 ScopedTaskRunActivity activity1(task1); | 145 ScopedTaskRunActivity activity1(task1); |
| 152 | 146 |
| 153 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 147 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 154 ASSERT_EQ(1U, snapshot.activity_stack_depth); | 148 ASSERT_EQ(1U, snapshot.activity_stack_depth); |
| 155 ASSERT_EQ(1U, snapshot.activity_stack.size()); | 149 ASSERT_EQ(1U, snapshot.activity_stack.size()); |
| 156 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, | 150 EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); |
| 157 snapshot.activity_stack[0].activity_type); | |
| 158 | 151 |
| 159 { | 152 { |
| 160 PendingTask task2(FROM_HERE, base::Bind(&DoNothing)); | 153 PendingTask task2(FROM_HERE, base::Bind(&DoNothing)); |
| 161 ScopedTaskRunActivity activity2(task2); | 154 ScopedTaskRunActivity activity2(task2); |
| 162 | 155 |
| 163 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 156 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 164 ASSERT_EQ(2U, snapshot.activity_stack_depth); | 157 ASSERT_EQ(2U, snapshot.activity_stack_depth); |
| 165 ASSERT_EQ(2U, snapshot.activity_stack.size()); | 158 ASSERT_EQ(2U, snapshot.activity_stack.size()); |
| 166 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, | 159 EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[1].activity_type); |
| 167 snapshot.activity_stack[1].activity_type); | |
| 168 } | 160 } |
| 169 | 161 |
| 170 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 162 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 171 ASSERT_EQ(1U, snapshot.activity_stack_depth); | 163 ASSERT_EQ(1U, snapshot.activity_stack_depth); |
| 172 ASSERT_EQ(1U, snapshot.activity_stack.size()); | 164 ASSERT_EQ(1U, snapshot.activity_stack.size()); |
| 173 EXPECT_EQ(ThreadActivityTracker::ACT_TASK, | 165 EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); |
| 174 snapshot.activity_stack[0].activity_type); | |
| 175 } | 166 } |
| 176 | 167 |
| 177 ASSERT_TRUE(tracker->Snapshot(&snapshot)); | 168 ASSERT_TRUE(tracker->Snapshot(&snapshot)); |
| 178 ASSERT_EQ(0U, snapshot.activity_stack_depth); | 169 ASSERT_EQ(0U, snapshot.activity_stack_depth); |
| 179 ASSERT_EQ(0U, snapshot.activity_stack.size()); | 170 ASSERT_EQ(0U, snapshot.activity_stack.size()); |
| 180 } | 171 } |
| 181 | 172 |
| 182 TEST_F(ActivityTrackerTest, CreateWithFileTest) { | 173 TEST_F(ActivityTrackerTest, CreateWithFileTest) { |
| 183 const char temp_name[] = "CreateWithFileTest"; | 174 const char temp_name[] = "CreateWithFileTest"; |
| 184 ScopedTempDir temp_dir; | 175 ScopedTempDir temp_dir; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 204 delete global; | 195 delete global; |
| 205 } | 196 } |
| 206 | 197 |
| 207 | 198 |
| 208 // GlobalActivityTracker tests below. | 199 // GlobalActivityTracker tests below. |
| 209 | 200 |
| 210 class SimpleActivityThread : public SimpleThread { | 201 class SimpleActivityThread : public SimpleThread { |
| 211 public: | 202 public: |
| 212 SimpleActivityThread(const std::string& name, | 203 SimpleActivityThread(const std::string& name, |
| 213 const void* origin, | 204 const void* origin, |
| 214 ThreadActivityTracker::ActivityType activity, | 205 Activity::Type activity, |
| 215 const ThreadActivityTracker::ActivityData& data) | 206 const ActivityData& data) |
| 216 : SimpleThread(name, Options()), | 207 : SimpleThread(name, Options()), |
| 217 origin_(origin), | 208 origin_(origin), |
| 218 activity_(activity), | 209 activity_(activity), |
| 219 data_(data), | 210 data_(data), |
| 220 exit_condition_(&lock_) {} | 211 exit_condition_(&lock_) {} |
| 221 | 212 |
| 222 ~SimpleActivityThread() override {} | 213 ~SimpleActivityThread() override {} |
| 223 | 214 |
| 224 void Run() override { | 215 void Run() override { |
| 225 GlobalActivityTracker::Get() | 216 GlobalActivityTracker::Get() |
| (...skipping 17 matching lines...) Expand all Loading... |
| 243 exit_ = true; | 234 exit_ = true; |
| 244 exit_condition_.Signal(); | 235 exit_condition_.Signal(); |
| 245 } | 236 } |
| 246 | 237 |
| 247 void WaitReady() { | 238 void WaitReady() { |
| 248 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(ready_); | 239 SPIN_FOR_1_SECOND_OR_UNTIL_TRUE(ready_); |
| 249 } | 240 } |
| 250 | 241 |
| 251 private: | 242 private: |
| 252 const void* origin_; | 243 const void* origin_; |
| 253 ThreadActivityTracker::ActivityType activity_; | 244 Activity::Type activity_; |
| 254 ThreadActivityTracker::ActivityData data_; | 245 ActivityData data_; |
| 255 | 246 |
| 256 bool ready_ = false; | 247 bool ready_ = false; |
| 257 bool exit_ = false; | 248 bool exit_ = false; |
| 258 Lock lock_; | 249 Lock lock_; |
| 259 ConditionVariable exit_condition_; | 250 ConditionVariable exit_condition_; |
| 260 | 251 |
| 261 DISALLOW_COPY_AND_ASSIGN(SimpleActivityThread); | 252 DISALLOW_COPY_AND_ASSIGN(SimpleActivityThread); |
| 262 }; | 253 }; |
| 263 | 254 |
| 264 TEST_F(ActivityTrackerTest, ThreadDeathTest) { | 255 TEST_F(ActivityTrackerTest, ThreadDeathTest) { |
| 265 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); | 256 GlobalActivityTracker::CreateWithLocalMemory(kMemorySize, 0, "", 3); |
| 266 GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); | 257 GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); |
| 267 const size_t starting_active = GetGlobalActiveTrackerCount(); | 258 const size_t starting_active = GetGlobalActiveTrackerCount(); |
| 268 const size_t starting_inactive = GetGlobalInactiveTrackerCount(); | 259 const size_t starting_inactive = GetGlobalInactiveTrackerCount(); |
| 269 | 260 |
| 270 SimpleActivityThread t1("t1", nullptr, ThreadActivityTracker::ACT_TASK, | 261 SimpleActivityThread t1("t1", nullptr, Activity::ACT_TASK, |
| 271 ThreadActivityTracker::ActivityData::ForTask(11)); | 262 ActivityData::ForTask(11)); |
| 272 t1.Start(); | 263 t1.Start(); |
| 273 t1.WaitReady(); | 264 t1.WaitReady(); |
| 274 EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); | 265 EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); |
| 275 EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount()); | 266 EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount()); |
| 276 | 267 |
| 277 t1.Exit(); | 268 t1.Exit(); |
| 278 t1.Join(); | 269 t1.Join(); |
| 279 EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount()); | 270 EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount()); |
| 280 EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); | 271 EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); |
| 281 | 272 |
| 282 // Start another thread and ensure it re-uses the existing memory. | 273 // Start another thread and ensure it re-uses the existing memory. |
| 283 | 274 |
| 284 SimpleActivityThread t2("t2", nullptr, ThreadActivityTracker::ACT_TASK, | 275 SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK, |
| 285 ThreadActivityTracker::ActivityData::ForTask(22)); | 276 ActivityData::ForTask(22)); |
| 286 t2.Start(); | 277 t2.Start(); |
| 287 t2.WaitReady(); | 278 t2.WaitReady(); |
| 288 EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); | 279 EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); |
| 289 EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount()); | 280 EXPECT_EQ(starting_inactive, GetGlobalInactiveTrackerCount()); |
| 290 | 281 |
| 291 t2.Exit(); | 282 t2.Exit(); |
| 292 t2.Join(); | 283 t2.Join(); |
| 293 EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount()); | 284 EXPECT_EQ(starting_active, GetGlobalActiveTrackerCount()); |
| 294 EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); | 285 EXPECT_EQ(starting_inactive + 1, GetGlobalInactiveTrackerCount()); |
| 295 } | 286 } |
| 296 | 287 |
| 297 } // namespace debug | 288 } // namespace debug |
| 298 } // namespace base | 289 } // namespace base |
| OLD | NEW |