| 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 |