summaryrefslogtreecommitdiffstats
path: root/base/threading
diff options
context:
space:
mode:
authorcrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-17 20:01:25 +0000
committercrogers@google.com <crogers@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-17 20:01:25 +0000
commitabb9efae9c9aec7df42c499025a06ac2524d5322 (patch)
tree10e2c6e65a992f2e3d96aa8acb9e21b9f95fef74 /base/threading
parent35a85c05edb0047a99610f94857d974af1082977 (diff)
downloadchromium_src-abb9efae9c9aec7df42c499025a06ac2524d5322.zip
chromium_src-abb9efae9c9aec7df42c499025a06ac2524d5322.tar.gz
chromium_src-abb9efae9c9aec7df42c499025a06ac2524d5322.tar.bz2
Add support for real-time audio threads.
BUG=none TEST=none (tested locally on Mac OS X) Review URL: http://codereview.chromium.org/6949009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85663 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/threading')
-rw-r--r--base/threading/platform_thread.h10
-rw-r--r--base/threading/platform_thread_mac.mm104
-rw-r--r--base/threading/platform_thread_posix.cc10
-rw-r--r--base/threading/platform_thread_win.cc8
-rw-r--r--base/threading/simple_thread.h6
5 files changed, 136 insertions, 2 deletions
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index 40d445f..230d209 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -47,6 +47,13 @@ typedef pid_t PlatformThreadId;
const PlatformThreadId kInvalidThreadId = 0;
+// Valid values for SetThreadPriority()
+enum ThreadPriority{
+ kThreadPriority_Normal,
+ // Suitable for low-latency, glitch-resistant audio.
+ kThreadPriority_RealtimeAudio
+};
+
// A namespace for low-level thread functions.
class BASE_API PlatformThread {
public:
@@ -91,6 +98,9 @@ class BASE_API PlatformThread {
// |thread_handle|.
static void Join(PlatformThreadHandle thread_handle);
+ static void SetThreadPriority(PlatformThreadHandle handle,
+ ThreadPriority priority);
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread);
};
diff --git a/base/threading/platform_thread_mac.mm b/base/threading/platform_thread_mac.mm
index d77307c5..7d59064 100644
--- a/base/threading/platform_thread_mac.mm
+++ b/base/threading/platform_thread_mac.mm
@@ -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,103 @@ void PlatformThread::SetName(const char* name) {
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.
+ 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 the guaranteed and max fraction of time for the audio thread.
+ // These "duty cycle" values can range from 0 to 1. A value of 0.5
+ // means the scheduler would give half the time to the thread.
+ // These values have empirically been found to yield good behavior.
+ // Good means that audio performance is high and other threads won't starve.
+ const double kGuaranteedAudioDutyCycle = 0.75;
+ const double kMaxAudioDutyCycle = 0.85;
+
+ // Define constants determining how much time the audio thread can
+ // use in a given time quantum. All times are in milliseconds.
+
+ // About 128 frames @44.1KHz
+ const double kTimeQuantum = 2.9;
+
+ // Time guaranteed each quantum.
+ const double kAudioTimeNeeded = kGuaranteedAudioDutyCycle * kTimeQuantum;
+
+ // Maximum time each quantum.
+ const double kMaxTimeAllowed = kMaxAudioDutyCycle * kTimeQuantum;
+
+ // 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 ms_to_abs_time =
+ ((double)tb_info.denom / (double)tb_info.numer) * 1000000;
+
+ thread_time_constraint_policy_data_t time_constraints;
+ time_constraints.period = kTimeQuantum * ms_to_abs_time;
+ time_constraints.computation = kAudioTimeNeeded * ms_to_abs_time;
+ time_constraints.constraint = kMaxTimeAllowed * ms_to_abs_time;
+ 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
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index e880222..526e782 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -222,4 +222,14 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) {
pthread_join(thread_handle, NULL);
}
+#if !defined(OS_MACOSX)
+// Mac OS X uses lower-level mach APIs
+
+// static
+void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) {
+ // TODO(crogers): implement
+ NOTIMPLEMENTED();
+}
+#endif
+
} // namespace base
diff --git a/base/threading/platform_thread_win.cc b/base/threading/platform_thread_win.cc
index 734f404..56d7381 100644
--- a/base/threading/platform_thread_win.cc
+++ b/base/threading/platform_thread_win.cc
@@ -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.
@@ -144,4 +144,10 @@ void PlatformThread::Join(PlatformThreadHandle thread_handle) {
CloseHandle(thread_handle);
}
+// static
+void PlatformThread::SetThreadPriority(PlatformThreadHandle, ThreadPriority) {
+ // TODO(crogers): implement
+ NOTIMPLEMENTED();
+}
+
} // namespace base
diff --git a/base/threading/simple_thread.h b/base/threading/simple_thread.h
index f1b644b..5d8c458 100644
--- a/base/threading/simple_thread.h
+++ b/base/threading/simple_thread.h
@@ -104,6 +104,12 @@ class BASE_API SimpleThread : public PlatformThread::Delegate {
// Overridden from PlatformThread::Delegate:
virtual void ThreadMain();
+ // Only set priorities with a careful understanding of the consequences.
+ // This is meant for very limited use cases.
+ void SetThreadPriority(ThreadPriority priority) {
+ PlatformThread::SetThreadPriority(thread_, priority);
+ }
+
private:
const std::string name_prefix_;
std::string name_;