Temps (macOS): code refactors

This commit is contained in:
李通洲
2023-08-07 10:15:08 +08:00
parent f1d4611a7d
commit 74233ac0cb
6 changed files with 100 additions and 164 deletions
+2 -1
View File
@@ -11,7 +11,8 @@ Changes:
* Remove the special handling of Command module (it can be set once in the triditional `config.conf`). Use JSON config with Command module instead
* Change `--wm-theme-*` to `--wmtheme-*`. Affect `key` and `format` (WMTheme)
* Change `--terminal-font-*` to `--terminalfont-*`. Affect `key` and `format` (TerminalFont)
* Module `Command` uses `/bin/sh` as the default shell on systems other than Windows (Command)
* Module `Command` uses `/bin/sh` as the default shell on systems other than Windows (Command)
* Fix M2 CPU temperature detection (CPU, macOS)
Features:
* FreeBSD support is improved greatly, and actually tested in a phycial machine
+3 -18
View File
@@ -7,23 +7,11 @@
static double detectBatteryTemp(void)
{
FF_LIST_AUTO_DESTROY temps = ffListCreate(sizeof(FFTempValue));
double result = 0;
ffDetectCoreTemps(FF_TEMP_BATTERY, &temps);
if(temps.length == 0)
if(ffDetectCoreTemps(FF_TEMP_BATTERY, &result))
return FF_BATTERY_TEMP_UNSET;
double result = 0;
for(uint32_t i = 0; i < temps.length; ++i)
{
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
result += tempValue->value;
//TODO: do we really need this?
ffStrbufDestroy(&tempValue->name);
ffStrbufDestroy(&tempValue->deviceClass);
}
result /= temps.length;
return result;
}
@@ -90,10 +78,7 @@ const char* ffDetectBattery(FFBatteryOptions* options, FFlist* results)
else
ffStrbufAppendS(&battery->status, "");
if(options->temp)
battery->temperature = detectBatteryTemp();
else
battery->temperature = FF_BATTERY_TEMP_UNSET;
battery->temperature = options->temp ? detectBatteryTemp() : FF_BATTERY_TEMP_UNSET;
CFRelease(properties);
IOObjectRelease(registryEntry);
+8 -20
View File
@@ -15,28 +15,19 @@ static double getFrequency(const char* propName)
static double detectCpuTemp(const FFstrbuf* cpuName)
{
FF_LIST_AUTO_DESTROY temps = ffListCreate(sizeof(FFTempValue));
double result = 0;
const char* error = NULL;
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
ffDetectCoreTemps(FF_TEMP_CPU_M1X, &temps);
error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result);
else if(ffStrbufStartsWithS(cpuName, "Apple M2"))
ffDetectCoreTemps(FF_TEMP_CPU_M2X, &temps);
else //TODO: PPC?
ffDetectCoreTemps(FF_TEMP_CPU_X64, &temps);
error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result);
else // PPC?
error = ffDetectCoreTemps(FF_TEMP_CPU_X64, &result);
if(temps.length == 0)
if(error)
return FF_CPU_TEMP_UNSET;
double result = 0;
for(uint32_t i = 0; i < temps.length; ++i)
{
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
result += tempValue->value;
//TODO: do we really need this?
ffStrbufDestroy(&tempValue->name);
ffStrbufDestroy(&tempValue->deviceClass);
}
result /= temps.length;
return result;
}
@@ -63,10 +54,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
if(cpu->frequencyMax == 0.0)
cpu->frequencyMax = getFrequency("hw.cpufrequency");
if (options->temp)
cpu->temperature = detectCpuTemp(&cpu->name);
else
cpu->temperature = FF_CPU_TEMP_UNSET;
cpu->temperature = options->temp ? detectCpuTemp(&cpu->name) : FF_CPU_TEMP_UNSET;
return NULL;
}
+9 -21
View File
@@ -8,32 +8,23 @@
static double detectGpuTemp(const FFstrbuf* gpuName)
{
FF_LIST_AUTO_DESTROY temps = ffListCreate(sizeof(FFTempValue));
double result = 0;
const char* error;
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
ffDetectCoreTemps(FF_TEMP_GPU_M1X, &temps);
error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result);
else if(ffStrbufStartsWithS(gpuName, "Apple M2"))
ffDetectCoreTemps(FF_TEMP_GPU_M2X, &temps);
error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result);
else if(ffStrbufStartsWithS(gpuName, "Intel"))
ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &temps);
error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result);
else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
ffDetectCoreTemps(FF_TEMP_GPU_AMD, &temps);
error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result);
else
ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &temps);
error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result);
if(temps.length == 0)
if(error)
return FF_GPU_TEMP_UNSET;
double result = 0;
for(uint32_t i = 0; i < temps.length; ++i)
{
FFTempValue* tempValue = (FFTempValue*)ffListGet(&temps, i);
result += tempValue->value;
//TODO: do we really need this?
ffStrbufDestroy(&tempValue->name);
ffStrbufDestroy(&tempValue->deviceClass);
}
result /= temps.length;
return result;
}
@@ -99,10 +90,7 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
gpu->type = FF_GPU_TYPE_DISCRETE;
}
if(options->temp)
gpu->temperature = detectGpuTemp(&gpu->name);
else
gpu->temperature = FF_GPU_TEMP_UNSET;
gpu->temperature = options->temp ? detectGpuTemp(&gpu->name) : FF_GPU_TEMP_UNSET;
CFRelease(properties);
IOObjectRelease(registryEntry);
+77 -103
View File
@@ -6,35 +6,6 @@
#include <math.h>
#include <IOKit/IOKitLib.h>
static const char kDataTypeFlt[] = "flt ";
static const char kDataTypeFp1f[] = "fp1f";
static const char kDataTypeFp4c[] = "fp4c";
static const char kDataTypeFp5b[] = "fp5b";
static const char kDataTypeFp6a[] = "fp6a";
static const char kDataTypeFp79[] = "fp79";
static const char kDataTypeFp88[] = "fp88";
static const char kDataTypeFpa6[] = "fpa6";
static const char kDataTypeFpc4[] = "fpc4";
static const char kDataTypeFpe2[] = "fpe2";
static const char kDataTypeSp1e[] = "sp1e";
static const char kDataTypeSp3c[] = "sp3c";
static const char kDataTypeSp4b[] = "sp4b";
static const char kDataTypeSp5a[] = "sp5a";
static const char kDataTypeSp69[] = "sp69";
static const char kDataTypeSp78[] = "sp78";
static const char kDataTypeSp87[] = "sp87";
static const char kDataTypeSp96[] = "sp96";
static const char kDataTypeSpb4[] = "spb4";
static const char kDataTypeSpf0[] = "spf0";
static const char kDataTypeUi8[] = "ui8 ";
static const char kDataTypeUi16[] = "ui16";
static const char kDataTypeUi32[] = "ui32";
static const char kDataTypeUi64[] = "ui64";
static const char kDataTypeSi8[] = "si8 ";
static const char kDataTypeSi16[] = "si16";
static const char kDataTypePwm[] = "{pwm";
static const char *kIOAppleSmcHiddenClassName = "AppleSMC";
static const char kSmcCmdReadBytes = 5;
static const char kSmcCmdReadKeyInfo = 9;
static const uint32_t kKernelIndexSmc = 2;
@@ -169,7 +140,7 @@ static const char *smcReadSmcVal(io_connect_t conn, const UInt32Char_t key, SmcV
static const char *smcOpen(io_connect_t *conn)
{
CFMutableDictionaryRef matchDict = IOServiceMatching(kIOAppleSmcHiddenClassName);
CFMutableDictionaryRef matchDict = IOServiceMatching("AppleSMC");
if (matchDict == NULL)
return "IOServiceMatching(\"AppleSmartBattery\") failed";
@@ -199,108 +170,108 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
if (val.dataSize == 0)
return "Empty SMC result";
if (ffStrEquals(val.dataType, kDataTypeUi8) ||
ffStrEquals(val.dataType, kDataTypeUi16) ||
ffStrEquals(val.dataType, kDataTypeUi32) ||
ffStrEquals(val.dataType, kDataTypeUi64))
if (ffStrEquals(val.dataType, "ui8 ") ||
ffStrEquals(val.dataType, "ui16") ||
ffStrEquals(val.dataType, "ui32") ||
ffStrEquals(val.dataType, "ui64"))
{
uint64_t tmp = 0;
for (uint32_t i = 0; i < val.dataSize; i++)
tmp += (uint64_t)((uint8_t)(val.bytes[i]) * pow(256, val.dataSize - 1 - i));
*value = (double)tmp;
}
else if (ffStrEquals(val.dataType, kDataTypeFlt))
else if (ffStrEquals(val.dataType, "flt "))
{
*value = *(float *)(val.bytes);
}
else if (ffStrEquals(val.dataType, kDataTypeFp1f) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fp1f") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 32768.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFp4c) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fp4c") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFp5b) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fp5b") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFp6a) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fp6a") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFp79) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fp79") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFp88) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fp88") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFpa6) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fpa6") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFpc4) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fpc4") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
}
else if (ffStrEquals(val.dataType, kDataTypeFpe2) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "fpe2") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 4.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp1e) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp1e") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 16384.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp3c) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp3c") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 4096.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp4b) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp4b") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 2048.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp5a) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp5a") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 1024.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp69) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp69") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 512.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp78) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp78") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 256.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp87) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp87") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 128.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSp96) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "sp96") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 64.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSpb4) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "spb4") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 16.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSpf0) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "spf0") && val.dataSize == 2)
{
*value = ntohs(*(uint16_t *)(val.bytes)) / 1.0;
}
else if (ffStrEquals(val.dataType, kDataTypeSi8) && val.dataSize == 1)
else if (ffStrEquals(val.dataType, "si8 ") && val.dataSize == 1)
{
signed char *bytes = (signed char *)val.bytes;
int16_t temp = 0;
temp += (int8_t)(bytes[0]);
*value = temp;
}
else if (ffStrEquals(val.dataType, kDataTypeSi16) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "si16") && val.dataSize == 2)
{
*value = ntohs(*(int16_t *)(val.bytes));
}
else if (ffStrEquals(val.dataType, kDataTypePwm) && val.dataSize == 2)
else if (ffStrEquals(val.dataType, "{pwm") && val.dataSize == 2)
{
*value = (double)ntohs(*(uint16_t *)(val.bytes)) * 100 / 65536.0;
}
@@ -309,23 +280,18 @@ static const char *smcReadValue(io_connect_t conn, const UInt32Char_t key, doubl
return NULL;
}
static void detectTemp(io_connect_t conn, const char *sensor, const char *name, FFlist *list)
static bool detectTemp(io_connect_t conn, const char *sensor, double* sum)
{
double temp = 0;
const char* error = smcReadValue(conn, sensor, &temp);
if (error)
return;
FFTempValue* tempValue= (FFTempValue*)ffListAdd(list);
tempValue->value = temp;
assert(strlen(sensor) == 4);
ffStrbufInitNS(&tempValue->deviceClass, 4, sensor);
ffStrbufInitS(&tempValue->name, name);
if (error) return false;
// https://github.com/exelban/stats/blob/14e29c4d60229c363cca9c9d25c30c87b7870830/Modules/Sensors/readers.swift#L124
if (temp < 10 || temp > 120) return false;
*sum += temp;
return true;
}
const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result)
const char *ffDetectCoreTemps(enum FFTempType type, double *result)
{
static io_connect_t conn;
static dispatch_once_t once_control;
@@ -333,75 +299,83 @@ const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result)
if(!conn)
return "smcOpen() failed";
uint32_t count = 0;
*result = 0;
// https://github.com/exelban/stats/blob/master/Modules/Sensors/values.swift
switch (type)
{
case FF_TEMP_CPU_X64:
detectTemp(conn, "TC0D", "CPU diode", result);
detectTemp(conn, "TC0E", "CPU diode virtual", result);
detectTemp(conn, "TC0F", "CPU diode filtered", result);
detectTemp(conn, "TC0P", "CPU proximity", result);
count += detectTemp(conn, "TC0D", result); // CPU diode
count += detectTemp(conn, "TC0E", result); // CPU diode virtual
count += detectTemp(conn, "TC0F", result); // CPU diode filtered
count += detectTemp(conn, "TC0P", result); // CPU proximity
break;
case FF_TEMP_CPU_M1X:
detectTemp(conn, "Tp09", "CPU efficient core 1", result);
detectTemp(conn, "Tp0T", "CPU efficient core 2", result);
count += detectTemp(conn, "Tp09", result); // CPU efficient core 1
count += detectTemp(conn, "Tp0T", result); // CPU efficient core 2
detectTemp(conn, "Tp01", "CPU performance core 1", result);
detectTemp(conn, "Tp05", "CPU performance core 2", result);
detectTemp(conn, "Tp0D", "CPU performance core 3", result);
detectTemp(conn, "Tp0H", "CPU performance core 4", result);
detectTemp(conn, "Tp0L", "CPU performance core 5", result);
detectTemp(conn, "Tp0P", "CPU performance core 6", result);
detectTemp(conn, "Tp0X", "CPU performance core 7", result);
detectTemp(conn, "Tp0b", "CPU performance core 8", result);
count += detectTemp(conn, "Tp01", result); // CPU performance core 1
count += detectTemp(conn, "Tp05", result); // CPU performance core 2
count += detectTemp(conn, "Tp0D", result); // CPU performance core 3
count += detectTemp(conn, "Tp0H", result); // CPU performance core 4
count += detectTemp(conn, "Tp0L", result); // CPU performance core 5
count += detectTemp(conn, "Tp0P", result); // CPU performance core 6
count += detectTemp(conn, "Tp0X", result); // CPU performance core 7
count += detectTemp(conn, "Tp0b", result); // CPU performance core 8
break;
case FF_TEMP_CPU_M2X:
detectTemp(conn, "Tp0A", "CPU core 1", result);
detectTemp(conn, "Tp0D", "CPU core 2", result);
detectTemp(conn, "Tp0E", "CPU core 3", result);
detectTemp(conn, "Tp01", "CPU core 4", result);
detectTemp(conn, "Tp02", "CPU core 5", result);
detectTemp(conn, "Tp05", "CPU core 6", result);
detectTemp(conn, "Tp06", "CPU core 7", result);
detectTemp(conn, "Tp09", "CPU core 8", result);
count += detectTemp(conn, "Tp0A", result); // CPU core 1
count += detectTemp(conn, "Tp0D", result); // CPU core 2
count += detectTemp(conn, "Tp0E", result); // CPU core 3
count += detectTemp(conn, "Tp01", result); // CPU core 4
count += detectTemp(conn, "Tp02", result); // CPU core 5
count += detectTemp(conn, "Tp05", result); // CPU core 6
count += detectTemp(conn, "Tp06", result); // CPU core 7
count += detectTemp(conn, "Tp09", result); // CPU core 8
break;
case FF_TEMP_GPU_INTEL:
detectTemp(conn, "TCGC", "GPU Intel Graphics", result);
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
goto gpu_unknown;
case FF_TEMP_GPU_AMD:
detectTemp(conn, "TGDD", "GPU AMD Radeon", result);
count += detectTemp(conn, "TGDD", result); // GPU AMD Radeon
goto gpu_unknown;
case FF_TEMP_GPU_UNKNOWN: // Nvidia?
gpu_unknown:
detectTemp(conn, "TG0D", "GPU diode", result);
detectTemp(conn, "TG0P", "GPU proximity", result);
count += detectTemp(conn, "TG0D", result); // GPU diode
count += detectTemp(conn, "TG0P", result); // GPU proximity
break;
case FF_TEMP_GPU_M1X:
detectTemp(conn, "Tg05", "GPU 1", result);
detectTemp(conn, "Tg0D", "GPU 2", result);
detectTemp(conn, "Tg0L", "GPU 3", result);
detectTemp(conn, "Tg0T", "GPU 4", result);
count += detectTemp(conn, "Tg05", result); // GPU 1
count += detectTemp(conn, "Tg0D", result); // GPU 2
count += detectTemp(conn, "Tg0L", result); // GPU 3
count += detectTemp(conn, "Tg0T", result); // GPU 4
break;
case FF_TEMP_GPU_M2X:
detectTemp(conn, "Tg0f", "GPU 1", result);
detectTemp(conn, "Tg0j", "GPU 2", result);
count += detectTemp(conn, "Tg0f", result); // GPU 1
count += detectTemp(conn, "Tg0j", result); // GPU 2
break;
case FF_TEMP_BATTERY:
detectTemp(conn, "TB1T", "Battery", result);
count += detectTemp(conn, "TB1T", result); // Battery
break;
case FF_TEMP_MEMORY:
detectTemp(conn, "Tm02", "Memory", result);
count += detectTemp(conn, "Tm02", result); // Memory
break;
}
if (count == 0)
return "No temperatures detected";
*result /= count;
return NULL;
}
+1 -1
View File
@@ -30,6 +30,6 @@ enum FFTempType
FF_TEMP_MEMORY,
};
const char *ffDetectCoreTemps(enum FFTempType type, FFlist *result);
const char *ffDetectCoreTemps(enum FFTempType type, double* result);
#endif