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/basictypes.h"
21 : #include "base/time/time.h"
22 : #include "base/win/scoped_handle.h"
23 :
24 : namespace sampler {
25 :
26 : // This class exposes the functionality of Window's built-in sampling profiler.
27 : // Each profiler instance covers a range of memory, and while the profiler is
28 : // running, its buckets will count the number of times the instruction counter
29 : // lands in the associated range of memory on a sample.
30 : // The sampling interval is settable, but the setting is system-wide.
31 : class SamplingProfiler {
32 : public:
33 : // Create an uninitialized sampling profiler.
34 : SamplingProfiler();
35 : ~SamplingProfiler();
36 :
37 : // Initializes the profiler to cover the memory range |start| through
38 : // |start| + |size|, in the process |process_handle| with bucket size
39 : // |2^log2_bucket_size|, |log2_bucket_size| must be in the range 2-31,
40 : // for bucket sizes of 4 bytes to 2 gigabytes.
41 : // The process handle must grant at least PROCESS_QUERY_INFORMATION.
42 : // The memory range should be exectuable code, like e.g. the text segment
43 : // of an exectuable (whether DLL or EXE).
44 : // Returns true on success.
45 : bool Initialize(HANDLE process_handle,
46 : void* start,
47 : size_t size,
48 : size_t log2_bucket_size);
49 :
50 : // Start this profiler, which must be initialized and not started.
51 : bool Start();
52 : // Stop this profiler, which must be started.
53 : bool Stop();
54 :
55 : // Get and set the sampling interval.
56 : // Note that this is a system-wide setting.
57 : static bool SetSamplingInterval(base::TimeDelta sampling_interval);
58 : static bool GetSamplingInterval(base::TimeDelta* sampling_interval);
59 :
60 : // Accessors.
61 : bool is_started() const { return is_started_; }
62 :
63 : // It is safe to read the counts in the sampling buckets at any time.
64 : // Note however that there's no guarantee that you'll read consistent counts
65 : // until the profiler has been stopped, as the counts may be updating on other
66 : // CPU cores.
67 E : const std::vector<ULONG>& buckets() const { return buckets_; }
68 :
69 : private:
70 : // Handle to the corresponding kernel object.
71 : base::win::ScopedHandle profile_handle_;
72 : // True iff this profiler is started.
73 : bool is_started_;
74 : std::vector<ULONG> buckets_;
75 :
76 : DISALLOW_COPY_AND_ASSIGN(SamplingProfiler);
77 : };
78 :
79 : } // namespace sampler
80 :
81 : #endif // SYZYGY_SAMPLER_SAMPLING_PROFILER_H_
|