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;
openSUSE Build Service is sponsored by