arithmetics with microseconds, to make the code clearer. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@489 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
@@ -51,7 +51,7 @@ void CPUMonitor::update() | |||
int CPUMonitor::check() | |||
{ | |||
struct timeval timeNow; | |||
TimeMillis timeNow; | |||
clock_t clockNow; | |||
getClock(&timeNow, &clockNow); | |||
@@ -60,8 +60,8 @@ int CPUMonitor::check() | |||
if (m_savedClock != (clock_t)-1 && clockNow != (clock_t)-1) { | |||
// Find out how much real time has been elapsed (in milliseconds). | |||
int timeDiff = (int)((timeNow.tv_usec - m_savedTime.tv_usec + 500) / 1000 + | |||
(timeNow.tv_sec - m_savedTime.tv_sec) * 1000); | |||
int timeDiff = timeNow.diffFrom(m_savedTime); | |||
if (timeDiff < m_updatePeriod) { | |||
// Measuring CPU usage is problematic in this case. So return | |||
// 100 and do not update saved time and clock numbers. | |||
@@ -92,11 +92,11 @@ int CPUMonitor::check() | |||
return coeff; | |||
} | |||
void CPUMonitor::getClock(struct timeval *tv, clock_t *clk) | |||
void CPUMonitor::getClock(TimeMillis *tm, clock_t *clk) | |||
{ | |||
if (gettimeofday(tv, NULL) != 0) { | |||
*clk = (clock_t)-1; | |||
} else { | |||
if (tm->update()) { | |||
*clk = clock(); | |||
} else { | |||
*clk = (clock_t)-1; | |||
} | |||
} |
@@ -23,9 +23,10 @@ | |||
#ifndef __CPUMONITOR_H__ | |||
#define __CPUMONITOR_H__ | |||
#include <sys/time.h> | |||
#include <time.h> | |||
#include <x0vncserver/TimeMillis.h> | |||
class CPUMonitor { | |||
public: | |||
@@ -65,11 +66,11 @@ public: | |||
protected: | |||
static void getClock(struct timeval *tv, clock_t *clk); | |||
static void getClock(TimeMillis *tm, clock_t *clk); | |||
int m_optimalLevel; | |||
int m_updatePeriod; | |||
struct timeval m_savedTime; | |||
TimeMillis m_savedTime; | |||
clock_t m_savedClock; | |||
}; |
@@ -31,7 +31,6 @@ | |||
#include <rfb/Configuration.h> | |||
#include <rfb/ServerCore.h> | |||
#include <x0vncserver/Image.h> | |||
#include <x0vncserver/PollingManager.h> | |||
BoolParameter PollingManager::pollPointer | |||
@@ -95,10 +94,6 @@ PollingManager::PollingManager(Display *dpy, Image *image, | |||
memset(m_rateMatrix, 0, numTiles); | |||
memset(m_videoFlags, 0, numTiles); | |||
memset(m_changedFlags, 0, numTiles); | |||
#ifdef DEBUG | |||
memset(&m_timeSaved, 0, sizeof(m_timeSaved)); | |||
#endif | |||
} | |||
PollingManager::~PollingManager() | |||
@@ -152,22 +147,16 @@ void PollingManager::unsetPointerPos() | |||
#ifdef DEBUG | |||
void PollingManager::debugBeforePoll() | |||
{ | |||
struct timeval timeNow; | |||
struct timezone tz; | |||
gettimeofday(&timeNow, &tz); | |||
int diff = (int)((timeNow.tv_usec - m_timeSaved.tv_usec + 500) / 1000 + | |||
(timeNow.tv_sec - m_timeSaved.tv_sec) * 1000); | |||
TimeMillis timeNow; | |||
int diff = timeNow.diffFrom(m_timeSaved); | |||
fprintf(stderr, "[wait%4dms]\t[step %2d]\t", diff, m_pollingStep % 32); | |||
m_timeSaved = timeNow; | |||
} | |||
void PollingManager::debugAfterPoll() | |||
{ | |||
struct timeval timeNow; | |||
struct timezone tz; | |||
gettimeofday(&timeNow, &tz); | |||
int diff = (int)((timeNow.tv_usec - m_timeSaved.tv_usec + 500) / 1000 + | |||
(timeNow.tv_sec - m_timeSaved.tv_sec) * 1000); | |||
TimeMillis timeNow; | |||
int diff = timeNow.diffFrom(m_timeSaved); | |||
fprintf(stderr, "[poll%4dms]\n", diff); | |||
m_timeSaved = timeNow; | |||
} |
@@ -23,13 +23,15 @@ | |||
#ifndef __POLLINGMANAGER_H__ | |||
#define __POLLINGMANAGER_H__ | |||
#include <sys/time.h> | |||
#include <X11/Xlib.h> | |||
#include <rfb/VNCServer.h> | |||
#include <x0vncserver/Image.h> | |||
#ifdef DEBUG | |||
#include <x0vncserver/TimeMillis.h> | |||
#endif | |||
using namespace rfb; | |||
class PollingManager { | |||
@@ -103,7 +105,7 @@ private: | |||
void debugBeforePoll(); | |||
void debugAfterPoll(); | |||
struct timeval m_timeSaved; | |||
TimeMillis m_timeSaved; | |||
#endif | |||
}; |
@@ -0,0 +1,44 @@ | |||
/* Copyright (C) 2006 Constantin Kaplinsky. All Rights Reserved. | |||
* | |||
* This is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This software 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 General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
// | |||
// TimeMillis.cxx | |||
// | |||
#include <x0vncserver/TimeMillis.h> | |||
TimeMillis::TimeMillis() | |||
{ | |||
update(); | |||
} | |||
bool TimeMillis::update() | |||
{ | |||
struct timezone tz; | |||
return (gettimeofday(&m_timeval, &tz) == 0); | |||
} | |||
int TimeMillis::diffFrom(const TimeMillis &older) const | |||
{ | |||
int diff = (int) | |||
((m_timeval.tv_usec - older.m_timeval.tv_usec + 500) / 1000 + | |||
(m_timeval.tv_sec - older.m_timeval.tv_sec) * 1000); | |||
return diff; | |||
} | |||
@@ -0,0 +1,47 @@ | |||
/* Copyright (C) 2006 Constantin Kaplinsky. All Rights Reserved. | |||
* | |||
* This is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This software 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 General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this software; if not, write to the Free Software | |||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |||
* USA. | |||
*/ | |||
// | |||
// TimeMillis.h | |||
// | |||
#ifndef __TIMEMILLIS_H__ | |||
#define __TIMEMILLIS_H__ | |||
#include <sys/time.h> | |||
class TimeMillis { | |||
public: | |||
TimeMillis(); | |||
// Set this object to current time, returns true on sucess. | |||
bool update(); | |||
// Return difference in milliseconds between two time points. | |||
int diffFrom(const TimeMillis &older) const; | |||
protected: | |||
struct timeval m_timeval; | |||
}; | |||
#endif // __TIMEMILLIS_H__ | |||
@@ -21,7 +21,6 @@ | |||
// e.g. 800x600. | |||
#include <strings.h> | |||
#include <sys/time.h> | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <unistd.h> | |||
@@ -45,6 +44,7 @@ | |||
#include <x0vncserver/Image.h> | |||
#include <x0vncserver/PollingManager.h> | |||
#include <x0vncserver/CPUMonitor.h> | |||
#include <x0vncserver/TimeMillis.h> | |||
using namespace rfb; | |||
using namespace network; | |||
@@ -324,6 +324,30 @@ static void usage() | |||
exit(1); | |||
} | |||
// | |||
// Adjust polling cycle to satisfy MaxProcessorUsage setting. | |||
// | |||
static void adjustPollingCycle(int *cycle, CPUMonitor *mon) | |||
{ | |||
int coeff = mon->check(); | |||
if (coeff < 90 || coeff > 110) { | |||
#ifdef DEBUG | |||
int oldPollingCycle = *cycle; | |||
#endif | |||
*cycle = (*cycle * 100 + coeff/2) / coeff; | |||
if (*cycle < (int)pollingCycle) { | |||
*cycle = (int)pollingCycle; | |||
} else if (*cycle > (int)pollingCycle * 32) { | |||
*cycle = (int)pollingCycle * 32; | |||
} | |||
#ifdef DEBUG | |||
if (*cycle != oldPollingCycle) | |||
fprintf(stderr, "\t[new cycle %dms]\n", *cycle); | |||
#endif | |||
} | |||
} | |||
int main(int argc, char** argv) | |||
{ | |||
initStdIOLoggers(); | |||
@@ -376,15 +400,13 @@ int main(int argc, char** argv) | |||
CPUMonitor cpumon((int)maxProcessorUsage, 1000); | |||
int dynPollingCycle = (int)pollingCycle; | |||
struct timeval timeSaved, timeNow; | |||
struct timezone tz; | |||
gettimeofday(&timeSaved, &tz); | |||
timeSaved.tv_sec -= 60; | |||
TimeMillis timeSaved, timeNow; | |||
while (true) { | |||
fd_set rfds; | |||
struct timeval tv; | |||
// FIXME: This seems to be wrong. | |||
tv.tv_sec = 0; | |||
tv.tv_usec = dynPollingCycle * 1000; | |||
if (tv.tv_usec > 500000) { | |||
@@ -435,32 +457,15 @@ int main(int argc, char** argv) | |||
server.checkTimeouts(); | |||
if (gettimeofday(&timeNow, &tz) == 0) { | |||
int diff = (int)((timeNow.tv_usec - timeSaved.tv_usec + 500) / 1000 + | |||
(timeNow.tv_sec - timeSaved.tv_sec) * 1000); | |||
if (timeNow.update()) { | |||
int diff = timeNow.diffFrom(timeSaved); | |||
if (diff >= dynPollingCycle) { | |||
adjustPollingCycle(&dynPollingCycle, &cpumon); | |||
timeSaved = timeNow; | |||
int coeff = cpumon.check(); | |||
if (coeff < 90 || coeff > 110) { | |||
// Adjust polling cycle to satisfy MaxProcessorUsage setting | |||
#ifdef DEBUG | |||
int oldPollingCycle = dynPollingCycle; | |||
#endif | |||
dynPollingCycle = (dynPollingCycle * 100 + coeff/2) / coeff; | |||
if (dynPollingCycle < (int)pollingCycle) { | |||
dynPollingCycle = (int)pollingCycle; | |||
} else if (dynPollingCycle > (int)pollingCycle * 32) { | |||
dynPollingCycle = (int)pollingCycle * 32; | |||
} | |||
#ifdef DEBUG | |||
if (dynPollingCycle != oldPollingCycle) | |||
fprintf(stderr, "\t[new cycle %dms]\n", dynPollingCycle); | |||
#endif | |||
} | |||
desktop.poll(); | |||
} | |||
} else { | |||
// Something strange has happened -- gettimeofday(2) failed. | |||
// Something strange has happened -- TimeMillis::update() failed. | |||
// Poll after each select(), as in the original VNC4 code. | |||
desktop.poll(); | |||
} |