Add detailed CPU information gathering to the TDE hardware library

pull/16/head
Timothy Pearson 12 years ago
parent 8f76b98ccc
commit 81dacc29a4

@ -123,7 +123,7 @@ set( ${target}_SRCS
ktempdir.cpp kshell.cpp kmountpoint.cpp kcalendarsystemjalali.cpp
kprotocolinfo_tdecore.cpp kprotocolinfofactory.cpp kxerrorhandler.cpp
kuser.cpp kconfigskeleton.cpp kconfigdialogmanager.cpp klockfile.cpp
kqiodevicegzip_p.cpp ktimezones.cpp tdehardwaredevices.cpp
kqiodevicegzip_p.cpp ktimezones.cpp tdehardwaredevices.cpp ksimpledirwatch.cpp
)
tde_add_library( ${target} SHARED AUTOMOC

File diff suppressed because it is too large Load Diff

@ -0,0 +1,293 @@
/* This file is part of the KDE libraries
Copyright (C) 1998 Sven Radej <sven@lisa.exp.univie.ac.at>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _KSIMPLEDIRWATCH_H
#define _KSIMPLEDIRWATCH_H
#include <tqtimer.h>
#include <tqdatetime.h>
#include <tqmap.h>
#include <tdelibs_export.h>
#define kdirwatch KSimpleDirWatch::self()
class KSimpleDirWatchPrivate;
/**
* KSimpleDirWatch is a basic copy of KDirWatch
* but with the KIO linking requirement removed
*
* Watch directories and files for changes.
* The watched directories or files don't have to exist yet.
*
* When a watched directory is changed, i.e. when files therein are
* created or deleted, KSimpleDirWatch will emit the signal dirty().
*
* When a watched, but previously not existing directory gets created,
* KSimpleDirWatch will emit the signal created().
*
* When a watched directory gets deleted, KSimpleDirWatch will emit the
* signal deleted(). The directory is still watched for new
* creation.
*
* When a watched file is changed, i.e. attributes changed or written
* to, KSimpleDirWatch will emit the signal dirty().
*
* Scanning of particular directories or files can be stopped temporarily
* and restarted. The whole class can be stopped and restarted.
* Directories and files can be added/removed from the list in any state.
*
* The implementation uses the FAM service when available;
* if FAM is not available, the DNOTIFY functionality is used on LINUX.
* As a last resort, a regular polling for change of modification times
* is done; the polling interval is a global config option:
* DirWatch/PollInterval and DirWatch/NFSPollInterval for NFS mounted
* directories.
*
* @see self()
* @short Class for watching directory and file changes.
* @author Sven Radej <sven@lisa.exp.univie.ac.at>
*/
class KIO_EXPORT KSimpleDirWatch : public TQObject
{
Q_OBJECT
public:
/**
* Constructor.
*
* Scanning begins immediately when a dir/file watch
* is added.
* @param parent the parent of the TQObject (or 0 for parent-less KDataTools)
* @param name the name of the TQObject, can be 0
*/
KSimpleDirWatch (TQObject* parent = 0, const char* name = 0);
/**
* Destructor.
*
* Stops scanning and cleans up.
*/
~KSimpleDirWatch();
/**
* Adds a directory to be watched.
*
* The directory does not have to exist. When @p watchFiles is
* false (the default), the signals dirty(), created(), deleted()
* can be emitted, all for the watched directory.
* When @p watchFiles is true, all files in the watched directory
* are watched for changes, too. Thus, the signals dirty(),
* created(), deleted() can be emitted.
*
* @param path the path to watch
* @param watchFiles if true, the KSimpleDirWatch will also watch files - NOT IMPLEMENTED YET
* @param recursive if true, all sub directories are also watched - NOT IMPLEMENTED YET
*/
void addDir(const TQString& path,
bool watchFiles = false, bool recursive = false);
/**
* Adds a file to be watched.
* @param file the file to watch
*/
void addFile(const TQString& file);
/**
* Returns the time the directory/file was last changed.
* @param path the file to check
* @return the date of the last modification
*/
TQDateTime ctime(const TQString& path);
/**
* Removes a directory from the list of scanned directories.
*
* If specified path is not in the list this does nothing.
* @param path the path of the dir to be removed from the list
*/
void removeDir(const TQString& path);
/**
* Removes a file from the list of watched files.
*
* If specified path is not in the list this does nothing.
* @param file the file to be removed from the list
*/
void removeFile(const TQString& file);
/**
* Stops scanning the specified path.
*
* The @p path is not deleted from the interal just, it is just skipped.
* Call this function when you perform an huge operation
* on this directory (copy/move big files or many files). When finished,
* call restartDirScan(path).
*
* @param path the path to skip
* @return true if the @p path is being watched, otherwise false
* @see restartDirScanning()
*/
bool stopDirScan(const TQString& path);
/**
* Restarts scanning for specified path.
*
* Resets ctime. It doesn't notify
* the change (by emitted a signal), since the ctime value is reset.
*
* Call it when you are finished with big operations on that path,
* @em and when @em you have refreshed that path.
*
* @param path the path to restart scanning
* @return true if the @p path is being watched, otherwise false
* @see stopDirScanning()
*/
bool restartDirScan(const TQString& path);
/**
* Starts scanning of all dirs in list.
*
* @param notify If true, all changed directories (since
* stopScan() call) will be notified for refresh. If notify is
* false, all ctimes will be reset (except those who are stopped,
* but only if @p skippedToo is false) and changed dirs won't be
* notified. You can start scanning even if the list is
* empty. First call should be called with @p false or else all
* directories
* in list will be notified.
* @param skippedToo if true, the skipped directoris (scanning of which was
* stopped with stopDirScan() ) will be reset and notified
* for change. Otherwise, stopped directories will continue to be
* unnotified.
*/
void startScan( bool notify=false, bool skippedToo=false );
/**
* Stops scanning of all directories in internal list.
*
* The timer is stopped, but the list is not cleared.
*/
void stopScan();
/**
* Is scanning stopped?
* After creation of a KSimpleDirWatch instance, this is false.
* @return true when scanning stopped
*/
bool isStopped() { return _isStopped; }
/**
* Check if a directory is being watched by this KSimpleDirWatch instance
* @param path the directory to check
* @return true if the directory is being watched
*/
bool contains( const TQString& path ) const;
/**
* Dump statistic information about all KSimpleDirWatch instances.
* This checks for consistency, too.
*/
static void statistics();
/**
* Emits created().
* @param path the path of the file or directory
*/
void setCreated( const TQString &path );
/**
* Emits dirty().
* @param path the path of the file or directory
*/
void setDirty( const TQString &path );
/**
* Emits deleted().
* @param path the path of the file or directory
*/
void setDeleted( const TQString &path );
enum Method { FAM, DNotify, Stat, INotify };
/**
* Returns the preferred internal method to
* watch for changes.
* @since 3.2
*/
Method internalMethod();
/**
* The KSimpleDirWatch instance usually globally used in an application.
* It is automatically deleted when the application exits.
*
* However, you can create an arbitrary number of KSimpleDirWatch instances
* aside from this one - for those you have to take care of memory management.
*
* This function returns an instance of KSimpleDirWatch. If there is none, it
* will be created.
*
* @return a KSimpleDirWatch instance
*/
static KSimpleDirWatch* self();
/**
* Returns true if there is an instance of KSimpleDirWatch.
* @return true if there is an instance of KSimpleDirWatch.
* @see KSimpleDirWatch::self()
* @since 3.1
*/
static bool exists();
signals:
/**
* Emitted when a watched object is changed.
* For a directory this signal is emitted when files
* therein are created or deleted.
* For a file this signal is emitted when its size or attributes change.
*
* When you watch a directory, changes in the size or attributes of
* contained files may or may not trigger this signal to be emitted
* depending on which backend is used by KSimpleDirWatch.
*
* The new ctime is set before the signal is emitted.
* @param path the path of the file or directory
*/
void dirty (const TQString &path);
/**
* Emitted when a file or directory is created.
* @param path the path of the file or directory
*/
void created (const TQString &path );
/**
* Emitted when a file or directory is deleted.
*
* The object is still watched for new creation.
* @param path the path of the file or directory
*/
void deleted (const TQString &path );
private:
bool _isStopped;
KSimpleDirWatchPrivate *d;
static KSimpleDirWatch* s_pSelf;
};
#endif
// vim: sw=3 et

@ -0,0 +1,161 @@
/* Private Header for class of KSimpleDirWatchPrivate
*
* this separate header file is needed for TQMOC processing
* because KSimpleDirWatchPrivate has signals and slots
*
* KSimpleDirWatch is a basic copy of KDirWatch
* but with the KIO linking requirement removed
*/
#ifndef _KSIMPLEDIRWATCH_P_H
#define _KSIMPLEDIRWATCH_P_H
#ifdef HAVE_FAM
#include <fam.h>
#endif
#include <ctime>
#define invalid_ctime ((time_t)-1)
/* KSimpleDirWatchPrivate is a singleton and does the watching
* for every KSimpleDirWatch instance in the application.
*/
class KSimpleDirWatchPrivate : public TQObject
{
Q_OBJECT
public:
enum entryStatus { Normal = 0, NonExistent };
enum entryMode { UnknownMode = 0, StatMode, DNotifyMode, INotifyMode, FAMMode };
enum { NoChange=0, Changed=1, Created=2, Deleted=4 };
struct Client {
KSimpleDirWatch* instance;
int count;
// did the instance stop watching
bool watchingStopped;
// events blocked when stopped
int pending;
};
class Entry
{
public:
// the last observed modification time
time_t m_ctime;
// the last observed link count
int m_nlink;
entryStatus m_status;
entryMode m_mode;
bool isDir;
// instances interested in events
TQPtrList<Client> m_clients;
// nonexistent entries of this directory
TQPtrList<Entry> m_entries;
TQString path;
int msecLeft, freq;
void addClient(KSimpleDirWatch*);
void removeClient(KSimpleDirWatch*);
int clients();
bool isValid() { return m_clients.count() || m_entries.count(); }
bool dirty;
void propagate_dirty();
#ifdef HAVE_FAM
FAMRequest fr;
#endif
#ifdef HAVE_DNOTIFY
int dn_fd;
#endif
#ifdef HAVE_INOTIFY
int wd;
#endif
};
typedef TQMap<TQString,Entry> EntryMap;
KSimpleDirWatchPrivate();
~KSimpleDirWatchPrivate();
void resetList (KSimpleDirWatch*,bool);
void useFreq(Entry* e, int newFreq);
void addEntry(KSimpleDirWatch*,const TQString&, Entry*, bool);
void removeEntry(KSimpleDirWatch*,const TQString&, Entry*);
bool stopEntryScan(KSimpleDirWatch*, Entry*);
bool restartEntryScan(KSimpleDirWatch*, Entry*, bool );
void stopScan(KSimpleDirWatch*);
void startScan(KSimpleDirWatch*, bool, bool);
void removeEntries(KSimpleDirWatch*);
void statistics();
Entry* entry(const TQString&);
int scanEntry(Entry* e);
void emitEvent(Entry* e, int event, const TQString &fileName = TQString::null);
// Memory management - delete when last KSimpleDirWatch gets deleted
void ref() { m_ref++; }
bool deref() { return ( --m_ref == 0 ); }
static bool isNoisyFile( const char *filename );
public slots:
void slotRescan();
void famEventReceived(); // for FAM
void slotActivated(); // for DNOTIFY
void slotRemoveDelayed();
public:
TQTimer *timer;
EntryMap m_mapEntries;
int freq;
int statEntries;
int m_nfsPollInterval, m_PollInterval;
int m_ref;
bool useStat(Entry*);
bool delayRemove;
TQPtrList<Entry> removeList;
bool rescan_all;
TQTimer rescan_timer;
#ifdef HAVE_FAM
TQSocketNotifier *sn;
FAMConnection fc;
bool use_fam;
void checkFAMEvent(FAMEvent*);
bool useFAM(Entry*);
#endif
#if defined(HAVE_DNOTIFY) || defined(HAVE_INOTIFY)
TQSocketNotifier *mSn;
#endif
#ifdef HAVE_DNOTIFY
bool supports_dnotify;
int mPipe[2];
TQIntDict<Entry> fd_Entry;
static void dnotify_handler(int, siginfo_t *si, void *);
static void dnotify_sigio_handler(int, siginfo_t *si, void *);
bool useDNotify(Entry*);
#endif
#ifdef HAVE_INOTIFY
bool supports_inotify;
int m_inotify_fd;
bool useINotify(Entry*);
#endif
};
#endif // KSIMPLEDIRWATCH_P_H

@ -27,6 +27,7 @@
#include <klocale.h>
#include <kconfig.h>
#include <ktempfile.h>
#include <ksimpledirwatch.h>
#include <kstandarddirs.h>
#include <libudev.h>
@ -767,6 +768,76 @@ bool TDEStorageDevice::unmountDevice(TQString* errRet, int* retcode) {
return false;
}
TDECPUDevice::TDECPUDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn) : TDEGenericDevice(dt, dn) {
}
TDECPUDevice::~TDECPUDevice() {
}
double &TDECPUDevice::frequency() {
return m_frequency;
}
void TDECPUDevice::setFrequency(double fr) {
m_frequency = fr;
}
double &TDECPUDevice::minFrequency() {
return m_minfrequency;
}
void TDECPUDevice::setMinFrequency(double fr) {
m_minfrequency = fr;
}
double &TDECPUDevice::maxFrequency() {
return m_maxfrequency;
}
void TDECPUDevice::setMaxFrequency(double fr) {
m_maxfrequency = fr;
}
double &TDECPUDevice::transitionLatency() {
return m_transitionlatency;
}
void TDECPUDevice::setTransitionLatency(double tl) {
m_transitionlatency = tl;
}
TQString &TDECPUDevice::governor() {
return m_governor;
}
void TDECPUDevice::setGovernor(TQString gr) {
m_governor = gr;
}
TQString &TDECPUDevice::scalingDriver() {
return m_scalingdriver;
}
void TDECPUDevice::setScalingDriver(TQString dr) {
m_scalingdriver = dr;
}
TQStringList &TDECPUDevice::dependentProcessors() {
return m_tiedprocs;
}
void TDECPUDevice::setDependentProcessors(TQStringList dp) {
m_tiedprocs = dp;
}
TQStringList &TDECPUDevice::availableFrequencies() {
return m_frequencies;
}
void TDECPUDevice::setAvailableFrequencies(TQStringList af) {
m_frequencies = af;
}
TDEHardwareDevices::TDEHardwareDevices() {
// Initialize members
pci_id_map = 0;
@ -808,12 +879,49 @@ TDEHardwareDevices::TDEHardwareDevices() {
m_mountScanNotifier = new TQSocketNotifier(m_procMountsFd, TQSocketNotifier::Exception, this);
connect( m_mountScanNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(processModifiedMounts()) );
// Read in the current cpu information
// Yes, a race condition exists between this and the cpu monitor start below, but it shouldn't be a problem 99.99% of the time
m_cpuInfo.clear();
TQFile cpufile( "/proc/cpuinfo" );
if ( cpufile.open( IO_ReadOnly ) ) {
TQTextStream stream( &cpufile );
while ( !stream.atEnd() ) {
m_cpuInfo.append(stream.readLine());
}
cpufile.close();
}
// [FIXME 0.01]
// Apparently the Linux kernel just does not notify userspace applications of CPU frequency changes
// This is STUPID, as it means I have to poll the CPU information structures with a 0.5 second or so timer just to keep the information up to date
#if 0
// Monitor for changed cpu information
// Watched directories are set up during the initial CPU scan
m_cpuWatch = new KSimpleDirWatch(this);
connect( m_cpuWatch, TQT_SIGNAL(dirty(const TQString &)), this, TQT_SLOT(processModifiedCPUs()) );
#else
m_cpuWatchTimer = new TQTimer(this);
connect( m_cpuWatchTimer, SIGNAL(timeout()), this, SLOT(processModifiedCPUs()) );
TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
if (nodezerocpufreq.exists()) {
m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
}
#endif
// Update internal device information
queryHardwareInformation();
}
}
TDEHardwareDevices::~TDEHardwareDevices() {
// [FIXME 0.01]
#if 0
// Stop CPU scanning
m_cpuWatch->stopScan();
#else
m_cpuWatchTimer->stop();
#endif
// Stop mount scanning
close(m_procMountsFd);
@ -946,6 +1054,158 @@ void TDEHardwareDevices::processHotPluggedHardware() {
}
}
void TDEHardwareDevices::processModifiedCPUs() {
// Detect what changed between the old cpu information and the new information,
// and emit appropriate events
// Read new CPU information table
m_cpuInfo.clear();
TQFile cpufile( "/proc/cpuinfo" );
if ( cpufile.open( IO_ReadOnly ) ) {
TQTextStream stream( &cpufile );
while ( !stream.atEnd() ) {
m_cpuInfo.append(stream.readLine());
}
cpufile.close();
}
// Parse CPU information table
TDECPUDevice *cdevice;
cdevice = 0;
bool modified = false;
TQString curline;
int processorNumber = 0;
int processorCount = 0;
for (TQStringList::Iterator cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
// WARNING This routine assumes that "processor" is always the first entry in /proc/cpuinfo!
curline = *cpuit;
if (curline.startsWith("processor")) {
curline.remove(0, curline.find(":")+1);
curline = curline.stripWhiteSpace();
processorNumber = curline.toInt();
cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
}
if (curline.startsWith("model name")) {
curline.remove(0, curline.find(":")+1);
curline = curline.stripWhiteSpace();
if (cdevice->name() != curline) modified = true;
cdevice->setName(curline);
}
if (curline.startsWith("cpu MHz")) {
curline.remove(0, curline.find(":")+1);
curline = curline.stripWhiteSpace();
if (cdevice->frequency() != curline.toDouble()) modified = true;
cdevice->setFrequency(curline.toDouble());
}
if (curline.startsWith("vendor_id")) {
curline.remove(0, curline.find(":")+1);
curline = curline.stripWhiteSpace();
if (cdevice->vendorName() != curline) modified = true;
cdevice->setVendorName(curline);
if (cdevice->vendorEncoded() != curline) modified = true;
cdevice->setVendorEncoded(curline);
}
}
processorCount = processorNumber+1;
// Read in other information from cpufreq, if available
for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
TQDir cpufreq_dir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber));
TQString scalinggovernor;
TQString scalingdriver;
double minfrequency = -1;
double maxfrequency = -1;
double trlatency = -1;
TQStringList affectedcpulist;
TQStringList frequencylist;
if (cpufreq_dir.exists()) {
TQString nodename = cpufreq_dir.path();
nodename.append("/scaling_governor");
TQFile scalinggovernorfile(nodename);
if (scalinggovernorfile.open(IO_ReadOnly)) {
TQTextStream stream( &scalinggovernorfile );
scalinggovernor = stream.readLine();
scalinggovernorfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/scaling_driver");
TQFile scalingdriverfile(nodename);
if (scalingdriverfile.open(IO_ReadOnly)) {
TQTextStream stream( &scalingdriverfile );
scalingdriver = stream.readLine();
scalingdriverfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/scaling_min_freq");
TQFile minfrequencyfile(nodename);
if (minfrequencyfile.open(IO_ReadOnly)) {
TQTextStream stream( &minfrequencyfile );
minfrequency = stream.readLine().toDouble()/1000.0;
minfrequencyfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/scaling_max_freq");
TQFile maxfrequencyfile(nodename);
if (maxfrequencyfile.open(IO_ReadOnly)) {
TQTextStream stream( &maxfrequencyfile );
maxfrequency = stream.readLine().toDouble()/1000.0;
maxfrequencyfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/cpuinfo_transition_latency");
TQFile trlatencyfile(nodename);
if (trlatencyfile.open(IO_ReadOnly)) {
TQTextStream stream( &trlatencyfile );
trlatency = stream.readLine().toDouble()/1000.0;
trlatencyfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/affected_cpus");
TQFile tiedcpusfile(nodename);
if (tiedcpusfile.open(IO_ReadOnly)) {
TQTextStream stream( &tiedcpusfile );
affectedcpulist = TQStringList::split(" ", stream.readLine());
tiedcpusfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/scaling_available_frequencies");
TQFile availfreqsfile(nodename);
if (availfreqsfile.open(IO_ReadOnly)) {
TQTextStream stream( &availfreqsfile );
frequencylist = TQStringList::split(" ", stream.readLine());
availfreqsfile.close();
}
}
// Update CPU information structure
if (cdevice->governor() != scalinggovernor) modified = true;
cdevice->setGovernor(scalinggovernor);
if (cdevice->scalingDriver() != scalingdriver) modified = true;
cdevice->setScalingDriver(scalingdriver);
if (cdevice->minFrequency() != minfrequency) modified = true;
cdevice->setMinFrequency(minfrequency);
if (cdevice->maxFrequency() != maxfrequency) modified = true;
cdevice->setMaxFrequency(maxfrequency);
if (cdevice->transitionLatency() != trlatency) modified = true;
cdevice->setTransitionLatency(trlatency);
if (cdevice->dependentProcessors().join(" ") != affectedcpulist.join(" ")) modified = true;
cdevice->setDependentProcessors(affectedcpulist);
if (cdevice->availableFrequencies().join(" ") != frequencylist.join(" ")) modified = true;
cdevice->setAvailableFrequencies(frequencylist);
}
if (modified) {
for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
TDEGenericDevice* hwdevice = findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
// Signal new information available
emit hardwareUpdated(hwdevice);
}
}
}
void TDEHardwareDevices::processModifiedMounts() {
// Detect what changed between the old mount table and the new one,
// and emit appropriate events
@ -2325,22 +2585,23 @@ void TDEHardwareDevices::addCoreSystemDevices() {
line.remove(0, line.find(":")+1);
line = line.stripWhiteSpace();
processorNumber = line.toInt();
hwdevice = new TDEGenericDevice(TDEGenericDeviceType::CPU);
hwdevice = new TDECPUDevice(TDEGenericDeviceType::CPU);
hwdevice->setSystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
m_deviceList.append(hwdevice);
}
if (line.startsWith("model name")) {
line.remove(0, line.find(":")+1);
line = line.stripWhiteSpace();
hwdevice->setName(line);
#if 0
// Set up CPU information monitor
// The only way CPU information can be changed is if something changes in the cpufreq node
// This may change in the future, but for now it is a fairly good assumption
m_cpuWatch->addDir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber));
#endif
}
lines += line;
}
file.close();
}
// FIXME
// For each CPU, look for cpufreq and parse as much information as possible
// Populate CPU information
processModifiedCPUs();
}
TQString TDEHardwareDevices::findPCIDeviceName(TQString vendorid, TQString modelid, TQString subvendorid, TQString submodelid) {

@ -636,10 +636,116 @@ class TDECORE_EXPORT TDEStorageDevice : public TDEGenericDevice
TQStringList m_slaveDevices;
};
class TDECORE_EXPORT TDECPUDevice : public TDEGenericDevice
{
public:
/**
* Constructor.
* @param Device type
*/
TDECPUDevice(TDEGenericDeviceType::TDEGenericDeviceType dt, TQString dn=TQString::null);
/**
* Destructor.
*/
~TDECPUDevice();
/**
* @return a double with the current CPU frequency in MHz, if available
*/
double &frequency();
/**
* @param a double with the current CPU frequency in MHz, if available
*/
void setFrequency(double fr);
/**
* @return a double with the minimum CPU frequency in MHz, if available
*/
double &minFrequency();
/**
* @param a double with the minimum CPU frequency in MHz, if available
*/
void setMinFrequency(double fr);
/**
* @return a double with the maximum CPU frequency in MHz, if available
*/
double &maxFrequency();
/**
* @param a double with the maximum CPU frequency in MHz, if available
*/
void setMaxFrequency(double fr);
/**
* @return a double with the transition latency in ns, if available
*/
double &transitionLatency();
/**
* @param a double with the transition latency in ns, if available
*/
void setTransitionLatency(double tl);
/**
* @return a TQString with the current CPU governor policy, if available
*/
TQString &governor();
/**
* @param a TQString with the current CPU governor policy, if available
*/
void setGovernor(TQString gr);
/**
* @return a TQString with the current CPU scaling driver, if available
*/
TQString &scalingDriver();
/**
* @param a TQString with the current CPU scaling driver, if available
*/
void setScalingDriver(TQString dr);
/**
* @return a TQStringList with the IDs of all processors that are dependent on the frequency/power settings of this one, if available
*/
TQStringList &dependentProcessors();
/**
* @param a TQStringList with the IDs of all processors that are dependent on the frequency/power settings of this one, if available
*/
void setDependentProcessors(TQStringList dp);
/**
* @return a TQStringList with all valid scaling frequencies in Hz, if available
*/
TQStringList &availableFrequencies();
/**
* @param a TQStringList with all valid scaling frequencies in Hz, if available
*/
void setAvailableFrequencies(TQStringList af);
private:
double m_frequency;
double m_minfrequency;
double m_maxfrequency;
double m_transitionlatency;
TQString m_governor;
TQString m_scalingdriver;
TQStringList m_tiedprocs;
TQStringList m_frequencies;
};
typedef TQPtrList<TDEGenericDevice> TDEGenericHardwareList;
typedef TQMap<TQString, TQString> TDEDeviceIDMap;
class TQSocketNotifier;
class KSimpleDirWatch;
class TDECORE_EXPORT TDEHardwareDevices : public TQObject
{
@ -750,6 +856,7 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
private slots:
void processHotPluggedHardware();
void processModifiedMounts();
void processModifiedCPUs();
private:
void rescanDeviceInformation(TDEGenericDevice* hwdevice);
@ -768,11 +875,14 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
struct udev_monitor *m_udevMonitorStruct;
TDEGenericHardwareList m_deviceList;
int m_procMountsFd;
KSimpleDirWatch* m_cpuWatch;
TQTimer* m_cpuWatchTimer;
TQSocketNotifier* m_devScanNotifier;
TQSocketNotifier* m_mountScanNotifier;
TQStringList m_mountTable;
TQStringList m_cpuInfo;
TDEDeviceIDMap* pci_id_map;
TDEDeviceIDMap* usb_id_map;

Loading…
Cancel
Save