apm/controller: Make SetPerformanceConfiguration() use an array of pairs over a map

While a map is an OK way to do lookups (and usually recommended in most
cases), this is a map that lives for the entire duration of the program
and only deallocates its contents when the program terminates.

Given the total size of the map is quite small, we can simply use a
std::array of pairs and utilize std::find_if to perform the same
behavior without loss of performance.

This eliminates a static constructor and places the data into the
read-only segment.

While we're at it, we can also handle malformed inputs instead of
directly dereferencing the resulting iterator.
merge-requests/60/head
Lioncash 2019-10-17 16:10:24 +07:00
parent 141d929929
commit b77430df70
1 changed files with 33 additions and 13 deletions

@ -2,6 +2,10 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm>
#include <array>
#include <utility>
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hle/service/apm/controller.h" #include "core/hle/service/apm/controller.h"
@ -9,8 +13,7 @@
namespace Service::APM { namespace Service::APM {
constexpr PerformanceConfiguration DEFAULT_PERFORMANCE_CONFIGURATION = constexpr auto DEFAULT_PERFORMANCE_CONFIGURATION = PerformanceConfiguration::Config7;
PerformanceConfiguration::Config7;
Controller::Controller(Core::Timing::CoreTiming& core_timing) Controller::Controller(Core::Timing::CoreTiming& core_timing)
: core_timing{core_timing}, configs{ : core_timing{core_timing}, configs{
@ -22,18 +25,35 @@ Controller::~Controller() = default;
void Controller::SetPerformanceConfiguration(PerformanceMode mode, void Controller::SetPerformanceConfiguration(PerformanceMode mode,
PerformanceConfiguration config) { PerformanceConfiguration config) {
static const std::map<PerformanceConfiguration, u32> PCONFIG_TO_SPEED_MAP{ static constexpr std::array<std::pair<PerformanceConfiguration, u32>, 16> config_to_speed{{
{PerformanceConfiguration::Config1, 1020}, {PerformanceConfiguration::Config2, 1020}, {PerformanceConfiguration::Config1, 1020},
{PerformanceConfiguration::Config3, 1224}, {PerformanceConfiguration::Config4, 1020}, {PerformanceConfiguration::Config2, 1020},
{PerformanceConfiguration::Config5, 1020}, {PerformanceConfiguration::Config6, 1224}, {PerformanceConfiguration::Config3, 1224},
{PerformanceConfiguration::Config7, 1020}, {PerformanceConfiguration::Config8, 1020}, {PerformanceConfiguration::Config4, 1020},
{PerformanceConfiguration::Config9, 1020}, {PerformanceConfiguration::Config10, 1020}, {PerformanceConfiguration::Config5, 1020},
{PerformanceConfiguration::Config11, 1020}, {PerformanceConfiguration::Config12, 1020}, {PerformanceConfiguration::Config6, 1224},
{PerformanceConfiguration::Config13, 1785}, {PerformanceConfiguration::Config14, 1785}, {PerformanceConfiguration::Config7, 1020},
{PerformanceConfiguration::Config15, 1020}, {PerformanceConfiguration::Config16, 1020}, {PerformanceConfiguration::Config8, 1020},
}; {PerformanceConfiguration::Config9, 1020},
{PerformanceConfiguration::Config10, 1020},
{PerformanceConfiguration::Config11, 1020},
{PerformanceConfiguration::Config12, 1020},
{PerformanceConfiguration::Config13, 1785},
{PerformanceConfiguration::Config14, 1785},
{PerformanceConfiguration::Config15, 1020},
{PerformanceConfiguration::Config16, 1020},
}};
SetClockSpeed(PCONFIG_TO_SPEED_MAP.find(config)->second); const auto iter = std::find_if(config_to_speed.cbegin(), config_to_speed.cend(),
[config](const auto& entry) { return entry.first == config; });
if (iter == config_to_speed.cend()) {
LOG_ERROR(Service_APM, "Invalid performance configuration value provided: {}",
static_cast<u32>(config));
return;
}
SetClockSpeed(iter->second);
configs.insert_or_assign(mode, config); configs.insert_or_assign(mode, config);
} }