From d7155e8f6c1460eb5ff57164da6a05a470ca0e65 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Wed, 20 Jun 2007 14:43:34 +0000 Subject: [PATCH] 2007-06-20 Tatsuhiro Tsujikawa 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. --- ChangeLog | 29 +++++++++++++++++++++++++++++ src/DefaultBtInteractive.cc | 15 +++++++++++++++ src/DefaultBtInteractive.h | 6 ++++++ src/DefaultPeerStorage.cc | 10 ++++++++-- src/Makefile.am | 4 ++-- src/Makefile.in | 4 ++-- src/MultiUrlRequestInfo.cc | 4 ++-- src/Peer.h | 12 ++++++++++-- src/PeerStat.h | 13 +++++++++++-- src/SpeedCalc.cc | 34 +++++++++++++++++++++++----------- src/SpeedCalc.h | 20 +++++++++++--------- src/TimeA2.cc | 5 +++++ src/TimeA2.h | 2 ++ src/TrackerWatcherCommand.cc | 2 +- 14 files changed, 127 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index c5396264..61401460 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,37 @@ +2007-06-20 Tatsuhiro Tsujikawa + + 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 Changed format of log file. * src/SimpleLogger.cc + * Release 0.11.0 + 2007-06-10 Tatsuhiro Tsujikawa * src/AbstractCommand.cc diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc index f22c2e49..714f9630 100644 --- a/src/DefaultBtInteractive.cc +++ b/src/DefaultBtInteractive.cc @@ -40,6 +40,8 @@ #include "BtKeepAliveMessage.h" #include "BtChokeMessage.h" #include "BtUnchokeMessage.h" +#include "BtRequestMessage.h" +#include "BtPieceMessage.h" #include "DlAbortEx.h" void DefaultBtInteractive::initiateHandshake() { @@ -173,6 +175,10 @@ void DefaultBtInteractive::receiveMessages() { floodingStat.incChokeUnchokeCount(); } 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() { + checkActiveInteraction(); + decideChoking(); detectMessageFlooding(); diff --git a/src/DefaultBtInteractive.h b/src/DefaultBtInteractive.h index 0a0a8258..fa546f70 100644 --- a/src/DefaultBtInteractive.h +++ b/src/DefaultBtInteractive.h @@ -89,6 +89,7 @@ private: BtContextHandle btContext; PeerStorageHandle peerStorage; PieceStorageHandle pieceStorage; + BtRuntimeHandle btRuntime; BtMessageReceiverWeakHandle btMessageReceiver; BtMessageDispatcherWeakHandle dispatcher; BtRequestFactoryWeakHandle btRequestFactory; @@ -100,6 +101,7 @@ private: Time keepAliveCheckPoint; Time floodingCheckPoint; FloodingStat floodingStat; + Time inactiveCheckPoint; int32_t keepAliveInterval; int32_t maxDownloadSpeedLimit; @@ -114,11 +116,14 @@ private: void fillPiece(int maxPieceNum); void addRequests(); void detectMessageFlooding(); + void checkActiveInteraction(); + public: DefaultBtInteractive():peer(0), btContext(0), peerStorage(0), pieceStorage(0), + btRuntime(0), btMessageReceiver(0), dispatcher(0), btRequestFactory(0), @@ -167,6 +172,7 @@ public: this->btContext = btContext; this->peerStorage = PEER_STORAGE(btContext); this->pieceStorage = PIECE_STORAGE(btContext); + this->btRuntime = BT_RUNTIME(btContext); } void setBtMessageReceiver(const BtMessageReceiverWeakHandle& receiver) { diff --git a/src/DefaultPeerStorage.cc b/src/DefaultPeerStorage.cc index a0a8df1f..9339ff84 100644 --- a/src/DefaultPeerStorage.cc +++ b/src/DefaultPeerStorage.cc @@ -162,12 +162,18 @@ Peers DefaultPeerStorage::getActivePeers() { class CalculateStat { private: TransferStat _stat; + struct timeval _now; public: + CalculateStat() + { + gettimeofday(&_now, 0); + } + void operator()(const PeerHandle& peer) { if(peer->isActive()) { - _stat.downloadSpeed += peer->calculateDownloadSpeed(); - _stat.uploadSpeed += peer->calculateUploadSpeed(); + _stat.downloadSpeed += peer->calculateDownloadSpeed(_now); + _stat.uploadSpeed += peer->calculateUploadSpeed(_now); } _stat.sessionDownloadLength += peer->getSessionDownloadLength(); _stat.sessionUploadLength += peer->getSessionUploadLength(); diff --git a/src/Makefile.am b/src/Makefile.am index 67c47874..bf034904 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -227,8 +227,8 @@ noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ - @LIBCARES_LIBS@ -#aria2c_LDFLAGS = -pg + @LIBCARES_LIBS@ -lprofiler +#aria2c_LDFLAGS = #-pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ diff --git a/src/Makefile.in b/src/Makefile.in index 9c7c2697..4dc57634 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -668,9 +668,9 @@ noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBARES_LIBS@\ - @LIBCARES_LIBS@ + @LIBCARES_LIBS@ -lprofiler -#aria2c_LDFLAGS = -pg +#aria2c_LDFLAGS = #-pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc index 2f11c186..8683ec2c 100644 --- a/src/MultiUrlRequestInfo.cc +++ b/src/MultiUrlRequestInfo.cc @@ -47,13 +47,13 @@ RequestInfoHandle MultiUrlRequestInfo::createNextRequestInfo(const string& filen { #ifdef ENABLE_BITTORRENT if(op->getAsBool(PREF_FOLLOW_TORRENT) && - Util::endsWith(fileInfo.filename, ".torrent")) { + Util::endsWith(filename, ".torrent")) { return new TorrentRequestInfo(filename, op); } else #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK if(op->getAsBool(PREF_FOLLOW_METALINK) && - Util::endsWith(fileInfo.filename, ".metalink")) { + Util::endsWith(filename, ".metalink")) { return new MetalinkRequestInfo(filename, op); } else #endif // ENABLE_METALINK diff --git a/src/Peer.h b/src/Peer.h index 5197583b..a15464f2 100644 --- a/src/Peer.h +++ b/src/Peer.h @@ -113,17 +113,25 @@ public: /** * Returns the transfer rate from localhost to remote host. */ - int calculateUploadSpeed() { + int32_t calculateUploadSpeed() { return peerStat.calculateUploadSpeed(); } + int32_t calculateUploadSpeed(const struct timeval& now) { + return peerStat.calculateUploadSpeed(now); + } + /** * Returns the transfer rate from remote host to localhost. */ - int calculateDownloadSpeed() { + int32_t 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. */ diff --git a/src/PeerStat.h b/src/PeerStat.h index 3d654be4..9b90eac0 100644 --- a/src/PeerStat.h +++ b/src/PeerStat.h @@ -38,6 +38,7 @@ #include "common.h" #include "SpeedCalc.h" #include "SharedHandle.h" +#include class PeerStat { public: @@ -61,14 +62,22 @@ public: /** * Returns current download speed in byte per sec. */ - int calculateDownloadSpeed() { + int32_t calculateDownloadSpeed() { return downloadSpeed.calculateSpeed(); } - int calculateUploadSpeed() { + int32_t calculateDownloadSpeed(const struct timeval& now) { + return downloadSpeed.calculateSpeed(now); + } + + int32_t calculateUploadSpeed() { return uploadSpeed.calculateSpeed(); } + int32_t calculateUploadSpeed(const struct timeval& now) { + return uploadSpeed.calculateSpeed(now); + } + void updateDownloadLength(int bytes) { downloadSpeed.update(bytes); } diff --git a/src/SpeedCalc.cc b/src/SpeedCalc.cc index af3d2d7f..65346de4 100644 --- a/src/SpeedCalc.cc +++ b/src/SpeedCalc.cc @@ -57,12 +57,24 @@ void SpeedCalc::reset() { nextInterval = CHANGE_INTERVAL_SEC; } -int SpeedCalc::calculateSpeed() { - int milliElapsed = cpArray[sw].differenceInMillis(); +int32_t SpeedCalc::calculateSpeed() { + int32_t milliElapsed = cpArray[sw].differenceInMillis(); if(milliElapsed) { - int speed = lengthArray[sw]*1000/milliElapsed; + int32_t speed = lengthArray[sw]*1000/milliElapsed; prevSpeed = speed; - maxSpeed = max(speed, maxSpeed); + maxSpeed = max(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(speed, maxSpeed); return speed; } else { return prevSpeed; @@ -71,16 +83,16 @@ int SpeedCalc::calculateSpeed() { class Plus { private: - int d; + int32_t d; 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; } }; -void SpeedCalc::update(int bytes) { +void SpeedCalc::update(int32_t bytes) { accumulatedLength += bytes; for_each(&lengthArray[0], &lengthArray[2], Plus(bytes)); if(isIntervalOver()) { @@ -99,10 +111,10 @@ void SpeedCalc::changeSw() { nextInterval = cpArray[sw].difference()+CHANGE_INTERVAL_SEC; } -int SpeedCalc::getAvgSpeed() const { - int milliElapsed = start.differenceInMillis(); +int32_t SpeedCalc::getAvgSpeed() const { + int32_t milliElapsed = start.differenceInMillis(); if(milliElapsed) { - int speed = accumulatedLength*1000/milliElapsed; + int32_t speed = accumulatedLength*1000/milliElapsed; return speed; } else { return 0; diff --git a/src/SpeedCalc.h b/src/SpeedCalc.h index b8d64d14..25a8b93d 100644 --- a/src/SpeedCalc.h +++ b/src/SpeedCalc.h @@ -40,14 +40,14 @@ class SpeedCalc { private: - long long int lengthArray[2]; - int sw; + int64_t lengthArray[2]; + int32_t sw; Time cpArray[2]; - int maxSpeed; - int prevSpeed; + int32_t maxSpeed; + int32_t prevSpeed; Time start; - long long int accumulatedLength; - int nextInterval; + int64_t accumulatedLength; + int32_t nextInterval; bool isIntervalOver() const; void changeSw(); @@ -61,13 +61,15 @@ public: /** * 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; } - int getAvgSpeed() const; + int32_t getAvgSpeed() const; void update(int bytes); diff --git a/src/TimeA2.cc b/src/TimeA2.cc index 7c56ed65..421760cd 100644 --- a/src/TimeA2.cc +++ b/src/TimeA2.cc @@ -79,6 +79,11 @@ long long int Time::differenceInMillis() const { 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) { tv.tv_sec = sec; tv.tv_usec = 0; diff --git a/src/TimeA2.h b/src/TimeA2.h index da5f2d4f..5ac66416 100644 --- a/src/TimeA2.h +++ b/src/TimeA2.h @@ -69,6 +69,8 @@ public: int difference() const; long long int differenceInMillis() const; + int64_t differenceInMillis(const struct timeval& now) const; + // Returns true if this object's time value is zero. bool isZero() const { return tv.tv_sec == 0 && tv.tv_usec == 0; } diff --git a/src/TrackerWatcherCommand.cc b/src/TrackerWatcherCommand.cc index 7c463251..35df1ff8 100644 --- a/src/TrackerWatcherCommand.cc +++ b/src/TrackerWatcherCommand.cc @@ -95,7 +95,7 @@ Command* TrackerWatcherCommand::createRequestCommand(const string& url) Commands commands = e->_requestGroupMan->getInitialCommands(e); if(commands.empty()) { - logger->error("CUID#%d - Cannot create tracker request."); + logger->error("CUID#%d - Cannot create tracker request.", cuid); return 0; } logger->info("CUID#%d - Creating new tracker request command #%d", cuid,