Chromium Code Reviews| Index: base/threading/platform_thread_mac.mm |
| =================================================================== |
| --- base/threading/platform_thread_mac.mm (revision 84711) |
| +++ base/threading/platform_thread_mac.mm (working copy) |
| @@ -1,4 +1,4 @@ |
| -// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| @@ -6,6 +6,9 @@ |
| #import <Foundation/Foundation.h> |
| #include <dlfcn.h> |
| +#include <mach/mach.h> |
| +#include <mach/mach_time.h> |
| +#include <mach/thread_policy.h> |
| #include "base/logging.h" |
| @@ -51,4 +54,95 @@ |
| dynamic_pthread_setname_np(shortened_name.c_str()); |
| } |
| +namespace { |
| + |
| +void SetPriorityNormal(mach_port_t mach_thread_id) { |
| + // Make thread standard policy. |
| + thread_standard_policy policy; |
| + kern_return_t result = thread_policy_set(mach_thread_id, |
| + THREAD_STANDARD_POLICY, |
| + (thread_policy_t)&policy, |
| + THREAD_STANDARD_POLICY_COUNT); |
| + |
| + DCHECK_EQ(KERN_SUCCESS, result); |
| +} |
| + |
| +// Enables time-contraint policy and priority suitable for low-latency, |
| +// glitch-resistant audio. |
| +void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { |
| + kern_return_t result; |
| + |
| + // Increase thread priority to real-time. |
| + |
| + // Make thread fixed priority. |
| + thread_extended_policy_data_t policy; |
| + policy.timeshare = 0; // set to 1 for a non-fixed thread |
|
brettw
2011/05/12 22:26:03
This should be a complete sentence w/ capitals and
Chris Rogers
2011/05/12 23:01:55
Done.
|
| + result = thread_policy_set(mach_thread_id, |
| + THREAD_EXTENDED_POLICY, |
| + (thread_policy_t)&policy, |
| + THREAD_EXTENDED_POLICY_COUNT); |
| + |
| + DCHECK_EQ(KERN_SUCCESS, result); |
| + |
| + // Set to relatively high priority. |
| + thread_precedence_policy_data_t precedence; |
| + precedence.importance = 63; |
| + result = thread_policy_set(mach_thread_id, |
| + THREAD_PRECEDENCE_POLICY, |
| + (thread_policy_t)&precedence, |
| + THREAD_PRECEDENCE_POLICY_COUNT); |
| + DCHECK_EQ(KERN_SUCCESS, result); |
| + |
| + // Most important, set real-time constraints. |
| + |
| + // Define constants determining how much time we will be guaranteed. |
| + // All times are in milliseconds. |
| + |
| + // About 128 frames @44.1KHz |
| + const double kTimeQuantum = 2.9; |
| + |
| + // Time guaranteed each quantum. 75% Duty cycle. |
| + const double kAudioTimeNeeded = 0.75 * kTimeQuantum; |
| + |
| + // Maximum time allowed for work. |
| + const double kMaxTimeAllowed = 0.85 * kTimeQuantum; |
|
brettw
2011/05/12 22:26:03
All of these numbers look magic. Where did you get
Chris Rogers
2011/05/12 23:01:55
I've added comments and defined more constants to
|
| + |
| + // Get the conversion factor from milliseconds to absolute time |
| + // which is what the time-constraints call needs. |
| + mach_timebase_info_data_t tb_info; |
| + mach_timebase_info(&tb_info); |
| + double msToAbsTime = |
|
brettw
2011/05/12 22:26:03
Should should use lowercase_with_underscores.
Chris Rogers
2011/05/12 23:01:55
Done.
|
| + ((double)tb_info.denom / (double)tb_info.numer) * 1000000; |
| + |
| + thread_time_constraint_policy_data_t time_constraints; |
| + time_constraints.period = kTimeQuantum * msToAbsTime; |
| + time_constraints.computation = kAudioTimeNeeded * msToAbsTime; |
| + time_constraints.constraint = kMaxTimeAllowed * msToAbsTime; |
| + time_constraints.preemptible = 0; |
| + |
| + result = thread_policy_set(mach_thread_id, |
| + THREAD_TIME_CONSTRAINT_POLICY, |
| + (thread_policy_t)&time_constraints, |
| + THREAD_TIME_CONSTRAINT_POLICY_COUNT); |
| + DCHECK_EQ(KERN_SUCCESS, result); |
| +} |
| + |
| +} // anonymous namespace |
| + |
| +// static |
| +void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, |
| + ThreadPriority priority) { |
| + // Convert from pthread_t to mach thread identifier. |
| + mach_port_t mach_thread_id = pthread_mach_thread_np(handle); |
| + |
| + switch (priority) { |
| + case kThreadPriority_Normal: |
| + SetPriorityNormal(mach_thread_id); |
| + break; |
| + case kThreadPriority_RealtimeAudio: |
| + SetPriorityRealtimeAudio(mach_thread_id); |
| + break; |
| + } |
| +} |
| + |
| } // namespace base |