Browse Source

Using new TimeMillis class instead of calls to gettimeofday() and

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-ca57d06f2519
tags/v0.0.90
Constantin Kaplinsky 18 years ago
parent
commit
fbaab7f5a9

+ 7
- 7
x0vncserver/CPUMonitor.cxx View File



int CPUMonitor::check() int CPUMonitor::check()
{ {
struct timeval timeNow;
TimeMillis timeNow;
clock_t clockNow; clock_t clockNow;
getClock(&timeNow, &clockNow); getClock(&timeNow, &clockNow);


if (m_savedClock != (clock_t)-1 && clockNow != (clock_t)-1) { if (m_savedClock != (clock_t)-1 && clockNow != (clock_t)-1) {


// Find out how much real time has been elapsed (in milliseconds). // 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) { if (timeDiff < m_updatePeriod) {
// Measuring CPU usage is problematic in this case. So return // Measuring CPU usage is problematic in this case. So return
// 100 and do not update saved time and clock numbers. // 100 and do not update saved time and clock numbers.
return coeff; 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(); *clk = clock();
} else {
*clk = (clock_t)-1;
} }
} }

+ 4
- 3
x0vncserver/CPUMonitor.h View File

#ifndef __CPUMONITOR_H__ #ifndef __CPUMONITOR_H__
#define __CPUMONITOR_H__ #define __CPUMONITOR_H__


#include <sys/time.h>
#include <time.h> #include <time.h>


#include <x0vncserver/TimeMillis.h>

class CPUMonitor { class CPUMonitor {


public: public:


protected: protected:


static void getClock(struct timeval *tv, clock_t *clk);
static void getClock(TimeMillis *tm, clock_t *clk);


int m_optimalLevel; int m_optimalLevel;
int m_updatePeriod; int m_updatePeriod;
struct timeval m_savedTime;
TimeMillis m_savedTime;
clock_t m_savedClock; clock_t m_savedClock;


}; };

+ 4
- 15
x0vncserver/PollingManager.cxx View File

#include <rfb/Configuration.h> #include <rfb/Configuration.h>
#include <rfb/ServerCore.h> #include <rfb/ServerCore.h>


#include <x0vncserver/Image.h>
#include <x0vncserver/PollingManager.h> #include <x0vncserver/PollingManager.h>


BoolParameter PollingManager::pollPointer BoolParameter PollingManager::pollPointer
memset(m_rateMatrix, 0, numTiles); memset(m_rateMatrix, 0, numTiles);
memset(m_videoFlags, 0, numTiles); memset(m_videoFlags, 0, numTiles);
memset(m_changedFlags, 0, numTiles); memset(m_changedFlags, 0, numTiles);

#ifdef DEBUG
memset(&m_timeSaved, 0, sizeof(m_timeSaved));
#endif
} }


PollingManager::~PollingManager() PollingManager::~PollingManager()
#ifdef DEBUG #ifdef DEBUG
void PollingManager::debugBeforePoll() 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); fprintf(stderr, "[wait%4dms]\t[step %2d]\t", diff, m_pollingStep % 32);
m_timeSaved = timeNow; m_timeSaved = timeNow;
} }


void PollingManager::debugAfterPoll() 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); fprintf(stderr, "[poll%4dms]\n", diff);
m_timeSaved = timeNow; m_timeSaved = timeNow;
} }

+ 5
- 3
x0vncserver/PollingManager.h View File

#ifndef __POLLINGMANAGER_H__ #ifndef __POLLINGMANAGER_H__
#define __POLLINGMANAGER_H__ #define __POLLINGMANAGER_H__


#include <sys/time.h>

#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <rfb/VNCServer.h> #include <rfb/VNCServer.h>


#include <x0vncserver/Image.h> #include <x0vncserver/Image.h>


#ifdef DEBUG
#include <x0vncserver/TimeMillis.h>
#endif

using namespace rfb; using namespace rfb;


class PollingManager { class PollingManager {
void debugBeforePoll(); void debugBeforePoll();
void debugAfterPoll(); void debugAfterPoll();


struct timeval m_timeSaved;
TimeMillis m_timeSaved;
#endif #endif


}; };

+ 44
- 0
x0vncserver/TimeMillis.cxx View File

/* 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;
}


+ 47
- 0
x0vncserver/TimeMillis.h View File

/* 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__


+ 31
- 26
x0vncserver/x0vncserver.cxx View File

// e.g. 800x600. // e.g. 800x600.


#include <strings.h> #include <strings.h>
#include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <x0vncserver/Image.h> #include <x0vncserver/Image.h>
#include <x0vncserver/PollingManager.h> #include <x0vncserver/PollingManager.h>
#include <x0vncserver/CPUMonitor.h> #include <x0vncserver/CPUMonitor.h>
#include <x0vncserver/TimeMillis.h>


using namespace rfb; using namespace rfb;
using namespace network; using namespace network;
exit(1); 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) int main(int argc, char** argv)
{ {
initStdIOLoggers(); initStdIOLoggers();
CPUMonitor cpumon((int)maxProcessorUsage, 1000); CPUMonitor cpumon((int)maxProcessorUsage, 1000);
int dynPollingCycle = (int)pollingCycle; int dynPollingCycle = (int)pollingCycle;


struct timeval timeSaved, timeNow;
struct timezone tz;
gettimeofday(&timeSaved, &tz);
timeSaved.tv_sec -= 60;
TimeMillis timeSaved, timeNow;


while (true) { while (true) {
fd_set rfds; fd_set rfds;
struct timeval tv; struct timeval tv;


// FIXME: This seems to be wrong.
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = dynPollingCycle * 1000; tv.tv_usec = dynPollingCycle * 1000;
if (tv.tv_usec > 500000) { if (tv.tv_usec > 500000) {


server.checkTimeouts(); 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) { if (diff >= dynPollingCycle) {
adjustPollingCycle(&dynPollingCycle, &cpumon);
timeSaved = timeNow; 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(); desktop.poll();
} }
} else { } 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. // Poll after each select(), as in the original VNC4 code.
desktop.poll(); desktop.poll();
} }

Loading…
Cancel
Save