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 #include <errno.h> 8 #include <sched.h> 9 #include <stddef.h> 10 11 #include "base/lazy_instance.h" 12 #include "base/logging.h" 13 #include "base/threading/platform_thread_internal_posix.h" 14 #include "base/threading/thread_id_name_manager.h" 15 #include "base/tracked_objects.h" 16 #include "build/build_config.h" 17 18 #if !defined(OS_NACL) 19 #include <pthread.h> 20 #include <sys/prctl.h> 21 #include <sys/types.h> 22 #include <unistd.h> 23 #endif 24 25 namespace base { 26 27 namespace internal { 28 29 namespace { 30 #if !defined(OS_NACL) 31 const struct sched_param kRealTimePrio = {8}; 32 #endif 33 } // namespace 34 35 const ThreadPriorityToNiceValuePair kThreadPriorityToNiceValueMap[4] = { 36 {ThreadPriority::BACKGROUND, 10}, 37 {ThreadPriority::NORMAL, 0}, 38 {ThreadPriority::DISPLAY, -8}, 39 {ThreadPriority::REALTIME_AUDIO, -10}, 40 }; 41 42 bool SetCurrentThreadPriorityForPlatform(ThreadPriority priority) { 43 #if !defined(OS_NACL) 44 return priority == ThreadPriority::REALTIME_AUDIO && 45 pthread_setschedparam(pthread_self(), SCHED_RR, &kRealTimePrio) == 0; 46 #else 47 return false; 48 #endif 49 } 50 51 bool GetCurrentThreadPriorityForPlatform(ThreadPriority* priority) { 52 #if !defined(OS_NACL) 53 int maybe_sched_rr = 0; 54 struct sched_param maybe_realtime_prio = {0}; 55 if (pthread_getschedparam(pthread_self(), &maybe_sched_rr, 56 &maybe_realtime_prio) == 0 && 57 maybe_sched_rr == SCHED_RR && 58 maybe_realtime_prio.sched_priority == kRealTimePrio.sched_priority) { 59 *priority = ThreadPriority::REALTIME_AUDIO; 60 return true; 61 } 62 #endif 63 return false; 64 } 65 66 } // namespace internal 67 68 // static 69 void PlatformThread::SetName(const std::string& name) { 70 ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); 71 tracked_objects::ThreadData::InitializeThreadContext(name); 72 73 #if !defined(OS_NACL) 74 // On linux we can get the thread names to show up in the debugger by setting 75 // the process name for the LWP. We don't want to do this for the main 76 // thread because that would rename the process, causing tools like killall 77 // to stop working. 78 if (PlatformThread::CurrentId() == getpid()) 79 return; 80 81 // http://0pointer.de/blog/projects/name-your-threads.html 82 // Set the name for the LWP (which gets truncated to 15 characters). 83 // Note that glibc also has a 'pthread_setname_np' api, but it may not be 84 // available everywhere and it's only benefit over using prctl directly is 85 // that it can set the name of threads other than the current thread. 86 int err = prctl(PR_SET_NAME, name.c_str()); 87 // We expect EPERM failures in sandboxed processes, just ignore those. 88 if (err < 0 && errno != EPERM) 89 DPLOG(ERROR) << "prctl(PR_SET_NAME)"; 90 #endif // !defined(OS_NACL) 91 } 92 93 void InitThreading() {} 94 95 void TerminateOnThread() {} 96 97 size_t GetDefaultThreadStackSize(const pthread_attr_t& /*attributes*/) { 98 #if !defined(THREAD_SANITIZER) 99 return 0; 100 #else 101 // ThreadSanitizer bloats the stack heavily. Evidence has been that the 102 // default stack size isn't enough for some browser tests. 103 return 2 * (1 << 23); // 2 times 8192K (the default stack size on Linux). 104 #endif 105 } 106 107 } // namespace base 108