int CPUMonitor::check()
{
- struct timeval timeNow;
+ TimeMillis timeNow;
clock_t clockNow;
getClock(&timeNow, &clockNow);
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.
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;
}
}
#ifndef __CPUMONITOR_H__
#define __CPUMONITOR_H__
-#include <sys/time.h>
#include <time.h>
+#include <x0vncserver/TimeMillis.h>
+
class CPUMonitor {
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;
};
#include <rfb/Configuration.h>
#include <rfb/ServerCore.h>
-#include <x0vncserver/Image.h>
#include <x0vncserver/PollingManager.h>
BoolParameter PollingManager::pollPointer
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()
#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;
}
#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 {
void debugBeforePoll();
void debugAfterPoll();
- struct timeval m_timeSaved;
+ TimeMillis m_timeSaved;
#endif
};
--- /dev/null
+/* 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;
+}
+
--- /dev/null
+/* 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__
+
// e.g. 800x600.
#include <strings.h>
-#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <x0vncserver/Image.h>
#include <x0vncserver/PollingManager.h>
#include <x0vncserver/CPUMonitor.h>
+#include <x0vncserver/TimeMillis.h>
using namespace rfb;
using namespace network;
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();
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) {
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();
}