Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: base/process/process_mac.cc

Issue 2454073003: Allow backgrounding processes on Mac (Closed)
Patch Set: Rename feature and fix comment indentation Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/process.h"
6
7 #include "base/feature_list.h"
8 #include "base/mac/mac_util.h"
9 #include "base/mac/mach_logging.h"
10
11 #include <mach/mach.h>
12
13 // The following was added to <mach/task_policy.h> after 10.8.
14 // TODO(shrike): Remove the TASK_OVERRIDE_QOS_POLICY ifndef once builders
Robert Sesek 2016/11/03 20:18:42 I think this may have happened! https://bugs.chrom
lgrey 2016/11/04 16:09:40 Done.
15 // reach 10.9 or higher.
16 #ifndef TASK_OVERRIDE_QOS_POLICY
17
18 #define TASK_OVERRIDE_QOS_POLICY 9
19
20 typedef struct task_category_policy task_category_policy_data_t;
21 typedef struct task_category_policy* task_category_policy_t;
22
23 enum task_latency_qos {
24 LATENCY_QOS_TIER_UNSPECIFIED = 0x0,
25 LATENCY_QOS_TIER_0 = ((0xFF << 16) | 1),
26 LATENCY_QOS_TIER_1 = ((0xFF << 16) | 2),
27 LATENCY_QOS_TIER_2 = ((0xFF << 16) | 3),
28 LATENCY_QOS_TIER_3 = ((0xFF << 16) | 4),
29 LATENCY_QOS_TIER_4 = ((0xFF << 16) | 5),
30 LATENCY_QOS_TIER_5 = ((0xFF << 16) | 6)
31 };
32 typedef integer_t task_latency_qos_t;
33 enum task_throughput_qos {
34 THROUGHPUT_QOS_TIER_UNSPECIFIED = 0x0,
35 THROUGHPUT_QOS_TIER_0 = ((0xFE << 16) | 1),
36 THROUGHPUT_QOS_TIER_1 = ((0xFE << 16) | 2),
37 THROUGHPUT_QOS_TIER_2 = ((0xFE << 16) | 3),
38 THROUGHPUT_QOS_TIER_3 = ((0xFE << 16) | 4),
39 THROUGHPUT_QOS_TIER_4 = ((0xFE << 16) | 5),
40 THROUGHPUT_QOS_TIER_5 = ((0xFE << 16) | 6),
41 };
42
43 #define LATENCY_QOS_LAUNCH_DEFAULT_TIER LATENCY_QOS_TIER_3
44 #define THROUGHPUT_QOS_LAUNCH_DEFAULT_TIER THROUGHPUT_QOS_TIER_3
45
46 typedef integer_t task_throughput_qos_t;
47
48 struct task_qos_policy {
49 task_latency_qos_t task_latency_qos_tier;
50 task_throughput_qos_t task_throughput_qos_tier;
51 };
52
53 typedef struct task_qos_policy* task_qos_policy_t;
54 #define TASK_QOS_POLICY_COUNT \
55 ((mach_msg_type_number_t)(sizeof(struct task_qos_policy) / sizeof(integer_t)))
56
57 #endif // TASK_OVERRIDE_QOS_POLICY
58
59 namespace base {
60
61 // Enables backgrounding hidden renderers on Mac.
62 const Feature kMacAllowBackgroundingProcesses{
63 "MacAllowBackgroundingProcesses", FEATURE_DISABLED_BY_DEFAULT};
64
65 bool Process::CanBackgroundProcesses() {
66 return FeatureList::IsEnabled(kMacAllowBackgroundingProcesses);
67 }
68
69 bool Process::IsProcessBackgrounded(PortProvider* port_provider) const {
70 DCHECK(IsValid());
71 if (port_provider == nullptr || !CanBackgroundProcesses())
72 return false;
73
74 mach_port_t task_port = port_provider->TaskForPid(Pid());
75 if (task_port == TASK_NULL)
76 return false;
77
78 task_category_policy_data_t category_policy;
79 mach_msg_type_number_t task_info_count = TASK_CATEGORY_POLICY_COUNT;
80 boolean_t get_default = FALSE;
81
82 kern_return_t result =
83 task_policy_get(task_port, TASK_CATEGORY_POLICY,
84 reinterpret_cast<task_policy_t>(&category_policy),
85 &task_info_count, &get_default);
86 MACH_LOG_IF(ERROR, result != KERN_SUCCESS, result)
87 << "task_policy_get TASK_CATEGORY_POLICY";
88
89 if (result == KERN_SUCCESS && get_default == FALSE) {
90 return category_policy.role == TASK_BACKGROUND_APPLICATION;
91 }
92 return false;
93 }
94
95 bool Process::SetProcessBackgrounded(PortProvider* port_provider,
96 bool background) {
97 DCHECK(IsValid());
98 if (port_provider == nullptr)
99 return false;
100
101 mach_port_t task_port = port_provider->TaskForPid(Pid());
102 if (task_port == TASK_NULL)
103 return false;
104
105 if (!CanBackgroundProcesses()) {
106 return false;
107 } else if (IsProcessBackgrounded(port_provider) == background) {
108 return true;
109 }
110
111 task_category_policy category_policy;
112 category_policy.role =
113 background ? TASK_BACKGROUND_APPLICATION : TASK_FOREGROUND_APPLICATION;
114 kern_return_t result =
115 task_policy_set(task_port, TASK_CATEGORY_POLICY,
116 reinterpret_cast<task_policy_t>(&category_policy),
117 TASK_CATEGORY_POLICY_COUNT);
118
119 if (result != KERN_SUCCESS) {
120 MACH_LOG(ERROR, result) << "task_policy_set TASK_CATEGORY_POLICY";
121 return false;
122 } else if (!mac::IsAtLeastOS10_9()) {
Robert Sesek 2016/11/03 20:18:42 This is always true.
lgrey 2016/11/04 16:09:40 Done.
123 return true;
124 }
125
126 // Latency QoS regulates timer throttling/accuracy. Select default tier
127 // on foreground because precise timer firing isn't needed.
128 struct task_qos_policy qos_policy = {
129 background ? LATENCY_QOS_TIER_5 : LATENCY_QOS_TIER_UNSPECIFIED,
130 background ? THROUGHPUT_QOS_TIER_5 : THROUGHPUT_QOS_TIER_UNSPECIFIED};
131 result = task_policy_set(task_port, TASK_OVERRIDE_QOS_POLICY,
132 reinterpret_cast<task_policy_t>(&qos_policy),
133 TASK_QOS_POLICY_COUNT);
134 if (result != KERN_SUCCESS) {
135 MACH_LOG(ERROR, result) << "task_policy_set TASK_OVERRIDE_QOS_POLICY";
136 return false;
137 }
138
139 return true;
140 }
141
142 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698