2007-06-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Reduce the number of calls to gettimeofday to lower CPU load.
	* src/TimeA2.h, src/TimeA2.cc (differenceInMillis): New 
function.
	* src/SpeedCalc.h, src/SpeedCalc.cc (calculateSpeed): New 
function.
	* src/Peer.h (calculateUploadSpeed): New function.
	(calculateDownloadSpeed): New function.
	* src/DefaultPeerStorage.cc
	(CalculateStat): Added _now variable.
	In operator(), call Peer::calculateDownloadSpeed(const struct 
timeval&)
	and Peer::calculateUploadSpeed(const struct timeval&)
	
	Drop connection if no request or piece message is exchanged in
	a certain interval.
	* src/DefaultBtInteractive.h
	(btRuntime): New variable.
	(inactiveCheckPoint): New variable.
	(checkActiveInteraction): New function.
	* src/DefaultBtInteractive.cc (receiveMessages): Reset timer 
when
	request or piece message is received.
	(checkActiveInteraction): New function.
	(doInteractionProcessing): Call checkActiveInteraction.

	Fixed the bug that causes remote Metalink and Torrent files are 
not
	processed.
	* src/MultiUrlRequestInfo.cc (createNextRequestInfo): Fixed the 
bug.
pull/1/head
Tatsuhiro Tsujikawa 2007-06-20 14:43:34 +00:00
parent be9dec8535
commit d7155e8f6c
14 changed files with 127 additions and 33 deletions

View File

@ -1,8 +1,37 @@
2007-06-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Reduce the number of calls to gettimeofday to lower CPU load.
* src/TimeA2.h, src/TimeA2.cc (differenceInMillis): New function.
* src/SpeedCalc.h, src/SpeedCalc.cc (calculateSpeed): New function.
* src/Peer.h (calculateUploadSpeed): New function.
(calculateDownloadSpeed): New function.
* src/DefaultPeerStorage.cc
(CalculateStat): Added _now variable.
In operator(), call Peer::calculateDownloadSpeed(const struct timeval&)
and Peer::calculateUploadSpeed(const struct timeval&)
Drop connection if no request or piece message is exchanged in
a certain interval.
* src/DefaultBtInteractive.h
(btRuntime): New variable.
(inactiveCheckPoint): New variable.
(checkActiveInteraction): New function.
* src/DefaultBtInteractive.cc (receiveMessages): Reset timer when
request or piece message is received.
(checkActiveInteraction): New function.
(doInteractionProcessing): Call checkActiveInteraction.
Fixed the bug that causes remote Metalink and Torrent files are not
processed.
* src/MultiUrlRequestInfo.cc (createNextRequestInfo): Fixed the bug.
2007-06-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-06-12 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Changed format of log file. Changed format of log file.
* src/SimpleLogger.cc * src/SimpleLogger.cc
* Release 0.11.0
2007-06-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-06-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
* src/AbstractCommand.cc * src/AbstractCommand.cc

View File

