OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/threading/platform_thread.h" | 5 #include "base/threading/platform_thread.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <sched.h> | 8 #include <sched.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 | 10 |
11 #include "base/files/file_util.h" | |
11 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/strings/string_number_conversions.h" | |
13 #include "base/threading/platform_thread_internal_posix.h" | 15 #include "base/threading/platform_thread_internal_posix.h" |
14 #include "base/threading/thread_id_name_manager.h" | 16 #include "base/threading/thread_id_name_manager.h" |
15 #include "base/tracked_objects.h" | 17 #include "base/tracked_objects.h" |
16 #include "build/build_config.h" | 18 #include "build/build_config.h" |
17 | 19 |
18 #if !defined(OS_NACL) | 20 #if !defined(OS_NACL) |
19 #include <pthread.h> | 21 #include <pthread.h> |
20 #include <sys/prctl.h> | 22 #include <sys/prctl.h> |
21 #include <sys/types.h> | 23 #include <sys/types.h> |
22 #include <unistd.h> | 24 #include <unistd.h> |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 maybe_realtime_prio.sched_priority == kRealTimePrio.sched_priority) { | 60 maybe_realtime_prio.sched_priority == kRealTimePrio.sched_priority) { |
59 *priority = ThreadPriority::REALTIME_AUDIO; | 61 *priority = ThreadPriority::REALTIME_AUDIO; |
60 return true; | 62 return true; |
61 } | 63 } |
62 #endif | 64 #endif |
63 return false; | 65 return false; |
64 } | 66 } |
65 | 67 |
66 } // namespace internal | 68 } // namespace internal |
67 | 69 |
70 namespace { | |
71 #if !defined(OS_NACL) | |
72 const FilePath::CharType kCpusetDirectory[] = | |
73 FILE_PATH_LITERAL("/sys/fs/cgroup/cpuset/chrome"); | |
Dmitry Torokhov
2016/09/12 16:18:09
I wonder if, instead of having static cpuset place
reveman
2016/09/16 22:16:11
sgtm.
dtor, can you take care of starting chrome
| |
74 #endif | |
75 } // namespace | |
76 | |
68 // static | 77 // static |
69 void PlatformThread::SetName(const std::string& name) { | 78 void PlatformThread::SetName(const std::string& name) { |
70 ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); | 79 ThreadIdNameManager::GetInstance()->SetName(CurrentId(), name); |
71 tracked_objects::ThreadData::InitializeThreadContext(name); | 80 tracked_objects::ThreadData::InitializeThreadContext(name); |
72 | 81 |
73 #if !defined(OS_NACL) | 82 #if !defined(OS_NACL) |
74 // On linux we can get the thread names to show up in the debugger by setting | 83 // 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 | 84 // 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 | 85 // thread because that would rename the process, causing tools like killall |
77 // to stop working. | 86 // to stop working. |
78 if (PlatformThread::CurrentId() == getpid()) | 87 if (PlatformThread::CurrentId() == getpid()) |
79 return; | 88 return; |
80 | 89 |
81 // http://0pointer.de/blog/projects/name-your-threads.html | 90 // http://0pointer.de/blog/projects/name-your-threads.html |
82 // Set the name for the LWP (which gets truncated to 15 characters). | 91 // 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 | 92 // 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 | 93 // 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. | 94 // that it can set the name of threads other than the current thread. |
86 int err = prctl(PR_SET_NAME, name.c_str()); | 95 int err = prctl(PR_SET_NAME, name.c_str()); |
87 // We expect EPERM failures in sandboxed processes, just ignore those. | 96 // We expect EPERM failures in sandboxed processes, just ignore those. |
88 if (err < 0 && errno != EPERM) | 97 if (err < 0 && errno != EPERM) |
89 DPLOG(ERROR) << "prctl(PR_SET_NAME)"; | 98 DPLOG(ERROR) << "prctl(PR_SET_NAME)"; |
90 #endif // !defined(OS_NACL) | 99 #endif // !defined(OS_NACL) |
91 } | 100 } |
92 | 101 |
102 #if !defined(OS_NACL) | |
103 // static | |
104 void PlatformThread::SetThreadAffinity(PlatformThreadId id, | |
105 ThreadPriority priority) { | |
106 // Move thread into the appropriate cpuset when chrome cpuset directory | |
107 // exists. Threads with BACKGROUND priority are move to the "non-urgent" | |
108 // cpuset and threads with DISPLAY and REALTIME_AUDIO priority are moved | |
109 // to "urgent" cpuset. | |
110 FilePath cpuset_filepath(kCpusetDirectory); | |
111 switch (priority) { | |
112 case ThreadPriority::NORMAL: | |
113 break; | |
114 case ThreadPriority::BACKGROUND: | |
115 cpuset_filepath = cpuset_filepath.Append(FILE_PATH_LITERAL("non-urgent")); | |
116 break; | |
117 case ThreadPriority::DISPLAY: | |
118 case ThreadPriority::REALTIME_AUDIO: | |
119 cpuset_filepath = cpuset_filepath.Append(FILE_PATH_LITERAL("urgent")); | |
120 break; | |
121 } | |
122 if (DirectoryExists(cpuset_filepath)) { | |
123 FilePath tasks_filepath = | |
124 cpuset_filepath.Append(FILE_PATH_LITERAL("tasks")); | |
125 std::string tid = IntToString(id); | |
126 int bytes_written = WriteFile(tasks_filepath, tid.c_str(), tid.size()); | |
127 if (bytes_written != static_cast<int>(tid.size())) { | |
128 DVLOG(1) << "Failed to add " << tid << " to " << tasks_filepath.value(); | |
129 } | |
130 } | |
131 } | |
132 #endif // !defined(OS_NACL) | |
133 | |
93 void InitThreading() {} | 134 void InitThreading() {} |
94 | 135 |
95 void TerminateOnThread() {} | 136 void TerminateOnThread() {} |
96 | 137 |
97 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { | 138 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) { |
98 #if !defined(THREAD_SANITIZER) | 139 #if !defined(THREAD_SANITIZER) |
99 return 0; | 140 return 0; |
100 #else | 141 #else |
101 // ThreadSanitizer bloats the stack heavily. Evidence has been that the | 142 // ThreadSanitizer bloats the stack heavily. Evidence has been that the |
102 // default stack size isn't enough for some browser tests. | 143 // default stack size isn't enough for some browser tests. |
103 return 2 * (1 << 23); // 2 times 8192K (the default stack size on Linux). | 144 return 2 * (1 << 23); // 2 times 8192K (the default stack size on Linux). |
104 #endif | 145 #endif |
105 } | 146 } |
106 | 147 |
107 } // namespace base | 148 } // namespace base |
OLD | NEW |