Skip to content

Commit

Permalink
Add support for Apple M2
Browse files Browse the repository at this point in the history
  • Loading branch information
enen92 committed Aug 27, 2023
1 parent e633039 commit 92019bb
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 32 deletions.
115 changes: 93 additions & 22 deletions smctemp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@

#include "smctemp_string.h"

#if defined(ARCH_TYPE_ARM64)
#include <sys/sysctl.h>
#include <algorithm>

namespace {
std::string getCPUModel() {
std::array<char, 512> buffer;
size_t bufferLength = buffer.size();
sysctlbyname("machdep.cpu.brand_string", buffer.data(), &bufferLength, nullptr, 0);
std::string cpuModel = buffer.data();
std::transform(cpuModel.begin(), cpuModel.end(), cpuModel.begin(), ::tolower);
return cpuModel;
}
}
#endif

// Cache the keyInfo to lower the energy impact of SmcReadKey() / SmcReadKey2()
#define KEY_INFO_CACHE_SIZE 100
namespace smctemp {
Expand Down Expand Up @@ -388,35 +404,90 @@ double SmcTemp::GetCpuTemp() {
return temp;
}
#elif defined(ARCH_TYPE_ARM64)
std::vector<std::string> sensors{
static_cast<std::string>(kSensorTp01),
static_cast<std::string>(kSensorTp05),
static_cast<std::string>(kSensorTp0d),
static_cast<std::string>(kSensorTp0h),
static_cast<std::string>(kSensorTp0l),
static_cast<std::string>(kSensorTp0p),
static_cast<std::string>(kSensorTp0x),
static_cast<std::string>(kSensorTp0b),
static_cast<std::string>(kSensorTp09),
static_cast<std::string>(kSensorTp0t),
};
std::vector<std::string> sensors;
std::vector<std::string> aux_sensors;

const std::string cpumodel = getCPUModel();
if (cpumodel.find("m2") != std::string::npos ) { // Apple M2
// CPU performance core 1 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp01));
// CPU performance core 2 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp09));
// CPU performance core 3 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0f));
// CPU performance core 4 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0n));
// CPU efficient core 1 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp05));
// CPU efficient core 2 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0d));
// CPU efficient core 3 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0j));
// CPU efficient core 4 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0r));

// TODO: m2 pro, m2 max, m2 ultra have more cpu cores (unknown sensors)
//if (cpumodel.find("pro") != std::string::npos ||
// cpumodel.find("max") != std::string::npos ||
// cpumodel.find("ultra") != std::string::npos) {
// // TODO: add additional sensors
// }

} else if (cpumodel.find("m1") != std::string::npos) { // Apple M1
// CPU performance core 1 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp01));
// CPU performance core 2 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp05));
// CPU performance core 3 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0d));
// CPU performance core 4 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0h));
// CPU performance core 5 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0l));
// CPU performance core 6 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0p));
// CPU performance core 7 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0x));
// CPU performance core 8 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0b));
// CPU efficient core 1 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp09));
// CPU efficient core 2 temperature
sensors.emplace_back(static_cast<std::string>(kSensorTp0t));

aux_sensors.emplace_back(static_cast<std::string>(kSensorTc0a));
aux_sensors.emplace_back(static_cast<std::string>(kSensorTc0b));
aux_sensors.emplace_back(static_cast<std::string>(kSensorTc0x));
aux_sensors.emplace_back(static_cast<std::string>(kSensorTc0z));
} else {
// not supported
return temp;
}

size_t valid_sensor_count = 0;
for (auto sensor : sensors) {
temp += smc_accessor_.ReadValue(sensor.c_str());
auto sensor_value = smc_accessor_.ReadValue(sensor.c_str());
if (sensor_value > 0.0) {
temp += sensor_value;
valid_sensor_count++;
}
}
temp /= sensors.size();
temp /= valid_sensor_count;
if (temp > std::numeric_limits<double>::epsilon()) {
return temp;
}
std::vector<std::string> aux_sensors{
static_cast<std::string>(kSensorTc0a),
static_cast<std::string>(kSensorTc0b),
static_cast<std::string>(kSensorTc0x),
static_cast<std::string>(kSensorTc0z),
};

size_t valid_aux_sensor_count = 0;
for (auto sensor : aux_sensors) {
temp += smc_accessor_.ReadValue(sensor.c_str());
auto sensor_value = smc_accessor_.ReadValue(sensor.c_str());
if (sensor_value > 0.0) {
temp += sensor_value;
valid_aux_sensor_count++;
}
}
if (valid_aux_sensor_count > 0) {
temp /= valid_aux_sensor_count;
}
temp /= aux_sensors.size();
#endif
return temp;
}
Expand Down
24 changes: 14 additions & 10 deletions smctemp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,20 @@ constexpr UInt32Char_t kSensorTc0a = "Tc0a";
constexpr UInt32Char_t kSensorTc0b = "Tc0b";
constexpr UInt32Char_t kSensorTc0x = "Tc0x";
constexpr UInt32Char_t kSensorTc0z = "Tc0z";
constexpr UInt32Char_t kSensorTp01 = "Tp01"; // CPU performance core 1 temperature
constexpr UInt32Char_t kSensorTp05 = "Tp05"; // CPU performance core 2 temperature
constexpr UInt32Char_t kSensorTp0d = "Tp0D"; // CPU performance core 3 temperature
constexpr UInt32Char_t kSensorTp0h = "Tp0H"; // CPU performance core 4 temperature
constexpr UInt32Char_t kSensorTp0l = "Tp0L"; // CPU performance core 5 temperature
constexpr UInt32Char_t kSensorTp0p = "Tp0P"; // CPU performance core 6 temperature
constexpr UInt32Char_t kSensorTp0x = "Tp0X"; // CPU performance core 7 temperature
constexpr UInt32Char_t kSensorTp0b = "Tp0b"; // CPU performance core 8 temperature
constexpr UInt32Char_t kSensorTp09 = "Tp09"; // CPU efficient core 1 temperature
constexpr UInt32Char_t kSensorTp0t = "Tp0T"; // CPU efficient core 2 temperature
constexpr UInt32Char_t kSensorTp01 = "Tp01";
constexpr UInt32Char_t kSensorTp05 = "Tp05";
constexpr UInt32Char_t kSensorTp0d = "Tp0D";
constexpr UInt32Char_t kSensorTp0h = "Tp0H";
constexpr UInt32Char_t kSensorTp0l = "Tp0L";
constexpr UInt32Char_t kSensorTp0p = "Tp0P";
constexpr UInt32Char_t kSensorTp0x = "Tp0X";
constexpr UInt32Char_t kSensorTp0b = "Tp0b";
constexpr UInt32Char_t kSensorTp09 = "Tp09";
constexpr UInt32Char_t kSensorTp0t = "Tp0T";
constexpr UInt32Char_t kSensorTp0j = "Tp0j";
constexpr UInt32Char_t kSensorTp0r = "Tp0r";
constexpr UInt32Char_t kSensorTp0f = "Tp0f";
constexpr UInt32Char_t kSensorTp0n = "Tp0n";
#endif

class SmcAccessor {
Expand Down

0 comments on commit 92019bb

Please sign in to comment.