1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_METRICS_CALL_STACKS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_ 6 #define COMPONENTS_METRICS_CALL_STACKS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/memory/ref_counted.h" 12 #include "base/synchronization/lock.h" 13 #include "base/task/single_thread_task_runner.h" 14 #include "base/time/time.h" 15 #include "components/metrics/public/mojom/call_stack_profile_collector.mojom.h" 16 #include "mojo/public/cpp/bindings/pending_remote.h" 17 #include "mojo/public/cpp/bindings/remote.h" 18 19 namespace service_manager { 20 class InterfaceProvider; 21 } 22 23 namespace metrics { 24 25 class SampledProfile; 26 27 // ChildCallStackProfileCollector collects stacks at startup, caching them 28 // internally until a CallStackProfileCollector interface is available. If a 29 // CallStackProfileCollector is provided via the InterfaceProvider supplied to 30 // SetParentProfileCollector, the cached stacks are sent via that interface. All 31 // future stacks received via callbacks supplied by GetProfilerCallback are sent 32 // via that interface as well. 33 // 34 // If no CallStackProfileCollector is provided via InterfaceProvider, any cached 35 // stacks and all future stacks received via callbacks supplied by 36 // GetProfilerCallback are flushed. In typical usage this should not happen 37 // because the browser is expected to always supply a CallStackProfileCollector. 38 // 39 // This class is only necessary if a CallStackProfileCollector is not available 40 // at the time the profiler is created. Otherwise the CallStackProfileCollector 41 // can be used directly. 42 // 43 // CallStackProfileBuilder owns and manages a ChildCallStackProfileCollector. It 44 // invokes Collect() in CallStackProfileBuilder::OnProfileCompleted() to collect 45 // a profile. 46 // 47 // When the mojo InterfaceProvider becomes available, provide it via 48 // SetParentProfileCollector(). 49 class ChildCallStackProfileCollector { 50 public: 51 ChildCallStackProfileCollector(); 52 53 ChildCallStackProfileCollector(const ChildCallStackProfileCollector&) = 54 delete; 55 ChildCallStackProfileCollector& operator=( 56 const ChildCallStackProfileCollector&) = delete; 57 58 ~ChildCallStackProfileCollector(); 59 60 // Sets the CallStackProfileCollector interface from |parent_collector|. This 61 // function MUST be invoked exactly once, regardless of whether 62 // |parent_collector| is mojo::NullRemote(), as it flushes pending data in 63 // either case. 64 void SetParentProfileCollector( 65 mojo::PendingRemote<metrics::mojom::CallStackProfileCollector> 66 parent_collector); 67 68 // Collects |profile| whose collection start time is |start_timestamp|. 69 void Collect(base::TimeTicks start_timestamp, SampledProfile profile); 70 71 private: 72 friend class ChildCallStackProfileCollectorTest; 73 74 // Bundles together a collected serialized profile and the collection state 75 // for storage, pending availability of the parent mojo interface. 76 struct ProfileState { 77 ProfileState(); 78 // |profile| can be very large and must be passed with std::move. 79 ProfileState(base::TimeTicks start_timestamp, 80 mojom::ProfileType profile_type, 81 std::string&& profile); 82 83 ProfileState(const ProfileState&) = delete; 84 ProfileState& operator=(const ProfileState&) = delete; 85 86 ProfileState(ProfileState&&); 87 88 ~ProfileState(); 89 90 ProfileState& operator=(ProfileState&&); 91 92 base::TimeTicks start_timestamp; 93 mojom::ProfileType profile_type; 94 95 // The serialized sampled profile. 96 std::string profile; 97 }; 98 99 // This object may be accessed on any thread, including the profiler 100 // thread. The expected use case for the object is to be created and have 101 // GetProfilerCallback before the message loop starts, which prevents the use 102 // of PostTask and the like for inter-thread communication. 103 base::Lock lock_; 104 105 // Whether to retain the profile when the interface is not set. Remains true 106 // until the invocation of SetParentProfileCollector(), at which point it is 107 // false for the rest of the object lifetime. 108 bool retain_profiles_ = true; 109 110 // The task runner associated with the parent interface. 111 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 112 113 // The interface to use to collect the stack profiles provided to this 114 // object. Initially mojo::NullRemote() until SetParentProfileCollector() is 115 // invoked, at which point it may either become set or remain 116 // mojo::NullRemote(). If set, stacks are collected via the interface, 117 // otherwise they are ignored. 118 mojo::Remote<mojom::CallStackProfileCollector> parent_collector_; 119 120 // Profiles being cached by this object, pending a parent interface to be 121 // supplied. 122 std::vector<ProfileState> profiles_; 123 }; 124 125 } // namespace metrics 126 127 #endif // COMPONENTS_METRICS_CALL_STACKS_CHILD_CALL_STACK_PROFILE_COLLECTOR_H_ 128