platform_thread_mac.mm revision effb81e5f8246d0db0270817048dc992db66e9fb
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" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_id_name_manager.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If Cocoa is to be used on more than one thread, it must know that the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// application is multithreaded. Since it's possible to enter Cocoa code 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from threads created by pthread_thread_create, Cocoa won't necessarily 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be aware that the application is multithreaded. Spawning an NSThread is 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enough to get Cocoa to set up for multithreaded operation, so this is done 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if necessary before pthread_thread_create spawns any threads. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_4.html 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitThreading() { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static BOOL multithreaded = [NSThread isMultiThreaded]; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!multithreaded) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // +[NSObject class] is idempotent. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [NSThread detachNewThreadSelector:@selector(class) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toTarget:[NSObject class] 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) withObject:nil]; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) multithreaded = YES; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK([NSThread isMultiThreaded]); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::SetName(const char* name) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tracked_objects::ThreadData::InitializeThreadContext(name); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mac OS X does not expose the length limit of the name, so 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hardcode it. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxNameLength = 63; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string shortened_name = std::string(name).substr(0, kMaxNameLength); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pthread_setname() fails (harmlessly) in the sandbox, ignore when it does. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://crbug.com/47058 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch pthread_setname_np(shortened_name.c_str()); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetPriorityNormal(mach_port_t mach_thread_id) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make thread standard policy. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Please note that this call could fail in rare cases depending 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on runtime conditions. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_standard_policy policy; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kern_return_t result = thread_policy_set(mach_thread_id, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_STANDARD_POLICY, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (thread_policy_t)&policy, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_STANDARD_POLICY_COUNT); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "thread_policy_set() failure: " << result; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enables time-contraint policy and priority suitable for low-latency, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// glitch-resistant audio. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetPriorityRealtimeAudio(mach_port_t mach_thread_id) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kern_return_t result; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 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. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = thread_policy_set(mach_thread_id, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_EXTENDED_POLICY, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (thread_policy_t)&policy, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_EXTENDED_POLICY_COUNT); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "thread_policy_set() failure: " << result; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set to relatively high priority. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_precedence_policy_data_t precedence; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) precedence.importance = 63; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = thread_policy_set(mach_thread_id, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_PRECEDENCE_POLICY, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (thread_policy_t)&precedence, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_PRECEDENCE_POLICY_COUNT); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "thread_policy_set() failure: " << result; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Most important, set real-time constraints. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Define the guaranteed and max fraction of time for the audio thread. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These "duty cycle" values can range from 0 to 1. A value of 0.5 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // means the scheduler would give half the time to the thread. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These values have empirically been found to yield good behavior. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Good means that audio performance is high and other threads won't starve. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kGuaranteedAudioDutyCycle = 0.75; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kMaxAudioDutyCycle = 0.85; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Define constants determining how much time the audio thread can 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // use in a given time quantum. All times are in milliseconds. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // About 128 frames @44.1KHz 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kTimeQuantum = 2.9; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Time guaranteed each quantum. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kAudioTimeNeeded = kGuaranteedAudioDutyCycle * kTimeQuantum; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maximum time each quantum. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const double kMaxTimeAllowed = kMaxAudioDutyCycle * kTimeQuantum; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the conversion factor from milliseconds to absolute time 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which is what the time-constraints call needs. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mach_timebase_info_data_t tb_info; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mach_timebase_info(&tb_info); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double ms_to_abs_time = 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((double)tb_info.denom / (double)tb_info.numer) * 1000000; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_time_constraint_policy_data_t time_constraints; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.period = kTimeQuantum * ms_to_abs_time; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.computation = kAudioTimeNeeded * ms_to_abs_time; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.constraint = kMaxTimeAllowed * ms_to_abs_time; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_constraints.preemptible = 0; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = thread_policy_set(mach_thread_id, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_TIME_CONSTRAINT_POLICY, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (thread_policy_t)&time_constraints, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) THREAD_TIME_CONSTRAINT_POLICY_COUNT); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != KERN_SUCCESS) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "thread_policy_set() failure: " << result; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadPriority priority) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert from pthread_t to mach thread identifier. 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) mach_port_t mach_thread_id = pthread_mach_thread_np(handle.handle_); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (priority) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kThreadPriority_Normal: 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPriorityNormal(mach_thread_id); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kThreadPriority_RealtimeAudio: 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPriorityRealtimeAudio(mach_thread_id); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Unknown priority."; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_IOS) 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The Mac OS X default for a pthread stack size is 512kB. 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Libc-594.1.4/pthreads/pthread.c's pthread_attr_init uses 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // DEFAULT_STACK_SIZE for this purpose. 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 512kB isn't quite generous enough for some deeply recursive threads that 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // otherwise request the default stack size by specifying 0. Here, adopt 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // glibc's behavior as on Linux, which is to use the current stack size 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // limit (ulimit -s) as the default stack size. See 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // glibc-2.11.1/nptl/nptl-init.c's __pthread_initialize_minimal_internal. To 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // avoid setting the limit below the Mac OS X default or the minimum usable 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // stack size, these values are also considered. If any of these values 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // can't be determined, or if stack size is unlimited (ulimit -s unlimited), 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // stack_size is left at 0 to get the system default. 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Mac OS X normally only applies ulimit -s to the main thread stack. On 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // contemporary OS X and Linux systems alike, this value is generally 8MB 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // or in that neighborhood. 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t default_stack_size = 0; 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct rlimit stack_rlimit; 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pthread_attr_getstacksize(&attributes, &default_stack_size) == 0 && 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) getrlimit(RLIMIT_STACK, &stack_rlimit) == 0 && 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stack_rlimit.rlim_cur != RLIM_INFINITY) { 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default_stack_size = 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::max(std::max(default_stack_size, 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<size_t>(PTHREAD_STACK_MIN)), 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<size_t>(stack_rlimit.rlim_cur)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return default_stack_size; 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void InitOnThread() { 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TerminateOnThread() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 217