OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/process.h" | |
6 #include "base/logging.h" | |
7 #include "base/process_util.h" | |
8 #include "base/scoped_ptr.h" | |
9 | |
10 bool Process::IsProcessBackgrounded() { | |
11 DCHECK(process_); | |
12 DWORD priority = GetPriorityClass(process_); | |
13 if (priority == 0) | |
14 return false; // Failure case. | |
15 return priority == BELOW_NORMAL_PRIORITY_CLASS; | |
16 } | |
17 | |
18 bool Process::SetProcessBackgrounded(bool value) { | |
19 DCHECK(process_); | |
20 DWORD priority = value ? BELOW_NORMAL_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS; | |
21 return (SetPriorityClass(process_, priority) != 0); | |
22 } | |
23 | |
24 // According to MSDN, these are the default values which XP | |
25 // uses to govern working set soft limits. | |
26 // http://msdn.microsoft.com/en-us/library/ms686234.aspx | |
27 static const int kWinDefaultMinSet = 50 * 4096; | |
28 static const int kWinDefaultMaxSet = 345 * 4096; | |
29 static const int kDampingFactor = 2; | |
30 | |
31 bool Process::ReduceWorkingSet() { | |
32 if (!process_) | |
33 return false; | |
34 // The idea here is that when we the process' working set has gone | |
35 // down, we want to release those pages to the OS quickly. However, | |
36 // when it is not going down, we want to be careful not to release | |
37 // too much back to the OS, as it could cause additional paging. | |
38 | |
39 // We use a damping function to lessen the working set over time. | |
40 // As the process grows/shrinks, this algorithm will lag with | |
41 // working set reduction. | |
42 // | |
43 // The intended algorithm is: | |
44 // TargetWorkingSetSize = (LastWorkingSet/2 + CurrentWorkingSet) /2 | |
45 | |
46 scoped_ptr<process_util::ProcessMetrics> metrics( | |
47 process_util::ProcessMetrics::CreateProcessMetrics(process_)); | |
48 process_util::WorkingSetKBytes working_set; | |
49 if (!metrics->GetWorkingSetKBytes(&working_set)) | |
50 return false; | |
51 | |
52 | |
53 // We want to compute the amount of working set that the process | |
54 // needs to keep in memory. Since other processes contain the | |
55 // pages which are shared, we don't need to reserve them in our | |
56 // process, the system already has them tagged. Keep in mind, we | |
57 // don't get to control *which* pages get released, but if we | |
58 // assume reasonable distribution of pages, this should generally | |
59 // be the right value. | |
60 size_t current_working_set_size = working_set.priv + | |
61 working_set.shareable; | |
62 | |
63 size_t max_size = current_working_set_size; | |
64 if (last_working_set_size_) | |
65 max_size = (max_size + last_working_set_size_) / 2; // Average. | |
66 max_size *= 1024; // Convert to KBytes. | |
67 last_working_set_size_ = current_working_set_size / kDampingFactor; | |
68 | |
69 BOOL rv = SetProcessWorkingSetSize(process_, kWinDefaultMinSet, max_size); | |
70 return rv == TRUE; | |
71 } | |
72 | |
73 bool Process::UnReduceWorkingSet() { | |
74 if (!process_) | |
75 return false; | |
76 | |
77 if (!last_working_set_size_) | |
78 return true; // There was nothing to undo. | |
79 | |
80 // We've had a reduced working set. Make sure we have lots of | |
81 // headroom now that we're active again. | |
82 size_t limit = last_working_set_size_ * kDampingFactor * 2 * 1024; | |
83 BOOL rv = SetProcessWorkingSetSize(process_, kWinDefaultMinSet, limit); | |
84 return rv == TRUE; | |
85 } | |
86 | |
87 bool Process::EmptyWorkingSet() { | |
88 if (!process_) | |
89 return false; | |
90 | |
91 BOOL rv = SetProcessWorkingSetSize(process_, -1, -1); | |
92 return rv == TRUE; | |
93 } | |
94 | |
95 int32 Process::pid() const { | |
96 if (process_ == 0) | |
97 return 0; | |
98 | |
99 return process_util::GetProcId(process_); | |
100 } | |
101 | |
102 bool Process::is_current() const { | |
103 return process_ == GetCurrentProcess(); | |
104 } | |
105 | |
106 // static | |
107 Process Process::Current() { | |
108 return Process(GetCurrentProcess()); | |
109 } | |
110 | |
OLD | NEW |