diff --git a/CHANGELOG.md b/CHANGELOG.md index 403c33fef..3d627cd44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/detection/battery/battery_apple.c b/src/detection/battery/battery_apple.c index 82b020179..dc1281dda 100644 --- a/src/detection/battery/battery_apple.c +++ b/src/detection/battery/battery_apple.c @@ -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); diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 6de492132..9dcb07edd 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -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; } diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 21c2a0a27..6cb786d6a 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -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); diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c index 0a612edb6..7af1e12fe 100644 --- a/src/detection/temps/temps_apple.c +++ b/src/detection/temps/temps_apple.c @@ -6,35 +6,6 @@ #include #include -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; } diff --git a/src/detection/temps/temps_apple.h b/src/detection/temps/temps_apple.h index 147c32d07..0fe4b0174 100644 --- a/src/detection/temps/temps_apple.h +++ b/src/detection/temps/temps_apple.h @@ -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