1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #ifndef SYZYGY_SAMPLER_SAMPLING_PROFILER_H_
16 : #define SYZYGY_SAMPLER_SAMPLING_PROFILER_H_
17 :
18 : #include <vector>
19 :
20 : #include "base/time/time.h"
21 : #include "base/win/scoped_handle.h"
22 :
23 : namespace sampler {
24 :
25 : // This class exposes the functionality of Window's built-in sampling profiler.
26 : // Each profiler instance covers a range of memory, and while the profiler is
27 : // running, its buckets will count the number of times the instruction counter
28 : // lands in the associated range of memory on a sample.
29 : // The sampling interval is settable, but the setting is system-wide.
30 : class SamplingProfiler {
31 : public:
32 : // Create an uninitialized sampling profiler.
33 : SamplingProfiler();
34 : ~SamplingProfiler();
35 :
36 : // Initializes the profiler to cover the memory range |start| through
37 : // |start| + |size|, in the process |process_handle| with bucket size
38 : // |2^log2_bucket_size|, |log2_bucket_size| must be in the range 2-31,
39 : // for bucket sizes of 4 bytes to 2 gigabytes.
40 : // The process handle must grant at least PROCESS_QUERY_INFORMATION.
41 : // The memory range should be exectuable code, like e.g. the text segment
42 : // of an exectuable (whether DLL or EXE).
43 : // Returns true on success.
44 : bool Initialize(HANDLE process_handle,
45 : void* start,
46 : size_t size,
47 : size_t log2_bucket_size);
48 :
49 : // Start this profiler, which must be initialized and not started.
50 : bool Start();
51 : // Stop this profiler, which must be started.
52 : bool Stop();
53 :
54 : // Get and set the sampling interval.
55 : // Note that this is a system-wide setting.
56 : static bool SetSamplingInterval(base::TimeDelta sampling_interval);
57 : static bool GetSamplingInterval(base::TimeDelta* sampling_interval);
58 :
59 : // Accessors.
60 : bool is_started() const { return is_started_; }
61 :
62 : // It is safe to read the counts in the sampling buckets at any time.
63 : // Note however that there's no guarantee that you'll read consistent counts
64 : // until the profiler has been stopped, as the counts may be updating on other
65 : // CPU cores.
66 E : const std::vector<ULONG>& buckets() const { return buckets_; }
67 :
68 : private:
69 : // Handle to the corresponding kernel object.
70 : base::win::ScopedHandle profile_handle_;
71 : // True iff this profiler is started.
72 : bool is_started_;
73 : std::vector<ULONG> buckets_;
74 :
75 : DISALLOW_COPY_AND_ASSIGN(SamplingProfiler);
76 : };
77 :
78 : } // namespace sampler
79 :
80 : #endif // SYZYGY_SAMPLER_SAMPLING_PROFILER_H_
|