15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <Foundation/Foundation.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mach/mach.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mach/mach_time.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mach/thread_policy.h> 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <sys/resource.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include <algorithm> 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/mac/mach_logging.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_id_name_manager.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If Cocoa is to be used on more than one thread, it must know that the 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// application is multithreaded. Since it's possible to enter Cocoa code 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from threads created by pthread_thread_create, Cocoa won't necessarily 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be aware that the application is multithreaded. Spawning an NSThread is 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enough to get Cocoa to set up for multithreaded operation, so this is done 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if necessary before pthread_thread_create spawns any threads. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_4.html 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitThreading() { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BOOL multithreaded = [NSThread isMultiThreaded]; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!multithreaded) { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +[NSObject class] is idempotent. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [NSThread detachNewThreadSelector:@selector(class) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toTarget:[NSObject class] 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) withObject:nil]; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multithreaded = YES; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK([NSThread isMultiThreaded]); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::SetName(const char* name) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracked_objects::ThreadData::InitializeThreadContext(name); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mac OS X does not expose the length limit of the name, so 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hardcode it. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxNameLength = 63; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string shortened_name = std::string(name).substr(0, kMaxNameLength); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pthread_setname() fails (harmlessly) in the sandbox, ignore when it does. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://crbug.com/47058 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pthread_setname_np(shortened_name.c_str()); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetPriorityNormal(mach_port_t mach_thread_id) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make thread standard policy. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Please note that this call could fail in rare cases depending 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on runtime conditions. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_standard_policy policy; 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kern_return_t result = 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) thread_policy_set(mach_thread_id, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) THREAD_STANDARD_POLICY, 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reinterpret_cast<thread_policy_t>(&policy), 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) THREAD_STANDARD_POLICY_COUNT); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MACH_DVLOG(1, result) << "thread_policy_set"; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enables time-contraint policy and priority suitable for low-latency, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// glitch-resistant audio. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Increase thread priority to real-time. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Please note that the thread_policy_set() calls may fail in 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rare cases if the kernel decides the system is under heavy load 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and is unable to handle boosting the thread priority. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In these cases we just return early and go on with life. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make thread fixed priority. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_extended_policy_data_t policy; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy.timeshare = 0; // Set to 1 for a non-fixed thread. 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kern_return_t result = 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) thread_policy_set(mach_thread_id, 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) THREAD_EXTENDED_POLICY, 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reinterpret_cast<thread_policy_t>(&policy), 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) THREAD_EXTENDED_POLICY_COUNT); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) { 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MACH_DVLOG(1, result) << "thread_policy_set"; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to relatively high priority. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_precedence_policy_data_t precedence; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) precedence.importance = 63; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = thread_policy_set(mach_thread_id, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_PRECEDENCE_POLICY, 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reinterpret_cast<thread_policy_t>(&precedence), 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_PRECEDENCE_POLICY_COUNT); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) { 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MACH_DVLOG(1, result) << "thread_policy_set"; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Most important, set real-time constraints. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Define the guaranteed and max fraction of time for the audio thread. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These "duty cycle" values can range from 0 to 1. A value of 0.5 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // means the scheduler would give half the time to the thread. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These values have empirically been found to yield good behavior. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Good means that audio performance is high and other threads won't starve. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kGuaranteedAudioDutyCycle = 0.75; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kMaxAudioDutyCycle = 0.85; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Define constants determining how much time the audio thread can 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use in a given time quantum. All times are in milliseconds. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // About 128 frames @44.1KHz 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kTimeQuantum = 2.9; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Time guaranteed each quantum. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kAudioTimeNeeded = kGuaranteedAudioDutyCycle * kTimeQuantum; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maximum time each quantum. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kMaxTimeAllowed = kMaxAudioDutyCycle * kTimeQuantum; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the conversion factor from milliseconds to absolute time 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which is what the time-constraints call needs. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mach_timebase_info_data_t tb_info; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mach_timebase_info(&tb_info); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double ms_to_abs_time = 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) (static_cast<double>(tb_info.denom) / tb_info.numer) * 1000000; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_time_constraint_policy_data_t time_constraints; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.period = kTimeQuantum * ms_to_abs_time; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.computation = kAudioTimeNeeded * ms_to_abs_time; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.constraint = kMaxTimeAllowed * ms_to_abs_time; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.preemptible = 0; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result = 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) thread_policy_set(mach_thread_id, 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) THREAD_TIME_CONSTRAINT_POLICY, 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) reinterpret_cast<thread_policy_t>(&time_constraints), 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) THREAD_TIME_CONSTRAINT_POLICY_COUNT); 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) MACH_DVLOG_IF(1, result != KERN_SUCCESS, result) << "thread_policy_set"; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadPriority priority) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert from pthread_t to mach thread identifier. 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mach_port_t mach_thread_id = pthread_mach_thread_np(handle.handle_); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (priority) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kThreadPriority_Normal: 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPriorityNormal(mach_thread_id); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kThreadPriority_RealtimeAudio: 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPriorityRealtimeAudio(mach_thread_id); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Unknown priority."; 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_IOS) 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The Mac OS X default for a pthread stack size is 512kB. 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // DEFAULT_STACK_SIZE for this purpose. 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 512kB isn't quite generous enough for some deeply recursive threads that 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // otherwise request the default stack size by specifying 0. Here, adopt 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // glibc's behavior as on Linux, which is to use the current stack size 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // limit (ulimit -s) as the default stack size. See 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // avoid setting the limit below the Mac OS X default or the minimum usable 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // stack size, these values are also considered. If any of these values 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // can't be determined, or if stack size is unlimited (ulimit -s unlimited), 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // stack_size is left at 0 to get the system default. 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Mac OS X normally only applies ulimit -s to the main thread stack. On 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // contemporary OS X and Linux systems alike, this value is generally 8MB 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // or in that neighborhood. 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t default_stack_size = 0; 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct rlimit stack_rlimit; 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 && 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 && 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stack_rlimit.rlim_cur != RLIM_INFINITY) { 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default_stack_size = 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::max(std::max(default_stack_size, 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<size_t>(PTHREAD_STACK_MIN)), 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<size_t>(stack_rlimit.rlim_cur)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return default_stack_size; 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void InitOnThread() { 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TerminateOnThread() { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 218