diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/base/profiler | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/base/profiler')
-rw-r--r-- | chromium/base/profiler/native_stack_sampler_mac.cc | 59 | ||||
-rw-r--r-- | chromium/base/profiler/scoped_profile.h | 1 | ||||
-rw-r--r-- | chromium/base/profiler/stack_sampling_profiler.cc | 129 | ||||
-rw-r--r-- | chromium/base/profiler/stack_sampling_profiler.h | 12 | ||||
-rw-r--r-- | chromium/base/profiler/stack_sampling_profiler_unittest.cc | 246 | ||||
-rw-r--r-- | chromium/base/profiler/tracked_time.cc | 68 | ||||
-rw-r--r-- | chromium/base/profiler/tracked_time.h | 71 | ||||
-rw-r--r-- | chromium/base/profiler/tracked_time_unittest.cc | 105 |
8 files changed, 234 insertions, 457 deletions
diff --git a/chromium/base/profiler/native_stack_sampler_mac.cc b/chromium/base/profiler/native_stack_sampler_mac.cc index 4e5108e5daa..c4982ccbb19 100644 --- a/chromium/base/profiler/native_stack_sampler_mac.cc +++ b/chromium/base/profiler/native_stack_sampler_mac.cc @@ -8,6 +8,7 @@ #include <libkern/OSByteOrder.h> #include <libunwind.h> #include <mach-o/compact_unwind_encoding.h> +#include <mach-o/getsect.h> #include <mach-o/swap.h> #include <mach/kern_return.h> #include <mach/mach.h> @@ -30,6 +31,19 @@ namespace base { namespace { +// Maps a module's address range (half-open) in memory to an index in a separate +// data structure. +struct ModuleIndex { + ModuleIndex(uintptr_t start, uintptr_t end, size_t idx) + : base_address(start), end_address(end), index(idx){}; + // Base address of the represented module. + uintptr_t base_address; + // First address off the end of the represented module. + uintptr_t end_address; + // An index to the represented module in a separate container. + size_t index; +}; + // Stack walking -------------------------------------------------------------- // Fills |state| with |target_thread|'s context. @@ -269,23 +283,38 @@ std::string GetUniqueId(const void* module_addr) { // determined for |module|. size_t GetModuleIndex(const uintptr_t instruction_pointer, std::vector<StackSamplingProfiler::Module>* modules, - std::map<const void*, size_t>* profile_module_index) { + std::vector<ModuleIndex>* profile_module_index) { + // Check if |instruction_pointer| is in the address range of a module we've + // already seen. + auto module_index = + std::find_if(profile_module_index->begin(), profile_module_index->end(), + [instruction_pointer](const ModuleIndex& index) { + return instruction_pointer >= index.base_address && + instruction_pointer < index.end_address; + }); + if (module_index != profile_module_index->end()) { + return module_index->index; + } Dl_info inf; if (!dladdr(reinterpret_cast<const void*>(instruction_pointer), &inf)) return StackSamplingProfiler::Frame::kUnknownModuleIndex; - auto module_index = profile_module_index->find(inf.dli_fbase); - if (module_index == profile_module_index->end()) { - StackSamplingProfiler::Module module( - reinterpret_cast<uintptr_t>(inf.dli_fbase), GetUniqueId(inf.dli_fbase), - base::FilePath(inf.dli_fname)); - modules->push_back(module); - module_index = - profile_module_index - ->insert(std::make_pair(inf.dli_fbase, modules->size() - 1)) - .first; - } - return module_index->second; + StackSamplingProfiler::Module module( + reinterpret_cast<uintptr_t>(inf.dli_fbase), GetUniqueId(inf.dli_fbase), + base::FilePath(inf.dli_fname)); + modules->push_back(module); + + const mach_header_64* mach_header = + reinterpret_cast<const mach_header_64*>(inf.dli_fbase); + DCHECK_EQ(MH_MAGIC_64, mach_header->magic); + + unsigned long module_size; + getsegmentdata(mach_header, SEG_TEXT, &module_size); + uintptr_t base_module_address = reinterpret_cast<uintptr_t>(mach_header); + size_t index = modules->size() - 1; + profile_module_index->emplace_back(base_module_address, + base_module_address + module_size, index); + return index; } // ScopedSuspendThread -------------------------------------------------------- @@ -350,9 +379,9 @@ class NativeStackSamplerMac : public NativeStackSampler { // between ProfileRecordingStarting() and ProfileRecordingStopped(). std::vector<StackSamplingProfiler::Module>* current_modules_ = nullptr; - // Maps a module's base address to the corresponding Module's index within + // Maps a module's address range to the corresponding Module's index within // current_modules_. - std::map<const void*, size_t> profile_module_index_; + std::vector<ModuleIndex> profile_module_index_; DISALLOW_COPY_AND_ASSIGN(NativeStackSamplerMac); }; diff --git a/chromium/base/profiler/scoped_profile.h b/chromium/base/profiler/scoped_profile.h index 4df6a1bc024..b862bbc2cf1 100644 --- a/chromium/base/profiler/scoped_profile.h +++ b/chromium/base/profiler/scoped_profile.h @@ -15,7 +15,6 @@ #include "base/base_export.h" #include "base/location.h" #include "base/macros.h" -#include "base/profiler/tracked_time.h" #include "base/trace_event/heap_profiler.h" #include "base/tracked_objects.h" diff --git a/chromium/base/profiler/stack_sampling_profiler.cc b/chromium/base/profiler/stack_sampling_profiler.cc index 76ad81df9e8..6e8370e92c9 100644 --- a/chromium/base/profiler/stack_sampling_profiler.cc +++ b/chromium/base/profiler/stack_sampling_profiler.cc @@ -31,7 +31,7 @@ namespace { // This value is used when there is no collection in progress and thus no ID // for referencing the active collection to the SamplingThread. -const int NULL_COLLECTION_ID = -1; +const int NULL_PROFILER_ID = -1; void ChangeAtomicFlags(subtle::Atomic32* flags, subtle::Atomic32 set, @@ -139,12 +139,13 @@ class StackSamplingProfiler::SamplingThread : public Thread { }; struct CollectionContext { - CollectionContext(PlatformThreadId target, + CollectionContext(int profiler_id, + PlatformThreadId target, const SamplingParams& params, const CompletedCallback& callback, WaitableEvent* finished, std::unique_ptr<NativeStackSampler> sampler) - : collection_id(next_collection_id_.GetNext()), + : profiler_id(profiler_id), target(target), params(params), callback(callback), @@ -152,9 +153,9 @@ class StackSamplingProfiler::SamplingThread : public Thread { native_sampler(std::move(sampler)) {} ~CollectionContext() {} - // An identifier for this collection, used to uniquely identify it to - // outside interests. - const int collection_id; + // An identifier for the profiler associated with this collection, used to + // uniquely identify the collection to outside interests. + const int profiler_id; const PlatformThreadId target; // ID of The thread being sampled. const SamplingParams params; // Information about how to sample. @@ -177,8 +178,8 @@ class StackSamplingProfiler::SamplingThread : public Thread { // The collected stack samples. The active profile is always at the back(). CallStackProfiles profiles; - private: - static StaticAtomicSequenceNumber next_collection_id_; + // Sequence number for generating new profiler ids. + static AtomicSequenceNumber next_profiler_id; }; // Gets the single instance of this class. @@ -228,8 +229,11 @@ class StackSamplingProfiler::SamplingThread : public Thread { // Get task runner that is usable from the sampling thread itself. scoped_refptr<SingleThreadTaskRunner> GetTaskRunnerOnSamplingThread(); - // Finishes a collection and reports collected data via callback. - void FinishCollection(CollectionContext* collection); + // Finishes a collection and reports collected data via callback. Returns + // the new collection params, if a new collection should be started. The + // |collection| should already have been removed from |active_collections_| + // by the caller, as this is needed to avoid flakyness in unit tests. + Optional<SamplingParams> FinishCollection(CollectionContext* collection); // Records a single sample of a collection. void RecordSample(CollectionContext* collection); @@ -346,9 +350,9 @@ void StackSamplingProfiler::SamplingThread::TestAPI::ShutdownAssumingIdle( WaitableEvent::InitialState::NOT_SIGNALED); // PostTaskAndReply won't work because thread and associated message-loop may // be shut down. - task_runner->PostTask(FROM_HERE, - Bind(&ShutdownTaskAndSignalEvent, Unretained(sampler), - add_events, Unretained(&executed))); + task_runner->PostTask( + FROM_HERE, BindOnce(&ShutdownTaskAndSignalEvent, Unretained(sampler), + add_events, Unretained(&executed))); executed.Wait(); } @@ -361,8 +365,8 @@ void StackSamplingProfiler::SamplingThread::TestAPI::ShutdownTaskAndSignalEvent( event->Signal(); } -StaticAtomicSequenceNumber StackSamplingProfiler::SamplingThread:: - CollectionContext::next_collection_id_; +AtomicSequenceNumber + StackSamplingProfiler::SamplingThread::CollectionContext::next_profiler_id; StackSamplingProfiler::SamplingThread::SamplingThread() : Thread("StackSamplingProfiler") {} @@ -378,12 +382,13 @@ int StackSamplingProfiler::SamplingThread::Add( std::unique_ptr<CollectionContext> collection) { // This is not to be run on the sampling thread. - int id = collection->collection_id; + int id = collection->profiler_id; scoped_refptr<SingleThreadTaskRunner> task_runner = GetOrCreateTaskRunnerForAdd(); - task_runner->PostTask(FROM_HERE, Bind(&SamplingThread::AddCollectionTask, - Unretained(this), Passed(&collection))); + task_runner->PostTask( + FROM_HERE, BindOnce(&SamplingThread::AddCollectionTask, Unretained(this), + Passed(&collection))); return id; } @@ -400,8 +405,9 @@ void StackSamplingProfiler::SamplingThread::Remove(int id) { // This can fail if the thread were to exit between acquisition of the task // runner above and the call below. In that case, however, everything has // stopped so there's no need to try to stop it. - task_runner->PostTask(FROM_HERE, Bind(&SamplingThread::RemoveCollectionTask, - Unretained(this), id)); + task_runner->PostTask( + FROM_HERE, + BindOnce(&SamplingThread::RemoveCollectionTask, Unretained(this), id)); } scoped_refptr<SingleThreadTaskRunner> @@ -473,16 +479,19 @@ StackSamplingProfiler::SamplingThread::GetTaskRunnerOnSamplingThread() { return Thread::task_runner(); } -void StackSamplingProfiler::SamplingThread::FinishCollection( +Optional<StackSamplingProfiler::SamplingParams> +StackSamplingProfiler::SamplingThread::FinishCollection( CollectionContext* collection) { DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId()); + DCHECK_EQ(0u, active_collections_.count(collection->profiler_id)); // If there is no duration for the final profile (because it was stopped), // calculate it now. if (!collection->profiles.empty() && collection->profiles.back().profile_duration == TimeDelta()) { collection->profiles.back().profile_duration = - Time::Now() - collection->profile_start_time; + Time::Now() - collection->profile_start_time + + collection->params.sampling_interval; } // Extract some information so callback and event-signalling can still be @@ -493,16 +502,13 @@ void StackSamplingProfiler::SamplingThread::FinishCollection( CallStackProfiles profiles = std::move(collection->profiles); WaitableEvent* finished = collection->finished; - // Remove this collection from the map of known ones. The |collection| - // parameter is invalid after this point. - size_t count = active_collections_.erase(collection->collection_id); - DCHECK_EQ(1U, count); - // Run the associated callback, passing the collected profiles. - callback.Run(std::move(profiles)); + Optional<SamplingParams> new_params = callback.Run(std::move(profiles)); // Signal that this collection is finished. finished->Signal(); + + return new_params; } void StackSamplingProfiler::SamplingThread::RecordSample( @@ -530,7 +536,8 @@ void StackSamplingProfiler::SamplingThread::RecordSample( // If this is the last sample of a burst, record the total time. if (collection->sample == collection->params.samples_per_burst - 1) { - profile.profile_duration = Time::Now() - collection->profile_start_time; + profile.profile_duration = Time::Now() - collection->profile_start_time + + collection->params.sampling_interval; collection->native_sampler->ProfileRecordingStopped(stack_buffer_.get()); } } @@ -551,7 +558,7 @@ void StackSamplingProfiler::SamplingThread::ScheduleShutdownIfIdle() { GetTaskRunnerOnSamplingThread()->PostDelayedTask( FROM_HERE, - Bind(&SamplingThread::ShutdownTask, Unretained(this), add_events), + BindOnce(&SamplingThread::ShutdownTask, Unretained(this), add_events), TimeDelta::FromSeconds(60)); } @@ -559,16 +566,16 @@ void StackSamplingProfiler::SamplingThread::AddCollectionTask( std::unique_ptr<CollectionContext> collection) { DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId()); - const int collection_id = collection->collection_id; + const int profiler_id = collection->profiler_id; const TimeDelta initial_delay = collection->params.initial_delay; active_collections_.insert( - std::make_pair(collection_id, std::move(collection))); + std::make_pair(profiler_id, std::move(collection))); GetTaskRunnerOnSamplingThread()->PostDelayedTask( FROM_HERE, - Bind(&SamplingThread::PerformCollectionTask, Unretained(this), - collection_id), + BindOnce(&SamplingThread::PerformCollectionTask, Unretained(this), + profiler_id), initial_delay); // Another increment of "add events" serves to invalidate any pending @@ -587,7 +594,12 @@ void StackSamplingProfiler::SamplingThread::RemoveCollectionTask(int id) { if (found == active_collections_.end()) return; - FinishCollection(found->second.get()); + // Remove |collection| from |active_collections_|. + std::unique_ptr<CollectionContext> collection = std::move(found->second); + size_t count = active_collections_.erase(id); + DCHECK_EQ(1U, count); + + FinishCollection(collection.get()); ScheduleShutdownIfIdle(); } @@ -610,19 +622,39 @@ void StackSamplingProfiler::SamplingThread::PerformCollectionTask(int id) { RecordSample(collection); // Update the time of the next sample recording. - if (UpdateNextSampleTime(collection)) { + const bool collection_finished = !UpdateNextSampleTime(collection); + if (!collection_finished) { bool success = GetTaskRunnerOnSamplingThread()->PostDelayedTask( FROM_HERE, - Bind(&SamplingThread::PerformCollectionTask, Unretained(this), id), + BindOnce(&SamplingThread::PerformCollectionTask, Unretained(this), id), std::max(collection->next_sample_time - Time::Now(), TimeDelta())); DCHECK(success); - } else { - // All capturing has completed so finish the collection. By not re-adding - // it to the task queue, the collection will "expire" (i.e. no further work - // will be done). The |collection| variable will be invalid after this call. - FinishCollection(collection); + return; + } + + // Take ownership of |collection| and remove it from the map. If collection is + // to be restarted, a new collection task will be added below. + std::unique_ptr<CollectionContext> owned_collection = + std::move(found->second); + size_t count = active_collections_.erase(id); + DCHECK_EQ(1U, count); + + // All capturing has completed so finish the collection. If no new params + // are returned, a new collection should not be started. + Optional<SamplingParams> new_params = FinishCollection(collection); + if (!new_params.has_value()) { + // By not adding it to the task queue, the collection will "expire" (i.e. + // no further work will be done). ScheduleShutdownIfIdle(); + return; } + + // Restart the collection with the new params. Keep the same id so the + // Stop() operation continues to work. + auto new_collection = MakeUnique<SamplingThread::CollectionContext>( + id, collection->target, new_params.value(), collection->callback, + collection->finished, std::move(collection->native_sampler)); + AddCollectionTask(std::move(new_collection)); } void StackSamplingProfiler::SamplingThread::ShutdownTask(int add_events) { @@ -742,7 +774,7 @@ StackSamplingProfiler::StackSamplingProfiler( // and "manual" so that it can be waited in multiple places. profiling_inactive_(WaitableEvent::ResetPolicy::MANUAL, WaitableEvent::InitialState::SIGNALED), - collection_id_(NULL_COLLECTION_ID), + profiler_id_(NULL_PROFILER_ID), test_delegate_(test_delegate) {} StackSamplingProfiler::~StackSamplingProfiler() { @@ -779,17 +811,18 @@ void StackSamplingProfiler::Start() { profiling_inactive_.Wait(); profiling_inactive_.Reset(); - DCHECK_EQ(NULL_COLLECTION_ID, collection_id_); - collection_id_ = SamplingThread::GetInstance()->Add( + DCHECK_EQ(NULL_PROFILER_ID, profiler_id_); + profiler_id_ = SamplingThread::GetInstance()->Add( MakeUnique<SamplingThread::CollectionContext>( + SamplingThread::CollectionContext::next_profiler_id.GetNext(), thread_id_, params_, completed_callback_, &profiling_inactive_, std::move(native_sampler))); - DCHECK_NE(NULL_COLLECTION_ID, collection_id_); + DCHECK_NE(NULL_PROFILER_ID, profiler_id_); } void StackSamplingProfiler::Stop() { - SamplingThread::GetInstance()->Remove(collection_id_); - collection_id_ = NULL_COLLECTION_ID; + SamplingThread::GetInstance()->Remove(profiler_id_); + profiler_id_ = NULL_PROFILER_ID; } // static diff --git a/chromium/base/profiler/stack_sampling_profiler.h b/chromium/base/profiler/stack_sampling_profiler.h index a5e30e9fa0e..c2c89dd0dab 100644 --- a/chromium/base/profiler/stack_sampling_profiler.h +++ b/chromium/base/profiler/stack_sampling_profiler.h @@ -16,6 +16,7 @@ #include "base/callback.h" #include "base/files/file_path.h" #include "base/macros.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" @@ -215,13 +216,18 @@ class BASE_EXPORT StackSamplingProfiler { // are move-only. Other threads, including the UI thread, may block on // callback completion so this should run as quickly as possible. // + // After collection completion, the callback may instruct the profiler to do + // additional collection(s) by returning a SamplingParams object to indicate + // collection should be started again. + // // IMPORTANT NOTE: The callback is invoked on a thread the profiler // constructs, rather than on the thread used to construct the profiler and // set the callback, and thus the callback must be callable on any thread. For // threads with message loops that create StackSamplingProfilers, posting a // task to the message loop with the moved (i.e. std::move) profiles is the // thread-safe callback implementation. - using CompletedCallback = Callback<void(CallStackProfiles)>; + using CompletedCallback = + Callback<Optional<SamplingParams>(CallStackProfiles)>; // Creates a profiler for the CURRENT thread that sends completed profiles // to |callback|. An optional |test_delegate| can be supplied by tests. @@ -299,9 +305,9 @@ class BASE_EXPORT StackSamplingProfiler { // and later passed to the sampling thread when profiling is started. std::unique_ptr<NativeStackSampler> native_sampler_; - // An ID uniquely identifying this collection to the sampling thread. This + // An ID uniquely identifying this profiler to the sampling thread. This // will be an internal "null" value when no collection has been started. - int collection_id_; + int profiler_id_; // Stored until it can be passed to the NativeStackSampler created in Start(). NativeStackSamplerTestDelegate* const test_delegate_; diff --git a/chromium/base/profiler/stack_sampling_profiler_unittest.cc b/chromium/base/profiler/stack_sampling_profiler_unittest.cc index 7cae10455d9..407e3f875c7 100644 --- a/chromium/base/profiler/stack_sampling_profiler_unittest.cc +++ b/chromium/base/profiler/stack_sampling_profiler_unittest.cc @@ -5,6 +5,7 @@ #include <stddef.h> #include <stdint.h> +#include <algorithm> #include <cstdlib> #include <memory> #include <utility> @@ -51,6 +52,13 @@ namespace base { +#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) +#define PROFILER_TEST_F(TestClass, TestName) TEST_F(TestClass, TestName) +#else +#define PROFILER_TEST_F(TestClass, TestName) \ + TEST_F(TestClass, DISABLED_##TestName) +#endif + using SamplingParams = StackSamplingProfiler::SamplingParams; using Frame = StackSamplingProfiler::Frame; using Frames = std::vector<StackSamplingProfiler::Frame>; @@ -316,19 +324,46 @@ void SynchronousUnloadNativeLibrary(NativeLibrary library) { } // Called on the profiler thread when complete, to collect profiles. -void SaveProfiles(CallStackProfiles* profiles, - CallStackProfiles pending_profiles) { +Optional<StackSamplingProfiler::SamplingParams> SaveProfiles( + CallStackProfiles* profiles, + CallStackProfiles pending_profiles) { *profiles = std::move(pending_profiles); + return Optional<StackSamplingProfiler::SamplingParams>(); } // Called on the profiler thread when complete. Collects profiles produced by // the profiler, and signals an event to allow the main thread to know that that // the profiler is done. -void SaveProfilesAndSignalEvent(CallStackProfiles* profiles, - WaitableEvent* event, - CallStackProfiles pending_profiles) { +Optional<StackSamplingProfiler::SamplingParams> SaveProfilesAndSignalEvent( + CallStackProfiles* profiles, + WaitableEvent* event, + CallStackProfiles pending_profiles) { *profiles = std::move(pending_profiles); event->Signal(); + return Optional<StackSamplingProfiler::SamplingParams>(); +} + +// Similar to SaveProfilesAndSignalEvent(), but will schedule a second +// collection after the first call back. +Optional<StackSamplingProfiler::SamplingParams> SaveProfilesAndReschedule( + std::vector<CallStackProfiles>* profiles, + WaitableEvent* event, + CallStackProfiles pending_profiles) { + profiles->push_back(std::move(pending_profiles)); + + event->Signal(); + + if (profiles->size() == 2) + return Optional<StackSamplingProfiler::SamplingParams>(); + + StackSamplingProfiler::SamplingParams sampling_params; + sampling_params.initial_delay = base::TimeDelta::FromMilliseconds(100); + sampling_params.bursts = 1; + sampling_params.samples_per_burst = 1; + // Below are unused: + sampling_params.burst_interval = base::TimeDelta::FromMilliseconds(0); + sampling_params.sampling_interval = base::TimeDelta::FromMilliseconds(0); + return sampling_params; } // Executes the function with the target thread running and executing within @@ -651,13 +686,12 @@ class StackSamplingProfilerTest : public testing::Test { // Checks that the basic expected information is present in a sampled call stack // profile. // macOS ASAN is not yet supported - crbug.com/718628. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) && \ - !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) +#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) #define MAYBE_Basic Basic #else #define MAYBE_Basic DISABLED_Basic #endif -TEST_F(StackSamplingProfilerTest, MAYBE_Basic) { +PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Basic) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -696,12 +730,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_Basic) { } // Checks that annotations are recorded in samples. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_Annotations Annotations -#else -#define MAYBE_Annotations DISABLED_Annotations -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_Annotations) { +PROFILER_TEST_F(StackSamplingProfilerTest, Annotations) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -731,13 +760,12 @@ TEST_F(StackSamplingProfilerTest, MAYBE_Annotations) { // Checks that the profiler handles stacks containing dynamically-allocated // stack memory. // macOS ASAN is not yet supported - crbug.com/718628. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) && \ - !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) +#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) #define MAYBE_Alloca Alloca #else #define MAYBE_Alloca DISABLED_Alloca #endif -TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) { +PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -792,12 +820,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_Alloca) { // Checks that the expected number of profiles and samples are present in the // call stack profiles produced. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_MultipleProfilesAndSamples MultipleProfilesAndSamples -#else -#define MAYBE_MultipleProfilesAndSamples DISABLED_MultipleProfilesAndSamples -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { +PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilesAndSamples) { SamplingParams params; params.burst_interval = params.sampling_interval = TimeDelta::FromMilliseconds(0); @@ -813,12 +836,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_MultipleProfilesAndSamples) { } // Checks that a profiler can stop/destruct without ever having started. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_StopWithoutStarting StopWithoutStarting -#else -#define MAYBE_StopWithoutStarting DISABLED_StopWithoutStarting -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_StopWithoutStarting) { +PROFILER_TEST_F(StackSamplingProfilerTest, StopWithoutStarting) { WithTargetThread([](PlatformThreadId target_thread_id) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); @@ -839,12 +857,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_StopWithoutStarting) { // Checks that its okay to stop a profiler before it finishes even when the // sampling thread continues to run. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_StopSafely StopSafely -#else -#define MAYBE_StopSafely DISABLED_StopSafely -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_StopSafely) { +PROFILER_TEST_F(StackSamplingProfilerTest, StopSafely) { // Test delegate that counts samples. class SampleRecordedCounter : public NativeStackSamplerTestDelegate { public: @@ -919,12 +932,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_StopSafely) { // Checks that no call stack profiles are captured if the profiling is stopped // during the initial delay. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_StopDuringInitialDelay StopDuringInitialDelay -#else -#define MAYBE_StopDuringInitialDelay DISABLED_StopDuringInitialDelay -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { +PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInitialDelay) { SamplingParams params; params.initial_delay = TimeDelta::FromSeconds(60); @@ -936,12 +944,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInitialDelay) { // Checks that the single completed call stack profile is captured if the // profiling is stopped between bursts. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_StopDuringInterBurstInterval StopDuringInterBurstInterval -#else -#define MAYBE_StopDuringInterBurstInterval DISABLED_StopDuringInterBurstInterval -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) { +PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterBurstInterval) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.burst_interval = TimeDelta::FromSeconds(60); @@ -957,13 +960,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInterBurstInterval) { // Checks that tasks can be stopped before completion and incomplete call stack // profiles are captured. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_StopDuringInterSampleInterval StopDuringInterSampleInterval -#else -#define MAYBE_StopDuringInterSampleInterval \ - DISABLED_StopDuringInterSampleInterval -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) { +PROFILER_TEST_F(StackSamplingProfilerTest, StopDuringInterSampleInterval) { // Test delegate that counts samples. class SampleRecordedEvent : public NativeStackSamplerTestDelegate { public: @@ -1003,13 +1000,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_StopDuringInterSampleInterval) { } // Checks that we can destroy the profiler while profiling. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_DestroyProfilerWhileProfiling DestroyProfilerWhileProfiling -#else -#define MAYBE_DestroyProfilerWhileProfiling \ - DISABLED_DestroyProfilerWhileProfiling -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_DestroyProfilerWhileProfiling) { +PROFILER_TEST_F(StackSamplingProfilerTest, DestroyProfilerWhileProfiling) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(10); @@ -1028,12 +1019,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_DestroyProfilerWhileProfiling) { } // Checks that the same profiler may be run multiple times. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_CanRunMultipleTimes CanRunMultipleTimes -#else -#define MAYBE_CanRunMultipleTimes DISABLED_CanRunMultipleTimes -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { +PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleTimes) { WithTargetThread([](PlatformThreadId target_thread_id) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); @@ -1062,13 +1048,36 @@ TEST_F(StackSamplingProfilerTest, MAYBE_CanRunMultipleTimes) { }); } +PROFILER_TEST_F(StackSamplingProfilerTest, RescheduledByCallback) { + WithTargetThread([](PlatformThreadId target_thread_id) { + SamplingParams params; + params.sampling_interval = TimeDelta::FromMilliseconds(0); + params.samples_per_burst = 1; + + std::vector<CallStackProfiles> profiles; + WaitableEvent sampling_completed(WaitableEvent::ResetPolicy::AUTOMATIC, + WaitableEvent::InitialState::NOT_SIGNALED); + const StackSamplingProfiler::CompletedCallback callback = + Bind(&SaveProfilesAndReschedule, Unretained(&profiles), + Unretained(&sampling_completed)); + StackSamplingProfiler profiler(target_thread_id, params, callback); + + // Start once and wait for it to be completed. + profiler.Start(); + sampling_completed.Wait(); + ASSERT_EQ(1u, profiles.size()); + ASSERT_EQ(1u, profiles[0].size()); + + // Now, wait for the second callback call. + sampling_completed.Wait(); + profiler.Stop(); + ASSERT_EQ(2u, profiles.size()); + ASSERT_EQ(1u, profiles[1].size()); + }); +} + // Checks that the different profilers may be run. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_CanRunMultipleProfilers CanRunMultipleProfilers -#else -#define MAYBE_CanRunMultipleProfilers DISABLED_CanRunMultipleProfilers -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_CanRunMultipleProfilers) { +PROFILER_TEST_F(StackSamplingProfilerTest, CanRunMultipleProfilers) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -1083,12 +1092,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_CanRunMultipleProfilers) { } // Checks that a sampler can be started while another is running. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_MultipleStart MultipleStart -#else -#define MAYBE_MultipleStart DISABLED_MultipleStart -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_MultipleStart) { +PROFILER_TEST_F(StackSamplingProfilerTest, MultipleStart) { WithTargetThread([](PlatformThreadId target_thread_id) { std::vector<SamplingParams> params(2); @@ -1109,12 +1113,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_MultipleStart) { } // Checks that the sampling thread can shut down. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_SamplerIdleShutdown SamplerIdleShutdown -#else -#define MAYBE_SamplerIdleShutdown DISABLED_SamplerIdleShutdown -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_SamplerIdleShutdown) { +PROFILER_TEST_F(StackSamplingProfilerTest, SamplerIdleShutdown) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -1139,14 +1138,8 @@ TEST_F(StackSamplingProfilerTest, MAYBE_SamplerIdleShutdown) { } // Checks that additional requests will restart a stopped profiler. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_WillRestartSamplerAfterIdleShutdown \ - WillRestartSamplerAfterIdleShutdown -#else -#define MAYBE_WillRestartSamplerAfterIdleShutdown \ - DISABLED_WillRestartSamplerAfterIdleShutdown -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_WillRestartSamplerAfterIdleShutdown) { +PROFILER_TEST_F(StackSamplingProfilerTest, + WillRestartSamplerAfterIdleShutdown) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -1171,12 +1164,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_WillRestartSamplerAfterIdleShutdown) { // Checks that it's safe to stop a task after it's completed and the sampling // thread has shut-down for being idle. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_StopAfterIdleShutdown StopAfterIdleShutdown -#else -#define MAYBE_StopAfterIdleShutdown DISABLED_StopAfterIdleShutdown -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_StopAfterIdleShutdown) { +PROFILER_TEST_F(StackSamplingProfilerTest, StopAfterIdleShutdown) { WithTargetThread([](PlatformThreadId target_thread_id) { SamplingParams params; @@ -1202,15 +1190,8 @@ TEST_F(StackSamplingProfilerTest, MAYBE_StopAfterIdleShutdown) { // Checks that profilers can run both before and after the sampling thread has // started. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_ProfileBeforeAndAfterSamplingThreadRunning \ - ProfileBeforeAndAfterSamplingThreadRunning -#else -#define MAYBE_ProfileBeforeAndAfterSamplingThreadRunning \ - DISABLED_ProfileBeforeAndAfterSamplingThreadRunning -#endif -TEST_F(StackSamplingProfilerTest, - MAYBE_ProfileBeforeAndAfterSamplingThreadRunning) { +PROFILER_TEST_F(StackSamplingProfilerTest, + ProfileBeforeAndAfterSamplingThreadRunning) { WithTargetThread([](PlatformThreadId target_thread_id) { std::vector<SamplingParams> params(2); @@ -1240,12 +1221,7 @@ TEST_F(StackSamplingProfilerTest, // Checks that an idle-shutdown task will abort if a new profiler starts // between when it was posted and when it runs. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_IdleShutdownAbort IdleShutdownAbort -#else -#define MAYBE_IdleShutdownAbort DISABLED_IdleShutdownAbort -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_IdleShutdownAbort) { +PROFILER_TEST_F(StackSamplingProfilerTest, IdleShutdownAbort) { WithTargetThread([](PlatformThreadId target_thread_id) { SamplingParams params; @@ -1279,12 +1255,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_IdleShutdownAbort) { } // Checks that synchronized multiple sampling requests execute in parallel. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_ConcurrentProfiling_InSync ConcurrentProfiling_InSync -#else -#define MAYBE_ConcurrentProfiling_InSync DISABLED_ConcurrentProfiling_InSync -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_InSync) { +PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_InSync) { WithTargetThread([](PlatformThreadId target_thread_id) { std::vector<SamplingParams> params(2); @@ -1323,12 +1294,7 @@ TEST_F(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_InSync) { } // Checks that several mixed sampling requests execute in parallel. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_ConcurrentProfiling_Mixed ConcurrentProfiling_Mixed -#else -#define MAYBE_ConcurrentProfiling_Mixed DISABLED_ConcurrentProfiling_Mixed -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_Mixed) { +PROFILER_TEST_F(StackSamplingProfilerTest, ConcurrentProfiling_Mixed) { WithTargetThread([](PlatformThreadId target_thread_id) { std::vector<SamplingParams> params(3); @@ -1364,13 +1330,12 @@ TEST_F(StackSamplingProfilerTest, MAYBE_ConcurrentProfiling_Mixed) { // Checks that a stack that runs through another library produces a stack with // the expected functions. // macOS ASAN is not yet supported - crbug.com/718628. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) && \ - !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) +#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) #define MAYBE_OtherLibrary OtherLibrary #else #define MAYBE_OtherLibrary DISABLED_OtherLibrary #endif -TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) { +PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) { SamplingParams params; params.sampling_interval = TimeDelta::FromMilliseconds(0); params.samples_per_burst = 1; @@ -1437,35 +1402,29 @@ TEST_F(StackSamplingProfilerTest, MAYBE_OtherLibrary) { // Checks that a stack that runs through a library that is unloading produces a // stack, and doesn't crash. // Unloading is synchronous on the Mac, so this test is inapplicable. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) && !defined(OS_MACOSX) +#if !defined(OS_MACOSX) #define MAYBE_UnloadingLibrary UnloadingLibrary #else #define MAYBE_UnloadingLibrary DISABLED_UnloadingLibrary #endif -TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) { +PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadingLibrary) { TestLibraryUnload(false); } // Checks that a stack that runs through a library that has been unloaded // produces a stack, and doesn't crash. // macOS ASAN is not yet supported - crbug.com/718628. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) && \ - !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) +#if !(defined(ADDRESS_SANITIZER) && defined(OS_MACOSX)) #define MAYBE_UnloadedLibrary UnloadedLibrary #else #define MAYBE_UnloadedLibrary DISABLED_UnloadedLibrary #endif -TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { +PROFILER_TEST_F(StackSamplingProfilerTest, MAYBE_UnloadedLibrary) { TestLibraryUnload(true); } // Checks that different threads can be sampled in parallel. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_MultipleSampledThreads MultipleSampledThreads -#else -#define MAYBE_MultipleSampledThreads DISABLED_MultipleSampledThreads -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_MultipleSampledThreads) { +PROFILER_TEST_F(StackSamplingProfilerTest, MultipleSampledThreads) { // Create target threads. The extra parethesis around the StackConfiguration // call are to avoid the most-vexing-parse problem. TargetThread target_thread1((StackConfiguration(StackConfiguration::NORMAL))); @@ -1561,12 +1520,7 @@ class ProfilerThread : public SimpleThread { }; // Checks that different threads can run samplers in parallel. -#if defined(STACK_SAMPLING_PROFILER_SUPPORTED) -#define MAYBE_MultipleProfilerThreads MultipleProfilerThreads -#else -#define MAYBE_MultipleProfilerThreads DISABLED_MultipleProfilerThreads -#endif -TEST_F(StackSamplingProfilerTest, MAYBE_MultipleProfilerThreads) { +PROFILER_TEST_F(StackSamplingProfilerTest, MultipleProfilerThreads) { WithTargetThread([](PlatformThreadId target_thread_id) { // Providing an initial delay makes it more likely that both will be // scheduled before either starts to run. Once started, samples will diff --git a/chromium/base/profiler/tracked_time.cc b/chromium/base/profiler/tracked_time.cc deleted file mode 100644 index 7e0040c03c8..00000000000 --- a/chromium/base/profiler/tracked_time.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/profiler/tracked_time.h" - -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <mmsystem.h> // Declare timeGetTime()... after including build_config. -#endif - -namespace tracked_objects { - -Duration::Duration() : ms_(0) {} -Duration::Duration(int32_t duration) : ms_(duration) {} - -Duration& Duration::operator+=(const Duration& other) { - ms_ += other.ms_; - return *this; -} - -Duration Duration::operator+(const Duration& other) const { - return Duration(ms_ + other.ms_); -} - -bool Duration::operator==(const Duration& other) const { - return ms_ == other.ms_; -} - -bool Duration::operator!=(const Duration& other) const { - return ms_ != other.ms_; -} - -bool Duration::operator>(const Duration& other) const { - return ms_ > other.ms_; -} - -// static -Duration Duration::FromMilliseconds(int ms) { return Duration(ms); } - -int32_t Duration::InMilliseconds() const { - return ms_; -} - -//------------------------------------------------------------------------------ - -TrackedTime::TrackedTime() : ms_(0) {} -TrackedTime::TrackedTime(int32_t ms) : ms_(ms) {} -TrackedTime::TrackedTime(const base::TimeTicks& time) - : ms_(static_cast<int32_t>((time - base::TimeTicks()).InMilliseconds())) {} - -// static -TrackedTime TrackedTime::Now() { - return TrackedTime(base::TimeTicks::Now()); -} - -Duration TrackedTime::operator-(const TrackedTime& other) const { - return Duration(ms_ - other.ms_); -} - -TrackedTime TrackedTime::operator+(const Duration& other) const { - return TrackedTime(ms_ + other.ms_); -} - -bool TrackedTime::is_null() const { return ms_ == 0; } - -} // namespace tracked_objects diff --git a/chromium/base/profiler/tracked_time.h b/chromium/base/profiler/tracked_time.h deleted file mode 100644 index b32f41b39cb..00000000000 --- a/chromium/base/profiler/tracked_time.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_PROFILER_TRACKED_TIME_H_ -#define BASE_PROFILER_TRACKED_TIME_H_ - -#include <stdint.h> - -#include "base/base_export.h" -#include "base/time/time.h" - -namespace tracked_objects { - -//------------------------------------------------------------------------------ - -// TimeTicks maintains a wasteful 64 bits of data (we need less than 32), and on -// windows, a 64 bit timer is expensive to even obtain. We use a simple -// millisecond counter for most of our time values, as well as millisecond units -// of duration between those values. This means we can only handle durations -// up to 49 days (range), or 24 days (non-negative time durations). -// We only define enough methods to service the needs of the tracking classes, -// and our interfaces are modeled after what TimeTicks and TimeDelta use (so we -// can swap them into place if we want to use the "real" classes). - -class BASE_EXPORT Duration { // Similar to base::TimeDelta. - public: - Duration(); - - Duration& operator+=(const Duration& other); - Duration operator+(const Duration& other) const; - - bool operator==(const Duration& other) const; - bool operator!=(const Duration& other) const; - bool operator>(const Duration& other) const; - - static Duration FromMilliseconds(int ms); - - int32_t InMilliseconds() const; - - private: - friend class TrackedTime; - explicit Duration(int32_t duration); - - // Internal time is stored directly in milliseconds. - int32_t ms_; -}; - -class BASE_EXPORT TrackedTime { // Similar to base::TimeTicks. - public: - TrackedTime(); - explicit TrackedTime(const base::TimeTicks& time); - - static TrackedTime Now(); - Duration operator-(const TrackedTime& other) const; - TrackedTime operator+(const Duration& other) const; - bool is_null() const; - - static TrackedTime FromMilliseconds(int32_t ms) { return TrackedTime(ms); } - - private: - friend class Duration; - explicit TrackedTime(int32_t ms); - - // Internal duration is stored directly in milliseconds. - uint32_t ms_; -}; - -} // namespace tracked_objects - -#endif // BASE_PROFILER_TRACKED_TIME_H_ diff --git a/chromium/base/profiler/tracked_time_unittest.cc b/chromium/base/profiler/tracked_time_unittest.cc deleted file mode 100644 index f6d35baab39..00000000000 --- a/chromium/base/profiler/tracked_time_unittest.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Test of classes in tracked_time.cc - -#include <stdint.h> - -#include "base/profiler/tracked_time.h" -#include "base/time/time.h" -#include "base/tracked_objects.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace tracked_objects { - -TEST(TrackedTimeTest, TrackedTimerMilliseconds) { - // First make sure we basicallly transfer simple milliseconds values as - // expected. Most critically, things should not become null. - int32_t kSomeMilliseconds = 243; // Some example times. - int64_t kReallyBigMilliseconds = (1LL << 35) + kSomeMilliseconds; - - TrackedTime some = TrackedTime() + - Duration::FromMilliseconds(kSomeMilliseconds); - EXPECT_EQ(kSomeMilliseconds, (some - TrackedTime()).InMilliseconds()); - EXPECT_FALSE(some.is_null()); - - // Now create a big time, to check that it is wrapped modulo 2^32. - base::TimeTicks big = base::TimeTicks() + - base::TimeDelta::FromMilliseconds(kReallyBigMilliseconds); - EXPECT_EQ(kReallyBigMilliseconds, (big - base::TimeTicks()).InMilliseconds()); - - TrackedTime wrapped_big(big); - // Expect wrapping at 32 bits. - EXPECT_EQ(kSomeMilliseconds, (wrapped_big - TrackedTime()).InMilliseconds()); -} - -TEST(TrackedTimeTest, TrackedTimerDuration) { - int kFirstMilliseconds = 793; - int kSecondMilliseconds = 14889; - - Duration first = Duration::FromMilliseconds(kFirstMilliseconds); - Duration second = Duration::FromMilliseconds(kSecondMilliseconds); - - EXPECT_EQ(kFirstMilliseconds, first.InMilliseconds()); - EXPECT_EQ(kSecondMilliseconds, second.InMilliseconds()); - - Duration sum = first + second; - EXPECT_EQ(kFirstMilliseconds + kSecondMilliseconds, sum.InMilliseconds()); -} - -TEST(TrackedTimeTest, TrackedTimerVsTimeTicks) { - // Make sure that our 32 bit timer is aligned with the TimeTicks() timer. - - // First get a 64 bit timer (which should not be null). - base::TimeTicks ticks_before = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_before.is_null()); - - // Then get a 32 bit timer that can be be null when it wraps. - TrackedTime now = TrackedTime::Now(); - - // Then get a bracketing time. - base::TimeTicks ticks_after = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_after.is_null()); - - // Now make sure that we bracketed our tracked time nicely. - Duration before = now - TrackedTime(ticks_before); - EXPECT_LE(0, before.InMilliseconds()); - Duration after = now - TrackedTime(ticks_after); - EXPECT_GE(0, after.InMilliseconds()); -} - -TEST(TrackedTimeTest, TrackedTimerDisabled) { - // Check to be sure disabling the collection of data induces a null time - // (which we know will return much faster). - ThreadData::InitializeAndSetTrackingStatus(ThreadData::DEACTIVATED); - // Since we disabled tracking, we should get a null response. - TrackedTime track_now = ThreadData::Now(); - EXPECT_TRUE(track_now.is_null()); -} - -TEST(TrackedTimeTest, TrackedTimerEnabled) { - ThreadData::InitializeAndSetTrackingStatus(ThreadData::PROFILING_ACTIVE); - // Make sure that when we enable tracking, we get a real timer result. - - // First get a 64 bit timer (which should not be null). - base::TimeTicks ticks_before = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_before.is_null()); - - // Then get a 32 bit timer that can be null when it wraps. - // Crtical difference from the TrackedTimerVsTimeTicks test, is that we use - // ThreadData::Now(). It can sometimes return the null time. - TrackedTime now = ThreadData::Now(); - - // Then get a bracketing time. - base::TimeTicks ticks_after = base::TimeTicks::Now(); - EXPECT_FALSE(ticks_after.is_null()); - - // Now make sure that we bracketed our tracked time nicely. - Duration before = now - TrackedTime(ticks_before); - EXPECT_LE(0, before.InMilliseconds()); - Duration after = now - TrackedTime(ticks_after); - EXPECT_GE(0, after.InMilliseconds()); -} - -} // namespace tracked_objects |