Index: base/threading/platform_thread_linux.cc |
diff --git a/base/threading/platform_thread_linux.cc b/base/threading/platform_thread_linux.cc |
index 95ed32418ff49bdce1cfc91b846374000f62a4e3..299ae2b927749e5fb0fb4818103ea0437a80b7a8 100644 |
--- a/base/threading/platform_thread_linux.cc |
+++ b/base/threading/platform_thread_linux.cc |
@@ -8,8 +8,10 @@ |
#include <sched.h> |
#include <stddef.h> |
+#include "base/files/file_util.h" |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/threading/platform_thread_internal_posix.h" |
#include "base/threading/thread_id_name_manager.h" |
#include "base/tracked_objects.h" |
@@ -18,11 +20,47 @@ |
#if !defined(OS_NACL) |
#include <pthread.h> |
#include <sys/prctl.h> |
+#include <sys/resource.h> |
+#include <sys/time.h> |
#include <sys/types.h> |
#include <unistd.h> |
#endif |
namespace base { |
+namespace { |
+#if !defined(OS_NACL) |
+const FilePath::CharType kCpusetDirectory[] = |
+ FILE_PATH_LITERAL("/sys/fs/cgroup/cpuset/chrome"); |
+ |
+FilePath ThreadPriorityToCpusetDirectory(ThreadPriority priority) { |
+ FilePath cpuset_filepath(kCpusetDirectory); |
+ switch (priority) { |
+ case ThreadPriority::NORMAL: |
+ return cpuset_filepath; |
+ case ThreadPriority::BACKGROUND: |
+ return cpuset_filepath.Append(FILE_PATH_LITERAL("non-urgent")); |
+ case ThreadPriority::DISPLAY: |
+ case ThreadPriority::REALTIME_AUDIO: |
+ return cpuset_filepath.Append(FILE_PATH_LITERAL("urgent")); |
+ } |
+ NOTREACHED(); |
+ return FilePath(); |
+} |
+ |
+void SetThreadCpuset(PlatformThreadId thread_id, |
+ const FilePath& cpuset_directory) { |
+ // Silently ignore request if cpuset directory doesn't exist. |
+ if (!DirectoryExists(cpuset_directory)) |
+ return; |
+ FilePath tasks_filepath = cpuset_directory.Append(FILE_PATH_LITERAL("tasks")); |
+ std::string tid = IntToString(thread_id); |
+ int bytes_written = WriteFile(tasks_filepath, tid.c_str(), tid.size()); |
+ if (bytes_written != static_cast<int>(tid.size())) { |
+ DVLOG(1) << "Failed to add " << tid << " to " << tasks_filepath.value(); |
+ } |
+} |
+#endif |
+} // namespace |
namespace internal { |
@@ -41,6 +79,8 @@ const ThreadPriorityToNiceValuePair kThreadPriorityToNiceValueMap[4] = { |
bool SetCurrentThreadPriorityForPlatform(ThreadPriority priority) { |
#if !defined(OS_NACL) |
+ FilePath cpuset_directory = ThreadPriorityToCpusetDirectory(priority); |
+ SetThreadCpuset(PlatformThread::CurrentId(), cpuset_directory); |
return priority == ThreadPriority::REALTIME_AUDIO && |
pthread_setschedparam(pthread_self(), SCHED_RR, &kRealTimePrio) == 0; |
#else |
@@ -90,6 +130,26 @@ void PlatformThread::SetName(const std::string& name) { |
#endif // !defined(OS_NACL) |
} |
+#if !defined(OS_NACL) |
+// static |
+void PlatformThread::SetThreadPriority(PlatformThreadId thread_id, |
+ ThreadPriority priority) { |
+ // Changing current main threads' priority is not permitted in favor of |
+ // security, this interface is restricted to change only non-main thread |
+ // priority. |
+ CHECK_NE(thread_id, getpid()); |
+ |
+ FilePath cpuset_directory = ThreadPriorityToCpusetDirectory(priority); |
+ SetThreadCpuset(thread_id, cpuset_directory); |
+ |
+ const int nice_setting = internal::ThreadPriorityToNiceValue(priority); |
+ if (setpriority(PRIO_PROCESS, thread_id, nice_setting)) { |
+ DVPLOG(1) << "Failed to set nice value of thread (" << thread_id << ") to " |
+ << nice_setting; |
+ } |
+} |
+#endif // !defined(OS_NACL) |
+ |
void InitThreading() {} |
void TerminateOnThread() {} |