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

Side by Side Diff: base/threading/platform_thread_mac.mm

Issue 1647803004: Move base to DEPS (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months 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
« no previous file with comments | « base/threading/platform_thread_linux.cc ('k') | base/threading/platform_thread_posix.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/threading/platform_thread.h"
6
7 #import <Foundation/Foundation.h>
8 #include <mach/mach.h>
9 #include <mach/mach_time.h>
10 #include <mach/thread_policy.h>
11 #include <sys/resource.h>
12
13 #include <algorithm>
14
15 #include "base/lazy_instance.h"
16 #include "base/logging.h"
17 #include "base/mac/mach_logging.h"
18 #include "base/threading/thread_id_name_manager.h"
19 #include "base/tracked_objects.h"
20
21 namespace base {
22
23 // If Cocoa is to be used on more than one thread, it must know that the
24 // application is multithreaded. Since it's possible to enter Cocoa code
25 // from threads created by pthread_thread_create, Cocoa won't necessarily
26 // be aware that the application is multithreaded. Spawning an NSThread is
27 // enough to get Cocoa to set up for multithreaded operation, so this is done
28 // if necessary before pthread_thread_create spawns any threads.
29 //
30 // http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/Crea tingThreads/chapter_4_section_4.html
31 void InitThreading() {
32 static BOOL multithreaded = [NSThread isMultiThreaded];
33 if (!multithreaded) {
34 // +[NSObject class] is idempotent.
35 [NSThread detachNewThreadSelector:@selector(class)
36 toTarget:[NSObject class]
37 withObject:nil];
38 multithreaded = YES;
39
40 DCHECK([NSThread isMultiThreaded]);
41 }
42 }
43
44 // static
45 void PlatformThread::SetName(const std::string& name) {
46 ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name);
47 tracked_objects::ThreadData::InitializeThreadContext(name);
48
49 // Mac OS X does not expose the length limit of the name, so
50 // hardcode it.
51 const int kMaxNameLength = 63;
52 std::string shortened_name = name.substr(0, kMaxNameLength);
53 // pthread_setname() fails (harmlessly) in the sandbox, ignore when it does.
54 // See http://crbug.com/47058
55 pthread_setname_np(shortened_name.c_str());
56 }
57
58 namespace {
59
60 void SetPriorityNormal(mach_port_t mach_thread_id) {
61 // Make thread standard policy.
62 // Please note that this call could fail in rare cases depending
63 // on runtime conditions.
64 thread_standard_policy policy;
65 kern_return_t result =
66 thread_policy_set(mach_thread_id,
67 THREAD_STANDARD_POLICY,
68 reinterpret_cast<thread_policy_t>(&policy),
69 THREAD_STANDARD_POLICY_COUNT);
70
71 if (result != KERN_SUCCESS)
72 MACH_DVLOG(1, result) << "thread_policy_set";
73 }
74
75 // Enables time-contraint policy and priority suitable for low-latency,
76 // glitch-resistant audio.
77 void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) {
78 // Increase thread priority to real-time.
79
80 // Please note that the thread_policy_set() calls may fail in
81 // rare cases if the kernel decides the system is under heavy load
82 // and is unable to handle boosting the thread priority.
83 // In these cases we just return early and go on with life.
84
85 // Make thread fixed priority.
86 thread_extended_policy_data_t policy;
87 policy.timeshare = 0; // Set to 1 for a non-fixed thread.
88 kern_return_t result =
89 thread_policy_set(mach_thread_id,
90 THREAD_EXTENDED_POLICY,
91 reinterpret_cast<thread_policy_t>(&policy),
92 THREAD_EXTENDED_POLICY_COUNT);
93 if (result != KERN_SUCCESS) {
94 MACH_DVLOG(1, result) << "thread_policy_set";
95 return;
96 }
97
98 // Set to relatively high priority.
99 thread_precedence_policy_data_t precedence;
100 precedence.importance = 63;
101 result = thread_policy_set(mach_thread_id,
102 THREAD_PRECEDENCE_POLICY,
103 reinterpret_cast<thread_policy_t>(&precedence),
104 THREAD_PRECEDENCE_POLICY_COUNT);
105 if (result != KERN_SUCCESS) {
106 MACH_DVLOG(1, result) << "thread_policy_set";
107 return;
108 }
109
110 // Most important, set real-time constraints.
111
112 // Define the guaranteed and max fraction of time for the audio thread.
113 // These "duty cycle" values can range from 0 to 1. A value of 0.5
114 // means the scheduler would give half the time to the thread.
115 // These values have empirically been found to yield good behavior.
116 // Good means that audio performance is high and other threads won't starve.
117 const double kGuaranteedAudioDutyCycle = 0.75;
118 const double kMaxAudioDutyCycle = 0.85;
119
120 // Define constants determining how much time the audio thread can
121 // use in a given time quantum. All times are in milliseconds.
122
123 // About 128 frames @44.1KHz
124 const double kTimeQuantum = 2.9;
125
126 // Time guaranteed each quantum.
127 const double kAudioTimeNeeded = kGuaranteedAudioDutyCycle * kTimeQuantum;
128
129 // Maximum time each quantum.
130 const double kMaxTimeAllowed = kMaxAudioDutyCycle * kTimeQuantum;
131
132 // Get the conversion factor from milliseconds to absolute time
133 // which is what the time-constraints call needs.
134 mach_timebase_info_data_t tb_info;
135 mach_timebase_info(&tb_info);
136 double ms_to_abs_time =
137 (static_cast<double>(tb_info.denom) / tb_info.numer) * 1000000;
138
139 thread_time_constraint_policy_data_t time_constraints;
140 time_constraints.period = kTimeQuantum * ms_to_abs_time;
141 time_constraints.computation = kAudioTimeNeeded * ms_to_abs_time;
142 time_constraints.constraint = kMaxTimeAllowed * ms_to_abs_time;
143 time_constraints.preemptible = 0;
144
145 result =
146 thread_policy_set(mach_thread_id,
147 THREAD_TIME_CONSTRAINT_POLICY,
148 reinterpret_cast<thread_policy_t>(&time_constraints),
149 THREAD_TIME_CONSTRAINT_POLICY_COUNT);
150 MACH_DVLOG_IF(1, result != KERN_SUCCESS, result) << "thread_policy_set";
151
152 return;
153 }
154
155 } // anonymous namespace
156
157 // static
158 void PlatformThread::SetCurrentThreadPriority(ThreadPriority priority) {
159 // Convert from pthread_t to mach thread identifier.
160 mach_port_t mach_thread_id =
161 pthread_mach_thread_np(PlatformThread::CurrentHandle().platform_handle());
162
163 switch (priority) {
164 case ThreadPriority::NORMAL:
165 SetPriorityNormal(mach_thread_id);
166 break;
167 case ThreadPriority::REALTIME_AUDIO:
168 SetPriorityRealtimeAudio(mach_thread_id);
169 break;
170 default:
171 NOTREACHED() << "Unknown priority.";
172 break;
173 }
174 }
175
176 // static
177 ThreadPriority PlatformThread::GetCurrentThreadPriority() {
178 NOTIMPLEMENTED();
179 return ThreadPriority::NORMAL;
180 }
181
182 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
183 #if defined(OS_IOS)
184 return 0;
185 #else
186 // The Mac OS X default for a pthread stack size is 512kB.
187 // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses
188 // DEFAULT_STACK_SIZE for this purpose.
189 //
190 // 512kB isn't quite generous enough for some deeply recursive threads that
191 // otherwise request the default stack size by specifying 0. Here, adopt
192 // glibc's behavior as on Linux, which is to use the current stack size
193 // limit (ulimit -s) as the default stack size. See
194 // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To
195 // avoid setting the limit below the Mac OS X default or the minimum usable
196 // stack size, these values are also considered. If any of these values
197 // can't be determined, or if stack size is unlimited (ulimit -s unlimited),
198 // stack_size is left at 0 to get the system default.
199 //
200 // Mac OS X normally only applies ulimit -s to the main thread stack. On
201 // contemporary OS X and Linux systems alike, this value is generally 8MB
202 // or in that neighborhood.
203 size_t default_stack_size = 0;
204 struct rlimit stack_rlimit;
205 if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 &&
206 getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 &&
207 stack_rlimit.rlim_cur != RLIM_INFINITY) {
208 default_stack_size =
209 std::max(std::max(default_stack_size,
210 static_cast<size_t>(PTHREAD_STACK_MIN)),
211 static_cast<size_t>(stack_rlimit.rlim_cur));
212 }
213 return default_stack_size;
214 #endif
215 }
216
217 void InitOnThread() {
218 }
219
220 void TerminateOnThread() {
221 }
222
223 } // namespace base
OLDNEW
« no previous file with comments | « base/threading/platform_thread_linux.cc ('k') | base/threading/platform_thread_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698