OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/threading/platform_thread.h" | 5 #include "base/threading/platform_thread.h" |
6 | 6 |
7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
8 #include <dlfcn.h> | 8 #include <dlfcn.h> |
9 #include <mach/mach.h> | 9 #include <mach/mach.h> |
10 #include <mach/mach_time.h> | 10 #include <mach/mach_time.h> |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 // Make thread standard policy. | 70 // Make thread standard policy. |
71 // Please note that this call could fail in rare cases depending | 71 // Please note that this call could fail in rare cases depending |
72 // on runtime conditions. | 72 // on runtime conditions. |
73 thread_standard_policy policy; | 73 thread_standard_policy policy; |
74 kern_return_t result = thread_policy_set(mach_thread_id, | 74 kern_return_t result = thread_policy_set(mach_thread_id, |
75 THREAD_STANDARD_POLICY, | 75 THREAD_STANDARD_POLICY, |
76 (thread_policy_t)&policy, | 76 (thread_policy_t)&policy, |
77 THREAD_STANDARD_POLICY_COUNT); | 77 THREAD_STANDARD_POLICY_COUNT); |
78 | 78 |
79 if (result != KERN_SUCCESS) | 79 if (result != KERN_SUCCESS) |
80 VLOG(1) << "thread_policy_set() failure: " << result; | 80 DVLOG(1) << "thread_policy_set() failure: " << result; |
81 } | 81 } |
82 | 82 |
83 // Enables time-contraint policy and priority suitable for low-latency, | 83 // Enables time-contraint policy and priority suitable for low-latency, |
84 // glitch-resistant audio. | 84 // glitch-resistant audio. |
85 void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { | 85 void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { |
86 kern_return_t result; | 86 kern_return_t result; |
87 | 87 |
88 // Increase thread priority to real-time. | 88 // Increase thread priority to real-time. |
89 | 89 |
90 // Please note that the thread_policy_set() calls may fail in | 90 // Please note that the thread_policy_set() calls may fail in |
91 // rare cases if the kernel decides the system is under heavy load | 91 // rare cases if the kernel decides the system is under heavy load |
92 // and is unable to handle boosting the thread priority. | 92 // and is unable to handle boosting the thread priority. |
93 // In these cases we just return early and go on with life. | 93 // In these cases we just return early and go on with life. |
94 | 94 |
95 // Make thread fixed priority. | 95 // Make thread fixed priority. |
96 thread_extended_policy_data_t policy; | 96 thread_extended_policy_data_t policy; |
97 policy.timeshare = 0; // Set to 1 for a non-fixed thread. | 97 policy.timeshare = 0; // Set to 1 for a non-fixed thread. |
98 result = thread_policy_set(mach_thread_id, | 98 result = thread_policy_set(mach_thread_id, |
99 THREAD_EXTENDED_POLICY, | 99 THREAD_EXTENDED_POLICY, |
100 (thread_policy_t)&policy, | 100 (thread_policy_t)&policy, |
101 THREAD_EXTENDED_POLICY_COUNT); | 101 THREAD_EXTENDED_POLICY_COUNT); |
102 if (result != KERN_SUCCESS) { | 102 if (result != KERN_SUCCESS) { |
103 VLOG(1) << "thread_policy_set() failure: " << result; | 103 DVLOG(1) << "thread_policy_set() failure: " << result; |
104 return; | 104 return; |
105 } | 105 } |
106 | 106 |
107 // Set to relatively high priority. | 107 // Set to relatively high priority. |
108 thread_precedence_policy_data_t precedence; | 108 thread_precedence_policy_data_t precedence; |
109 precedence.importance = 63; | 109 precedence.importance = 63; |
110 result = thread_policy_set(mach_thread_id, | 110 result = thread_policy_set(mach_thread_id, |
111 THREAD_PRECEDENCE_POLICY, | 111 THREAD_PRECEDENCE_POLICY, |
112 (thread_policy_t)&precedence, | 112 (thread_policy_t)&precedence, |
113 THREAD_PRECEDENCE_POLICY_COUNT); | 113 THREAD_PRECEDENCE_POLICY_COUNT); |
114 if (result != KERN_SUCCESS) { | 114 if (result != KERN_SUCCESS) { |
115 VLOG(1) << "thread_policy_set() failure: " << result; | 115 DVLOG(1) << "thread_policy_set() failure: " << result; |
116 return; | 116 return; |
117 } | 117 } |
118 | 118 |
119 // Most important, set real-time constraints. | 119 // Most important, set real-time constraints. |
120 | 120 |
121 // Define the guaranteed and max fraction of time for the audio thread. | 121 // Define the guaranteed and max fraction of time for the audio thread. |
122 // These "duty cycle" values can range from 0 to 1. A value of 0.5 | 122 // These "duty cycle" values can range from 0 to 1. A value of 0.5 |
123 // means the scheduler would give half the time to the thread. | 123 // means the scheduler would give half the time to the thread. |
124 // These values have empirically been found to yield good behavior. | 124 // These values have empirically been found to yield good behavior. |
125 // Good means that audio performance is high and other threads won't starve. | 125 // Good means that audio performance is high and other threads won't starve. |
(...skipping 23 matching lines...) Expand all Loading... |
149 time_constraints.period = kTimeQuantum * ms_to_abs_time; | 149 time_constraints.period = kTimeQuantum * ms_to_abs_time; |
150 time_constraints.computation = kAudioTimeNeeded * ms_to_abs_time; | 150 time_constraints.computation = kAudioTimeNeeded * ms_to_abs_time; |
151 time_constraints.constraint = kMaxTimeAllowed * ms_to_abs_time; | 151 time_constraints.constraint = kMaxTimeAllowed * ms_to_abs_time; |
152 time_constraints.preemptible = 0; | 152 time_constraints.preemptible = 0; |
153 | 153 |
154 result = thread_policy_set(mach_thread_id, | 154 result = thread_policy_set(mach_thread_id, |
155 THREAD_TIME_CONSTRAINT_POLICY, | 155 THREAD_TIME_CONSTRAINT_POLICY, |
156 (thread_policy_t)&time_constraints, | 156 (thread_policy_t)&time_constraints, |
157 THREAD_TIME_CONSTRAINT_POLICY_COUNT); | 157 THREAD_TIME_CONSTRAINT_POLICY_COUNT); |
158 if (result != KERN_SUCCESS) | 158 if (result != KERN_SUCCESS) |
159 VLOG(1) << "thread_policy_set() failure: " << result; | 159 DVLOG(1) << "thread_policy_set() failure: " << result; |
160 | 160 |
161 return; | 161 return; |
162 } | 162 } |
163 | 163 |
164 } // anonymous namespace | 164 } // anonymous namespace |
165 | 165 |
166 // static | 166 // static |
167 void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, | 167 void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, |
168 ThreadPriority priority) { | 168 ThreadPriority priority) { |
169 // Convert from pthread_t to mach thread identifier. | 169 // Convert from pthread_t to mach thread identifier. |
170 mach_port_t mach_thread_id = pthread_mach_thread_np(handle); | 170 mach_port_t mach_thread_id = pthread_mach_thread_np(handle); |
171 | 171 |
172 switch (priority) { | 172 switch (priority) { |
173 case kThreadPriority_Normal: | 173 case kThreadPriority_Normal: |
174 SetPriorityNormal(mach_thread_id); | 174 SetPriorityNormal(mach_thread_id); |
175 break; | 175 break; |
176 case kThreadPriority_RealtimeAudio: | 176 case kThreadPriority_RealtimeAudio: |
177 SetPriorityRealtimeAudio(mach_thread_id); | 177 SetPriorityRealtimeAudio(mach_thread_id); |
178 break; | 178 break; |
179 } | 179 } |
180 } | 180 } |
181 | 181 |
182 } // namespace base | 182 } // namespace base |
OLD | NEW |