| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/fml/cpu_affinity.h" |
| #include "flutter/fml/build_config.h" |
| |
| #include <fstream> |
| #include <optional> |
| #include <string> |
| |
| #ifdef FML_OS_ANDROID |
| #include "flutter/fml/platform/android/cpu_affinity.h" |
| #endif // FML_OS_ANDROID |
| |
| namespace fml { |
| |
| std::optional<size_t> EfficiencyCoreCount() { |
| #ifdef FML_OS_ANDROID |
| return AndroidEfficiencyCoreCount(); |
| #else |
| return std::nullopt; |
| #endif |
| } |
| |
| bool RequestAffinity(CpuAffinity affinity) { |
| #ifdef FML_OS_ANDROID |
| return AndroidRequestAffinity(affinity); |
| #else |
| return true; |
| #endif |
| } |
| |
| CPUSpeedTracker::CPUSpeedTracker(std::vector<CpuIndexAndSpeed> data) |
| : cpu_speeds_(std::move(data)) { |
| std::optional<int64_t> max_speed = std::nullopt; |
| std::optional<int64_t> min_speed = std::nullopt; |
| for (const auto& data : cpu_speeds_) { |
| if (!max_speed.has_value() || data.speed > max_speed.value()) { |
| max_speed = data.speed; |
| } |
| if (!min_speed.has_value() || data.speed < min_speed.value()) { |
| min_speed = data.speed; |
| } |
| } |
| if (!max_speed.has_value() || !min_speed.has_value() || |
| min_speed.value() == max_speed.value()) { |
| return; |
| } |
| const int64_t max_speed_value = max_speed.value(); |
| const int64_t min_speed_value = min_speed.value(); |
| |
| for (const auto& data : cpu_speeds_) { |
| if (data.speed == max_speed_value) { |
| performance_.push_back(data.index); |
| } else { |
| not_performance_.push_back(data.index); |
| } |
| if (data.speed == min_speed_value) { |
| efficiency_.push_back(data.index); |
| } |
| } |
| |
| valid_ = true; |
| } |
| |
| bool CPUSpeedTracker::IsValid() const { |
| return valid_; |
| } |
| |
| const std::vector<size_t>& CPUSpeedTracker::GetIndices( |
| CpuAffinity affinity) const { |
| switch (affinity) { |
| case CpuAffinity::kPerformance: |
| return performance_; |
| case CpuAffinity::kEfficiency: |
| return efficiency_; |
| case CpuAffinity::kNotPerformance: |
| return not_performance_; |
| } |
| } |
| |
| // Get the size of the cpuinfo file by reading it until the end. This is |
| // required because files under /proc do not always return a valid size |
| // when using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed. |
| std::optional<int64_t> ReadIntFromFile(const std::string& path) { |
| std::ifstream file; |
| file.open(path.c_str()); |
| |
| // Dont use stoi because if this data isnt a parseable number then it |
| // will abort, as we compile with exceptions disabled. |
| int64_t speed = 0; |
| file >> speed; |
| if (speed > 0) { |
| return speed; |
| } |
| return std::nullopt; |
| } |
| |
| } // namespace fml |