| 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 <cstdlib> | 8 #include <cstdlib> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 | 142 |
| 143 WaitableEvent thread_started_event_; | 143 WaitableEvent thread_started_event_; |
| 144 WaitableEvent finish_event_; | 144 WaitableEvent finish_event_; |
| 145 PlatformThreadId id_; | 145 PlatformThreadId id_; |
| 146 const StackConfiguration stack_config_; | 146 const StackConfiguration stack_config_; |
| 147 | 147 |
| 148 DISALLOW_COPY_AND_ASSIGN(TargetThread); | 148 DISALLOW_COPY_AND_ASSIGN(TargetThread); |
| 149 }; | 149 }; |
| 150 | 150 |
| 151 TargetThread::TargetThread(const StackConfiguration& stack_config) | 151 TargetThread::TargetThread(const StackConfiguration& stack_config) |
| 152 : thread_started_event_(false, false), finish_event_(false, false), | 152 : thread_started_event_(WaitableEvent::ResetPolicy::AUTOMATIC, |
| 153 id_(0), stack_config_(stack_config) {} | 153 WaitableEvent::InitialState::NOT_SIGNALED), |
| 154 finish_event_(WaitableEvent::ResetPolicy::AUTOMATIC, |
| 155 WaitableEvent::InitialState::NOT_SIGNALED), |
| 156 id_(0), |
| 157 stack_config_(stack_config) {} |
| 154 | 158 |
| 155 void TargetThread::ThreadMain() { | 159 void TargetThread::ThreadMain() { |
| 156 id_ = PlatformThread::CurrentId(); | 160 id_ = PlatformThread::CurrentId(); |
| 157 switch (stack_config_.config) { | 161 switch (stack_config_.config) { |
| 158 case StackConfiguration::NORMAL: | 162 case StackConfiguration::NORMAL: |
| 159 SignalAndWaitUntilSignaled(&thread_started_event_, &finish_event_, | 163 SignalAndWaitUntilSignaled(&thread_started_event_, &finish_event_, |
| 160 &stack_config_); | 164 &stack_config_); |
| 161 break; | 165 break; |
| 162 | 166 |
| 163 case StackConfiguration::WITH_ALLOCA: | 167 case StackConfiguration::WITH_ALLOCA: |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL)); | 348 WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL)); |
| 345 } | 349 } |
| 346 | 350 |
| 347 // Captures profiles as specified by |params| on the TargetThread, and returns | 351 // Captures profiles as specified by |params| on the TargetThread, and returns |
| 348 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to | 352 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to |
| 349 // complete. | 353 // complete. |
| 350 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time, | 354 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time, |
| 351 CallStackProfiles* profiles) { | 355 CallStackProfiles* profiles) { |
| 352 profiles->clear(); | 356 profiles->clear(); |
| 353 | 357 |
| 354 WithTargetThread([¶ms, profiles, profiler_wait_time]( | 358 WithTargetThread([¶ms, profiles, |
| 355 PlatformThreadId target_thread_id) { | 359 profiler_wait_time](PlatformThreadId target_thread_id) { |
| 356 WaitableEvent sampling_thread_completed(true, false); | 360 WaitableEvent sampling_thread_completed( |
| 361 WaitableEvent::ResetPolicy::MANUAL, |
| 362 WaitableEvent::InitialState::NOT_SIGNALED); |
| 357 const StackSamplingProfiler::CompletedCallback callback = | 363 const StackSamplingProfiler::CompletedCallback callback = |
| 358 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), | 364 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), |
| 359 Unretained(&sampling_thread_completed)); | 365 Unretained(&sampling_thread_completed)); |
| 360 StackSamplingProfiler profiler(target_thread_id, params, callback); | 366 StackSamplingProfiler profiler(target_thread_id, params, callback); |
| 361 profiler.Start(); | 367 profiler.Start(); |
| 362 sampling_thread_completed.TimedWait(profiler_wait_time); | 368 sampling_thread_completed.TimedWait(profiler_wait_time); |
| 363 profiler.Stop(); | 369 profiler.Stop(); |
| 364 sampling_thread_completed.Wait(); | 370 sampling_thread_completed.Wait(); |
| 365 }); | 371 }); |
| 366 } | 372 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 NativeLibrary other_library = LoadOtherLibrary(); | 464 NativeLibrary other_library = LoadOtherLibrary(); |
| 459 TargetThread target_thread(StackConfiguration( | 465 TargetThread target_thread(StackConfiguration( |
| 460 StackConfiguration::WITH_OTHER_LIBRARY, | 466 StackConfiguration::WITH_OTHER_LIBRARY, |
| 461 other_library)); | 467 other_library)); |
| 462 | 468 |
| 463 PlatformThreadHandle target_thread_handle; | 469 PlatformThreadHandle target_thread_handle; |
| 464 EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); | 470 EXPECT_TRUE(PlatformThread::Create(0, &target_thread, &target_thread_handle)); |
| 465 | 471 |
| 466 target_thread.WaitForThreadStart(); | 472 target_thread.WaitForThreadStart(); |
| 467 | 473 |
| 468 WaitableEvent sampling_thread_completed(true, false); | 474 WaitableEvent sampling_thread_completed( |
| 475 WaitableEvent::ResetPolicy::MANUAL, |
| 476 WaitableEvent::InitialState::NOT_SIGNALED); |
| 469 std::vector<CallStackProfile> profiles; | 477 std::vector<CallStackProfile> profiles; |
| 470 const StackSamplingProfiler::CompletedCallback callback = | 478 const StackSamplingProfiler::CompletedCallback callback = |
| 471 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), | 479 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), |
| 472 Unretained(&sampling_thread_completed)); | 480 Unretained(&sampling_thread_completed)); |
| 473 WaitableEvent stack_copied(true, false); | 481 WaitableEvent stack_copied(WaitableEvent::ResetPolicy::MANUAL, |
| 474 WaitableEvent start_stack_walk(true, false); | 482 WaitableEvent::InitialState::NOT_SIGNALED); |
| 483 WaitableEvent start_stack_walk(WaitableEvent::ResetPolicy::MANUAL, |
| 484 WaitableEvent::InitialState::NOT_SIGNALED); |
| 475 StackCopiedSignaler test_delegate(&stack_copied, &start_stack_walk, | 485 StackCopiedSignaler test_delegate(&stack_copied, &start_stack_walk, |
| 476 wait_until_unloaded); | 486 wait_until_unloaded); |
| 477 StackSamplingProfiler profiler(target_thread.id(), params, callback, | 487 StackSamplingProfiler profiler(target_thread.id(), params, callback, |
| 478 &test_delegate); | 488 &test_delegate); |
| 479 | 489 |
| 480 profiler.Start(); | 490 profiler.Start(); |
| 481 | 491 |
| 482 // Wait for the stack to be copied and the target thread to be resumed. | 492 // Wait for the stack to be copied and the target thread to be resumed. |
| 483 stack_copied.Wait(); | 493 stack_copied.Wait(); |
| 484 | 494 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 #define MAYBE_Alloca Alloca | 628 #define MAYBE_Alloca Alloca |
| 619 #else | 629 #else |
| 620 #define MAYBE_Alloca DISABLED_Alloca | 630 #define MAYBE_Alloca DISABLED_Alloca |
| 621 #endif | 631 #endif |
| 622 TEST(StackSamplingProfilerTest, MAYBE_Alloca) { | 632 TEST(StackSamplingProfilerTest, MAYBE_Alloca) { |
| 623 SamplingParams params; | 633 SamplingParams params; |
| 624 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 634 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
| 625 params.samples_per_burst = 1; | 635 params.samples_per_burst = 1; |
| 626 | 636 |
| 627 std::vector<CallStackProfile> profiles; | 637 std::vector<CallStackProfile> profiles; |
| 628 WithTargetThread([¶ms, &profiles]( | 638 WithTargetThread( |
| 629 PlatformThreadId target_thread_id) { | 639 [¶ms, &profiles](PlatformThreadId target_thread_id) { |
| 630 WaitableEvent sampling_thread_completed(true, false); | 640 WaitableEvent sampling_thread_completed( |
| 631 const StackSamplingProfiler::CompletedCallback callback = | 641 WaitableEvent::ResetPolicy::MANUAL, |
| 632 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), | 642 WaitableEvent::InitialState::NOT_SIGNALED); |
| 633 Unretained(&sampling_thread_completed)); | 643 const StackSamplingProfiler::CompletedCallback callback = |
| 634 StackSamplingProfiler profiler(target_thread_id, params, callback); | 644 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), |
| 635 profiler.Start(); | 645 Unretained(&sampling_thread_completed)); |
| 636 sampling_thread_completed.Wait(); | 646 StackSamplingProfiler profiler(target_thread_id, params, callback); |
| 637 }, StackConfiguration(StackConfiguration::WITH_ALLOCA)); | 647 profiler.Start(); |
| 648 sampling_thread_completed.Wait(); |
| 649 }, |
| 650 StackConfiguration(StackConfiguration::WITH_ALLOCA)); |
| 638 | 651 |
| 639 // Look up the sample. | 652 // Look up the sample. |
| 640 ASSERT_EQ(1u, profiles.size()); | 653 ASSERT_EQ(1u, profiles.size()); |
| 641 const CallStackProfile& profile = profiles[0]; | 654 const CallStackProfile& profile = profiles[0]; |
| 642 ASSERT_EQ(1u, profile.samples.size()); | 655 ASSERT_EQ(1u, profile.samples.size()); |
| 643 const Sample& sample = profile.samples[0]; | 656 const Sample& sample = profile.samples[0]; |
| 644 | 657 |
| 645 // Check that the stack contains a frame for | 658 // Check that the stack contains a frame for |
| 646 // TargetThread::SignalAndWaitUntilSignaled(). | 659 // TargetThread::SignalAndWaitUntilSignaled(). |
| 647 Sample::const_iterator end_frame = FindFirstFrameWithinFunction( | 660 Sample::const_iterator end_frame = FindFirstFrameWithinFunction( |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 #endif | 692 #endif |
| 680 TEST(StackSamplingProfilerTest, MAYBE_StartAndRunAsync) { | 693 TEST(StackSamplingProfilerTest, MAYBE_StartAndRunAsync) { |
| 681 // StartAndRunAsync requires the caller to have a message loop. | 694 // StartAndRunAsync requires the caller to have a message loop. |
| 682 MessageLoop message_loop; | 695 MessageLoop message_loop; |
| 683 | 696 |
| 684 SamplingParams params; | 697 SamplingParams params; |
| 685 params.samples_per_burst = 1; | 698 params.samples_per_burst = 1; |
| 686 | 699 |
| 687 CallStackProfiles profiles; | 700 CallStackProfiles profiles; |
| 688 WithTargetThread([¶ms, &profiles](PlatformThreadId target_thread_id) { | 701 WithTargetThread([¶ms, &profiles](PlatformThreadId target_thread_id) { |
| 689 WaitableEvent sampling_thread_completed(false, false); | 702 WaitableEvent sampling_thread_completed( |
| 703 WaitableEvent::ResetPolicy::AUTOMATIC, |
| 704 WaitableEvent::InitialState::NOT_SIGNALED); |
| 690 const StackSamplingProfiler::CompletedCallback callback = | 705 const StackSamplingProfiler::CompletedCallback callback = |
| 691 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), | 706 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), |
| 692 Unretained(&sampling_thread_completed)); | 707 Unretained(&sampling_thread_completed)); |
| 693 StackSamplingProfiler::StartAndRunAsync(target_thread_id, params, callback); | 708 StackSamplingProfiler::StartAndRunAsync(target_thread_id, params, callback); |
| 694 RunLoop().RunUntilIdle(); | 709 RunLoop().RunUntilIdle(); |
| 695 sampling_thread_completed.Wait(); | 710 sampling_thread_completed.Wait(); |
| 696 }); | 711 }); |
| 697 | 712 |
| 698 ASSERT_EQ(1u, profiles.size()); | 713 ASSERT_EQ(1u, profiles.size()); |
| 699 } | 714 } |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 836 params[0].sampling_interval = TimeDelta::FromMilliseconds(0); | 851 params[0].sampling_interval = TimeDelta::FromMilliseconds(0); |
| 837 params[0].samples_per_burst = 1; | 852 params[0].samples_per_burst = 1; |
| 838 | 853 |
| 839 params[1].sampling_interval = TimeDelta::FromMilliseconds(0); | 854 params[1].sampling_interval = TimeDelta::FromMilliseconds(0); |
| 840 params[1].samples_per_burst = 1; | 855 params[1].samples_per_burst = 1; |
| 841 | 856 |
| 842 CallStackProfiles profiles[2]; | 857 CallStackProfiles profiles[2]; |
| 843 ScopedVector<WaitableEvent> sampling_completed; | 858 ScopedVector<WaitableEvent> sampling_completed; |
| 844 ScopedVector<StackSamplingProfiler> profiler; | 859 ScopedVector<StackSamplingProfiler> profiler; |
| 845 for (int i = 0; i < 2; ++i) { | 860 for (int i = 0; i < 2; ++i) { |
| 846 sampling_completed.push_back(new WaitableEvent(false, false)); | 861 sampling_completed.push_back( |
| 862 new WaitableEvent(WaitableEvent::ResetPolicy::AUTOMATIC, |
| 863 WaitableEvent::InitialState::NOT_SIGNALED)); |
| 847 const StackSamplingProfiler::CompletedCallback callback = | 864 const StackSamplingProfiler::CompletedCallback callback = |
| 848 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]), | 865 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]), |
| 849 Unretained(sampling_completed[i])); | 866 Unretained(sampling_completed[i])); |
| 850 profiler.push_back( | 867 profiler.push_back( |
| 851 new StackSamplingProfiler(target_thread_id, params[i], callback)); | 868 new StackSamplingProfiler(target_thread_id, params[i], callback)); |
| 852 } | 869 } |
| 853 | 870 |
| 854 profiler[0]->Start(); | 871 profiler[0]->Start(); |
| 855 profiler[1]->Start(); | 872 profiler[1]->Start(); |
| 856 | 873 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 879 #define MAYBE_OtherLibrary DISABLED_OtherLibrary | 896 #define MAYBE_OtherLibrary DISABLED_OtherLibrary |
| 880 #endif | 897 #endif |
| 881 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) { | 898 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) { |
| 882 SamplingParams params; | 899 SamplingParams params; |
| 883 params.sampling_interval = TimeDelta::FromMilliseconds(0); | 900 params.sampling_interval = TimeDelta::FromMilliseconds(0); |
| 884 params.samples_per_burst = 1; | 901 params.samples_per_burst = 1; |
| 885 | 902 |
| 886 std::vector<CallStackProfile> profiles; | 903 std::vector<CallStackProfile> profiles; |
| 887 { | 904 { |
| 888 ScopedNativeLibrary other_library(LoadOtherLibrary()); | 905 ScopedNativeLibrary other_library(LoadOtherLibrary()); |
| 889 WithTargetThread([¶ms, &profiles]( | 906 WithTargetThread( |
| 890 PlatformThreadId target_thread_id) { | 907 [¶ms, &profiles](PlatformThreadId target_thread_id) { |
| 891 WaitableEvent sampling_thread_completed(true, false); | 908 WaitableEvent sampling_thread_completed( |
| 892 const StackSamplingProfiler::CompletedCallback callback = | 909 WaitableEvent::ResetPolicy::MANUAL, |
| 893 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), | 910 WaitableEvent::InitialState::NOT_SIGNALED); |
| 894 Unretained(&sampling_thread_completed)); | 911 const StackSamplingProfiler::CompletedCallback callback = |
| 895 StackSamplingProfiler profiler(target_thread_id, params, callback); | 912 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles), |
| 896 profiler.Start(); | 913 Unretained(&sampling_thread_completed)); |
| 897 sampling_thread_completed.Wait(); | 914 StackSamplingProfiler profiler(target_thread_id, params, callback); |
| 898 }, StackConfiguration(StackConfiguration::WITH_OTHER_LIBRARY, | 915 profiler.Start(); |
| 899 other_library.get())); | 916 sampling_thread_completed.Wait(); |
| 917 }, |
| 918 StackConfiguration(StackConfiguration::WITH_OTHER_LIBRARY, |
| 919 other_library.get())); |
| 900 } | 920 } |
| 901 | 921 |
| 902 // Look up the sample. | 922 // Look up the sample. |
| 903 ASSERT_EQ(1u, profiles.size()); | 923 ASSERT_EQ(1u, profiles.size()); |
| 904 const CallStackProfile& profile = profiles[0]; | 924 const CallStackProfile& profile = profiles[0]; |
| 905 ASSERT_EQ(1u, profile.samples.size()); | 925 ASSERT_EQ(1u, profile.samples.size()); |
| 906 const Sample& sample = profile.samples[0]; | 926 const Sample& sample = profile.samples[0]; |
| 907 | 927 |
| 908 // Check that the stack contains a frame for | 928 // Check that the stack contains a frame for |
| 909 // TargetThread::CallThroughOtherLibrary(). | 929 // TargetThread::CallThroughOtherLibrary(). |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) | 977 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) |
| 958 #define MAYBE_UnloadedLibrary UnloadedLibrary | 978 #define MAYBE_UnloadedLibrary UnloadedLibrary |
| 959 #else | 979 #else |
| 960 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary | 980 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary |
| 961 #endif | 981 #endif |
| 962 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { | 982 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { |
| 963 TestLibraryUnload(true); | 983 TestLibraryUnload(true); |
| 964 } | 984 } |
| 965 | 985 |
| 966 } // namespace base | 986 } // namespace base |
| OLD | NEW |