Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(556)

Side by Side Diff: base/profiler/stack_sampling_profiler_unittest.cc

Issue 2554123002: Support parallel captures from the StackSamplingProfiler. (Closed)
Patch Set: addressed review comments by wittman Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/profiler/stack_sampling_profiler.cc ('k') | base/threading/thread_restrictions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <memory> 9 #include <memory>
10 #include <utility> 10 #include <utility>
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 target_thread.SignalThreadToFinish(); 344 target_thread.SignalThreadToFinish();
345 345
346 PlatformThread::Join(target_thread_handle); 346 PlatformThread::Join(target_thread_handle);
347 } 347 }
348 348
349 template <class Function> 349 template <class Function>
350 void WithTargetThread(Function function) { 350 void WithTargetThread(Function function) {
351 WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL)); 351 WithTargetThread(function, StackConfiguration(StackConfiguration::NORMAL));
352 } 352 }
353 353
354 // Waits for one of multiple samplings to complete.
355 void CreateProfilers(
356 PlatformThreadId target_thread_id,
357 const std::vector<SamplingParams>& params,
358 std::vector<CallStackProfiles>* profiles,
359 std::vector<std::unique_ptr<StackSamplingProfiler>>* profilers,
360 std::vector<std::unique_ptr<WaitableEvent>>* completed) {
361 ASSERT_TRUE(!params.empty());
362 ASSERT_TRUE(profiles->empty());
363 ASSERT_TRUE(profilers->empty());
364 ASSERT_TRUE(completed->empty());
365
366 // Vectors have to be appropriately sized in advance so that the addresses of
367 // values don't change.
368 const size_t count = params.size();
369 profiles->reserve(count);
370 profilers->reserve(count);
371 completed->reserve(count);
372
373 for (size_t i = 0; i < count; ++i) {
374 profiles->push_back(CallStackProfiles());
375 completed->push_back(
376 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC,
377 WaitableEvent::InitialState::NOT_SIGNALED));
378 const StackSamplingProfiler::CompletedCallback callback =
379 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles->back()),
380 Unretained(completed->back().get()));
381 profilers->push_back(MakeUnique<StackSamplingProfiler>(
382 target_thread_id, params[i], callback));
383 }
384 }
385
354 // Captures profiles as specified by |params| on the TargetThread, and returns 386 // Captures profiles as specified by |params| on the TargetThread, and returns
355 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to 387 // them in |profiles|. Waits up to |profiler_wait_time| for the profiler to
356 // complete. 388 // complete.
357 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time, 389 void CaptureProfiles(const SamplingParams& params, TimeDelta profiler_wait_time,
358 CallStackProfiles* profiles) { 390 CallStackProfiles* profiles) {
359 profiles->clear(); 391 profiles->clear();
360 392
361 WithTargetThread([&params, profiles, 393 WithTargetThread([&params, profiles,
362 profiler_wait_time](PlatformThreadId target_thread_id) { 394 profiler_wait_time](PlatformThreadId target_thread_id) {
363 WaitableEvent sampling_thread_completed( 395 WaitableEvent sampling_thread_completed(
364 WaitableEvent::ResetPolicy::MANUAL, 396 WaitableEvent::ResetPolicy::MANUAL,
365 WaitableEvent::InitialState::NOT_SIGNALED); 397 WaitableEvent::InitialState::NOT_SIGNALED);
366 const StackSamplingProfiler::CompletedCallback callback = 398 const StackSamplingProfiler::CompletedCallback callback =
367 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles), 399 Bind(&SaveProfilesAndSignalEvent, Unretained(profiles),
368 Unretained(&sampling_thread_completed)); 400 Unretained(&sampling_thread_completed));
369 StackSamplingProfiler profiler(target_thread_id, params, callback); 401 StackSamplingProfiler profiler(target_thread_id, params, callback);
370 profiler.Start(); 402 profiler.Start();
371 sampling_thread_completed.TimedWait(profiler_wait_time); 403 sampling_thread_completed.TimedWait(profiler_wait_time);
372 profiler.Stop(); 404 profiler.Stop();
373 sampling_thread_completed.Wait(); 405 sampling_thread_completed.Wait();
374 }); 406 });
375 } 407 }
376 408
409 // Waits for one of multiple samplings to complete.
410 size_t WaitForSamplingComplete(
411 std::vector<std::unique_ptr<WaitableEvent>>* sampling_completed) {
412 // Map unique_ptrs to something that WaitMany can accept.
413 std::vector<WaitableEvent*> sampling_completed_rawptrs(
414 sampling_completed->size());
415 std::transform(
416 sampling_completed->begin(), sampling_completed->end(),
417 sampling_completed_rawptrs.begin(),
418 [](const std::unique_ptr<WaitableEvent>& elem) { return elem.get(); });
419 // Wait for one profiler to finish.
420 return WaitableEvent::WaitMany(sampling_completed_rawptrs.data(),
421 sampling_completed_rawptrs.size());
422 }
423
377 // If this executable was linked with /INCREMENTAL (the default for non-official 424 // If this executable was linked with /INCREMENTAL (the default for non-official
378 // debug and release builds on Windows), function addresses do not correspond to 425 // debug and release builds on Windows), function addresses do not correspond to
379 // function code itself, but instead to instructions in the Incremental Link 426 // function code itself, but instead to instructions in the Incremental Link
380 // Table that jump to the functions. Checks for a jump instruction and if 427 // Table that jump to the functions. Checks for a jump instruction and if
381 // present does a little decompilation to find the function's actual starting 428 // present does a little decompilation to find the function's actual starting
382 // address. 429 // address.
383 const void* MaybeFixupFunctionAddressForILT(const void* function_address) { 430 const void* MaybeFixupFunctionAddressForILT(const void* function_address) {
384 #if defined(_WIN64) 431 #if defined(_WIN64)
385 const unsigned char* opcode = 432 const unsigned char* opcode =
386 reinterpret_cast<const unsigned char*>(function_address); 433 reinterpret_cast<const unsigned char*>(function_address);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 // asynchronous library loading has completed before walking the stack. If 484 // asynchronous library loading has completed before walking the stack. If
438 // false, the unloading may still be occurring during the stack walk. 485 // false, the unloading may still be occurring during the stack walk.
439 void TestLibraryUnload(bool wait_until_unloaded) { 486 void TestLibraryUnload(bool wait_until_unloaded) {
440 // Test delegate that supports intervening between the copying of the stack 487 // Test delegate that supports intervening between the copying of the stack
441 // and the walking of the stack. 488 // and the walking of the stack.
442 class StackCopiedSignaler : public NativeStackSamplerTestDelegate { 489 class StackCopiedSignaler : public NativeStackSamplerTestDelegate {
443 public: 490 public:
444 StackCopiedSignaler(WaitableEvent* stack_copied, 491 StackCopiedSignaler(WaitableEvent* stack_copied,
445 WaitableEvent* start_stack_walk, 492 WaitableEvent* start_stack_walk,
446 bool wait_to_walk_stack) 493 bool wait_to_walk_stack)
447 : stack_copied_(stack_copied), start_stack_walk_(start_stack_walk), 494 : stack_copied_(stack_copied),
448 wait_to_walk_stack_(wait_to_walk_stack) { 495 start_stack_walk_(start_stack_walk),
449 } 496 wait_to_walk_stack_(wait_to_walk_stack) {}
450 497
451 void OnPreStackWalk() override { 498 void OnPreStackWalk() override {
452 stack_copied_->Signal(); 499 stack_copied_->Signal();
453 if (wait_to_walk_stack_) 500 if (wait_to_walk_stack_)
454 start_stack_walk_->Wait(); 501 start_stack_walk_->Wait();
455 } 502 }
456 503
457 private: 504 private:
458 WaitableEvent* const stack_copied_; 505 WaitableEvent* const stack_copied_;
459 WaitableEvent* const start_stack_walk_; 506 WaitableEvent* const start_stack_walk_;
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca)) 760 reinterpret_cast<const void*>(&TargetThread::CallWithAlloca))
714 << " was not found in stack:\n" 761 << " was not found in stack:\n"
715 << FormatSampleForDiagnosticOutput(sample, profile.modules); 762 << FormatSampleForDiagnosticOutput(sample, profile.modules);
716 763
717 // These frames should be adjacent on the stack. 764 // These frames should be adjacent on the stack.
718 EXPECT_EQ(1, alloca_frame - end_frame) 765 EXPECT_EQ(1, alloca_frame - end_frame)
719 << "Stack:\n" 766 << "Stack:\n"
720 << FormatSampleForDiagnosticOutput(sample, profile.modules); 767 << FormatSampleForDiagnosticOutput(sample, profile.modules);
721 } 768 }
722 769
723 // Checks that the fire-and-forget interface works.
724 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
725 #define MAYBE_StartAndRunAsync StartAndRunAsync
726 #else
727 #define MAYBE_StartAndRunAsync DISABLED_StartAndRunAsync
728 #endif
729 TEST(StackSamplingProfilerTest, MAYBE_StartAndRunAsync) {
730 // StartAndRunAsync requires the caller to have a message loop.
731 MessageLoop message_loop;
732
733 SamplingParams params;
734 params.samples_per_burst = 1;
735
736 CallStackProfiles profiles;
737 WithTargetThread([&params, &profiles](PlatformThreadId target_thread_id) {
738 WaitableEvent sampling_thread_completed(
739 WaitableEvent::ResetPolicy::AUTOMATIC,
740 WaitableEvent::InitialState::NOT_SIGNALED);
741 const StackSamplingProfiler::CompletedCallback callback =
742 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
743 Unretained(&sampling_thread_completed));
744 StackSamplingProfiler::StartAndRunAsync(target_thread_id, params, callback);
745 RunLoop().RunUntilIdle();
746 sampling_thread_completed.Wait();
747 });
748
749 ASSERT_EQ(1u, profiles.size());
750 }
751
752 // Checks that the expected number of profiles and samples are present in the 770 // Checks that the expected number of profiles and samples are present in the
753 // call stack profiles produced. 771 // call stack profiles produced.
754 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 772 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
755 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples 773 #define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples
756 #else 774 #else
757 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples 775 #define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples
758 #endif 776 #endif
759 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { 777 TEST(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) {
760 SamplingParams params; 778 SamplingParams params;
761 params.burst_interval = params.sampling_interval = 779 params.burst_interval = params.sampling_interval =
762 TimeDelta::FromMilliseconds(0); 780 TimeDelta::FromMilliseconds(0);
763 params.bursts = 2; 781 params.bursts = 2;
764 params.samples_per_burst = 3; 782 params.samples_per_burst = 3;
765 783
766 std::vector<CallStackProfile> profiles; 784 std::vector<CallStackProfile> profiles;
767 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 785 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
768 786
769 ASSERT_EQ(2u, profiles.size()); 787 ASSERT_EQ(2u, profiles.size());
770 EXPECT_EQ(3u, profiles[0].samples.size()); 788 EXPECT_EQ(3u, profiles[0].samples.size());
771 EXPECT_EQ(3u, profiles[1].samples.size()); 789 EXPECT_EQ(3u, profiles[1].samples.size());
772 } 790 }
773 791
792 // Checks that a profiler can stop/destruct without ever having started.
793 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
794 #define MAYBE_StopWithoutStarting StopWithoutStarting
795 #else
796 #define MAYBE_StopWithoutStarting DISABLED_StopWithoutStarting
797 #endif
798 TEST(StackSamplingProfilerTest, MAYBE_StopWithoutStarting) {
799 WithTargetThread([](PlatformThreadId target_thread_id) {
800 SamplingParams params;
801 params.sampling_interval = TimeDelta::FromMilliseconds(0);
802 params.samples_per_burst = 1;
803
804 CallStackProfiles profiles;
805 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
806 WaitableEvent::InitialState::NOT_SIGNALED);
807 const StackSamplingProfiler::CompletedCallback callback =
808 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
809 Unretained(&sampling_completed));
810 StackSamplingProfiler profiler(target_thread_id, params, callback);
811
812 profiler.Stop(); // Constructed but never started.
813 EXPECT_FALSE(sampling_completed.IsSignaled());
814 });
815 }
816
774 // Checks that no call stack profiles are captured if the profiling is stopped 817 // Checks that no call stack profiles are captured if the profiling is stopped
775 // during the initial delay. 818 // during the initial delay.
776 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 819 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
777 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay 820 #define MAYBE_StopDuringInitialDelay StopDuringInitialDelay
778 #else 821 #else
779 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay 822 #define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay
780 #endif 823 #endif
781 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { 824 TEST(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) {
782 SamplingParams params; 825 SamplingParams params;
783 params.initial_delay = TimeDelta::FromSeconds(60); 826 params.initial_delay = TimeDelta::FromSeconds(60);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 }); 896 });
854 } 897 }
855 898
856 // Checks that the same profiler may be run multiple times. 899 // Checks that the same profiler may be run multiple times.
857 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 900 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
858 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes 901 #define MAYBE_CanRunMultipleTimes CanRunMultipleTimes
859 #else 902 #else
860 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes 903 #define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes
861 #endif 904 #endif
862 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { 905 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) {
906 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
907
908 WithTargetThread([](PlatformThreadId target_thread_id) {
909 SamplingParams params;
910 params.sampling_interval = TimeDelta::FromMilliseconds(0);
911 params.samples_per_burst = 1;
912
913 CallStackProfiles profiles;
914 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
915 WaitableEvent::InitialState::NOT_SIGNALED);
916 const StackSamplingProfiler::CompletedCallback callback =
917 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
918 Unretained(&sampling_completed));
919 StackSamplingProfiler profiler(target_thread_id, params, callback);
920
921 // Just start and stop to execute code paths.
922 profiler.Start();
923 profiler.Stop();
924 sampling_completed.Wait();
925
926 // Ensure a second request will run and not block.
927 sampling_completed.Reset();
928 profiles.clear();
929 profiler.Start();
930 sampling_completed.Wait();
931 profiler.Stop();
932 ASSERT_EQ(1u, profiles.size());
933 });
934 }
935
936 // Checks that the different profilers may be run.
937 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
938 #define MAYBE_CanRunMultipleProfilers CanRunMultipleProfilers
939 #else
940 #define MAYBE_CanRunMultipleProfilers DISABLED_CanRunMultipleProfilers
941 #endif
942 TEST(StackSamplingProfilerTest, MAYBE_CanRunMultipleProfilers) {
943 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
944
863 SamplingParams params; 945 SamplingParams params;
864 params.sampling_interval = TimeDelta::FromMilliseconds(0); 946 params.sampling_interval = TimeDelta::FromMilliseconds(0);
865 params.samples_per_burst = 1; 947 params.samples_per_burst = 1;
948
949 std::vector<CallStackProfile> profiles;
950 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
951 ASSERT_EQ(1u, profiles.size());
952
953 profiles.clear();
954 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
955 ASSERT_EQ(1u, profiles.size());
956 }
957
958 // Checks that the sampling thread can shut down.
959 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
960 #define MAYBE_SamplerIdleShutdown SamplerIdleShutdown
961 #else
962 #define MAYBE_SamplerIdleShutdown DISABLED_SamplerIdleShutdown
963 #endif
964 TEST(StackSamplingProfilerTest, MAYBE_SamplerIdleShutdown) {
965 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
966
967 SamplingParams params;
968 params.sampling_interval = TimeDelta::FromMilliseconds(0);
969 params.samples_per_burst = 1;
970
971 std::vector<CallStackProfile> profiles;
972 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
973 ASSERT_EQ(1u, profiles.size());
974
975 // Capture thread should still be running at this point.
976 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
977
978 // Initiate an "idle" shutdown and ensure it happens. Idle-shutdown was
979 // disabled above so the test will fail due to a timeout if it does not
980 // exit.
981 StackSamplingProfiler::TestAPI::InitiateSamplingThreadIdleShutdown();
982 while (StackSamplingProfiler::TestAPI::IsSamplingThreadRunning())
983 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
984 }
985
986 // Checks that additional requests will restart a stopped profiler.
987 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
988 #define MAYBE_WillRestartSamplerAfterIdleShutdown \
989 WillRestartSamplerAfterIdleShutdown
990 #else
991 #define MAYBE_WillRestartSamplerAfterIdleShutdown \
992 DISABLED_WillRestartSamplerAfterIdleShutdown
993 #endif
994 TEST(StackSamplingProfilerTest, MAYBE_WillRestartSamplerAfterIdleShutdown) {
995 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
996
997 SamplingParams params;
998 params.sampling_interval = TimeDelta::FromMilliseconds(0);
999 params.samples_per_burst = 1;
866 1000
867 std::vector<CallStackProfile> profiles; 1001 std::vector<CallStackProfile> profiles;
868 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 1002 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
869 ASSERT_EQ(1u, profiles.size()); 1003 ASSERT_EQ(1u, profiles.size());
870 1004
1005 // Capture thread should still be running at this point.
1006 ASSERT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
1007
1008 // Initiate an "idle" shutdown. Waiting for it to actually exit is the only
1009 // way of knowing below that the thread "restarted".
1010 StackSamplingProfiler::TestAPI::InitiateSamplingThreadIdleShutdown();
1011 while (StackSamplingProfiler::TestAPI::IsSamplingThreadRunning())
Mike Wittman 2017/03/23 22:18:31 Since the previous test has already established th
bcwhite 2017/03/27 17:52:43 It's not enough to know that it will exit. It mus
Mike Wittman 2017/03/28 19:32:02 That's true. The explicit event for shutdown run r
1012 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
1013
1014 // Ensure another capture will start the sampling thread and run.
871 profiles.clear(); 1015 profiles.clear();
872 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles); 1016 CaptureProfiles(params, AVeryLongTimeDelta(), &profiles);
873 ASSERT_EQ(1u, profiles.size()); 1017 ASSERT_EQ(1u, profiles.size());
1018 EXPECT_TRUE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
874 } 1019 }
875 1020
876 // Checks that requests to start profiling while another profile is taking place 1021 // Checks that it's safe to stop a task after it's completed and the sampling
877 // are ignored. 1022 // thread has shut-down for being idle.
878 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1023 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
879 #define MAYBE_ConcurrentProfiling ConcurrentProfiling 1024 #define MAYBE_StopAfterIdleShutdown StopAfterIdleShutdown
880 #else 1025 #else
881 #define MAYBE_ConcurrentProfiling DISABLED_ConcurrentProfiling 1026 #define MAYBE_StopAfterIdleShutdown DISABLED_StopAfterIdleShutdown
882 #endif 1027 #endif
883 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling) { 1028 TEST(StackSamplingProfilerTest, MAYBE_StopAfterIdleShutdown) {
1029 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1030
884 WithTargetThread([](PlatformThreadId target_thread_id) { 1031 WithTargetThread([](PlatformThreadId target_thread_id) {
885 SamplingParams params[2]; 1032 SamplingParams params;
886 params[0].initial_delay = TimeDelta::FromMilliseconds(10); 1033 params.sampling_interval = TimeDelta::FromMilliseconds(0);
887 params[0].sampling_interval = TimeDelta::FromMilliseconds(0); 1034 params.samples_per_burst = 1;
888 params[0].samples_per_burst = 1;
889 1035
890 params[1].sampling_interval = TimeDelta::FromMilliseconds(0); 1036 CallStackProfiles profiles;
891 params[1].samples_per_burst = 1; 1037 WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::MANUAL,
1038 WaitableEvent::InitialState::NOT_SIGNALED);
1039 const StackSamplingProfiler::CompletedCallback callback =
1040 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles),
1041 Unretained(&sampling_completed));
1042 StackSamplingProfiler profiler(target_thread_id, params, callback);
892 1043
893 CallStackProfiles profiles[2]; 1044 // Let it run and then stop due to being idle. The thread will go into the
894 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed(2); 1045 // EXITING state (and remain there) sometime after the Initiate call posts
895 std::vector<std::unique_ptr<StackSamplingProfiler>> profiler(2); 1046 // its task and before the thread actually exits.
Mike Wittman 2017/03/23 22:18:31 This is much better, although I think this informa
bcwhite 2017/03/27 17:52:43 Acknowledged.
896 for (int i = 0; i < 2; ++i) { 1047 profiler.Start();
897 sampling_completed[i] = 1048 sampling_completed.Wait();
898 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::AUTOMATIC, 1049 StackSamplingProfiler::TestAPI::InitiateSamplingThreadIdleShutdown();
Mike Wittman 2017/03/23 22:18:31 // Post a ShutdownTask on the sampling thread, whi
bcwhite 2017/03/27 17:52:43 Done.
899 WaitableEvent::InitialState::NOT_SIGNALED); 1050 while (StackSamplingProfiler::TestAPI::IsSamplingThreadRunning())
Mike Wittman 2017/03/23 22:18:31 // Wait for the thread to exit to ensure the Shutd
bcwhite 2017/03/27 17:52:43 Done.
900 const StackSamplingProfiler::CompletedCallback callback = 1051 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1));
901 Bind(&SaveProfilesAndSignalEvent, Unretained(&profiles[i]),
902 Unretained(sampling_completed[i].get()));
903 profiler[i] = MakeUnique<StackSamplingProfiler>(target_thread_id,
904 params[i], callback);
905 }
906 1052
907 profiler[0]->Start(); 1053 // Ensure it's still safe to stop.
Mike Wittman 2017/03/23 22:18:31 // Attempt to stop the profiler now that we know t
bcwhite 2017/03/27 17:52:43 Done.
908 profiler[1]->Start(); 1054 profiler.Stop();
909 1055 EXPECT_FALSE(StackSamplingProfiler::TestAPI::IsSamplingThreadRunning());
910 std::vector<WaitableEvent*> sampling_completed_rawptrs(
911 sampling_completed.size());
912 std::transform(
913 sampling_completed.begin(), sampling_completed.end(),
914 sampling_completed_rawptrs.begin(),
915 [](const std::unique_ptr<WaitableEvent>& elem) { return elem.get(); });
916 // Wait for one profiler to finish.
917 size_t completed_profiler =
918 WaitableEvent::WaitMany(sampling_completed_rawptrs.data(), 2);
919 EXPECT_EQ(1u, profiles[completed_profiler].size());
920
921 size_t other_profiler = 1 - completed_profiler;
922 // Give the other profiler a chance to run and observe that it hasn't.
923 EXPECT_FALSE(sampling_completed[other_profiler]->TimedWait(
924 TimeDelta::FromMilliseconds(25)));
925
926 // Start the other profiler again and it should run.
927 profiler[other_profiler]->Start();
928 sampling_completed[other_profiler]->Wait();
929 EXPECT_EQ(1u, profiles[other_profiler].size());
930 }); 1056 });
931 } 1057 }
932 1058
1059 // Checks that synchronized multiple sampling requests execute in parallel.
1060 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1061 #define MAYBE_ConcurrentProfiling_InSync ConcurrentProfiling_InSync
1062 #else
1063 #define MAYBE_ConcurrentProfiling_InSync DISABLED_ConcurrentProfiling_InSync
1064 #endif
1065 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_InSync) {
1066 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1067
1068 WithTargetThread([](PlatformThreadId target_thread_id) {
1069 std::vector<SamplingParams> params(2);
1070
1071 // Providing an initial delay makes it more likely that both will be
1072 // scheduled before either starts to run. Once started, samples will
1073 // run ordered by their scheduled, interleaved times regardless of
1074 // whatever interval the thread wakes up. Thus, total execution time
1075 // will be 10ms (delay) + 10x1ms (sampling) + 1/2 timer minimum interval.
1076 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
1077 params[0].sampling_interval = TimeDelta::FromMilliseconds(1);
1078 params[0].samples_per_burst = 9;
1079
1080 params[1].initial_delay = TimeDelta::FromMilliseconds(11);
1081 params[1].sampling_interval = TimeDelta::FromMilliseconds(1);
1082 params[1].samples_per_burst = 8;
1083
1084 std::vector<CallStackProfiles> profiles;
1085 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1086 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1087 CreateProfilers(target_thread_id, params, &profiles, &profilers,
1088 &sampling_completed);
1089
1090 profilers[0]->Start();
1091 profilers[1]->Start();
1092
1093 // Wait for one profiler to finish.
1094 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
1095 ASSERT_EQ(1u, profiles[completed_profiler].size());
1096
1097 size_t other_profiler = 1 - completed_profiler;
1098 // Wait for the other profiler to finish.
1099 sampling_completed[other_profiler]->Wait();
1100 ASSERT_EQ(1u, profiles[other_profiler].size());
1101
1102 // Ensure each got the correct number of samples.
1103 EXPECT_EQ(9u, profiles[0][0].samples.size());
1104 EXPECT_EQ(8u, profiles[1][0].samples.size());
1105 });
1106 }
1107
1108 // Checks that several mixed sampling requests execute in parallel.
1109 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1110 #define MAYBE_ConcurrentProfiling_Mixed ConcurrentProfiling_Mixed
1111 #else
1112 #define MAYBE_ConcurrentProfiling_Mixed DISABLED_ConcurrentProfiling_Mixed
1113 #endif
1114 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_Mixed) {
1115 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1116
1117 WithTargetThread([](PlatformThreadId target_thread_id) {
1118 std::vector<SamplingParams> params(3);
1119
1120 params[0].initial_delay = TimeDelta::FromMilliseconds(8);
1121 params[0].sampling_interval = TimeDelta::FromMilliseconds(4);
1122 params[0].samples_per_burst = 10;
1123
1124 params[1].initial_delay = TimeDelta::FromMilliseconds(9);
1125 params[1].sampling_interval = TimeDelta::FromMilliseconds(3);
1126 params[1].samples_per_burst = 10;
1127
1128 params[2].initial_delay = TimeDelta::FromMilliseconds(10);
1129 params[2].sampling_interval = TimeDelta::FromMilliseconds(2);
1130 params[2].samples_per_burst = 10;
1131
1132 std::vector<CallStackProfiles> profiles;
1133 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1134 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1135 CreateProfilers(target_thread_id, params, &profiles, &profilers,
1136 &sampling_completed);
1137
1138 for (size_t i = 0; i < profilers.size(); ++i)
1139 profilers[i]->Start();
1140
1141 // Wait for one profiler to finish.
1142 size_t completed_profiler = WaitForSamplingComplete(&sampling_completed);
1143 EXPECT_EQ(1u, profiles[completed_profiler].size());
1144 // Stop and destroy all profilers, always in the same order. Don't crash.
1145 for (size_t i = 0; i < profilers.size(); ++i)
1146 profilers[i]->Stop();
1147 for (size_t i = 0; i < profilers.size(); ++i)
1148 profilers[i].reset();
1149 });
1150 }
1151
1152 // Checks that sampling requests execute in a staggered manner.
1153 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1154 #define MAYBE_ConcurrentProfiling_Staggered ConcurrentProfiling_Staggered
1155 #else
1156 #define MAYBE_ConcurrentProfiling_Staggered \
1157 DISABLED_ConcurrentProfiling_Staggered
1158 #endif
1159 TEST(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_Staggered) {
1160 StackSamplingProfiler::TestAPI::DisableIdleShutdown();
1161
1162 WithTargetThread([](PlatformThreadId target_thread_id) {
1163 std::vector<SamplingParams> params(3);
1164
1165 // Create an arbitrary variety of sampling parameters. The exact values of
1166 // these are unimportant other than they should not run too long.
1167 params[0].initial_delay = TimeDelta::FromMilliseconds(10);
1168 params[0].sampling_interval = TimeDelta::FromMilliseconds(10);
1169 params[0].samples_per_burst = 1;
1170
1171 params[1].initial_delay = TimeDelta::FromMilliseconds(5);
1172 params[1].sampling_interval = TimeDelta::FromMilliseconds(10);
1173 params[1].samples_per_burst = 2;
1174
1175 params[2].initial_delay = TimeDelta::FromMilliseconds(0);
1176 params[2].sampling_interval = TimeDelta::FromMilliseconds(10);
1177 params[2].samples_per_burst = 3;
1178
1179 std::vector<CallStackProfiles> profiles;
1180 std::vector<std::unique_ptr<StackSamplingProfiler>> profilers;
1181 std::vector<std::unique_ptr<WaitableEvent>> sampling_completed;
1182 CreateProfilers(target_thread_id, params, &profiles, &profilers,
1183 &sampling_completed);
1184
1185 profilers[0]->Start();
1186 profilers[1]->Start();
1187 sampling_completed[0]->Wait();
1188 profilers[0]->Stop();
1189 profilers[2]->Start();
1190 profilers[1]->Stop();
1191 sampling_completed[1]->Wait();
1192 sampling_completed[2]->Wait();
1193 EXPECT_EQ(1u, profiles[0].size());
1194 EXPECT_EQ(1u, profiles[1].size());
1195 EXPECT_EQ(1u, profiles[2].size());
1196 });
1197 }
1198
933 // Checks that a stack that runs through another library produces a stack with 1199 // Checks that a stack that runs through another library produces a stack with
934 // the expected functions. 1200 // the expected functions.
935 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1201 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
936 #define MAYBE_OtherLibrary OtherLibrary 1202 #define MAYBE_OtherLibrary OtherLibrary
937 #else 1203 #else
938 #define MAYBE_OtherLibrary DISABLED_OtherLibrary 1204 #define MAYBE_OtherLibrary DISABLED_OtherLibrary
939 #endif 1205 #endif
940 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) { 1206 TEST(StackSamplingProfilerTest, MAYBE_OtherLibrary) {
941 SamplingParams params; 1207 SamplingParams params;
942 params.sampling_interval = TimeDelta::FromMilliseconds(0); 1208 params.sampling_interval = TimeDelta::FromMilliseconds(0);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED) 1283 #if defined(STACK_SAMPLING_PROFILER_SUPPORTED)
1018 #define MAYBE_UnloadedLibrary UnloadedLibrary 1284 #define MAYBE_UnloadedLibrary UnloadedLibrary
1019 #else 1285 #else
1020 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary 1286 #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary
1021 #endif 1287 #endif
1022 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { 1288 TEST(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) {
1023 TestLibraryUnload(true); 1289 TestLibraryUnload(true);
1024 } 1290 }
1025 1291
1026 } // namespace base 1292 } // namespace base
OLDNEW
« no previous file with comments | « base/profiler/stack_sampling_profiler.cc ('k') | base/threading/thread_restrictions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698