Greatly improve tdehwlib polling performance

This relates to Bug 1992
pull/16/head
Francois Andriot 11 years ago committed by Timothy Pearson
parent 37906b5b72
commit 3c9d481f7f

@ -70,6 +70,24 @@ extern "C" {
// Compile-time configuration // Compile-time configuration
#include "config.h" #include "config.h"
// Profiling stuff
//#define CPUPROFILING
//#define STATELESSPROFILING
#include <time.h>
timespec diff(timespec start, timespec end)
{
timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
}
return temp;
}
// BEGIN BLOCK // BEGIN BLOCK
// Copied from include/linux/genhd.h // Copied from include/linux/genhd.h
#define GENHD_FL_REMOVABLE 1 #define GENHD_FL_REMOVABLE 1
@ -199,6 +217,10 @@ TDEHardwareDevices::TDEHardwareDevices() {
m_deviceWatchTimer = new TQTimer(this); m_deviceWatchTimer = new TQTimer(this);
connect( m_deviceWatchTimer, SIGNAL(timeout()), this, SLOT(processStatelessDevices()) ); connect( m_deviceWatchTimer, SIGNAL(timeout()), this, SLOT(processStatelessDevices()) );
// Special case for battery polling (longer delay, 5 seconds)
m_batteryWatchTimer = new TQTimer(this);
connect( m_batteryWatchTimer, SIGNAL(timeout()), this, SLOT(processBatteryDevices()) );
// Update internal device information // Update internal device information
queryHardwareInformation(); queryHardwareInformation();
} }
@ -207,6 +229,7 @@ TDEHardwareDevices::TDEHardwareDevices() {
TDEHardwareDevices::~TDEHardwareDevices() { TDEHardwareDevices::~TDEHardwareDevices() {
// Stop device scanning // Stop device scanning
m_deviceWatchTimer->stop(); m_deviceWatchTimer->stop();
m_batteryWatchTimer->stop();
// [FIXME 0.01] // [FIXME 0.01]
#if 0 #if 0
@ -243,6 +266,7 @@ void TDEHardwareDevices::setTriggerlessHardwareUpdatesEnabled(bool enable) {
if (nodezerocpufreq.exists()) { if (nodezerocpufreq.exists()) {
m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
} }
m_batteryWatchTimer->stop(); // Battery devices are included in stateless devices
m_deviceWatchTimer->start( 1000, FALSE ); // 1 second repeating timer m_deviceWatchTimer->start( 1000, FALSE ); // 1 second repeating timer
} }
else { else {
@ -251,6 +275,20 @@ void TDEHardwareDevices::setTriggerlessHardwareUpdatesEnabled(bool enable) {
} }
} }
void TDEHardwareDevices::setBatteryUpdatesEnabled(bool enable) {
if (enable) {
TQDir nodezerocpufreq("/sys/devices/system/cpu/cpu0/cpufreq");
if (nodezerocpufreq.exists()) {
m_cpuWatchTimer->start( 500, FALSE ); // 0.5 second repeating timer
}
m_batteryWatchTimer->start( 5000, FALSE ); // 5 second repeating timer
}
else {
m_cpuWatchTimer->stop();
m_batteryWatchTimer->stop();
}
}
void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) { void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) {
rescanDeviceInformation(hwdevice, true); rescanDeviceInformation(hwdevice, true);
} }
@ -270,6 +308,7 @@ TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
syspath += "/"; syspath += "/";
} }
TDEGenericDevice *hwdevice; TDEGenericDevice *hwdevice;
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
TDEGenericHardwareList devList = listAllPhysicalDevices(); TDEGenericHardwareList devList = listAllPhysicalDevices();
for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) { for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
@ -281,6 +320,30 @@ TDEGenericDevice* TDEHardwareDevices::findBySystemPath(TQString syspath) {
return 0; return 0;
} }
TDECPUDevice* TDEHardwareDevices::findCPUBySystemPath(TQString syspath, bool inCache=true) {
TDECPUDevice* cdevice;
// Look for the device in the cache first
if(inCache && !m_cpuByPathCache.isEmpty()) {
cdevice = m_cpuByPathCache.find(syspath);
if(cdevice) {
return cdevice;
}
}
// If the CPU was not found in cache, we need to parse the entire device list to get it.
cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(syspath));
if(cdevice) {
if(inCache) {
m_cpuByPathCache.insert(syspath, cdevice); // Add the device to the cache
}
return cdevice;
}
return 0;
}
TDEGenericDevice* TDEHardwareDevices::findByUniqueID(TQString uid) { TDEGenericDevice* TDEHardwareDevices::findByUniqueID(TQString uid) {
TDEGenericDevice *hwdevice; TDEGenericDevice *hwdevice;
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
@ -410,17 +473,29 @@ void TDEHardwareDevices::processModifiedCPUs() {
// Detect what changed between the old cpu information and the new information, // Detect what changed between the old cpu information and the new information,
// and emit appropriate events // and emit appropriate events
#ifdef CPUPROFILING
timespec time1, time2, time3;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
time3 = time1;
printf("TDEHardwareDevices::processModifiedCPUs() : begin at '%u'\n", time1.tv_nsec);
#endif
// Read new CPU information table // Read new CPU information table
m_cpuInfo.clear(); m_cpuInfo.clear();
TQFile cpufile( "/proc/cpuinfo" ); TQFile cpufile( "/proc/cpuinfo" );
if ( cpufile.open( IO_ReadOnly ) ) { if ( cpufile.open( IO_ReadOnly ) ) {
TQTextStream stream( &cpufile ); TQTextStream stream( &cpufile );
while ( !stream.atEnd() ) { // Using read() instead of readLine() inside a loop is 4 times faster !
m_cpuInfo.append(stream.readLine()); m_cpuInfo = TQStringList::split('\n', stream.read(), true);
}
cpufile.close(); cpufile.close();
} }
#ifdef CPUPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint1 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
time1 = time2;
#endif
// Ensure "processor" is the first entry in each block and determine which cpuinfo type is in use // Ensure "processor" is the first entry in each block and determine which cpuinfo type is in use
bool cpuinfo_format_x86 = true; bool cpuinfo_format_x86 = true;
bool cpuinfo_format_arm = false; bool cpuinfo_format_arm = false;
@ -431,39 +506,43 @@ void TDEHardwareDevices::processModifiedCPUs() {
TQStringList::Iterator blockBegin = m_cpuInfo.begin(); TQStringList::Iterator blockBegin = m_cpuInfo.begin();
for (TQStringList::Iterator cpuit1 = m_cpuInfo.begin(); cpuit1 != m_cpuInfo.end(); ++cpuit1) { for (TQStringList::Iterator cpuit1 = m_cpuInfo.begin(); cpuit1 != m_cpuInfo.end(); ++cpuit1) {
curline1 = *cpuit1; curline1 = *cpuit1;
curline1 = curline1.stripWhiteSpace();
if (!(*blockBegin).startsWith("processor")) { if (!(*blockBegin).startsWith("processor")) {
bool found = false; bool found = false;
TQStringList::Iterator cpuit2; TQStringList::Iterator cpuit2;
for (cpuit2 = blockBegin; cpuit2 != m_cpuInfo.end(); ++cpuit2) { for (cpuit2 = blockBegin; cpuit2 != m_cpuInfo.end(); ++cpuit2) {
curline2 = *cpuit2; curline2 = *cpuit2;
curline2 = curline2.stripWhiteSpace();
if (curline2.startsWith("processor")) { if (curline2.startsWith("processor")) {
found = true; found = true;
break; break;
} }
else if (curline2 == "") { else if (curline2 == NULL || curline2 == "") {
break; break;
} }
} }
if (found) { if (found) {
m_cpuInfo.insert(blockBegin, (*cpuit2)); m_cpuInfo.insert(blockBegin, (*cpuit2));
} }
else { else if(blockNumber == 0) {
m_cpuInfo.insert(blockBegin, "processor : 0"); m_cpuInfo.insert(blockBegin, "processor : 0");
} }
} }
if (curline1 == "") { if (curline1 == NULL || curline1 == "") {
blockNumber++; blockNumber++;
blockBegin = cpuit1; blockBegin = cpuit1;
blockBegin++; blockBegin++;
} }
if (curline1.startsWith("Processor")) { else if (curline1.startsWith("Processor")) {
cpuinfo_format_x86 = false; cpuinfo_format_x86 = false;
cpuinfo_format_arm = true; cpuinfo_format_arm = true;
} }
} }
#ifdef CPUPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint2 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
time1 = time2;
#endif
// Parse CPU information table // Parse CPU information table
TDECPUDevice *cdevice; TDECPUDevice *cdevice;
cdevice = 0; cdevice = 0;
@ -482,44 +561,45 @@ void TDEHardwareDevices::processModifiedCPUs() {
for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) { for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
curline = *cpuit; curline = *cpuit;
if (curline.startsWith("processor")) { if (curline.startsWith("processor")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace();
processorNumber = curline.toInt(); processorNumber = curline.toInt();
if (!cdevice) cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber))); if (!cdevice) {
cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
}
if (cdevice) { if (cdevice) {
if (cdevice->coreNumber() != processorNumber) modified = true; if (cdevice->coreNumber() != processorNumber) {
cdevice->internalSetCoreNumber(processorNumber); modified = true;
cdevice->internalSetCoreNumber(processorNumber);
}
} }
} }
if (curline.startsWith("model name")) { else if (cdevice && curline.startsWith("model name")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace(); if (cdevice->name() != curline) {
if (cdevice) { modified = true;
if (cdevice->name() != curline) modified = true;
cdevice->internalSetName(curline); cdevice->internalSetName(curline);
} }
} }
if (curline.startsWith("cpu MHz")) { else if (cdevice && curline.startsWith("cpu MHz")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace(); if (cdevice->frequency() != curline.toDouble()) {
if (cdevice) { modified = true;
if (cdevice->frequency() != curline.toDouble()) modified = true;
cdevice->internalSetFrequency(curline.toDouble()); cdevice->internalSetFrequency(curline.toDouble());
have_frequency = true;
} }
have_frequency = true;
} }
if (curline.startsWith("vendor_id")) { else if (cdevice && curline.startsWith("vendor_id")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace(); if (cdevice->vendorName() != curline) {
if (cdevice) { modified = true;
if (cdevice->vendorName() != curline) modified = true;
cdevice->internalSetVendorName(curline); cdevice->internalSetVendorName(curline);
if (cdevice->vendorEncoded() != curline) modified = true; }
if (cdevice->vendorEncoded() != curline) {
modified = true;
cdevice->internalSetVendorEncoded(curline); cdevice->internalSetVendorEncoded(curline);
} }
} }
curline = curline.stripWhiteSpace(); else if (curline == NULL || curline == "") {
if (curline == "") {
cdevice = 0; cdevice = 0;
} }
} }
@ -535,29 +615,25 @@ void TDEHardwareDevices::processModifiedCPUs() {
for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) { for (cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
curline = *cpuit; curline = *cpuit;
if (curline.startsWith("Processor")) { if (curline.startsWith("Processor")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace();
modelName = curline; modelName = curline;
} }
if (curline.startsWith("Hardware")) { else if (curline.startsWith("Hardware")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace();
vendorName = curline; vendorName = curline;
} }
if (curline.startsWith("Serial")) { else if (curline.startsWith("Serial")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace();
serialNumber = curline; serialNumber = curline;
} }
} }
for (TQStringList::Iterator cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) { for (TQStringList::Iterator cpuit = m_cpuInfo.begin(); cpuit != m_cpuInfo.end(); ++cpuit) {
curline = *cpuit; curline = *cpuit;
if (curline.startsWith("processor")) { if (curline.startsWith("processor")) {
curline.remove(0, curline.find(":")+1); curline.remove(0, curline.find(":")+2);
curline = curline.stripWhiteSpace();
processorNumber = curline.toInt(); processorNumber = curline.toInt();
if (!cdevice) { if (!cdevice) {
cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber))); cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
if (cdevice) { if (cdevice) {
// Set up CPU information structures // Set up CPU information structures
if (cdevice->coreNumber() != processorNumber) modified = true; if (cdevice->coreNumber() != processorNumber) modified = true;
@ -573,8 +649,7 @@ void TDEHardwareDevices::processModifiedCPUs() {
} }
} }
} }
curline = curline.stripWhiteSpace(); if (curline == NULL || curline == "") {
if (curline == "") {
cdevice = 0; cdevice = 0;
} }
} }
@ -582,9 +657,17 @@ void TDEHardwareDevices::processModifiedCPUs() {
processorCount = processorNumber+1; processorCount = processorNumber+1;
#ifdef CPUPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
time1 = time2;
#endif
TDECPUDevice* firstCPU;
// Read in other information from cpufreq, if available // Read in other information from cpufreq, if available
for (processorNumber=0; processorNumber<processorCount; processorNumber++) { for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
cdevice = dynamic_cast<TDECPUDevice*>(findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber))); cdevice = dynamic_cast<TDECPUDevice*>(findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)));
TQDir cpufreq_dir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber)); TQDir cpufreq_dir(TQString("/sys/devices/system/cpu/cpu%1/cpufreq").arg(processorNumber));
TQString scalinggovernor; TQString scalinggovernor;
TQString scalingdriver; TQString scalingdriver;
@ -595,107 +678,131 @@ void TDEHardwareDevices::processModifiedCPUs() {
TQStringList frequencylist; TQStringList frequencylist;
TQStringList governorlist; TQStringList governorlist;
if (cpufreq_dir.exists()) { if (cpufreq_dir.exists()) {
TQString nodename = cpufreq_dir.path(); TQString nodename;
nodename.append("/scaling_governor"); if(processorNumber == 0) {
TQFile scalinggovernorfile(nodename); // Remember the first CPU options so that we can reuse it later.
if (scalinggovernorfile.open(IO_ReadOnly)) { firstCPU = cdevice;
TQTextStream stream( &scalinggovernorfile );
scalinggovernor = stream.readLine(); nodename = cpufreq_dir.path();
scalinggovernorfile.close(); nodename.append("/scaling_governor");
} TQFile scalinggovernorfile(nodename);
nodename = cpufreq_dir.path(); if (scalinggovernorfile.open(IO_ReadOnly)) {
nodename.append("/scaling_driver"); TQTextStream stream( &scalinggovernorfile );
TQFile scalingdriverfile(nodename); scalinggovernor = stream.read();
if (scalingdriverfile.open(IO_ReadOnly)) { scalinggovernorfile.close();
TQTextStream stream( &scalingdriverfile ); }
scalingdriver = stream.readLine(); nodename = cpufreq_dir.path();
scalingdriverfile.close(); nodename.append("/scaling_driver");
} TQFile scalingdriverfile(nodename);
nodename = cpufreq_dir.path(); if (scalingdriverfile.open(IO_ReadOnly)) {
nodename.append("/cpuinfo_min_freq"); TQTextStream stream( &scalingdriverfile );
TQFile minfrequencyfile(nodename); scalingdriver = stream.read();
if (minfrequencyfile.open(IO_ReadOnly)) { scalingdriverfile.close();
TQTextStream stream( &minfrequencyfile ); }
minfrequency = stream.readLine().toDouble()/1000.0; nodename = cpufreq_dir.path();
minfrequencyfile.close(); nodename.append("/cpuinfo_min_freq");
} TQFile minfrequencyfile(nodename);
nodename = cpufreq_dir.path(); if (minfrequencyfile.open(IO_ReadOnly)) {
nodename.append("/cpuinfo_max_freq"); TQTextStream stream( &minfrequencyfile );
TQFile maxfrequencyfile(nodename); minfrequency = stream.read().toDouble()/1000.0;
if (maxfrequencyfile.open(IO_ReadOnly)) { minfrequencyfile.close();
TQTextStream stream( &maxfrequencyfile ); }
maxfrequency = stream.readLine().toDouble()/1000.0; nodename = cpufreq_dir.path();
maxfrequencyfile.close(); nodename.append("/cpuinfo_max_freq");
TQFile maxfrequencyfile(nodename);
if (maxfrequencyfile.open(IO_ReadOnly)) {
TQTextStream stream( &maxfrequencyfile );
maxfrequency = stream.read().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.read().toDouble()/1000.0;
trlatencyfile.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.read());
availfreqsfile.close();
}
nodename = cpufreq_dir.path();
nodename.append("/scaling_available_governors");
TQFile availgvrnsfile(nodename);
if (availgvrnsfile.open(IO_ReadOnly)) {
TQTextStream stream( &availgvrnsfile );
governorlist = TQStringList::split(" ", stream.read());
availgvrnsfile.close();
}
} }
nodename = cpufreq_dir.path(); // Other CPU should have the same values as the first one. Simply copy them.
nodename.append("/cpuinfo_transition_latency"); else {
TQFile trlatencyfile(nodename); scalinggovernor = firstCPU->governor();
if (trlatencyfile.open(IO_ReadOnly)) { scalingdriver = firstCPU->scalingDriver();
TQTextStream stream( &trlatencyfile ); minfrequency = firstCPU->minFrequency();
trlatency = stream.readLine().toDouble()/1000.0; maxfrequency = firstCPU->maxFrequency();
trlatencyfile.close(); trlatency = firstCPU->transitionLatency();
frequencylist = firstCPU->availableFrequencies();
governorlist = firstCPU->availableGovernors();
} }
// The following data are different on each CPU
nodename = cpufreq_dir.path(); nodename = cpufreq_dir.path();
nodename.append("/affected_cpus"); nodename.append("/affected_cpus");
TQFile tiedcpusfile(nodename); TQFile tiedcpusfile(nodename);
if (tiedcpusfile.open(IO_ReadOnly)) { if (tiedcpusfile.open(IO_ReadOnly)) {
TQTextStream stream( &tiedcpusfile ); TQTextStream stream( &tiedcpusfile );
affectedcpulist = TQStringList::split(" ", stream.readLine()); affectedcpulist = TQStringList::split(" ", stream.read());
tiedcpusfile.close(); 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();
}
nodename = cpufreq_dir.path();
nodename.append("/scaling_available_governors");
TQFile availgvrnsfile(nodename);
if (availgvrnsfile.open(IO_ReadOnly)) {
TQTextStream stream( &availgvrnsfile );
governorlist = TQStringList::split(" ", stream.readLine());
availgvrnsfile.close();
}
// We may already have the CPU Mhz information in '/proc/cpuinfo'
if (!have_frequency) { if (!have_frequency) {
nodename = cpufreq_dir.path(); nodename = cpufreq_dir.path();
nodename.append("/cpuinfo_cur_freq"); nodename.append("/cpuinfo_cur_freq");
TQFile cpufreqfile(nodename); TQFile cpufreqfile(nodename);
if (cpufreqfile.open(IO_ReadOnly)) { if (cpufreqfile.open(IO_ReadOnly)) {
TQTextStream stream( &cpufreqfile ); TQTextStream stream( &cpufreqfile );
if (cdevice) cdevice->internalSetFrequency(stream.readLine().toDouble()/1000.0); if (cdevice) {
cdevice->internalSetFrequency(stream.read().toDouble()/1000.0);
}
cpufreqfile.close(); cpufreqfile.close();
have_frequency = true; have_frequency = true;
} }
} }
bool frequencyFound; bool minfrequencyFound = false;
bool maxfrequencyFound = false;
TQStringList::Iterator freqit; TQStringList::Iterator freqit;
frequencyFound = false;
for ( freqit = frequencylist.begin(); freqit != frequencylist.end(); ++freqit ) { for ( freqit = frequencylist.begin(); freqit != frequencylist.end(); ++freqit ) {
double thisfrequency = (*freqit).toDouble()/1000.0; double thisfrequency = (*freqit).toDouble()/1000.0;
if (thisfrequency == minfrequency) { if (thisfrequency == minfrequency) {
frequencyFound = true; minfrequencyFound = true;
}
if (thisfrequency == maxfrequency) {
maxfrequencyFound = true;
} }
} }
if (!frequencyFound) { if (!minfrequencyFound) {
int minFrequencyInt = (minfrequency*1000.0); int minFrequencyInt = (minfrequency*1000.0);
frequencylist.prepend(TQString("%1").arg(minFrequencyInt)); frequencylist.prepend(TQString("%1").arg(minFrequencyInt));
} }
frequencyFound = false; if (!maxfrequencyFound) {
for ( freqit = frequencylist.begin(); freqit != frequencylist.end(); ++freqit ) {
double thisfrequency = (*freqit).toDouble()/1000.0;
if (thisfrequency == maxfrequency) {
frequencyFound = true;
}
}
if (!frequencyFound) {
int maxfrequencyInt = (maxfrequency*1000.0); int maxfrequencyInt = (maxfrequency*1000.0);
frequencylist.append(TQString("%1").arg(maxfrequencyInt)); frequencylist.append(TQString("%1").arg(maxfrequencyInt));
} }
#ifdef CPUPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint3.%u at %u [%u]\n", processorNumber, time2.tv_nsec, diff(time1,time2).tv_nsec);
time1 = time2;
#endif
} }
else { else {
if (have_frequency) { if (have_frequency) {
@ -708,33 +815,61 @@ void TDEHardwareDevices::processModifiedCPUs() {
// Update CPU information structure // Update CPU information structure
if (cdevice) { if (cdevice) {
if (cdevice->governor() != scalinggovernor) modified = true; if (cdevice->governor() != scalinggovernor) {
cdevice->internalSetGovernor(scalinggovernor); modified = true;
if (cdevice->scalingDriver() != scalingdriver) modified = true; cdevice->internalSetGovernor(scalinggovernor);
cdevice->internalSetScalingDriver(scalingdriver); }
if (cdevice->minFrequency() != minfrequency) modified = true; if (cdevice->scalingDriver() != scalingdriver) {
cdevice->internalSetMinFrequency(minfrequency); modified = true;
if (cdevice->maxFrequency() != maxfrequency) modified = true; cdevice->internalSetScalingDriver(scalingdriver);
cdevice->internalSetMaxFrequency(maxfrequency); }
if (cdevice->transitionLatency() != trlatency) modified = true; if (cdevice->minFrequency() != minfrequency) {
cdevice->internalSetTransitionLatency(trlatency); modified = true;
if (cdevice->dependentProcessors().join(" ") != affectedcpulist.join(" ")) modified = true; cdevice->internalSetMinFrequency(minfrequency);
cdevice->internalSetDependentProcessors(affectedcpulist); }
if (cdevice->availableFrequencies().join(" ") != frequencylist.join(" ")) modified = true; if (cdevice->maxFrequency() != maxfrequency) {
cdevice->internalSetAvailableFrequencies(frequencylist); modified = true;
if (cdevice->availableGovernors().join(" ") != governorlist.join(" ")) modified = true; cdevice->internalSetMaxFrequency(maxfrequency);
cdevice->internalSetAvailableGovernors(governorlist); }
if (cdevice->transitionLatency() != trlatency) {
modified = true;
cdevice->internalSetTransitionLatency(trlatency);
}
if (cdevice->dependentProcessors().join(" ") != affectedcpulist.join(" ")) {
modified = true;
cdevice->internalSetDependentProcessors(affectedcpulist);
}
if (cdevice->availableFrequencies().join(" ") != frequencylist.join(" ")) {
modified = true;
cdevice->internalSetAvailableFrequencies(frequencylist);
}
if (cdevice->availableGovernors().join(" ") != governorlist.join(" ")) {
modified = true;
cdevice->internalSetAvailableGovernors(governorlist);
}
} }
} }
#ifdef CPUPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processModifiedCPUs() : checkpoint4 at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
time1 = time2;
#endif
if (modified) { if (modified) {
for (processorNumber=0; processorNumber<processorCount; processorNumber++) { for (processorNumber=0; processorNumber<processorCount; processorNumber++) {
TDEGenericDevice* hwdevice = findBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber)); TDEGenericDevice* hwdevice = findCPUBySystemPath(TQString("/sys/devices/system/cpu/cpu%1").arg(processorNumber));
// Signal new information available // Signal new information available
emit hardwareUpdated(hwdevice); emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID()); emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
} }
} }
#ifdef CPUPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processModifiedCPUs() : end at %u [%u]\n", time2.tv_nsec, diff(time1,time2).tv_nsec);
printf("TDEHardwareDevices::processModifiedCPUs() : total time: %u\n", diff(time3,time2).tv_nsec);
#endif
} }
void TDEHardwareDevices::processStatelessDevices() { void TDEHardwareDevices::processStatelessDevices() {
@ -742,6 +877,13 @@ void TDEHardwareDevices::processStatelessDevices() {
// So far, network cards and sensors need to be polled // So far, network cards and sensors need to be polled
TDEGenericDevice *hwdevice; TDEGenericDevice *hwdevice;
#ifdef STATELESSPROFILING
timespec time1, time2, time3;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
printf("TDEHardwareDevices::processStatelessDevices() : begin at '%u'\n", time1.tv_nsec);
time3 = time1;
#endif
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time // We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
TDEGenericHardwareList devList = listAllPhysicalDevices(); TDEGenericHardwareList devList = listAllPhysicalDevices();
for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) { for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
@ -749,10 +891,36 @@ void TDEHardwareDevices::processStatelessDevices() {
rescanDeviceInformation(hwdevice, false); rescanDeviceInformation(hwdevice, false);
emit hardwareUpdated(hwdevice); emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID()); emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
#ifdef STATELESSPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processStatelessDevices() : '%s' finished at %u [%u]\n", (hwdevice->name()).ascii(), time2.tv_nsec, diff(time1,time2).tv_nsec);
time1 = time2;
#endif
}
}
#ifdef STATELESSPROFILING
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
printf("TDEHardwareDevices::processStatelessDevices() : end at '%u'\n", time2.tv_nsec);
printf("TDEHardwareDevices::processStatelessDevices() : took '%u'\n", diff(time3,time2).tv_nsec);
#endif
}
void TDEHardwareDevices::processBatteryDevices() {
TDEGenericDevice *hwdevice;
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
TDEGenericHardwareList devList = listAllPhysicalDevices();
for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
if (hwdevice->type() == TDEGenericDeviceType::Battery) {
rescanDeviceInformation(hwdevice, false);
emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
} }
} }
} }
void TDEHardwareDevices::processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice) { void TDEHardwareDevices::processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice) {
emit eventDeviceKeyPressed(keycode, edevice); emit eventDeviceKeyPressed(keycode, edevice);
} }
@ -2556,13 +2724,13 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (nodename == "address") { if (nodename == "address") {
ndevice->internalSetMacAddress(line); ndevice->internalSetMacAddress(line);
} }
if (nodename == "carrier") { else if (nodename == "carrier") {
ndevice->internalSetCarrierPresent(line.toInt()); ndevice->internalSetCarrierPresent(line.toInt());
} }
if (nodename == "dormant") { else if (nodename == "dormant") {
ndevice->internalSetDormant(line.toInt()); ndevice->internalSetDormant(line.toInt());
} }
if (nodename == "operstate") { else if (nodename == "operstate") {
TQString friendlyState = line.lower(); TQString friendlyState = line.lower();
friendlyState[0] = friendlyState[0].upper(); friendlyState[0] = friendlyState[0].upper();
ndevice->internalSetState(friendlyState); ndevice->internalSetState(friendlyState);
@ -2594,7 +2762,7 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (family == AF_INET) { if (family == AF_INET) {
ndevice->internalSetIpV4Address(address); ndevice->internalSetIpV4Address(address);
} }
if (family == AF_INET6) { else if (family == AF_INET6) {
address.truncate(address.findRev("%")); address.truncate(address.findRev("%"));
ndevice->internalSetIpV6Address(address); ndevice->internalSetIpV6Address(address);
} }
@ -2605,7 +2773,7 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (family == AF_INET) { if (family == AF_INET) {
ndevice->internalSetIpV4Netmask(address); ndevice->internalSetIpV4Netmask(address);
} }
if (family == AF_INET6) { else if (family == AF_INET6) {
address.truncate(address.findRev("%")); address.truncate(address.findRev("%"));
ndevice->internalSetIpV6Netmask(address); ndevice->internalSetIpV6Netmask(address);
} }
@ -2616,7 +2784,7 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (family == AF_INET) { if (family == AF_INET) {
ndevice->internalSetIpV4Broadcast(address); ndevice->internalSetIpV4Broadcast(address);
} }
if (family == AF_INET6) { else if (family == AF_INET6) {
address.truncate(address.findRev("%")); address.truncate(address.findRev("%"));
ndevice->internalSetIpV6Broadcast(address); ndevice->internalSetIpV6Broadcast(address);
} }
@ -2627,7 +2795,7 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (family == AF_INET) { if (family == AF_INET) {
ndevice->internalSetIpV4Destination(address); ndevice->internalSetIpV4Destination(address);
} }
if (family == AF_INET6) { else if (family == AF_INET6) {
address.truncate(address.findRev("%")); address.truncate(address.findRev("%"));
ndevice->internalSetIpV6Destination(address); ndevice->internalSetIpV6Destination(address);
} }
@ -2658,13 +2826,13 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (nodename == "rx_bytes") { if (nodename == "rx_bytes") {
ndevice->internalSetRxBytes(line.toDouble()); ndevice->internalSetRxBytes(line.toDouble());
} }
if (nodename == "tx_bytes") { else if (nodename == "tx_bytes") {
ndevice->internalSetTxBytes(line.toDouble()); ndevice->internalSetTxBytes(line.toDouble());
} }
if (nodename == "rx_packets") { else if (nodename == "rx_packets") {
ndevice->internalSetRxPackets(line.toDouble()); ndevice->internalSetRxPackets(line.toDouble());
} }
if (nodename == "tx_packets") { else if (nodename == "tx_packets") {
ndevice->internalSetTxPackets(line.toDouble()); ndevice->internalSetTxPackets(line.toDouble());
} }
file.close(); file.close();
@ -2705,19 +2873,19 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (sensornodetype == "label") { if (sensornodetype == "label") {
sensors[sensornodename].label = line; sensors[sensornodename].label = line;
} }
if (sensornodetype == "input") { else if (sensornodetype == "input") {
sensors[sensornodename].current = lineValue; sensors[sensornodename].current = lineValue;
} }
if (sensornodetype == "min") { else if (sensornodetype == "min") {
sensors[sensornodename].minimum = lineValue; sensors[sensornodename].minimum = lineValue;
} }
if (sensornodetype == "max") { else if (sensornodetype == "max") {
sensors[sensornodename].maximum = lineValue; sensors[sensornodename].maximum = lineValue;
} }
if (sensornodetype == "warn") { else if (sensornodetype == "warn") {
sensors[sensornodename].warning = lineValue; sensors[sensornodename].warning = lineValue;
} }
if (sensornodetype == "crit") { else if (sensornodetype == "crit") {
sensors[sensornodename].critical = lineValue; sensors[sensornodename].critical = lineValue;
} }
file.close(); file.close();
@ -2752,40 +2920,40 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (nodename == "alarm") { if (nodename == "alarm") {
bdevice->internalSetAlarmEnergy(line.toDouble()/1000000.0); bdevice->internalSetAlarmEnergy(line.toDouble()/1000000.0);
} }
if (nodename == "charge_full" || nodename == "energy_full") { else if (nodename == "charge_full" || nodename == "energy_full") {
bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0); bdevice->internalSetMaximumEnergy(line.toDouble()/1000000.0);
} }
if (nodename == "charge_full_design" || nodename == "energy_full_design") { else if (nodename == "charge_full_design" || nodename == "energy_full_design") {
bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0); bdevice->internalSetMaximumDesignEnergy(line.toDouble()/1000000.0);
} }
if (nodename == "charge_now" || nodename == "energy_now") { else if (nodename == "charge_now" || nodename == "energy_now") {
bdevice->internalSetEnergy(line.toDouble()/1000000.0); bdevice->internalSetEnergy(line.toDouble()/1000000.0);
} }
if (nodename == "manufacturer") { else if (nodename == "manufacturer") {
bdevice->internalSetVendorName(line.stripWhiteSpace()); bdevice->internalSetVendorName(line.stripWhiteSpace());
} }
if (nodename == "model_name") { else if (nodename == "model_name") {
bdevice->internalSetVendorModel(line.stripWhiteSpace()); bdevice->internalSetVendorModel(line.stripWhiteSpace());
} }
if (nodename == "power_now" || nodename == "current_now") { else if (nodename == "power_now" || nodename == "current_now") {
bdevice->internalSetDischargeRate(line.toDouble()/1000000.0); bdevice->internalSetDischargeRate(line.toDouble()/1000000.0);
} }
if (nodename == "present") { else if (nodename == "present") {
bdevice->internalSetInstalled(line.toInt()); bdevice->internalSetInstalled(line.toInt());
} }
if (nodename == "serial_number") { else if (nodename == "serial_number") {
bdevice->internalSetSerialNumber(line.stripWhiteSpace()); bdevice->internalSetSerialNumber(line.stripWhiteSpace());
} }
if (nodename == "status") { else if (nodename == "status") {
bdevice->internalSetStatus(line); bdevice->internalSetStatus(line);
} }
if (nodename == "technology") { else if (nodename == "technology") {
bdevice->internalSetTechnology(line); bdevice->internalSetTechnology(line);
} }
if (nodename == "voltage_min_design") { else if (nodename == "voltage_min_design") {
bdevice->internalSetMinimumVoltage(line.toDouble()/1000000.0); bdevice->internalSetMinimumVoltage(line.toDouble()/1000000.0);
} }
if (nodename == "voltage_now") { else if (nodename == "voltage_now") {
bdevice->internalSetVoltage(line.toDouble()/1000000.0); bdevice->internalSetVoltage(line.toDouble()/1000000.0);
} }
file.close(); file.close();
@ -2823,13 +2991,13 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (nodename == "manufacturer") { if (nodename == "manufacturer") {
pdevice->internalSetVendorName(line.stripWhiteSpace()); pdevice->internalSetVendorName(line.stripWhiteSpace());
} }
if (nodename == "model_name") { else if (nodename == "model_name") {
pdevice->internalSetVendorModel(line.stripWhiteSpace()); pdevice->internalSetVendorModel(line.stripWhiteSpace());
} }
if (nodename == "online") { else if (nodename == "online") {
pdevice->internalSetOnline(line.toInt()); pdevice->internalSetOnline(line.toInt());
} }
if (nodename == "serial_number") { else if (nodename == "serial_number") {
pdevice->internalSetSerialNumber(line.stripWhiteSpace()); pdevice->internalSetSerialNumber(line.stripWhiteSpace());
} }
file.close(); file.close();
@ -2868,10 +3036,10 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
} }
bdevice->internalSetPowerLevel(pl); bdevice->internalSetPowerLevel(pl);
} }
if (nodename == "max_brightness") { else if (nodename == "max_brightness") {
bdevice->internalSetMaximumRawBrightness(line.toInt()); bdevice->internalSetMaximumRawBrightness(line.toInt());
} }
if (nodename == "actual_brightness") { else if (nodename == "actual_brightness") {
bdevice->internalSetCurrentRawBrightness(line.toInt()); bdevice->internalSetCurrentRawBrightness(line.toInt());
} }
file.close(); file.close();
@ -2901,10 +3069,10 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
if (nodename == "status") { if (nodename == "status") {
mdevice->internalSetConnected(line.lower() == "connected"); mdevice->internalSetConnected(line.lower() == "connected");
} }
if (nodename == "enabled") { else if (nodename == "enabled") {
mdevice->internalSetEnabled(line.lower() == "enabled"); mdevice->internalSetEnabled(line.lower() == "enabled");
} }
if (nodename == "modes") { else if (nodename == "modes") {
TQStringList resinfo; TQStringList resinfo;
TQStringList resolutionsStringList = line.upper(); TQStringList resolutionsStringList = line.upper();
while ((!stream.atEnd()) && (!line.isNull())) { while ((!stream.atEnd()) && (!line.isNull())) {
@ -2921,7 +3089,7 @@ void TDEHardwareDevices::updateExistingDeviceInformation(TDEGenericDevice* exist
} }
mdevice->internalSetResolutions(resolutions); mdevice->internalSetResolutions(resolutions);
} }
if (nodename == "dpms") { else if (nodename == "dpms") {
TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On; TDEDisplayPowerLevel::TDEDisplayPowerLevel pl = TDEDisplayPowerLevel::On;
if (line == "On") { if (line == "On") {
pl = TDEDisplayPowerLevel::On; pl = TDEDisplayPowerLevel::On;

@ -23,6 +23,7 @@
#include <tqobject.h> #include <tqobject.h>
#include <tqptrlist.h> #include <tqptrlist.h>
#include <tqmap.h> #include <tqmap.h>
#include <tqdict.h>
#include <tqstring.h> #include <tqstring.h>
#include <tqstringlist.h> #include <tqstringlist.h>
@ -75,6 +76,7 @@ class TQSocketNotifier;
typedef TQPtrList<TDEGenericDevice> TDEGenericHardwareList; typedef TQPtrList<TDEGenericDevice> TDEGenericHardwareList;
typedef TQMap<TQString, TQString> TDEDeviceIDMap; typedef TQMap<TQString, TQString> TDEDeviceIDMap;
typedef TQDict<TDECPUDevice> TDECPUDeviceCache;
class TDECORE_EXPORT TDEHardwareDevices : public TQObject class TDECORE_EXPORT TDEHardwareDevices : public TQObject
{ {
@ -140,6 +142,12 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
*/ */
TDEStorageDevice* findDiskByUID(TQString uid); TDEStorageDevice* findDiskByUID(TQString uid);
/**
* Return the CPU device with system path @arg syspath, or 0 if no device exists for that path
* @return TDEGenericDevice
*/
TDECPUDevice* findCPUBySystemPath(TQString syspath, bool inCache);
/** /**
* Look up the device in the system PCI database * Look up the device in the system PCI database
* @param vendorid a TQString containing the vendor ID in hexadecimal * @param vendorid a TQString containing the vendor ID in hexadecimal
@ -221,6 +229,15 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
*/ */
void setTriggerlessHardwareUpdatesEnabled(bool enable); void setTriggerlessHardwareUpdatesEnabled(bool enable);
/**
* Enable or disable automatic state updates of battery hardware devices.
* When enabled, your application will use
* additional CPU resources to continually poll triggerless hardware devices.
* Automatic updates are disabled by default.
* @param enable a bool specifiying whether or not automatic updates should be enabled
*/
void setBatteryUpdatesEnabled(bool enable);
/** /**
* Convert a byte count to human readable form * Convert a byte count to human readable form
* @param bytes a double containing the number of bytes * @param bytes a double containing the number of bytes
@ -246,6 +263,7 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
void processHotPluggedHardware(); void processHotPluggedHardware();
void processModifiedMounts(); void processModifiedMounts();
void processModifiedCPUs(); void processModifiedCPUs();
void processBatteryDevices();
void processStatelessDevices(); void processStatelessDevices();
void processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice); void processEventDeviceKeyPressed(unsigned int keycode, TDEEventDevice* edevice);
@ -280,6 +298,7 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
int m_procMountsFd; int m_procMountsFd;
KSimpleDirWatch* m_cpuWatch; KSimpleDirWatch* m_cpuWatch;
TQTimer* m_cpuWatchTimer; TQTimer* m_cpuWatchTimer;
TQTimer* m_batteryWatchTimer;
TQTimer* m_deviceWatchTimer; TQTimer* m_deviceWatchTimer;
TQSocketNotifier* m_devScanNotifier; TQSocketNotifier* m_devScanNotifier;
@ -292,6 +311,8 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
TDEDeviceIDMap* usb_id_map; TDEDeviceIDMap* usb_id_map;
TDEDeviceIDMap* pnp_id_map; TDEDeviceIDMap* pnp_id_map;
TDEDeviceIDMap* dpy_id_map; TDEDeviceIDMap* dpy_id_map;
TDECPUDeviceCache m_cpuByPathCache;
friend class TDEGenericDevice; friend class TDEGenericDevice;
friend class TDEStorageDevice; friend class TDEStorageDevice;

Loading…
Cancel
Save