From 8d09b069e2b709d8657f5fdbcf2a933515545f39 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 6 Mar 2010 08:29:53 +0000 Subject: [PATCH] 2010-03-06 Tatsuhiro Tsujikawa Added Time global::wallclock to cache "current time" to reduce the call gettimeofday(). Global variables are now in namespace global. * src/AbstractCommand.cc * src/ActivePeerConnectionCommand.cc * src/AdaptiveURISelector.cc * src/BtLeecherStateChoke.cc * src/BtLeecherStateChoke.h * src/BtSeederStateChoke.cc * src/BtSeederStateChoke.h * src/BtStopDownloadCommand.cc * src/ConsoleStatCalc.cc * src/DHTBucket.cc * src/DHTGetPeersCommand.cc * src/DHTMessageTrackerEntry.cc * src/DHTNode.cc * src/DHTPeerAnnounceEntry.cc * src/DHTPeerAnnounceStorage.cc * src/DHTSetup.cc * src/DefaultBtAnnounce.cc * src/DefaultBtInteractive.cc * src/DefaultBtMessageDispatcher.cc * src/DefaultPeerStorage.cc * src/DefaultPieceStorage.cc * src/DownloadCommand.cc * src/DownloadEngine.cc * src/FileEntry.cc * src/HttpServerBodyCommand.cc * src/HttpServerCommand.cc * src/HttpServerResponseCommand.cc * src/LpdMessageDispatcher.cc * src/MultiUrlRequestInfo.cc * src/Peer.cc * src/Peer.h * src/PeerAbstractCommand.cc * src/PeerStat.h * src/RequestSlot.cc * src/RequestSlot.h * src/SegmentMan.cc * src/ServerStatMan.cc * src/SleepCommand.cc * src/SpeedCalc.cc * src/SpeedCalc.h * src/TimeA2.cc * src/TimeA2.h * src/TimeBasedCommand.cc * src/TimeSeedCriteria.h * src/UTMetadataRequestTracker.h * src/UTPexExtensionMessage.cc * src/wallclock.h --- ChangeLog | 52 ++++++++++++++++++++++++++++++ src/AbstractCommand.cc | 5 +-- src/ActivePeerConnectionCommand.cc | 5 +-- src/AdaptiveURISelector.cc | 3 +- src/BtLeecherStateChoke.cc | 23 ++++--------- src/BtLeecherStateChoke.h | 2 +- src/BtSeederStateChoke.cc | 16 +++------ src/BtSeederStateChoke.h | 2 +- src/BtStopDownloadCommand.cc | 5 +-- src/ConsoleStatCalc.cc | 9 +++--- src/DHTBucket.cc | 6 ++-- src/DHTGetPeersCommand.cc | 8 +++-- src/DHTMessageTrackerEntry.cc | 3 +- src/DHTNode.cc | 6 ++-- src/DHTPeerAnnounceEntry.cc | 5 +-- src/DHTPeerAnnounceStorage.cc | 4 ++- src/DHTSetup.cc | 5 ++- src/DefaultBtAnnounce.cc | 13 +++++--- src/DefaultBtInteractive.cc | 36 ++++++++++++--------- src/DefaultBtMessageDispatcher.cc | 15 ++------- src/DefaultPeerStorage.cc | 23 +++++++------ src/DefaultPieceStorage.cc | 3 +- src/DownloadCommand.cc | 4 ++- src/DownloadEngine.cc | 27 ++++++++++------ src/FileEntry.cc | 4 ++- src/HttpServerBodyCommand.cc | 5 +-- src/HttpServerCommand.cc | 5 +-- src/HttpServerResponseCommand.cc | 3 +- src/LpdMessageDispatcher.cc | 5 +-- src/MultiUrlRequestInfo.cc | 12 ++++--- src/Peer.cc | 18 +++-------- src/Peer.h | 4 --- src/PeerAbstractCommand.cc | 7 ++-- src/PeerStat.h | 10 ------ src/RequestSlot.cc | 9 ++---- src/RequestSlot.h | 3 +- src/SegmentMan.cc | 5 +-- src/ServerStatMan.cc | 3 +- src/SleepCommand.cc | 3 +- src/SpeedCalc.cc | 39 ++++++++-------------- src/SpeedCalc.h | 8 +---- src/TimeA2.cc | 12 +++++-- src/TimeA2.h | 12 +++++++ src/TimeBasedCommand.cc | 5 +-- src/TimeSeedCriteria.h | 5 +-- src/UTMetadataRequestTracker.h | 3 +- src/UTPexExtensionMessage.cc | 6 ++-- src/wallclock.h | 46 ++++++++++++++++++++++++++ test/TimeSeedCriteriaTest.cc | 5 +-- test/UTPexExtensionMessageTest.cc | 10 +++--- 50 files changed, 314 insertions(+), 213 deletions(-) create mode 100644 src/wallclock.h diff --git a/ChangeLog b/ChangeLog index 8546595d..3d2f274d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2010-03-06 Tatsuhiro Tsujikawa + + Added Time global::wallclock to cache "current time" to reduce the + call gettimeofday(). Global variables are now in namespace global. + * src/AbstractCommand.cc + * src/ActivePeerConnectionCommand.cc + * src/AdaptiveURISelector.cc + * src/BtLeecherStateChoke.cc + * src/BtLeecherStateChoke.h + * src/BtSeederStateChoke.cc + * src/BtSeederStateChoke.h + * src/BtStopDownloadCommand.cc + * src/ConsoleStatCalc.cc + * src/DHTBucket.cc + * src/DHTGetPeersCommand.cc + * src/DHTMessageTrackerEntry.cc + * src/DHTNode.cc + * src/DHTPeerAnnounceEntry.cc + * src/DHTPeerAnnounceStorage.cc + * src/DHTSetup.cc + * src/DefaultBtAnnounce.cc + * src/DefaultBtInteractive.cc + * src/DefaultBtMessageDispatcher.cc + * src/DefaultPeerStorage.cc + * src/DefaultPieceStorage.cc + * src/DownloadCommand.cc + * src/DownloadEngine.cc + * src/FileEntry.cc + * src/HttpServerBodyCommand.cc + * src/HttpServerCommand.cc + * src/HttpServerResponseCommand.cc + * src/LpdMessageDispatcher.cc + * src/MultiUrlRequestInfo.cc + * src/Peer.cc + * src/Peer.h + * src/PeerAbstractCommand.cc + * src/PeerStat.h + * src/RequestSlot.cc + * src/RequestSlot.h + * src/SegmentMan.cc + * src/ServerStatMan.cc + * src/SleepCommand.cc + * src/SpeedCalc.cc + * src/SpeedCalc.h + * src/TimeA2.cc + * src/TimeA2.h + * src/TimeBasedCommand.cc + * src/TimeSeedCriteria.h + * src/UTMetadataRequestTracker.h + * src/UTPexExtensionMessage.cc + * src/wallclock.h + 2010-03-05 Tatsuhiro Tsujikawa Fixed the bug that util::itos(INT64_MIN) fails. diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc index 9e8841af..e57f35af 100644 --- a/src/AbstractCommand.cc +++ b/src/AbstractCommand.cc @@ -64,6 +64,7 @@ #include "util.h" #include "LogFactory.h" #include "DownloadContext.h" +#include "wallclock.h" namespace aria2 { @@ -134,7 +135,7 @@ bool AbstractCommand::execute() { (nameResolverCheck && nameResolveFinished()) || #endif // ENABLE_ASYNC_DNS (!checkSocketIsReadable && !checkSocketIsWritable && !nameResolverCheck)) { - checkPoint.reset(); + checkPoint = global::wallclock; if(!_requestGroup->getPieceStorage().isNull()) { _segments.clear(); _requestGroup->getSegmentMan()->getInFlightSegment(_segments, cuid); @@ -175,7 +176,7 @@ bool AbstractCommand::execute() { (StringFormat(MSG_NETWORK_PROBLEM, socket->getSocketError().c_str()).str()); } else { - if(checkPoint.elapsed(timeout)) { + if(checkPoint.difference(global::wallclock) >= timeout) { // timeout triggers ServerStat error state. SharedHandle ss = diff --git a/src/ActivePeerConnectionCommand.cc b/src/ActivePeerConnectionCommand.cc index b7a6585c..995475c8 100644 --- a/src/ActivePeerConnectionCommand.cc +++ b/src/ActivePeerConnectionCommand.cc @@ -49,6 +49,7 @@ #include "RequestGroup.h" #include "DownloadContext.h" #include "bittorrent_helper.h" +#include "wallclock.h" namespace aria2 { @@ -76,8 +77,8 @@ bool ActivePeerConnectionCommand::execute() { if(_btRuntime->isHalt()) { return true; } - if(checkPoint.elapsed(interval)) { - checkPoint.reset(); + if(checkPoint.difference(global::wallclock) >= interval) { + checkPoint = global::wallclock; TransferStat tstat = _requestGroup->calculateStat(); const unsigned int maxDownloadLimit = _requestGroup->getMaxDownloadSpeedLimit(); diff --git a/src/AdaptiveURISelector.cc b/src/AdaptiveURISelector.cc index 0ac807cb..04c942c3 100644 --- a/src/AdaptiveURISelector.cc +++ b/src/AdaptiveURISelector.cc @@ -51,6 +51,7 @@ #include "SimpleRandomizer.h" #include "SocketCore.h" #include "FileEntry.h" +#include "wallclock.h" namespace aria2 { @@ -329,7 +330,7 @@ std::string AdaptiveURISelector::getFirstToTestUri power = (int)pow(2.0, (float)counter); /* We test the mirror another time if it has not been * tested since 2^counter days */ - if(ss->getLastUpdated().difference() > power*24*60*60) { + if(ss->getLastUpdated().difference(global::wallclock) > power*24*60*60) { return *i; } } diff --git a/src/BtLeecherStateChoke.cc b/src/BtLeecherStateChoke.cc index cf1283d1..bad3deaa 100644 --- a/src/BtLeecherStateChoke.cc +++ b/src/BtLeecherStateChoke.cc @@ -41,6 +41,7 @@ #include "LogFactory.h" #include "a2time.h" #include "SimpleRandomizer.h" +#include "wallclock.h" namespace aria2 { @@ -51,12 +52,12 @@ BtLeecherStateChoke::BtLeecherStateChoke(): BtLeecherStateChoke::~BtLeecherStateChoke() {} -BtLeecherStateChoke::PeerEntry::PeerEntry -(const SharedHandle& peer, const struct timeval& now): - _peer(peer), _downloadSpeed(peer->calculateDownloadSpeed(now)), +BtLeecherStateChoke::PeerEntry::PeerEntry(const SharedHandle& peer): + _peer(peer), _downloadSpeed(peer->calculateDownloadSpeed()), // peer must be interested to us and sent block in the last 30 seconds - _regularUnchoker(peer->peerInterested() && - !peer->getLastDownloadUpdate().elapsed(30)) {} + _regularUnchoker + (peer->peerInterested() && + peer->getLastDownloadUpdate().difference(global::wallclock) < 30) {} const SharedHandle& BtLeecherStateChoke::PeerEntry::getPeer() const { @@ -142,9 +143,6 @@ void BtLeecherStateChoke::regularUnchoke(std::vector& peerEntries) std::partition(peerEntries.begin(), peerEntries.end(), std::mem_fun_ref(&PeerEntry::isRegularUnchoker)); - struct timeval now; - gettimeofday(&now, 0); - std::sort(peerEntries.begin(), rest); // the number of regular unchokers @@ -180,18 +178,11 @@ void BtLeecherStateChoke::regularUnchoke(std::vector& peerEntries) } class BtLeecherStateChokeGenPeerEntry { -private: - struct timeval _now; public: - BtLeecherStateChokeGenPeerEntry() - { - gettimeofday(&_now, 0); - } - BtLeecherStateChoke::PeerEntry operator() (const SharedHandle& peer) const { - return BtLeecherStateChoke::PeerEntry(peer, _now); + return BtLeecherStateChoke::PeerEntry(peer); } }; diff --git a/src/BtLeecherStateChoke.h b/src/BtLeecherStateChoke.h index 06292b9b..062342d1 100644 --- a/src/BtLeecherStateChoke.h +++ b/src/BtLeecherStateChoke.h @@ -61,7 +61,7 @@ private: unsigned int _downloadSpeed; bool _regularUnchoker; public: - PeerEntry(const SharedHandle& peer, const struct timeval& now); + PeerEntry(const SharedHandle& peer); bool operator<(const PeerEntry& rhs) const; diff --git a/src/BtSeederStateChoke.cc b/src/BtSeederStateChoke.cc index e1731ae1..a2debb68 100644 --- a/src/BtSeederStateChoke.cc +++ b/src/BtSeederStateChoke.cc @@ -40,6 +40,7 @@ #include "Logger.h" #include "LogFactory.h" #include "SimpleRandomizer.h" +#include "wallclock.h" namespace aria2 { @@ -51,12 +52,12 @@ BtSeederStateChoke::BtSeederStateChoke(): BtSeederStateChoke::~BtSeederStateChoke() {} BtSeederStateChoke::PeerEntry::PeerEntry -(const SharedHandle& peer, const struct timeval& now): +(const SharedHandle& peer): _peer(peer), _outstandingUpload(peer->countOutstandingUpload()), _lastAmUnchoking(peer->getLastAmUnchoking()), - _recentUnchoking(!_lastAmUnchoking.elapsed(TIME_FRAME)), - _uploadSpeed(peer->calculateUploadSpeed(now)) + _recentUnchoking(_lastAmUnchoking.difference(global::wallclock) < TIME_FRAME), + _uploadSpeed(peer->calculateUploadSpeed()) {} bool @@ -118,17 +119,10 @@ public: }; class GenPeerEntry { -private: - struct timeval _now; public: - GenPeerEntry() - { - gettimeofday(&_now, 0); - } - BtSeederStateChoke::PeerEntry operator()(const SharedHandle& peer) const { - return BtSeederStateChoke::PeerEntry(peer, _now); + return BtSeederStateChoke::PeerEntry(peer); } }; diff --git a/src/BtSeederStateChoke.h b/src/BtSeederStateChoke.h index 8acc8833..eec74728 100644 --- a/src/BtSeederStateChoke.h +++ b/src/BtSeederStateChoke.h @@ -65,7 +65,7 @@ private: const static time_t TIME_FRAME = 20; public: - PeerEntry(const SharedHandle& peer, const struct timeval& now); + PeerEntry(const SharedHandle& peer); bool operator<(const PeerEntry& rhs) const; diff --git a/src/BtStopDownloadCommand.cc b/src/BtStopDownloadCommand.cc index 35de48e9..a1c36b62 100644 --- a/src/BtStopDownloadCommand.cc +++ b/src/BtStopDownloadCommand.cc @@ -39,6 +39,7 @@ #include "Peer.h" #include "DownloadContext.h" #include "Logger.h" +#include "wallclock.h" namespace aria2 { @@ -57,7 +58,7 @@ void BtStopDownloadCommand::preProcess() if(_btRuntime->isHalt() || _pieceStorage->downloadFinished()) { _exit = true; } - if(_checkPoint.elapsed(_timeout)) { + if(_checkPoint.difference(global::wallclock) >= _timeout) { logger->notice("GID#%d Stop downloading torrent due to" " --bt-stop-timeout option.", _requestGroup->getGID()); _requestGroup->setHaltRequested(true); @@ -68,7 +69,7 @@ void BtStopDownloadCommand::preProcess() void BtStopDownloadCommand::process() { if(_requestGroup->calculateStat().getDownloadSpeed() > 0) { - _checkPoint.reset(); + _checkPoint = global::wallclock; } } diff --git a/src/ConsoleStatCalc.cc b/src/ConsoleStatCalc.cc index b2d959fa..6eb52148 100644 --- a/src/ConsoleStatCalc.cc +++ b/src/ConsoleStatCalc.cc @@ -59,6 +59,7 @@ #include "CheckIntegrityEntry.h" #include "util.h" #include "DownloadContext.h" +#include "wallclock.h" #ifdef ENABLE_BITTORRENT # include "bittorrent_helper.h" # include "Peer.h" @@ -214,10 +215,10 @@ ConsoleStatCalc::ConsoleStatCalc(time_t summaryInterval, bool humanReadable): void ConsoleStatCalc::calculateStat(const DownloadEngine* e) { - if(!_cp.elapsed(1)) { + if(_cp.difference(global::wallclock) < 1) { return; } - _cp.reset(); + _cp = global::wallclock; const SizeFormatter& sizeFormatter = *_sizeFormatter.get(); #ifdef __MINGW32__ @@ -243,8 +244,8 @@ ConsoleStatCalc::calculateStat(const DownloadEngine* e) std::ostringstream o; if(e->_requestGroupMan->countRequestGroup() > 0) { if((_summaryInterval > 0) && - _lastSummaryNotified.elapsed(_summaryInterval)) { - _lastSummaryNotified.reset(); + _lastSummaryNotified.difference(global::wallclock) >= _summaryInterval) { + _lastSummaryNotified = global::wallclock; printProgressSummary(e->_requestGroupMan->getRequestGroups(), cols, e, sizeFormatter); std::cout << "\n"; diff --git a/src/DHTBucket.cc b/src/DHTBucket.cc index 02f9ce3f..643f919b 100644 --- a/src/DHTBucket.cc +++ b/src/DHTBucket.cc @@ -46,6 +46,7 @@ #include "a2functional.h" #include "bittorrent_helper.h" #include "bitfield.h" +#include "wallclock.h" namespace aria2 { @@ -246,12 +247,13 @@ bool DHTBucket::operator==(const DHTBucket& bucket) const bool DHTBucket::needsRefresh() const { - return _nodes.size() < K || _lastUpdated.elapsed(DHT_BUCKET_REFRESH_INTERVAL); + return _nodes.size() < K || + _lastUpdated.difference(global::wallclock) >= DHT_BUCKET_REFRESH_INTERVAL; } void DHTBucket::notifyUpdate() { - _lastUpdated.reset(); + _lastUpdated = global::wallclock; } class FindQuestionableNode { diff --git a/src/DHTGetPeersCommand.cc b/src/DHTGetPeersCommand.cc index 34d7d631..8ea2b499 100644 --- a/src/DHTGetPeersCommand.cc +++ b/src/DHTGetPeersCommand.cc @@ -46,6 +46,7 @@ #include "Logger.h" #include "bittorrent_helper.h" #include "DownloadContext.h" +#include "wallclock.h" namespace aria2 { @@ -72,8 +73,9 @@ bool DHTGetPeersCommand::execute() return true; } if(_task.isNull() && - ((_numRetry > 0 && _lastGetPeerTime.elapsed(RETRY_INTERVAL)) || - _lastGetPeerTime.elapsed(GET_PEER_INTERVAL))) { + ((_numRetry > 0 && + _lastGetPeerTime.difference(global::wallclock) >= RETRY_INTERVAL) || + _lastGetPeerTime.difference(global::wallclock) >= GET_PEER_INTERVAL)) { if(logger->debug()) { logger->debug("Issuing PeerLookup for infoHash=%s", bittorrent::getInfoHashString @@ -83,7 +85,7 @@ bool DHTGetPeersCommand::execute() (_requestGroup->getDownloadContext(), _btRuntime, _peerStorage); _taskQueue->addPeriodicTask2(_task); } else if(!_task.isNull() && _task->finished()) { - _lastGetPeerTime.reset(); + _lastGetPeerTime = global::wallclock; if(_numRetry < MAX_RETRIES && _btRuntime->lessThanMinPeers()) { ++_numRetry; } else { diff --git a/src/DHTMessageTrackerEntry.cc b/src/DHTMessageTrackerEntry.cc index 72423f1f..cdbe7f62 100644 --- a/src/DHTMessageTrackerEntry.cc +++ b/src/DHTMessageTrackerEntry.cc @@ -38,6 +38,7 @@ #include "DHTMessageCallback.h" #include "DHTConstants.h" #include "util.h" +#include "wallclock.h" namespace aria2 { @@ -53,7 +54,7 @@ DHTMessageTrackerEntry::DHTMessageTrackerEntry(const SharedHandle& s bool DHTMessageTrackerEntry::isTimeout() const { - return _dispatchedTime.elapsed(_timeout); + return _dispatchedTime.difference(global::wallclock) >= _timeout; } void DHTMessageTrackerEntry::extendTimeout() diff --git a/src/DHTNode.cc b/src/DHTNode.cc index ac20f84e..c0064a39 100644 --- a/src/DHTNode.cc +++ b/src/DHTNode.cc @@ -39,6 +39,7 @@ #include "util.h" #include "a2functional.h" #include "bittorrent_helper.h" +#include "wallclock.h" namespace aria2 { @@ -88,7 +89,8 @@ bool DHTNode::isBad() const bool DHTNode::isQuestionable() const { - return !isBad() && _lastContact.elapsed(DHT_NODE_CONTACT_INTERVAL); + return !isBad() && + _lastContact.difference(global::wallclock) >= DHT_NODE_CONTACT_INTERVAL; } void DHTNode::markGood() @@ -103,7 +105,7 @@ void DHTNode::markBad() void DHTNode::updateLastContact() { - _lastContact.reset(); + _lastContact = global::wallclock; } void DHTNode::timeout() diff --git a/src/DHTPeerAnnounceEntry.cc b/src/DHTPeerAnnounceEntry.cc index e2ed666f..666087de 100644 --- a/src/DHTPeerAnnounceEntry.cc +++ b/src/DHTPeerAnnounceEntry.cc @@ -38,6 +38,7 @@ #include #include "Peer.h" +#include "wallclock.h" namespace aria2 { @@ -73,7 +74,7 @@ public: bool operator()(const PeerAddrEntry& entry) const { - if(entry.getLastUpdated().elapsed(_timeout)) { + if(entry.getLastUpdated().difference(global::wallclock) >= _timeout) { return true; } else { return false; @@ -104,7 +105,7 @@ void DHTPeerAnnounceEntry::getPeers void DHTPeerAnnounceEntry::notifyUpdate() { - _lastUpdated.reset(); + _lastUpdated = global::wallclock; } } // namespace aria2 diff --git a/src/DHTPeerAnnounceStorage.cc b/src/DHTPeerAnnounceStorage.cc index 11a2dca1..d4371f58 100644 --- a/src/DHTPeerAnnounceStorage.cc +++ b/src/DHTPeerAnnounceStorage.cc @@ -47,6 +47,7 @@ #include "Logger.h" #include "util.h" #include "a2functional.h" +#include "wallclock.h" namespace aria2 { @@ -147,7 +148,8 @@ void DHTPeerAnnounceStorage::announcePeer() } for(std::deque >::iterator i = _entries.begin(), eoi = _entries.end(); i != eoi; ++i) { - if((*i)->getLastUpdated().elapsed(DHT_PEER_ANNOUNCE_INTERVAL)) { + if((*i)->getLastUpdated(). + difference(global::wallclock) >= DHT_PEER_ANNOUNCE_INTERVAL) { (*i)->notifyUpdate(); SharedHandle task = _taskFactory->createPeerAnnounceTask((*i)->getInfoHash()); diff --git a/src/DHTSetup.cc b/src/DHTSetup.cc index 8799e69f..6373c37a 100644 --- a/src/DHTSetup.cc +++ b/src/DHTSetup.cc @@ -70,6 +70,7 @@ #include "RecoverableException.h" #include "a2functional.h" #include "DownloadEngine.h" +#include "wallclock.h" namespace aria2 { @@ -185,7 +186,9 @@ void DHTSetup::setup(std::vector& commands, desnodes.begin(), eoi = desnodes.end(); i != eoi; ++i) { routingTable->addNode(*i); } - if(!desnodes.empty() && deserializer.getSerializedTime().elapsed(DHT_BUCKET_REFRESH_INTERVAL)) { + if(!desnodes.empty() && + deserializer.getSerializedTime(). + difference(global::wallclock) >= DHT_BUCKET_REFRESH_INTERVAL) { SharedHandle task (dynamic_pointer_cast(taskFactory->createBucketRefreshTask())); task->setForceRefresh(true); diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc index c8dcaa9c..8c0d7783 100644 --- a/src/DefaultBtAnnounce.cc +++ b/src/DefaultBtAnnounce.cc @@ -52,6 +52,7 @@ #include "Request.h" #include "bencode.h" #include "bittorrent_helper.h" +#include "wallclock.h" namespace aria2 { @@ -77,10 +78,12 @@ DefaultBtAnnounce::~DefaultBtAnnounce() { } bool DefaultBtAnnounce::isDefaultAnnounceReady() { - return (trackers == 0 && - prevAnnounceTime.elapsed(_userDefinedInterval==0? - minInterval:_userDefinedInterval) && - !announceList.allTiersFailed()); + return + (trackers == 0 && + prevAnnounceTime. + difference(global::wallclock) >= (_userDefinedInterval==0? + minInterval:_userDefinedInterval) && + !announceList.allTiersFailed()); } bool DefaultBtAnnounce::isStoppedAnnounceReady() { @@ -203,7 +206,7 @@ bool DefaultBtAnnounce::isAllAnnounceFailed() { } void DefaultBtAnnounce::resetAnnounce() { - prevAnnounceTime.reset(); + prevAnnounceTime = global::wallclock; announceList.resetTier(); } diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc index 268091c5..fd05ee39 100644 --- a/src/DefaultBtInteractive.cc +++ b/src/DefaultBtInteractive.cc @@ -72,6 +72,7 @@ #include "bittorrent_helper.h" #include "UTMetadataRequestFactory.h" #include "UTMetadataRequestTracker.h" +#include "wallclock.h" namespace aria2 { @@ -144,8 +145,8 @@ BtMessageHandle DefaultBtInteractive::receiveAndSendHandshake() { void DefaultBtInteractive::doPostHandshakeProcessing() { // Set time 0 to haveCheckPoint to cache http/ftp download piece completion haveCheckPoint.setTimeInSec(0); - keepAliveCheckPoint.reset(); - floodingCheckPoint.reset(); + keepAliveCheckPoint = global::wallclock; + floodingCheckPoint = global::wallclock; _pexCheckPoint.setTimeInSec(0); if(peer->isExtendedMessagingEnabled()) { addHandshakeExtendedMessageToQueue(); @@ -229,7 +230,7 @@ void DefaultBtInteractive::decideChoking() { void DefaultBtInteractive::checkHave() { std::vector indexes; _pieceStorage->getAdvertisedPieceIndexes(indexes, cuid, haveCheckPoint); - haveCheckPoint.reset(); + haveCheckPoint = global::wallclock; if(indexes.size() >= 20) { if(peer->isFastExtensionEnabled() && _pieceStorage->allDownloadFinished()) { dispatcher->addMessageToQueue(messageFactory->createHaveAllMessage()); @@ -245,10 +246,10 @@ void DefaultBtInteractive::checkHave() { } void DefaultBtInteractive::sendKeepAlive() { - if(keepAliveCheckPoint.elapsed(keepAliveInterval)) { + if(keepAliveCheckPoint.difference(global::wallclock) >= keepAliveInterval) { dispatcher->addMessageToQueue(messageFactory->createKeepAliveMessage()); dispatcher->sendMessages(); - keepAliveCheckPoint.reset(); + keepAliveCheckPoint = global::wallclock; } } @@ -290,7 +291,7 @@ size_t DefaultBtInteractive::receiveMessages() { _peerStorage->updateTransferStatFor(peer); // pass through case BtRequestMessage::ID: - inactiveCheckPoint.reset(); + inactiveCheckPoint = global::wallclock; break; } } @@ -401,25 +402,27 @@ void DefaultBtInteractive::sendPendingMessage() { } void DefaultBtInteractive::detectMessageFlooding() { - if(floodingCheckPoint.elapsed(FLOODING_CHECK_INTERVAL)) { + if(floodingCheckPoint. + difference(global::wallclock) >= FLOODING_CHECK_INTERVAL) { if(floodingStat.getChokeUnchokeCount() >= 2 || floodingStat.getKeepAliveCount() >= 2) { throw DL_ABORT_EX(EX_FLOODING_DETECTED); } else { floodingStat.reset(); } - floodingCheckPoint.reset(); + floodingCheckPoint = global::wallclock; } } void DefaultBtInteractive::checkActiveInteraction() { + time_t inactiveTime = inactiveCheckPoint.difference(global::wallclock); // To allow aria2 to accept mutially interested peer, disconnect unintersted // peer. { const time_t interval = 30; if(!peer->amInterested() && !peer->peerInterested() && - inactiveCheckPoint.elapsed(interval)) { + inactiveTime >= interval) { // TODO change the message throw DL_ABORT_EX (StringFormat("Disconnect peer because we are not interested each other" @@ -431,7 +434,7 @@ void DefaultBtInteractive::checkActiveInteraction() // are disconnected in a certain time period. { const time_t interval = 60; - if(inactiveCheckPoint.elapsed(interval)) { + if(inactiveTime >= interval) { throw DL_ABORT_EX (StringFormat(EX_DROP_INACTIVE_CONNECTION, interval).str()); } @@ -440,7 +443,8 @@ void DefaultBtInteractive::checkActiveInteraction() void DefaultBtInteractive::addPeerExchangeMessage() { - if(_pexCheckPoint.elapsed(UTPexExtensionMessage::DEFAULT_INTERVAL)) { + if(_pexCheckPoint. + difference(global::wallclock) >= UTPexExtensionMessage::DEFAULT_INTERVAL) { UTPexExtensionMessageHandle m (new UTPexExtensionMessage(peer->getExtensionMessageID("ut_pex"))); const std::deque >& peers = _peerStorage->getPeers(); @@ -465,7 +469,7 @@ void DefaultBtInteractive::addPeerExchangeMessage() } BtMessageHandle msg = messageFactory->createBtExtendedMessage(m); dispatcher->addMessageToQueue(msg); - _pexCheckPoint.reset(); + _pexCheckPoint = global::wallclock; } } @@ -486,8 +490,8 @@ void DefaultBtInteractive::doInteractionProcessing() { _utMetadataRequestFactory->create(requests, num, _pieceStorage); dispatcher->addMessageToQueue(requests); } - if(_perSecCheckPoint.elapsed(1)) { - _perSecCheckPoint.reset(); + if(_perSecCheckPoint.difference(global::wallclock) >= 1) { + _perSecCheckPoint = global::wallclock; // Drop timeout request after queuing message to give a chance // to other connection to request piece. std::vector indexes = @@ -509,8 +513,8 @@ void DefaultBtInteractive::doInteractionProcessing() { detectMessageFlooding(); - if(_perSecCheckPoint.elapsed(1)) { - _perSecCheckPoint.reset(); + if(_perSecCheckPoint.difference(global::wallclock) >= 1) { + _perSecCheckPoint = global::wallclock; dispatcher->checkRequestSlotAndDoNecessaryThing(); } checkHave(); diff --git a/src/DefaultBtMessageDispatcher.cc b/src/DefaultBtMessageDispatcher.cc index 7c3cb8ca..f67e39ab 100644 --- a/src/DefaultBtMessageDispatcher.cc +++ b/src/DefaultBtMessageDispatcher.cc @@ -257,7 +257,6 @@ private: SharedHandle _pieceStorage; BtMessageDispatcher* _messageDispatcher; WeakHandle _messageFactory; - const struct timeval& _now; time_t _requestTimeout; Logger* _logger; public: @@ -265,20 +264,18 @@ public: const SharedHandle& pieceStorage, BtMessageDispatcher* dispatcher, const WeakHandle& factory, - const struct timeval& now, time_t requestTimeout): _cuid(cuid), _peer(peer), _pieceStorage(pieceStorage), _messageDispatcher(dispatcher), _messageFactory(factory), - _now(now), _requestTimeout(requestTimeout), _logger(LogFactory::getInstance()) {} void operator()(const RequestSlot& slot) { - if(slot.isTimeout(_now, _requestTimeout)) { + if(slot.isTimeout(_requestTimeout)) { if(_logger->debug()) { _logger->debug(MSG_DELETING_REQUEST_SLOT_TIMEOUT, _cuid, @@ -305,19 +302,16 @@ public: class FindStaleRequestSlot { private: SharedHandle _pieceStorage; - const struct timeval& _now; time_t _requestTimeout; public: FindStaleRequestSlot(const SharedHandle& pieceStorage, - const struct timeval& now, time_t requestTimeout): _pieceStorage(pieceStorage), - _now(now), _requestTimeout(requestTimeout) {} bool operator()(const RequestSlot& slot) { - if(slot.isTimeout(_now, _requestTimeout)) { + if(slot.isTimeout(_requestTimeout)) { return true; } else { if(slot.getPiece()->hasBlock(slot.getBlockIndex())) { @@ -331,20 +325,15 @@ public: void DefaultBtMessageDispatcher::checkRequestSlotAndDoNecessaryThing() { - struct timeval now; - gettimeofday(&now, 0); - std::for_each(requestSlots.begin(), requestSlots.end(), ProcessStaleRequestSlot(cuid, peer, _pieceStorage, this, messageFactory, - now, requestTimeout)); requestSlots.erase(std::remove_if(requestSlots.begin(), requestSlots.end(), FindStaleRequestSlot(_pieceStorage, - now, requestTimeout)), requestSlots.end()); } diff --git a/src/DefaultPeerStorage.cc b/src/DefaultPeerStorage.cc index 2cced586..5f9053b7 100644 --- a/src/DefaultPeerStorage.cc +++ b/src/DefaultPeerStorage.cc @@ -45,6 +45,7 @@ #include "BtSeederStateChoke.h" #include "BtLeecherStateChoke.h" #include "PieceStorage.h" +#include "wallclock.h" namespace aria2 { @@ -200,11 +201,9 @@ void DefaultPeerStorage::getActivePeers static TransferStat calculateStatFor(const SharedHandle& peer) { - struct timeval now; - gettimeofday(&now, 0); TransferStat s; - s.downloadSpeed = peer->calculateDownloadSpeed(now); - s.uploadSpeed = peer->calculateUploadSpeed(now); + s.downloadSpeed = peer->calculateDownloadSpeed(); + s.uploadSpeed = peer->calculateUploadSpeed(); s.sessionDownloadLength = peer->getSessionDownloadLength(); s.sessionUploadLength = peer->getSessionUploadLength(); return s; @@ -213,21 +212,19 @@ static TransferStat calculateStatFor(const SharedHandle& peer) TransferStat DefaultPeerStorage::calculateStat() { TransferStat stat; - if(_lastTransferStatMapUpdated.elapsedInMillis(250)) { + if(_lastTransferStatMapUpdated.differenceInMillis(global::wallclock) >= 250) { if(logger->debug()) { logger->debug("Updating TransferStat of PeerStorage"); } - _lastTransferStatMapUpdated.reset(); + _lastTransferStatMapUpdated = global::wallclock; _peerTransferStatMap.clear(); std::vector > activePeers; getActivePeers(activePeers); - struct timeval now; - gettimeofday(&now, 0); for(std::vector >::const_iterator i = activePeers.begin(), eoi = activePeers.end(); i != eoi; ++i) { TransferStat s; - s.downloadSpeed = (*i)->calculateDownloadSpeed(now); - s.uploadSpeed = (*i)->calculateUploadSpeed(now); + s.downloadSpeed = (*i)->calculateDownloadSpeed(); + s.uploadSpeed = (*i)->calculateUploadSpeed(); s.sessionDownloadLength = (*i)->getSessionDownloadLength(); s.sessionUploadLength = (*i)->getSessionUploadLength(); @@ -319,9 +316,11 @@ bool DefaultPeerStorage::chokeRoundIntervalElapsed() { const time_t CHOKE_ROUND_INTERVAL = 10; if(_pieceStorage->downloadFinished()) { - return _seederStateChoke->getLastRound().elapsed(CHOKE_ROUND_INTERVAL); + return _seederStateChoke->getLastRound(). + difference(global::wallclock) >= CHOKE_ROUND_INTERVAL; } else { - return _leecherStateChoke->getLastRound().elapsed(CHOKE_ROUND_INTERVAL); + return _leecherStateChoke->getLastRound(). + difference(global::wallclock) >= CHOKE_ROUND_INTERVAL; } } diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc index 9be1b0b6..47d1254e 100644 --- a/src/DefaultPieceStorage.cc +++ b/src/DefaultPieceStorage.cc @@ -58,6 +58,7 @@ #include "RarestPieceSelector.h" #include "array_fun.h" #include "PieceStatMan.h" +#include "wallclock.h" namespace aria2 { @@ -566,7 +567,7 @@ public: FindElapsedHave(time_t elapsed):elapsed(elapsed) {} bool operator()(const HaveEntry& have) { - if(have.getRegisteredTime().elapsed(elapsed)) { + if(have.getRegisteredTime().difference(global::wallclock) >= elapsed) { return true; } else { return false; diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index 189eb2e5..224d689e 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -58,6 +58,7 @@ #include "StringFormat.h" #include "Decoder.h" #include "RequestGroupMan.h" +#include "wallclock.h" #ifdef ENABLE_MESSAGE_DIGEST # include "MessageDigestHelper.h" #endif // ENABLE_MESSAGE_DIGEST @@ -253,7 +254,8 @@ bool DownloadCommand::executeInternal() { void DownloadCommand::checkLowestDownloadSpeed() const { // calculate downloading speed - if(peerStat->getDownloadStartTime().elapsed(startupIdleTime)) { + if(peerStat->getDownloadStartTime().difference(global::wallclock) >= + startupIdleTime) { unsigned int nowSpeed = peerStat->calculateDownloadSpeed(); if(lowestDownloadSpeedLimit > 0 && nowSpeed <= lowestDownloadSpeedLimit) { throw DL_ABORT_EX2(StringFormat(EX_TOO_SLOW_DOWNLOAD_SPEED, diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc index c9f042c3..b4760253 100644 --- a/src/DownloadEngine.cc +++ b/src/DownloadEngine.cc @@ -76,6 +76,12 @@ namespace aria2 { +namespace global { + +// Global clock, this clock is reseted before executeCommand() call to +// reduce the call gettimeofday() system call. +Time wallclock; + // 0 ... running // 1 ... stop signal detected // 2 ... stop signal processed by DownloadEngine @@ -83,6 +89,8 @@ namespace aria2 { // 4 ... 2nd stop signal processed by DownloadEngine volatile sig_atomic_t globalHaltRequested = 0; +} // namespace global + DownloadEngine::DownloadEngine(const SharedHandle& eventPoll): _eventPoll(eventPoll), logger(LogFactory::getInstance()), @@ -136,9 +144,10 @@ void DownloadEngine::run() Time cp; cp.setTimeInSec(0); while(!commands.empty() || !_routineCommands.empty()) { - if(cp.elapsed(_refreshInterval)) { + global::wallclock.reset(); + if(cp.difference(global::wallclock) >= _refreshInterval) { _refreshInterval = DEFAULT_REFRESH_INTERVAL; - cp.reset(); + cp = global::wallclock; executeCommand(commands, Command::STATUS_ALL); } else { executeCommand(commands, Command::STATUS_ACTIVE); @@ -211,16 +220,16 @@ void DownloadEngine::onEndOfRun() void DownloadEngine::afterEachIteration() { _requestGroupMan->calculateStat(); - if(globalHaltRequested == 1) { + if(global::globalHaltRequested == 1) { logger->notice(_("Shutdown sequence commencing... Press Ctrl-C again for emergency shutdown.")); requestHalt(); - globalHaltRequested = 2; + global::globalHaltRequested = 2; setNoWait(true); setRefreshInterval(0); - } else if(globalHaltRequested == 3) { + } else if(global::globalHaltRequested == 3) { logger->notice(_("Emergency shutdown sequence commencing...")); _requestGroupMan->forceHalt(); - globalHaltRequested = 4; + global::globalHaltRequested = 4; setNoWait(true); setRefreshInterval(0); } @@ -275,12 +284,12 @@ void DownloadEngine::poolSocket(const std::string& ipaddr, std::multimap::value_type p(addr, entry); _socketPool.insert(p); - if(_lastSocketPoolScan.elapsed(60)) { + if(_lastSocketPoolScan.difference(global::wallclock) >= 60) { std::multimap newPool; if(logger->debug()) { logger->debug("Scaning SocketPool and erasing timed out entry."); } - _lastSocketPoolScan.reset(); + _lastSocketPoolScan = global::wallclock; for(std::multimap::iterator i = _socketPool.begin(), eoi = _socketPool.end(); i != eoi; ++i) { if(!(*i).second.isTimeout()) { @@ -439,7 +448,7 @@ DownloadEngine::SocketPoolEntry::~SocketPoolEntry() {} bool DownloadEngine::SocketPoolEntry::isTimeout() const { - return _registeredTime.elapsed(_timeout); + return _registeredTime.difference(global::wallclock) >= _timeout; } cuid_t DownloadEngine::newCUID() diff --git a/src/FileEntry.cc b/src/FileEntry.cc index 2aadad2c..adc12da4 100644 --- a/src/FileEntry.cc +++ b/src/FileEntry.cc @@ -40,6 +40,7 @@ #include "util.h" #include "URISelector.h" #include "LogFactory.h" +#include "wallclock.h" namespace aria2 { @@ -172,7 +173,8 @@ FileEntry::findFasterRequest(const SharedHandle& base) // TODO hard coded value. See PREF_STARTUP_IDLE_TIME const int startupIdleTime = 10; if(basestat.isNull() || - (basestat->getDownloadStartTime().elapsed(startupIdleTime) && + (basestat->getDownloadStartTime(). + difference(global::wallclock) >= startupIdleTime && fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){ // TODO we should consider that "fastest" is very slow. SharedHandle fastestRequest = _requestPool.front(); diff --git a/src/HttpServerBodyCommand.cc b/src/HttpServerBodyCommand.cc index 25eeab47..8bb7f11b 100644 --- a/src/HttpServerBodyCommand.cc +++ b/src/HttpServerBodyCommand.cc @@ -50,6 +50,7 @@ #include "XmlRpcMethodFactory.h" #include "XmlRpcResponse.h" #include "DownloadContext.h" +#include "wallclock.h" namespace aria2 { @@ -79,7 +80,7 @@ bool HttpServerBodyCommand::execute() } try { if(_socket->isReadable(0) || _httpServer->getContentLength() == 0) { - _timeout.reset(); + _timeout = global::wallclock; if(_httpServer->receiveBody()) { // Do something for requestpath and body @@ -106,7 +107,7 @@ bool HttpServerBodyCommand::execute() return false; } } else { - if(_timeout.elapsed(30)) { + if(_timeout.difference(global::wallclock) >= 30) { logger->info("HTTP request body timeout."); return true; } else { diff --git a/src/HttpServerCommand.cc b/src/HttpServerCommand.cc index 4a6bec49..f005fc61 100644 --- a/src/HttpServerCommand.cc +++ b/src/HttpServerCommand.cc @@ -47,6 +47,7 @@ #include "Option.h" #include "util.h" #include "DownloadContext.h" +#include "wallclock.h" namespace aria2 { @@ -92,7 +93,7 @@ bool HttpServerCommand::execute() } try { if(_socket->isReadable(0)) { - _timeout.reset(); + _timeout = global::wallclock; SharedHandle header; header = _httpServer->receiveRequest(); @@ -127,7 +128,7 @@ bool HttpServerCommand::execute() _e->setNoWait(true); return true; } else { - if(_timeout.elapsed(30)) { + if(_timeout.difference(global::wallclock) >= 30) { logger->info("HTTP request timeout."); return true; } else { diff --git a/src/HttpServerResponseCommand.cc b/src/HttpServerResponseCommand.cc index 5245ccf1..337e7c35 100644 --- a/src/HttpServerResponseCommand.cc +++ b/src/HttpServerResponseCommand.cc @@ -41,6 +41,7 @@ #include "RequestGroupMan.h" #include "RecoverableException.h" #include "FileEntry.h" +#include "wallclock.h" namespace aria2 { @@ -84,7 +85,7 @@ bool HttpServerResponseCommand::execute() } return true; } else { - if(_timeout.elapsed(10)) { + if(_timeout.difference(global::wallclock) >= 10) { logger->info("CUID#%d - HttpServer: Timeout while trasmitting response.", cuid); return true; diff --git a/src/LpdMessageDispatcher.cc b/src/LpdMessageDispatcher.cc index e51516a0..a0d5659e 100644 --- a/src/LpdMessageDispatcher.cc +++ b/src/LpdMessageDispatcher.cc @@ -38,6 +38,7 @@ #include "LogFactory.h" #include "BtConstants.h" #include "RecoverableException.h" +#include "wallclock.h" namespace aria2 { @@ -92,12 +93,12 @@ bool LpdMessageDispatcher::sendMessage() bool LpdMessageDispatcher::isAnnounceReady() const { - return _timer.elapsed(_interval); + return _timer.difference(global::wallclock) >= _interval; } void LpdMessageDispatcher::resetAnnounceTimer() { - _timer.reset(); + _timer = global::wallclock; } namespace bittorrent { diff --git a/src/MultiUrlRequestInfo.cc b/src/MultiUrlRequestInfo.cc index ca73a9c6..b70ebfb1 100644 --- a/src/MultiUrlRequestInfo.cc +++ b/src/MultiUrlRequestInfo.cc @@ -66,13 +66,17 @@ namespace aria2 { # define SA_RESETHAND 0x80000000 #endif // SA_RESETHAND +namespace global { + extern volatile sig_atomic_t globalHaltRequested; +} // namespace global + static void handler(int signal) { - if(globalHaltRequested == 0) { - globalHaltRequested = 1; - } else if(globalHaltRequested == 2) { - globalHaltRequested = 3; + if(global::globalHaltRequested == 0) { + global::globalHaltRequested = 1; + } else if(global::globalHaltRequested == 2) { + global::globalHaltRequested = 3; } } diff --git a/src/Peer.cc b/src/Peer.cc index da12a222..61ab9195 100644 --- a/src/Peer.cc +++ b/src/Peer.cc @@ -41,6 +41,7 @@ #include "a2functional.h" #include "PeerSessionResource.h" #include "BtMessageDispatcher.h" +#include "wallclock.h" namespace aria2 { @@ -215,24 +216,12 @@ unsigned int Peer::calculateUploadSpeed() return _res->getPeerStat().calculateUploadSpeed(); } -unsigned int Peer::calculateUploadSpeed(const struct timeval& now) -{ - assert(_res); - return _res->getPeerStat().calculateUploadSpeed(now); -} - unsigned int Peer::calculateDownloadSpeed() { assert(_res); return _res->getPeerStat().calculateDownloadSpeed(); } -unsigned int Peer::calculateDownloadSpeed(const struct timeval& now) -{ - assert(_res); - return _res->getPeerStat().calculateDownloadSpeed(now); -} - uint64_t Peer::getSessionUploadLength() const { assert(_res); @@ -330,12 +319,13 @@ void Peer::setAllBitfield() { void Peer::startBadCondition() { - _badConditionStartTime.reset(); + _badConditionStartTime = global::wallclock; } bool Peer::isGood() const { - return _badConditionStartTime.elapsed(BAD_CONDITION_INTERVAL); + return _badConditionStartTime. + difference(global::wallclock) >= BAD_CONDITION_INTERVAL; } uint8_t Peer::getExtensionMessageID(const std::string& name) const diff --git a/src/Peer.h b/src/Peer.h index bb2c54f8..23dc7957 100644 --- a/src/Peer.h +++ b/src/Peer.h @@ -205,15 +205,11 @@ public: */ unsigned int calculateUploadSpeed(); - unsigned int calculateUploadSpeed(const struct timeval& now); - /** * Returns the transfer rate from remote host to localhost. */ unsigned int calculateDownloadSpeed(); - unsigned int calculateDownloadSpeed(const struct timeval& now); - /** * Returns the number of bytes uploaded to the remote host. */ diff --git a/src/PeerAbstractCommand.cc b/src/PeerAbstractCommand.cc index f26cec59..0d3c8413 100644 --- a/src/PeerAbstractCommand.cc +++ b/src/PeerAbstractCommand.cc @@ -43,6 +43,7 @@ #include "prefs.h" #include "DownloadFailureException.h" #include "StringFormat.h" +#include "wallclock.h" namespace aria2 { @@ -88,13 +89,13 @@ bool PeerAbstractCommand::execute() (checkSocketIsReadable && _readEvent) || (checkSocketIsWritable && _writeEvent) || _hupEvent) { - checkPoint.reset(); + checkPoint = global::wallclock; } else if(_errorEvent) { throw DL_ABORT_EX (StringFormat(MSG_NETWORK_PROBLEM, socket->getSocketError().c_str()).str()); } - if(checkPoint.elapsed(timeout)) { + if(checkPoint.difference(global::wallclock) >= timeout) { throw DL_ABORT_EX(EX_TIME_OUT); } return executeInternal(); @@ -183,7 +184,7 @@ void PeerAbstractCommand::setNoCheck(bool check) void PeerAbstractCommand::updateKeepAlive() { - checkPoint.reset(); + checkPoint = global::wallclock; } } // namespace aria2 diff --git a/src/PeerStat.h b/src/PeerStat.h index 71e89925..11d2119d 100644 --- a/src/PeerStat.h +++ b/src/PeerStat.h @@ -82,8 +82,6 @@ public: _sessionDownloadLength(0), _sessionUploadLength(0) {} - ~PeerStat() {} - /** * Returns current download speed in byte per sec. */ @@ -91,10 +89,6 @@ public: return downloadSpeed.calculateSpeed(); } - unsigned int calculateDownloadSpeed(const struct timeval& now) { - return downloadSpeed.calculateSpeed(now); - } - unsigned int calculateAvgDownloadSpeed() { _avgDownloadSpeed = downloadSpeed.calculateAvgSpeed(); return _avgDownloadSpeed; @@ -104,10 +98,6 @@ public: return uploadSpeed.calculateSpeed(); } - unsigned int calculateUploadSpeed(const struct timeval& now) { - return uploadSpeed.calculateSpeed(now); - } - unsigned int calculateAvgUploadSpeed() { _avgUploadSpeed = uploadSpeed.calculateAvgSpeed(); return _avgUploadSpeed; diff --git a/src/RequestSlot.cc b/src/RequestSlot.cc index 44ca28ad..1f7fc1a2 100644 --- a/src/RequestSlot.cc +++ b/src/RequestSlot.cc @@ -33,6 +33,7 @@ */ /* copyright --> */ #include "RequestSlot.h" +#include "wallclock.h" namespace aria2 { @@ -46,12 +47,8 @@ void RequestSlot::setDispatchedTime(time_t secFromEpoch) { dispatchedTime.setTimeInSec(secFromEpoch); } -bool RequestSlot::isTimeout(const struct timeval& now, time_t timeoutSec) const { - return dispatchedTime.difference(now) >= timeoutSec; -} - -unsigned int RequestSlot::getLatencyInMillis() const { - return dispatchedTime.differenceInMillis(); +bool RequestSlot::isTimeout(time_t timeoutSec) const { + return dispatchedTime.difference(global::wallclock) >= timeoutSec; } bool RequestSlot::isNull(const RequestSlot& requestSlot) { diff --git a/src/RequestSlot.h b/src/RequestSlot.h index ddeb745e..7adc3202 100644 --- a/src/RequestSlot.h +++ b/src/RequestSlot.h @@ -113,8 +113,7 @@ public: void setDispatchedTime(); void setDispatchedTime(time_t secFromEpoch); - bool isTimeout(const struct timeval& now, time_t timeoutSec) const; - unsigned int getLatencyInMillis() const; + bool isTimeout(time_t timeoutSec) const; size_t getIndex() const { return index; } void setIndex(size_t index) { this->index = index; } diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc index b8ced1f1..47e47676 100644 --- a/src/SegmentMan.cc +++ b/src/SegmentMan.cc @@ -51,6 +51,7 @@ #include "DownloadContext.h" #include "Piece.h" #include "FileEntry.h" +#include "wallclock.h" namespace aria2 { @@ -336,8 +337,8 @@ void SegmentMan::updateFastestPeerStat(const SharedHandle& peerStat) unsigned int SegmentMan::calculateDownloadSpeed() { unsigned int speed = 0; - if(_lastPeerStatDlspdMapUpdated.elapsedInMillis(250)) { - _lastPeerStatDlspdMapUpdated.reset(); + if(_lastPeerStatDlspdMapUpdated.differenceInMillis(global::wallclock) >= 250){ + _lastPeerStatDlspdMapUpdated = global::wallclock; _peerStatDlspdMap.clear(); for(std::vector >::const_iterator i = peerStats.begin(), eoi = peerStats.end(); i != eoi; ++i) { diff --git a/src/ServerStatMan.cc b/src/ServerStatMan.cc index 8e90f323..23af57d5 100644 --- a/src/ServerStatMan.cc +++ b/src/ServerStatMan.cc @@ -43,6 +43,7 @@ #include "ServerStat.h" #include "util.h" #include "RecoverableException.h" +#include "wallclock.h" namespace aria2 { @@ -148,7 +149,7 @@ public: bool operator()(const SharedHandle& ss) const { - return ss->getLastUpdated().elapsed(_timeout); + return ss->getLastUpdated().difference(global::wallclock) >= _timeout; } }; diff --git a/src/SleepCommand.cc b/src/SleepCommand.cc index 9dde2176..1c22385d 100644 --- a/src/SleepCommand.cc +++ b/src/SleepCommand.cc @@ -36,6 +36,7 @@ #include "RequestGroup.h" #include "DownloadEngine.h" #include "DownloadContext.h" +#include "wallclock.h" namespace aria2 { @@ -54,7 +55,7 @@ SleepCommand::~SleepCommand() { bool SleepCommand::execute() { if(_requestGroup->downloadFinished() || _requestGroup->isHaltRequested()) { return true; - } else if(checkPoint.elapsed(wait)) { + } else if(checkPoint.difference(global::wallclock) >= wait) { engine->commands.push_back(nextCommand); nextCommand = 0; return true; diff --git a/src/SpeedCalc.cc b/src/SpeedCalc.cc index 6226bac2..59c4fe66 100644 --- a/src/SpeedCalc.cc +++ b/src/SpeedCalc.cc @@ -33,23 +33,25 @@ */ /* copyright --> */ #include "SpeedCalc.h" + #include #include +#include "wallclock.h" + namespace aria2 { #define CHANGE_INTERVAL_SEC 15 -class Reset { -public: - void operator()(Time& tm) { - tm.reset(); - } -}; +SpeedCalc::SpeedCalc():sw(0), maxSpeed(0), prevSpeed(0), accumulatedLength(0), + nextInterval(CHANGE_INTERVAL_SEC) +{ + std::fill(&lengthArray[0], &lengthArray[2], 0); +} void SpeedCalc::reset() { std::fill(&lengthArray[0], &lengthArray[2], 0); - std::for_each(&cpArray[0], &cpArray[2], Reset()); + std::for_each(&cpArray[0], &cpArray[2], std::mem_fun_ref(&Time::reset)); sw = 0; maxSpeed = 0; prevSpeed = 0; @@ -59,22 +61,7 @@ void SpeedCalc::reset() { } unsigned int SpeedCalc::calculateSpeed() { - int64_t milliElapsed = cpArray[sw].differenceInMillis(); - if(milliElapsed) { - unsigned int speed = lengthArray[sw]*1000/milliElapsed; - prevSpeed = speed; - maxSpeed = std::max(speed, maxSpeed); - if(isIntervalOver(milliElapsed)) { - changeSw(); - } - return speed; - } else { - return prevSpeed; - } -} - -unsigned int SpeedCalc::calculateSpeed(const struct timeval& now) { - int64_t milliElapsed = cpArray[sw].differenceInMillis(now); + int64_t milliElapsed = cpArray[sw].differenceInMillis(global::wallclock); if(milliElapsed) { unsigned int speed = lengthArray[sw]*1000/milliElapsed; prevSpeed = speed; @@ -98,7 +85,7 @@ void SpeedCalc::update(size_t bytes) { } bool SpeedCalc::isIntervalOver() const { - return nextInterval <= cpArray[sw].difference(); + return nextInterval <= cpArray[sw].difference(global::wallclock); } bool SpeedCalc::isIntervalOver(int64_t milliElapsed) const @@ -110,11 +97,11 @@ void SpeedCalc::changeSw() { lengthArray[sw] = 0; cpArray[sw].reset(); sw ^= 0x01; - nextInterval = cpArray[sw].difference()+CHANGE_INTERVAL_SEC; + nextInterval = cpArray[sw].difference(global::wallclock)+CHANGE_INTERVAL_SEC; } unsigned int SpeedCalc::calculateAvgSpeed() const { - uint64_t milliElapsed = start.differenceInMillis(); + uint64_t milliElapsed = start.differenceInMillis(global::wallclock); // if milliElapsed is too small, the average speed is rubish, better return 0 if(milliElapsed > 4) { diff --git a/src/SpeedCalc.h b/src/SpeedCalc.h index 47439941..40a18e2c 100644 --- a/src/SpeedCalc.h +++ b/src/SpeedCalc.h @@ -57,19 +57,13 @@ private: void changeSw(); public: - SpeedCalc() { - reset(); - } - - ~SpeedCalc() {} + SpeedCalc(); /** * Returns download/upload speed in byte per sec */ unsigned int calculateSpeed(); - unsigned int calculateSpeed(const struct timeval& now); - unsigned int getMaxSpeed() const { return maxSpeed; } diff --git a/src/TimeA2.cc b/src/TimeA2.cc index 5df6f118..8ddd9416 100644 --- a/src/TimeA2.cc +++ b/src/TimeA2.cc @@ -113,13 +113,14 @@ bool Time::isNewer(const Time& time) const { return util::difftv(this->tv, time.tv) > 0; } -time_t Time::difference() const { - return util::difftvsec(getCurrentTime(), tv); +time_t Time::difference() const +{ + return util::difftv(getCurrentTime(), tv)/1000000; } time_t Time::difference(const struct timeval& now) const { - return util::difftvsec(now, tv); + return util::difftv(now, tv)/1000000; } int64_t Time::differenceInMillis() const { @@ -156,6 +157,11 @@ void Time::setTimeInSec(time_t sec) { tv.tv_usec = 0; } +void Time::advance(time_t sec) +{ + tv.tv_sec += sec; +} + bool Time::good() const { return _good; diff --git a/src/TimeA2.h b/src/TimeA2.h index 0794fa4b..ce9378b6 100644 --- a/src/TimeA2.h +++ b/src/TimeA2.h @@ -77,10 +77,20 @@ public: time_t difference(const struct timeval& now) const; + time_t difference(const Time& now) const + { + return difference(now.tv); + } + int64_t differenceInMillis() const; int64_t differenceInMillis(const struct timeval& now) const; + int64_t differenceInMillis(const Time& now) const + { + return differenceInMillis(now.tv); + } + // Returns true if this object's time value is zero. bool isZero() const; @@ -95,6 +105,8 @@ public: bool isNewer(const Time& time) const; + void advance(time_t sec); + bool good() const; // Returns !good() diff --git a/src/TimeBasedCommand.cc b/src/TimeBasedCommand.cc index 2d438b27..23ee5248 100644 --- a/src/TimeBasedCommand.cc +++ b/src/TimeBasedCommand.cc @@ -34,6 +34,7 @@ /* copyright --> */ #include "TimeBasedCommand.h" #include "DownloadEngine.h" +#include "wallclock.h" namespace aria2 { @@ -51,8 +52,8 @@ bool TimeBasedCommand::execute() if(_exit) { return true; } - if(_checkPoint.elapsed(_interval)) { - _checkPoint.reset(); + if(_checkPoint.difference(global::wallclock) >= _interval) { + _checkPoint = global::wallclock; process(); if(_exit) { return true; diff --git a/src/TimeSeedCriteria.h b/src/TimeSeedCriteria.h index 19549c28..1c74649e 100644 --- a/src/TimeSeedCriteria.h +++ b/src/TimeSeedCriteria.h @@ -37,6 +37,7 @@ #include "SeedCriteria.h" #include "TimeA2.h" +#include "wallclock.h" namespace aria2 { @@ -50,11 +51,11 @@ public: virtual ~TimeSeedCriteria() {} virtual void reset() { - watch.reset(); + watch = global::wallclock; } virtual bool evaluate() { - return watch.elapsed(duration); + return watch.difference(global::wallclock) >= duration; } void setDuration(time_t duration) { diff --git a/src/UTMetadataRequestTracker.h b/src/UTMetadataRequestTracker.h index ffee2b50..3b197d63 100644 --- a/src/UTMetadataRequestTracker.h +++ b/src/UTMetadataRequestTracker.h @@ -40,6 +40,7 @@ #include #include "TimeA2.h" +#include "wallclock.h" namespace aria2 { @@ -55,7 +56,7 @@ private: bool elapsed(time_t t) const { - return _dispatchedTime.elapsed(t); + return _dispatchedTime.difference(global::wallclock) >= t; } bool operator==(const RequestEntry& e) const diff --git a/src/UTPexExtensionMessage.cc b/src/UTPexExtensionMessage.cc index e2ba37e6..77baf8fa 100644 --- a/src/UTPexExtensionMessage.cc +++ b/src/UTPexExtensionMessage.cc @@ -43,6 +43,7 @@ #include "StringFormat.h" #include "bencode.h" #include "a2functional.h" +#include "wallclock.h" namespace aria2 { @@ -101,7 +102,7 @@ void UTPexExtensionMessage::doReceivedAction() bool UTPexExtensionMessage::addFreshPeer(const SharedHandle& peer) { if(!peer->isIncomingPeer() && - !peer->getFirstContactTime().elapsed(_interval)) { + peer->getFirstContactTime().difference(global::wallclock) < _interval) { _freshPeers.push_back(peer); return true; } else { @@ -117,7 +118,8 @@ bool UTPexExtensionMessage::freshPeersAreFull() const bool UTPexExtensionMessage::addDroppedPeer(const SharedHandle& peer) { if(!peer->isIncomingPeer() && - !peer->getBadConditionStartTime().elapsed(_interval)) { + peer->getBadConditionStartTime(). + difference(global::wallclock) < _interval) { _droppedPeers.push_back(peer); return true; } else { diff --git a/src/wallclock.h b/src/wallclock.h new file mode 100644 index 00000000..5eab97ee --- /dev/null +++ b/src/wallclock.h @@ -0,0 +1,46 @@ +/* */ +#include "TimeA2.h" + +namespace aria2 { + +namespace global { + +// wallclock is defined in DownloadEngine.cc +extern Time wallclock; + +} // namespace global + +} // namespace aria2 diff --git a/test/TimeSeedCriteriaTest.cc b/test/TimeSeedCriteriaTest.cc index 216dce71..38d06971 100644 --- a/test/TimeSeedCriteriaTest.cc +++ b/test/TimeSeedCriteriaTest.cc @@ -3,6 +3,7 @@ #include #include "util.h" +#include "wallclock.h" namespace aria2 { @@ -21,8 +22,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeedCriteriaTest); void TimeSeedCriteriaTest::testEvaluate() { TimeSeedCriteria cri(1); - // Seel 2seconds. 1 seconds are not enough in some systems. - util::sleep(2); + global::wallclock.reset(); + global::wallclock.advance(2); CPPUNIT_ASSERT(cri.evaluate()); cri.reset(); cri.setDuration(10); diff --git a/test/UTPexExtensionMessageTest.cc b/test/UTPexExtensionMessageTest.cc index 1af6b3b6..f7fe075b 100644 --- a/test/UTPexExtensionMessageTest.cc +++ b/test/UTPexExtensionMessageTest.cc @@ -11,6 +11,7 @@ #include "MockPeerStorage.h" #include "Exception.h" #include "FileEntry.h" +#include "wallclock.h" namespace aria2 { @@ -34,6 +35,7 @@ public: void setUp() { _peerStorage.reset(new MockPeerStorage()); + global::wallclock.reset(); } void testGetExtensionMessageID(); @@ -69,15 +71,15 @@ void UTPexExtensionMessageTest::testGetBencodedData() SharedHandle p1(new Peer("192.168.0.1", 6881)); p1->allocateSessionResource(256*1024, 1024*1024); p1->setAllBitfield(); - msg.addFreshPeer(p1);// added seeder, check add.f flag + CPPUNIT_ASSERT(msg.addFreshPeer(p1));// added seeder, check add.f flag SharedHandle p2(new Peer("10.1.1.2", 9999)); - msg.addFreshPeer(p2); + CPPUNIT_ASSERT(msg.addFreshPeer(p2)); SharedHandle p3(new Peer("192.168.0.2", 6882)); p3->startBadCondition(); - msg.addDroppedPeer(p3); + CPPUNIT_ASSERT(msg.addDroppedPeer(p3)); SharedHandle p4(new Peer("10.1.1.3", 10000)); p4->startBadCondition(); - msg.addDroppedPeer(p4); + CPPUNIT_ASSERT(msg.addDroppedPeer(p4)); unsigned char c1[6]; unsigned char c2[6];