1 // Copyright 2020 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.
5 #include "base/cpu_affinity_posix.h"
10 #include "base/process/internal_linux.h"
11 #include "third_party/abseil-cpp/absl/types/optional.h"
17 const cpu_set_t& AllCores() {
18 static const cpu_set_t kAllCores = []() {
21 const std::vector<CPU::CoreType>& core_types = CPU::GetGuessedCoreTypes();
22 if (core_types.empty()) {
23 memset(&set, 0xff, sizeof(set));
25 for (size_t index = 0; index < core_types.size(); index++)
33 const cpu_set_t& LittleCores() {
34 static const cpu_set_t kLittleCores = []() {
35 const std::vector<CPU::CoreType>& core_types = CPU::GetGuessedCoreTypes();
36 if (core_types.empty())
41 for (size_t core_index = 0; core_index < core_types.size(); core_index++) {
42 switch (core_types[core_index]) {
43 case CPU::CoreType::kUnknown:
44 case CPU::CoreType::kOther:
45 case CPU::CoreType::kSymmetric:
46 // In the presence of an unknown core type or symmetric architecture,
47 // fall back to allowing all cores.
49 case CPU::CoreType::kBigLittle_Little:
50 case CPU::CoreType::kBigLittleBigger_Little:
51 CPU_SET(core_index, &set);
53 case CPU::CoreType::kBigLittle_Big:
54 case CPU::CoreType::kBigLittleBigger_Big:
55 case CPU::CoreType::kBigLittleBigger_Bigger:
64 } // anonymous namespace
66 bool HasBigCpuCores() {
67 static const bool kHasBigCores = []() {
68 const std::vector<CPU::CoreType>& core_types = CPU::GetGuessedCoreTypes();
69 if (core_types.empty())
71 for (CPU::CoreType core_type : core_types) {
73 case CPU::CoreType::kUnknown:
74 case CPU::CoreType::kOther:
75 case CPU::CoreType::kSymmetric:
77 case CPU::CoreType::kBigLittle_Little:
78 case CPU::CoreType::kBigLittleBigger_Little:
79 case CPU::CoreType::kBigLittle_Big:
80 case CPU::CoreType::kBigLittleBigger_Big:
81 case CPU::CoreType::kBigLittleBigger_Bigger:
90 bool SetThreadCpuAffinityMode(PlatformThreadId thread_id,
91 CpuAffinityMode affinity) {
94 case CpuAffinityMode::kDefault: {
95 const cpu_set_t& all_cores = AllCores();
96 result = sched_setaffinity(thread_id, sizeof(all_cores), &all_cores);
99 case CpuAffinityMode::kLittleCoresOnly: {
100 const cpu_set_t& little_cores = LittleCores();
102 sched_setaffinity(thread_id, sizeof(little_cores), &little_cores);
109 bool SetProcessCpuAffinityMode(ProcessHandle process_handle,
110 CpuAffinityMode affinity) {
111 bool any_threads = false;
114 internal::ForEachProcessTask(
115 process_handle, [&any_threads, &result, affinity](
116 PlatformThreadId tid, const FilePath& /*task_path*/) {
118 result &= SetThreadCpuAffinityMode(tid, affinity);
121 return any_threads && result;
124 absl::optional<CpuAffinityMode> CurrentThreadCpuAffinityMode() {
125 if (HasBigCpuCores()) {
127 sched_getaffinity(PlatformThread::CurrentId(), sizeof(set), &set);
128 if (CPU_EQUAL(&set, &AllCores()))
129 return CpuAffinityMode::kDefault;
130 if (CPU_EQUAL(&set, &LittleCores()))
131 return CpuAffinityMode::kLittleCoresOnly;
133 return absl::nullopt;