Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.2:Update
xosview
xosview-1.16-coretemp.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xosview-1.16-coretemp.patch of Package xosview
--- linux/MeterMaker.cc | 2 linux/coretemp.cc | 314 +++++++++++++++++++++++++++++----------------------- linux/coretemp.h | 10 - 3 files changed, 188 insertions(+), 138 deletions(-) --- linux/MeterMaker.cc +++ linux/MeterMaker.cc 2015-02-03 13:12:04.257518200 +0000 @@ -166,7 +166,7 @@ void MeterMaker::makeMeters(void){ snprintf(s, 80, "coretemp%dDisplayType", i); displayType = _xos->getResourceOrUseDefault( s, displayType ); if (strncmp(displayType, "separate", 1) == 0) { - unsigned int cpuCount = CoreTemp::countCpus(pkg); + unsigned int cpuCount = CoreTemp::countCpus(); char name[10]; for (uint cpu = 0; cpu < cpuCount; cpu++) { sprintf(name, "CPU%d", cpu); --- linux/coretemp.cc +++ linux/coretemp.cc 2015-02-03 10:32:16.237529561 +0100 @@ -1,7 +1,7 @@ // -// Copyright (c) 2008 by Tomi Tapper <tomi.o.tapper@jyu.fi> +// Copyright (c) 2008-2014 by Tomi Tapper <tomi.o.tapper@jyu.fi> // -// Read coretemp reading from /sys and display actual temperature. +// Read CPU temperature readings from /sys and display actual temperature. // If actual >= high, actual temp changes color to indicate alarm. // // File based on linux/lmstemp.* by @@ -10,24 +10,29 @@ // This file may be distributed under terms of the GPL // // -// + #include "coretemp.h" -#include "xosview.h" #include <stdlib.h> +#include <stdio.h> +#include <string.h> #include <glob.h> -#include <dirent.h> -#include <sys/stat.h> #include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> #include <fstream> +#include <iostream> +#include <string> #define PATH_SIZE 128 static const char SYS_HWMON[] = "/sys/class/hwmon"; static const char SYS_CORETEMP[] = "/sys/devices/platform/coretemp"; +static const char SYS_VIATEMP[] = "/sys/devices/platform/via_cputemp"; CoreTemp::CoreTemp( XOSView *parent, const char *label, const char *caption, int pkg, int cpu ) : FieldMeter( parent, 3, label, caption, 1, 1, 1 ), _pkg(pkg), _cpu(cpu) { + metric_ = true; _high = 0; } @@ -46,20 +51,91 @@ void CoreTemp::checkResources( void ) { priority_ = atoi( parent_->getResource( "coretempPriority" ) ); SetUsedFormat( parent_->getResource( "coretempUsedFormat" ) ); - unsigned int cpucount = countCpus(_pkg); + findSysFiles(); + if ( _cpus.empty() ) { // should not happen at this point + std::cerr << "BUG: Could not determine sysfs file(s) for coretemp." << std::endl; + parent_->done(1); + } + + // Get TjMax and use it for total, if available. + // Not found on k8temp and via-cputemp. + std::ifstream file; + std::string dummy = _cpus.front(); + dummy.replace(dummy.find_last_of('_'), 6, "_crit"); + file.open(dummy.c_str()); + if ( file.good() ) { + file >> total_; + file.close(); + total_ /= 1000.0; + } + else + total_ = atoi( parent_->getResourceOrUseDefault("coretempHighest", "100") ); + + // Use tTarget/tCtl (when maximum cooling needs to be turned on) as high, + // if found. On older Cores this MSR is empty and kernel sets this equal to + // tjMax. Not found on k8temp and via-cputemp. On k10temp this is fixed value. + char l[32]; + dummy = _cpus.front(); + dummy.replace(dummy.find_last_of('_'), 6, "_max"); + file.open(dummy.c_str()); + if ( file.good() ) { + file >> _high; + file.close(); + _high /= 1000.0; + snprintf(l, 32, "ACT(\260C)/%d/%d", (int)_high, (int)total_); + } + else + _high = total_; + + if (_high == total_) { // No tTarget/tCtl + // Use user-defined high, or "no high". + const char *high = parent_->getResourceOrUseDefault("coretempHigh", NULL); + if (high) { + _high = atoi(high); + snprintf(l, 32, "ACT(\260C)/%d/%d", (int)_high, (int)total_); + } + else + snprintf(l, 32, "ACT(\260C)/HIGH/%d", (int)total_); + } + legend(l); +} + +/* Find absolute paths of files to be used. */ +void CoreTemp::findSysFiles( void ) { + int cpu = 0; + unsigned int i = 0, cpucount = countCores(_pkg); char name[PATH_SIZE]; std::string dummy; std::ifstream file; + glob_t gbuf; DIR *dir; struct dirent *dent; - dir = opendir(SYS_HWMON); - if (!dir) { + // Intel and VIA CPUs. + snprintf(name, PATH_SIZE, "%s.%d/temp*_label", SYS_CORETEMP, _pkg); + glob(name, 0, NULL, &gbuf); + snprintf(name, PATH_SIZE, "%s.%d/temp*_label", SYS_VIATEMP, _pkg); + glob(name, GLOB_APPEND, NULL, &gbuf); + for (i = 0; i < gbuf.gl_pathc; i++) { + file.open(gbuf.gl_pathv[i]); + file >> dummy >> cpu; // "Core n" or "Physical id n" + file.close(); + if ( strncmp(dummy.c_str(), "Core", 4) == 0 ) { + strcpy(strrchr(gbuf.gl_pathv[i], '_'), "_input"); + if (_cpu < 0 || cpu == _cpu) + _cpus.push_back(gbuf.gl_pathv[i]); + } + } + globfree(&gbuf); + if ( !_cpus.empty() ) + return; + + // AMD CPUs. + if ( !(dir = opendir(SYS_HWMON)) ) { std::cerr << "Can not open " << SYS_HWMON << " directory." << std::endl; parent_->done(1); return; } - while ( (dent = readdir(dir)) ) { if ( !strncmp(dent->d_name, ".", 1) || !strncmp(dent->d_name, "..", 2) ) @@ -72,73 +148,27 @@ void CoreTemp::checkResources( void ) { file >> dummy; file.close(); - if (strncmp(dummy.c_str(), "k8temp", 6) == 0) { - // each core has two sensors with index starting from 1 + if ( strncmp(dummy.c_str(), "k8temp", 6) == 0 || + strncmp(dummy.c_str(), "k10temp", 7) == 0 ) { + if (cpu++ != _pkg) + continue; + // K8 core has two sensors with index starting from 1 + // K10 has only one sensor per physical CPU if (_cpu < 0) { // avg or max - for (uint i = 1; i <= cpucount; i++) { - snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", SYS_HWMON, dent->d_name, i); + for (i = 1; i <= cpucount; i++) { + snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", + SYS_HWMON, dent->d_name, i); _cpus.push_back(name); } } else { // single sensor - snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", SYS_HWMON, dent->d_name, _cpu + 1); + snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", + SYS_HWMON, dent->d_name, _cpu + 1); _cpus.push_back(name); } } - else if (strncmp(dummy.c_str(), "coretemp", 8) == 0) { - int i = 0, cpu = 0; - // Gather the sysfs indices which are not the same as core numbers. - // Core numbers are not unique across physical CPUs, but sysfs indices are. - while (_cpus.size() != cpucount) { - snprintf(name, PATH_SIZE, "%s.%d/temp%d_label", SYS_CORETEMP, _pkg, i); - file.open(name); - if (!file) { - i++; - continue; - } - file >> dummy >> cpu; // "Core n" or "Physical id n" - file.close(); - if (strncmp(dummy.c_str(), "Core", 1) != 0) { - i++; - continue; - } - snprintf(name, PATH_SIZE, "%s.%d/temp%d_input", SYS_CORETEMP, _pkg, i++); - if (_cpu < 0) - _cpus.push_back(name); - else if (cpu == _cpu) { - _cpus.push_back(name); - break; - } - } - } - else if (strncmp(dummy.c_str(), "k10temp", 7) == 0) { - _cpu = 1; - snprintf(name, PATH_SIZE, "%s/%s/device/temp%d_input", SYS_HWMON, dent->d_name, _cpu); - _cpus.push_back(name); // K10 has only one sensor per physical CPU - } - - if (_cpus.empty()) - continue; - - // sysfs node was found - // get TjMax and use it for total if available - dummy = _cpus.front(); - dummy.replace(dummy.find_last_of('_'), 6, "_crit"); - file.open(dummy.c_str()); - if (file) { - file >> total_; - file.close(); - total_ /= 1000.0; - } - else - total_ = atoi(parent_->getResourceOrUseDefault("coretempHighest", "100")); - - _high = total_; - closedir(dir); - return; } - std::cerr << "You do not seem to have CPU temperature sensor available." << std::endl; - parent_->done(1); + closedir(dir); } void CoreTemp::checkevent( void ) { @@ -148,10 +178,8 @@ void CoreTemp::checkevent( void ) { void CoreTemp::getcoretemp( void ) { std::ifstream file; - double dummy, high; - + double dummy; fields_[0] = 0.0; - high = 0.0; if (_cpu >= 0) { // only one core file.open(_cpus.back().c_str()); @@ -197,24 +225,12 @@ void CoreTemp::getcoretemp( void ) { return; } - // Use tCase (when maximum cooling needs to be turned on) as high, if found. - // Not found on k8temp, which uses user defined total as high (or default 100). - // This is the same for all cores in package. I don't know if this ever - // changes in real world, so it could be read once in checkResources(). - std::string tcase = _cpus.front(); - tcase.replace(tcase.find_last_of('_'), 6, "_max"); - file.open(tcase.c_str()); - if (file) { - file >> high; - file.close(); - high /= 1000.0; - } - else - high = _high; - fields_[0] /= 1000.0; + setUsed( fields_[0], total_ ); - fields_[1] = high - fields_[0]; + if (fields_[0] < 0) + fields_[0] = 0.0; + fields_[1] = _high - fields_[0]; if (fields_[1] < 0) { // alarm: T > high fields_[1] = 0; if (colors_[0] != _highcolor) { @@ -232,70 +248,102 @@ void CoreTemp::getcoretemp( void ) { fields_[2] = total_ - fields_[1] - fields_[0]; if (fields_[2] < 0) fields_[2] = 0; - - setUsed( fields_[0], total_ ); - - if (high != _high) { - char l[16]; - _high = high; - snprintf(l, 16, "ACT/%d/%d", (int)high, (int)total_); - legend(l); - drawlegend(); - } } /* Count sensors available to coretemp in the given package. */ -unsigned int CoreTemp::countCpus(int pkg) +unsigned int CoreTemp::countCores( unsigned int pkg ) { glob_t gbuf; char s[PATH_SIZE]; - struct stat sbuf; - int count = 0; + unsigned int i, count = 0, cpu = 0; + DIR *dir; + struct dirent *dent; std::string dummy; std::ifstream file; - snprintf(s, PATH_SIZE, "%s.%d", SYS_CORETEMP, pkg); - if (stat(s, &sbuf) == 0) { - strncat(s, "/temp*_label", PATH_SIZE - strlen(s) - 1); - glob(s, 0, NULL, &gbuf); - // loop through paths in gbuf and check if it is a core or package - for (uint i = 0; i < gbuf.gl_pathc; i++) { - file.open(gbuf.gl_pathv[i]); - file >> dummy; - file.close(); - if (strncmp(dummy.c_str(), "Core", 4) == 0) - count++; - } - globfree(&gbuf); + // Intel or VIA CPU. + snprintf(s, PATH_SIZE, "%s.%d/temp*_label", SYS_CORETEMP, pkg); + glob(s, 0, NULL, &gbuf); + snprintf(s, PATH_SIZE, "%s.%d/temp*_label", SYS_VIATEMP, pkg); + glob(s, GLOB_APPEND, NULL, &gbuf); + // loop through paths in gbuf and check if it is a core or package + for (i = 0; i < gbuf.gl_pathc; i++) { + file.open(gbuf.gl_pathv[i]); + file >> dummy; + file.close(); + if ( strncmp(dummy.c_str(), "Core", 4) == 0 ) + count++; } - else { - DIR *dir; - struct dirent *dent; - dir = opendir(SYS_HWMON); - if (!dir) - return 0; - - // loop through hwmon devices and if AMD sensor if found, count its inputs - while ( (dent = readdir(dir)) ) { - if ( !strncmp(dent->d_name, ".", 1) || - !strncmp(dent->d_name, "..", 2) ) - continue; - - snprintf(s, PATH_SIZE, "%s/%s/device/name", SYS_HWMON, dent->d_name); - file.open(s); + globfree(&gbuf); + if (count > 0) + return count; + + // AMD CPU. + if ( !(dir = opendir(SYS_HWMON)) ) + return 0; + // loop through hwmon devices and when AMD sensor is found, count its inputs + while ( (dent = readdir(dir)) ) { + if ( !strncmp(dent->d_name, ".", 1) || + !strncmp(dent->d_name, "..", 2) ) + continue; + snprintf(s, PATH_SIZE, "%s/%s/device/name", SYS_HWMON, dent->d_name); + file.open(s); + if ( file.good() ) { file >> dummy; file.close(); if ( strncmp(dummy.c_str(), "k8temp", 6) == 0 || strncmp(dummy.c_str(), "k10temp", 7) == 0 ) { + if (cpu++ < pkg) + continue; snprintf(s, PATH_SIZE, "%s/%s/device/temp*_input", SYS_HWMON, dent->d_name); - break; + glob(s, 0, NULL, &gbuf); + count += gbuf.gl_pathc; + globfree(&gbuf); } } - closedir(dir); + } + closedir(dir); + return count; +} + +/* Count physical CPUs with sensors. */ +unsigned int CoreTemp::countCpus( void ) +{ + glob_t gbuf; + char s[PATH_SIZE]; + unsigned int count = 0; + DIR *dir; + struct dirent *dent; + std::string dummy; + std::ifstream file; - glob(s, 0, NULL, &gbuf); - count = gbuf.gl_pathc; - globfree(&gbuf); + // Count Intel and VIA packages. + snprintf(s, PATH_SIZE, "%s.*", SYS_CORETEMP); + glob(s, 0, NULL, &gbuf); + snprintf(s, PATH_SIZE, "%s.*", SYS_VIATEMP); + glob(s, GLOB_APPEND, NULL, &gbuf); + count += gbuf.gl_pathc; + globfree(&gbuf); + if (count > 0) + return count; + + // Count AMD packages. + if ( !(dir = opendir(SYS_HWMON)) ) + return 0; + while ( (dent = readdir(dir)) ) { + if ( !strncmp(dent->d_name, ".", 1) || + !strncmp(dent->d_name, "..", 2) ) + continue; + snprintf(s, PATH_SIZE, "%s/%s/device/name", SYS_HWMON, dent->d_name); + file.open(s); + if ( file.good() ) { + file >> dummy; + file.close(); + if ( strncmp(dummy.c_str(), "k8temp", 6) == 0 || + strncmp(dummy.c_str(), "k10temp", 7) == 0 ) + count++; + } } + closedir(dir); return count; } --- linux/coretemp.h +++ linux/coretemp.h 2015-02-03 10:32:16.301619049 +0100 @@ -1,5 +1,5 @@ // -// Copyright (c) 2008 by Tomi Tapper <tomi.o.tapper@jyu.fi> +// Copyright (c) 2008-2014 by Tomi Tapper <tomi.o.tapper@jyu.fi> // // File based on linux/lmstemp.* by // Copyright (c) 2000, 2006 by Leopold Toetsch <lt@toetsch.at> @@ -7,12 +7,12 @@ // This file may be distributed under terms of the GPL // // -// + #ifndef _CORETEMP_H_ #define _CORETEMP_H_ -#include "cpumeter.h" #include "fieldmeter.h" +#include "xosview.h" #include <string> #include <vector> @@ -26,12 +26,14 @@ public: void checkevent( void ); void checkResources( void ); - static unsigned int countCpus(int pkg); + static unsigned int countCores( unsigned int pkg ); + static unsigned int countCpus( void ); protected: void getcoretemp( void ); private: + void findSysFiles( void ); int _pkg, _cpu, _high; std::vector<std::string> _cpus; unsigned long _actcolor, _highcolor;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor