blob: 38fe63c3ab00a6288984389e38b8b71ba5a51a42 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#include "base/process.h"
6#include "base/logging.h"
7#include "base/process_util.h"
8#include "base/scoped_ptr.h"
9
10bool 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
18bool 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
27static const int kWinDefaultMinSet = 50 * 4096;
28static const int kWinDefaultMaxSet = 345 * 4096;
29static const int kDampingFactor = 2;
30
31bool 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
73bool 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
87bool Process::EmptyWorkingSet() {
88 if (!process_)
89 return false;
90
91 BOOL rv = SetProcessWorkingSetSize(process_, -1, -1);
92 return rv == TRUE;
93}
94
95int32 Process::pid() const {
96 if (process_ == 0)
97 return 0;
98
99 return process_util::GetProcId(process_);
100}
101
102bool Process::is_current() const {
103 return process_ == GetCurrentProcess();
104}
105
106// static
107Process Process::Current() {
108 return Process(GetCurrentProcess());
109}
license.botf003cfe2008-08-24 09:55:55 +0900110