OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 | 7 |
8 #include <algorithm> | |
8 #include <cstdlib> | 9 #include <cstdlib> |
9 #include <memory> | 10 #include <memory> |
10 #include <utility> | 11 #include <utility> |
11 #include <vector> | 12 #include <vector> |
12 | 13 |
13 #include "base/bind.h" | 14 #include "base/bind.h" |
14 #include "base/compiler_specific.h" | 15 #include "base/compiler_specific.h" |
15 #include "base/files/file_util.h" | 16 #include "base/files/file_util.h" |
16 #include "base/macros.h" | 17 #include "base/macros.h" |
17 #include "base/memory/ptr_util.h" | 18 #include "base/memory/ptr_util.h" |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
316 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); | 317 PlatformThread::Sleep(TimeDelta::FromMilliseconds(1)); |
317 } | 318 } |
318 #elif defined(OS_MACOSX) | 319 #elif defined(OS_MACOSX) |
319 // Unloading a library on the Mac is synchronous. | 320 // Unloading a library on the Mac is synchronous. |
320 #else | 321 #else |
321 NOTIMPLEMENTED(); | 322 NOTIMPLEMENTED(); |
322 #endif | 323 #endif |
323 } | 324 } |
324 | 325 |
325 // Called on the profiler thread when complete, to collect profiles. | 326 // Called on the profiler thread when complete, to collect profiles. |
326 void SaveProfiles(CallStackProfiles* profiles, | 327 Optional<StackSamplingProfiler::SamplingParams> SaveProfiles( |
327 CallStackProfiles pending_profiles) { | 328 CallStackProfiles* profiles, |
329 CallStackProfiles pending_profiles) { | |
328 *profiles = std::move(pending_profiles); | 330 *profiles = std::move(pending_profiles); |
331 return Optional<StackSamplingProfiler::SamplingParams>(); | |
329 } | 332 } |
330 | 333 |
331 // Called on the profiler thread when complete. Collects profiles produced by | 334 // Called on the profiler thread when complete. Collects profiles produced by |
332 // the profiler, and signals an event to allow the main thread to know that that | 335 // the profiler, and signals an event to allow the main thread to know that that |
333 // the profiler is done. | 336 // the profiler is done. |
334 void SaveProfilesAndSignalEvent(CallStackProfiles* profiles, | 337 Optional<StackSamplingProfiler::SamplingParams> SaveProfilesAndSignalEvent( |
335 WaitableEvent* event, | 338 CallStackProfiles* profiles, |
336 CallStackProfiles pending_profiles) { | 339 WaitableEvent* event, |
340 CallStackProfiles pending_profiles) { | |
337 *profiles = std::move(pending_profiles); | 341 *profiles = std::move(pending_profiles); |
338 event->Signal(); | 342 event->Signal(); |
343 return Optional<StackSamplingProfiler::SamplingParams>(); | |
344 } | |
345 | |
346 // Similar to SaveProfilesAndSignalEvent(), but will schedule a second | |
347 // collection after the first call back. | |
348 Optional<StackSamplingProfiler::SamplingParams> SaveProfilesAndReschedule( | |
349 std::vector<CallStackProfiles>* profiles, | |
350 WaitableEvent* event, | |
351 CallStackProfiles pending_profiles) { | |
352 LOG(ERROR) << "SaveProfilesAndReschedule"; | |
353 profiles->push_back(std::move(pending_profiles)); | |
354 | |
355 event->Signal(); | |
356 event->Reset(); | |
Robert Sesek
2017/07/14 19:22:39
I've just rewritten WaitableEvent on Mac and it's
| |
357 | |
358 if (profiles->size() == 2) { | |
359 LOG(ERROR) << "Returning empty params"; | |
360 return Optional<StackSamplingProfiler::SamplingParams>(); | |
361 } | |
362 | |
363 StackSamplingProfiler::SamplingParams sampling_params; | |
364 sampling_params.initial_delay = base::TimeDelta::FromMilliseconds(100); | |
365 sampling_params.bursts = 1; | |
366 sampling_params.samples_per_burst = 1; | |
367 // Below are unused: | |
368 sampling_params.burst_interval = base::TimeDelta::FromMilliseconds(0); | |
369 sampling_params.sampling_interval = base::TimeDelta::FromMilliseconds(0); | |
370 LOG(ERROR) << "Returning new params"; | |
371 return sampling_params; | |
339 } | 372 } |
340 | 373 |
341 // Executes the function with the target thread running and executing within | 374 // Executes the function with the target thread running and executing within |
342 // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup | 375 // SignalAndWaitUntilSignaled(). Performs all necessary target thread startup |
343 // and shutdown work before and afterward. | 376 // and shutdown work before and afterward. |
344 template <class Function> | 377 template <class Function> |
345 void WithTargetThread(Function function, | 378 void WithTargetThread(Function function, |
346 const StackConfiguration& stack_config) { | 379 const StackConfiguration& stack_config) { |
347 TargetThread target_thread(stack_config); | 380 TargetThread target_thread(stack_config); |
348 PlatformThreadHandle target_thread_handle; | 381 PlatformThreadHandle target_thread_handle; |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1013 // Ensure a second request will run and not block. | 1046 // Ensure a second request will run and not block. |
1014 sampling_completed.Reset(); | 1047 sampling_completed.Reset(); |
1015 profiles.clear(); | 1048 profiles.clear(); |
1016 profiler.Start(); | 1049 profiler.Start(); |
1017 sampling_completed.Wait(); | 1050 sampling_completed.Wait(); |
1018 profiler.Stop(); | 1051 profiler.Stop(); |
1019 ASSERT_EQ(1u, profiles.size()); | 1052 ASSERT_EQ(1u, profiles.size()); |
1020 }); | 1053 }); |
1021 } | 1054 } |
1022 | 1055 |
1056 PROFILER_TEST_F(StackSamplingProfilerTest, RescheduledByCallback) { | |
1057 LOG(ERROR) << "RescheduledByCallback start"; | |
1058 WithTargetThread([](PlatformThreadId target_thread_id) { | |
1059 SamplingParams params; | |
1060 params.sampling_interval = TimeDelta::FromMilliseconds(0); | |
1061 params.samples_per_burst = 1; | |
1062 | |
1063 std::vector<CallStackProfiles> profiles; | |
1064 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL, | |
1065 WaitableEvent::InitialState::NOT_SIGNALED); | |
1066 const StackSamplingProfiler::CompletedCallback callback = | |
1067 Bind(&SaveProfilesAndReschedule, Unretained(&profiles), | |
1068 Unretained(&sampling_completed)); | |
1069 StackSamplingProfiler profiler(target_thread_id, params, callback); | |
1070 | |
1071 // Start once and wait for it to be completed. | |
1072 LOG(ERROR) << "RescheduledByCallback call start"; | |
1073 profiler.Start(); | |
1074 LOG(ERROR) << "RescheduledByCallback call wait1"; | |
1075 sampling_completed.Wait(); | |
1076 LOG(ERROR) << "RescheduledByCallback after wait1"; | |
1077 ASSERT_EQ(1u, profiles.size()); | |
1078 ASSERT_EQ(1u, profiles[0].size()); | |
1079 | |
1080 // Now, wait for the second callback call. | |
1081 LOG(ERROR) << "RescheduledByCallback call wait2"; | |
1082 sampling_completed.Wait(); | |
1083 LOG(ERROR) << "RescheduledByCallback after wait2"; | |
1084 profiler.Stop(); | |
1085 ASSERT_EQ(2u, profiles.size()); | |
1086 ASSERT_EQ(1u, profiles[1].size()); | |
1087 }); | |
1088 } | |
1089 | |
1023 // Checks that the different profilers may be run. | 1090 // Checks that the different profilers may be run. |
1024 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { | 1091 PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { |
1025 SamplingParams params; | 1092 SamplingParams params; |
1026 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 1093 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
1027 params.samples_per_burst = 1; | 1094 params.samples_per_burst = 1; |
1028 | 1095 |
1029 std::vector<CallStackProfile> profiles; | 1096 std::vector<CallStackProfile> profiles; |
1030 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); | 1097 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); |
1031 ASSERT_EQ(1u, profiles.size()); | 1098 ASSERT_EQ(1u, profiles.size()); |
1032 | 1099 |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1496 EXPECT_EQ(9u, profiler_thread1.profiles()[0].samples.size()); | 1563 EXPECT_EQ(9u, profiler_thread1.profiles()[0].samples.size()); |
1497 ASSERT_EQ(1u, profiler_thread2.profiles().size()); | 1564 ASSERT_EQ(1u, profiler_thread2.profiles().size()); |
1498 EXPECT_EQ(8u, profiler_thread2.profiles()[0].samples.size()); | 1565 EXPECT_EQ(8u, profiler_thread2.profiles()[0].samples.size()); |
1499 | 1566 |
1500 profiler_thread1.Join(); | 1567 profiler_thread1.Join(); |
1501 profiler_thread2.Join(); | 1568 profiler_thread2.Join(); |
1502 }); | 1569 }); |
1503 } | 1570 } |
1504 | 1571 |
1505 } // namespace base | 1572 } // namespace base |
OLD | NEW |