1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/threading/platform_thread.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <errno.h> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <sched.h> 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/lazy_instance.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/logging.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/safe_strerror_posix.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/threading/thread_id_name_manager.h" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/tracked_objects.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_NACL) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <sys/resource.h> 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <sys/syscall.h> 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <sys/time.h> 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <sys/types.h> 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <unistd.h> 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace base { 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int ThreadNiceValue(ThreadPriority priority) { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (priority) { 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case kThreadPriority_RealtimeAudio: 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return -10; 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case kThreadPriority_Background: 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 10; 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case kThreadPriority_Normal: 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 0; 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case kThreadPriority_Display: 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return -6; 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) default: 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED() << "Unknown priority."; 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 0; 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PlatformThread::SetName(const char* name) { 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) tracked_objects::ThreadData::InitializeThreadContext(name); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_NACL) 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // On FreeBSD we can get the thread names to show up in the debugger by 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // setting the process name for the LWP. We don't want to do this for the 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // main thread because that would rename the process, causing tools like 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // killall to stop working. 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (PlatformThread::CurrentId() == getpid()) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) setproctitle("%s", name); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // !defined(OS_NACL) 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PlatformThread::SetThreadPriority(PlatformThreadHandle handle, 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ThreadPriority priority) { 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_NACL) 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (priority == kThreadPriority_RealtimeAudio) { 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const struct sched_param kRealTimePrio = { 8 }; 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (pthread_setschedparam(pthread_self(), SCHED_RR, &kRealTimePrio) == 0) { 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Got real time priority, no need to set nice level. 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // setpriority(2) will set a thread's priority if it is passed a tid as 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // the 'process identifier', not affecting the rest of the threads in the 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // process. Setting this priority will only succeed if the user has been 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // granted permission to adjust nice values on the system. 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_NE(handle.id_, kInvalidThreadId); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const int kNiceSetting = ThreadNiceValue(priority); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (setpriority(PRIO_PROCESS, handle.id_, kNiceSetting)) { 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DVPLOG(1) << "Failed to set nice value of thread (" 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << handle.id_ << ") to " << kNiceSetting; 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // !defined(OS_NACL) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InitThreading() {} 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InitOnThread() {} 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TerminateOnThread() {} 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(THREAD_SANITIZER) 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 0; 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#else 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ThreadSanitizer bloats the stack heavily. Evidence has been that the 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // default stack size isn't enough for some browser tests. 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 2 * (1 << 23); // 2 times 8192K (the default stack size on Linux). 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace base 104