Configurable CPU Governor (fixed)

modified:   .vscode/launch.json
	modified:   react/CMakeLists.txt
	modified:   react/public/var/config.json
	new file:   react/src/GovernorSettings.tsx
	modified:   react/src/JackHostStatus.tsx
	new file:   react/src/ListSelectDialog.tsx
	modified:   react/src/PiPedalModel.tsx
	modified:   react/src/SettingsDialog.tsx
	modified:   react/tmp.txt
	modified:   src/BeastServer.cpp
	modified:   src/BeastServer.hpp
	modified:   src/CMakeLists.txt
	modified:   src/ConfigMain.cpp
	new file:   src/CpuGovernor.cpp
	new file:   src/CpuGovernor.hpp
	new file:   src/GovernorSettings.cpp
	new file:   src/GovernorSettings.hpp
	new file:   src/Ipv6Helpers.cpp
	new file:   src/Ipv6Helpers.hpp
	modified:   src/JackHost.cpp
	modified:   src/PiPedalModel.cpp
This commit is contained in:
Robin Davies
2022-03-09 21:35:01 -05:00
parent 5d42ec0753
commit 8ad2de8c72
31 changed files with 1642 additions and 377 deletions
+141
View File
@@ -0,0 +1,141 @@
// Copyright (c) 2022 Robin Davies
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "CpuGovernor.hpp"
#include "ss.hpp"
#include <fstream>
#include <filesystem>
#include "PiPedalException.hpp"
#include <unistd.h>
using namespace pipedal;
#ifdef __WIN32__
// not a feature on Win32.
void pipedal::SetCpuGovernor(const std::string &governor) { }
std::vector<std::string> pipedal::GetAvailableGovernors() { return std::vector<std::string>(); }
#else
static const int SYSFS_RETRIES = 3;
std::string pipedal::GetCpuGovernor()
{
std::string result;
try {
std::ifstream f("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor");
f >> result;
} catch (const std::exception &)
{
}
return result;
}
static bool writeAndVerify(std::filesystem::path&sysfsPath, const std::string &value)
{
// return if the value has already been set.
{
std::ifstream f;
f.open(sysfsPath);
if (f.is_open())
{
std::string line;
std::getline(f,line);
if (!f.fail() && value == line)
{
return true;
}
}
}
for (int i = 0; i < SYSFS_RETRIES; ++i)
{
{
// write the value.
// write the value.
std::ofstream f;
f.open(sysfsPath);
if (f.is_open())
{
f << value;
} else {
std::cout << SS("Can't open " << sysfsPath << " for writing.") << std::endl;
sleep(1);
continue;
}
}
// verify that we wrote it
{
std::ifstream f;
f.open(sysfsPath);
if (f.is_open())
{
std::string line;
std::getline(f,line);
if (value == line)
{
return true;
}
std::cout << "Read value: " << line << "Expected value: " << value << std::endl;
}
std::cout << "Failed to update " << sysfsPath << std::endl;
}
sleep(1);
}
return false;
}
void pipedal::SetCpuGovernor(const std::string &governor) {
// using sysfs
int nCpu = 0;
while (true)
{
std::filesystem::path base = SS("/sys/devices/system/cpu/cpu" << nCpu);
if (!std::filesystem::is_directory(base))
break;
std::filesystem::path sysFsPath = SS("/sys/devices/system/cpu/cpu" << nCpu << "/cpufreq/scaling_governor");
if (!writeAndVerify(sysFsPath,governor))
{
throw PiPedalException(SS("Write to " << sysFsPath << " failed."));
break;
}
++nCpu;
}
}
std::vector<std::string> pipedal::GetAvailableGovernors() {
return std::vector<std::string> {
"performance",
"ondemand",
"powersave"
};
}
#endif
void SetCpuGovernor(const std::string &governor);
std::vector<std::string> GetAvailableGovernors();