1 : // Copyright 2011 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 : // Implementation class to gather per-process, per-module working set
16 : // statistics.
17 :
18 : #ifndef SYZYGY_WSDUMP_PROCESS_WORKING_SET_H_
19 : #define SYZYGY_WSDUMP_PROCESS_WORKING_SET_H_
20 :
21 : #include <windows.h>
22 : #include <string>
23 : #include <vector>
24 :
25 : #include "base/memory/scoped_ptr.h"
26 :
27 : namespace core {
28 : template <typename AddressType, typename SizeType, typename ItemType>
29 : class AddressSpace;
30 : };
31 : struct _PSAPI_WORKING_SET_INFORMATION;
32 : typedef struct _PSAPI_WORKING_SET_INFORMATION PSAPI_WORKING_SET_INFORMATION;
33 :
34 : namespace wsdump {
35 :
36 : // Captures working set for a given process at a point in time,
37 : // summarizes per-module as well as overall statistics.
38 : class ProcessWorkingSet {
39 : public:
40 : // Non-module stats.
41 : struct Stats {
42 E : Stats() { memset(this, 0, sizeof(*this)); }
43 :
44 : size_t pages;
45 : size_t shareable_pages;
46 : size_t shared_pages;
47 : size_t read_only_pages;
48 : size_t writable_pages;
49 : size_t executable_pages;
50 : };
51 :
52 : // Per-module stats.
53 : struct ModuleStats : public Stats {
54 : std::wstring module_name;
55 : };
56 : typedef std::vector<ModuleStats> ModuleStatsVector;
57 :
58 : // Initialize working set statistics for the given process_id.
59 : // @returns true on success, false on failure.
60 : // @note total_stats(), non_module_stats() and module_stats() are valid only
61 : // after a successful call call to Initialize.
62 : bool Initialize(DWORD process_id);
63 :
64 : // @returns overall tally for the whole process.
65 E : const Stats& total_stats() const { return total_stats_; }
66 :
67 : // @returns tally for working set pages that don't belong to modules,
68 : // e.g. pages that belong to heaps, stacks, mapped files, etc.
69 E : const Stats& non_module_stats() const { return non_module_stats_; }
70 :
71 : // @returns per module tallies.
72 E : const ModuleStatsVector& module_stats() const { return module_stats_; }
73 :
74 : protected:
75 : // These are protected members to allow unittesting them.
76 : typedef scoped_ptr<PSAPI_WORKING_SET_INFORMATION> ScopedWsPtr;
77 : static bool CaptureWorkingSet(HANDLE process, ScopedWsPtr* working_set);
78 :
79 : typedef core::AddressSpace<size_t, size_t, std::wstring> ModuleAddressSpace;
80 : static bool CaptureModules(DWORD process_id, ModuleAddressSpace* modules);
81 :
82 : // Storage for stats.
83 : Stats total_stats_;
84 : Stats non_module_stats_;
85 : ModuleStatsVector module_stats_;
86 : };
87 :
88 : } // namespace wsdump
89 :
90 : #endif // SYZYGY_WSDUMP_PROCESS_WORKING_SET_H_
|