@ -40,6 +40,8 @@
#include "BtKeepAliveMessage.h" #include "BtKeepAliveMessage.h"
#include "BtChokeMessage.h" #include "BtChokeMessage.h"
#include "BtUnchokeMessage.h" #include "BtUnchokeMessage.h"
#include "BtRequestMessage.h"
#include "BtPieceMessage.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
void DefaultBtInteractive::initiateHandshake() { void DefaultBtInteractive::initiateHandshake() {
@ -173,6 +175,10 @@ void DefaultBtInteractive::receiveMessages() {
floodingStat.incChokeUnchokeCount(); floodingStat.incChokeUnchokeCount();
} }
break; break;
case BtRequestMessage::ID:
case BtPieceMessage::ID:
inactiveCheckPoint.reset();
break;
} }
} }
} }
@ -271,7 +277,16 @@ void DefaultBtInteractive::detectMessageFlooding() {
} }
} }
void DefaultBtInteractive::checkActiveInteraction()
{
if(inactiveCheckPoint.elapsed(10*60) && btRuntime->getConnections() >= MAX_PEERS) {
throw new DlAbortEx("Drop connection because of an inactive interaction.");
}
}
void DefaultBtInteractive::doInteractionProcessing() { void DefaultBtInteractive::doInteractionProcessing() {
checkActiveInteraction();
decideChoking(); decideChoking();
detectMessageFlooding(); detectMessageFlooding();

View File

@ -89,6 +89,7 @@ private:
BtContextHandle btContext; BtContextHandle btContext;
PeerStorageHandle peerStorage; PeerStorageHandle peerStorage;
PieceStorageHandle pieceStorage; PieceStorageHandle pieceStorage;
BtRuntimeHandle btRuntime;
BtMessageReceiverWeakHandle btMessageReceiver; BtMessageReceiverWeakHandle btMessageReceiver;
BtMessageDispatcherWeakHandle dispatcher; BtMessageDispatcherWeakHandle dispatcher;
BtRequestFactoryWeakHandle btRequestFactory; BtRequestFactoryWeakHandle btRequestFactory;
@ -100,6 +101,7 @@ private:
Time keepAliveCheckPoint; Time keepAliveCheckPoint;
Time floodingCheckPoint; Time floodingCheckPoint;
FloodingStat floodingStat; FloodingStat floodingStat;
Time inactiveCheckPoint;
int32_t keepAliveInterval; int32_t keepAliveInterval;
int32_t maxDownloadSpeedLimit; int32_t maxDownloadSpeedLimit;
@ -114,11 +116,14 @@ private:
void fillPiece(int maxPieceNum); void fillPiece(int maxPieceNum);
void addRequests(); void addRequests();
void detectMessageFlooding(); void detectMessageFlooding();
void checkActiveInteraction();
public: public:
DefaultBtInteractive():peer(0), DefaultBtInteractive():peer(0),
btContext(0), btContext(0),
peerStorage(0), peerStorage(0),
pieceStorage(0), pieceStorage(0),
btRuntime(0),
btMessageReceiver(0), btMessageReceiver(0),
dispatcher(0), dispatcher(0),
btRequestFactory(0), btRequestFactory(0),
@ -167,6 +172,7 @@ public:
this->btContext = btContext; this->btContext = btContext;
this->peerStorage = PEER_STORAGE(btContext); this->peerStorage = PEER_STORAGE(btContext);
this->pieceStorage = PIECE_STORAGE(btContext); this->pieceStorage = PIECE_STORAGE(btContext);
this->btRuntime = BT_RUNTIME(btContext);
} }
void setBtMessageReceiver(const BtMessageReceiverWeakHandle& receiver) { void setBtMessageReceiver(const BtMessageReceiverWeakHandle& receiver) {

View File

@ -162,12 +162,18 @@ Peers DefaultPeerStorage::getActivePeers() {
class CalculateStat { class CalculateStat {
private: private:
TransferStat _stat; TransferStat _stat;
struct timeval _now;
public: public:
CalculateStat()
{
gettimeofday(&_now, 0);
}
void operator()(const PeerHandle& peer) void operator()(const PeerHandle& peer)
{ {
if(peer->isActive()) { if(peer->isActive()) {
_stat.downloadSpeed += peer->calculateDownloadSpeed(); _stat.downloadSpeed += peer->calculateDownloadSpeed(_now);
_stat.uploadSpeed += peer->calculateUploadSpeed(); _stat.uploadSpeed += peer->calculateUploadSpeed(_now);
} }
_stat.sessionDownloadLength += peer->getSessionDownloadLength(); _stat.sessionDownloadLength += peer->getSessionDownloadLength();
_stat.sessionUploadLength += peer->getSessionUploadLength(); _stat.sessionUploadLength += peer->getSessionUploadLength();

View File

@ -227,8 +227,8 @@ noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
@LIBCARES_LIBS@ @LIBCARES_LIBS@ -lprofiler
#aria2c_LDFLAGS = -pg #aria2c_LDFLAGS = #-pg
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\

View File

@ -668,9 +668,9 @@ noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS) libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\
@LIBCARES_LIBS@ @LIBCARES_LIBS@ -lprofiler
#aria2c_LDFLAGS = -pg #aria2c_LDFLAGS = #-pg
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\

View File

@ -47,13 +47,13 @@ RequestInfoHandle MultiUrlRequestInfo::createNextRequestInfo(const string& filen
{ {
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
if(op->getAsBool(PREF_FOLLOW_TORRENT) && if(op->getAsBool(PREF_FOLLOW_TORRENT) &&
Util::endsWith(fileInfo.filename, ".torrent")) { Util::endsWith(filename, ".torrent")) {
return new TorrentRequestInfo(filename, op); return new TorrentRequestInfo(filename, op);
} else } else
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK #ifdef ENABLE_METALINK
if(op->getAsBool(PREF_FOLLOW_METALINK) && if(op->getAsBool(PREF_FOLLOW_METALINK) &&
Util::endsWith(fileInfo.filename, ".metalink")) { Util::endsWith(filename, ".metalink")) {
return new MetalinkRequestInfo(filename, op); return new MetalinkRequestInfo(filename, op);
} else } else
#endif // ENABLE_METALINK #endif // ENABLE_METALINK

View File

@ -113,17 +113,25 @@ public:
/** /**
* Returns the transfer rate from localhost to remote host. * Returns the transfer rate from localhost to remote host.
*/ */
int calculateUploadSpeed() { int32_t calculateUploadSpeed() {
return peerStat.calculateUploadSpeed(); return peerStat.calculateUploadSpeed();
} }
int32_t calculateUploadSpeed(const struct timeval& now) {
return peerStat.calculateUploadSpeed(now);
}
/** /**
* Returns the transfer rate from remote host to localhost. * Returns the transfer rate from remote host to localhost.
*/ */
int calculateDownloadSpeed() { int32_t calculateDownloadSpeed() {
return peerStat.calculateDownloadSpeed(); return peerStat.calculateDownloadSpeed();
} }
int32_t calculateDownloadSpeed(const struct timeval& now) {
return peerStat.calculateDownloadSpeed(now);
}
/** /**
* Returns the number of bytes uploaded to the remote host. * Returns the number of bytes uploaded to the remote host.
*/ */

View File

@ -38,6 +38,7 @@
#include "common.h" #include "common.h"
#include "SpeedCalc.h" #include "SpeedCalc.h"
#include "SharedHandle.h" #include "SharedHandle.h"
#include <sys/time.h>
class PeerStat { class PeerStat {
public: public:
@ -61,14 +62,22 @@ public:
/** /**
* Returns current download speed in byte per sec. * Returns current download speed in byte per sec.
*/ */
int calculateDownloadSpeed() { int32_t calculateDownloadSpeed() {
return downloadSpeed.calculateSpeed(); return downloadSpeed.calculateSpeed();
} }
int calculateUploadSpeed() { int32_t calculateDownloadSpeed(const struct timeval& now) {
return downloadSpeed.calculateSpeed(now);
}
int32_t calculateUploadSpeed() {
return uploadSpeed.calculateSpeed(); return uploadSpeed.calculateSpeed();
} }
int32_t calculateUploadSpeed(const struct timeval& now) {
return uploadSpeed.calculateSpeed(now);
}
void updateDownloadLength(int bytes) { void updateDownloadLength(int bytes) {
downloadSpeed.update(bytes); downloadSpeed.update(bytes);
} }

View File

@ -57,12 +57,24 @@ void SpeedCalc::reset() {
nextInterval = CHANGE_INTERVAL_SEC; nextInterval = CHANGE_INTERVAL_SEC;
} }
int SpeedCalc::calculateSpeed() { int32_t SpeedCalc::calculateSpeed() {
int milliElapsed = cpArray[sw].differenceInMillis(); int32_t milliElapsed = cpArray[sw].differenceInMillis();
if(milliElapsed) { if(milliElapsed) {
int speed = lengthArray[sw]*1000/milliElapsed; int32_t speed = lengthArray[sw]*1000/milliElapsed;
prevSpeed = speed; prevSpeed = speed;
maxSpeed = max<int>(speed, maxSpeed); maxSpeed = max<int32_t>(speed, maxSpeed);
return speed;
} else {
return prevSpeed;
}
}
int32_t SpeedCalc::calculateSpeed(const struct timeval& now) {
int64_t milliElapsed = cpArray[sw].differenceInMillis(now);
if(milliElapsed) {
int32_t speed = lengthArray[sw]*1000/milliElapsed;
prevSpeed = speed;
maxSpeed = max<int32_t>(speed, maxSpeed);
return speed; return speed;
} else { } else {
return prevSpeed; return prevSpeed;
@ -71,16 +83,16 @@ int SpeedCalc::calculateSpeed() {
class Plus { class Plus {
private: private:
int d; int32_t d;
public: public:
Plus(int d):d(d) {} Plus(int32_t d):d(d) {}
void operator()(long long int& length) { void operator()(int64_t& length) {
length += d; length += d;
} }
}; };
void SpeedCalc::update(int bytes) { void SpeedCalc::update(int32_t bytes) {
accumulatedLength += bytes; accumulatedLength += bytes;
for_each(&lengthArray[0], &lengthArray[2], Plus(bytes)); for_each(&lengthArray[0], &lengthArray[2], Plus(bytes));
if(isIntervalOver()) { if(isIntervalOver()) {
@ -99,10 +111,10 @@ void SpeedCalc::changeSw() {
nextInterval = cpArray[sw].difference()+CHANGE_INTERVAL_SEC; nextInterval = cpArray[sw].difference()+CHANGE_INTERVAL_SEC;
} }
int SpeedCalc::getAvgSpeed() const { int32_t SpeedCalc::getAvgSpeed() const {
int milliElapsed = start.differenceInMillis(); int32_t milliElapsed = start.differenceInMillis();
if(milliElapsed) { if(milliElapsed) {
int speed = accumulatedLength*1000/milliElapsed; int32_t speed = accumulatedLength*1000/milliElapsed;
return speed; return speed;
} else { } else {
return 0; return 0;

View File

@ -40,14 +40,14 @@
class SpeedCalc { class SpeedCalc {
private: private:
long long int lengthArray[2]; int64_t lengthArray[2];
int sw; int32_t sw;
Time cpArray[2]; Time cpArray[2];
int maxSpeed; int32_t maxSpeed;
int prevSpeed; int32_t prevSpeed;
Time start; Time start;
long long int accumulatedLength; int64_t accumulatedLength;
int nextInterval; int32_t nextInterval;
bool isIntervalOver() const; bool isIntervalOver() const;
void changeSw(); void changeSw();
@ -61,13 +61,15 @@ public:
/** /**
* Returns download/upload speed in byte per sec * Returns download/upload speed in byte per sec
*/ */
int calculateSpeed(); int32_t calculateSpeed();
int getMaxSpeed() const { int32_t calculateSpeed(const struct timeval& now);
int32_t getMaxSpeed() const {
return maxSpeed; return maxSpeed;
} }
int getAvgSpeed() const; int32_t getAvgSpeed() const;
void update(int bytes); void update(int bytes);

View File

@ -79,6 +79,11 @@ long long int Time::differenceInMillis() const {
return Util::difftv(getCurrentTime(), tv)/1000; return Util::difftv(getCurrentTime(), tv)/1000;
} }
int64_t Time::differenceInMillis(const struct timeval& now) const
{
return Util::difftv(now, tv)/1000;
}
void Time::setTimeInSec(int sec) { void Time::setTimeInSec(int sec) {
tv.tv_sec = sec; tv.tv_sec = sec;
tv.tv_usec = 0; tv.tv_usec = 0;

View File

@ -69,6 +69,8 @@ public:
int difference() const; int difference() const;
long long int differenceInMillis() const; long long int differenceInMillis() const;
int64_t differenceInMillis(const struct timeval& now) const;
// Returns true if this object's time value is zero. // Returns true if this object's time value is zero.
bool isZero() const { return tv.tv_sec == 0 && tv.tv_usec == 0; } bool isZero() const { return tv.tv_sec == 0 && tv.tv_usec == 0; }

View File

@ -95,7 +95,7 @@ Command* TrackerWatcherCommand::createRequestCommand(const string& url)
Commands commands = e->_requestGroupMan->getInitialCommands(e); Commands commands = e->_requestGroupMan->getInitialCommands(e);
if(commands.empty()) { if(commands.empty()) {
logger->error("CUID#%d - Cannot create tracker request."); logger->error("CUID#%d - Cannot create tracker request.", cuid);
return 0; return 0;
} }
logger->info("CUID#%d - Creating new tracker request command #%d", cuid, logger->info("CUID#%d - Creating new tracker request command #%d", cuid,