From e8e3a6f259ab74c486aec9b5ea95d3e1f5068f6c Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Wed, 10 Aug 2011 01:17:28 +0900
Subject: [PATCH] wallclock is now retrieved using global::wallclock() call.

This is necessary to avoid global variable initialization order
problem.
---
 src/AbstractCommand.cc             | 14 ++++-----
 src/ActivePeerConnectionCommand.cc |  4 +--
 src/BtLeecherStateChoke.cc         |  4 +--
 src/BtSeederStateChoke.cc          |  4 +--
 src/BtStopDownloadCommand.cc       |  4 +--
 src/ConsoleStatCalc.cc             |  8 ++---
 src/CreateRequestCommand.cc        |  2 +-
 src/DHTBucket.cc                   |  8 ++---
 src/DHTGetPeersCommand.cc          |  4 +--
 src/DHTMessageTrackerEntry.cc      |  6 ++--
 src/DHTMessageTrackerEntry.h       |  1 -
 src/DHTNode.cc                     |  4 +--
 src/DHTPeerAnnounceEntry.cc        |  4 +--
 src/DHTPeerAnnounceStorage.cc      |  2 +-
 src/DefaultBtAnnounce.cc           |  4 +--
 src/DefaultBtInteractive.cc        | 42 ++++++++++++-------------
 src/DefaultPeerStorage.cc          |  8 ++---
 src/DefaultPieceStorage.cc         |  4 +--
 src/DownloadCommand.cc             |  2 +-
 src/DownloadContext.cc             |  4 +--
 src/DownloadEngine.cc              | 17 +++++------
 src/FileAllocationCommand.cc       |  2 +-
 src/FileEntry.cc                   | 14 ++++-----
 src/FtpFinishDownloadCommand.cc    |  4 +--
 src/HttpServerBodyCommand.cc       |  4 +--
 src/HttpServerCommand.cc           |  4 +--
 src/HttpServerResponseCommand.cc   |  2 +-
 src/LpdMessageDispatcher.cc        |  4 +--
 src/Makefile.am                    |  2 +-
 src/Peer.cc                        |  6 ++--
 src/PeerAbstractCommand.cc         |  8 ++---
 src/PeerAddrEntry.cc               |  2 +-
 src/PeerSessionResource.cc         |  4 +--
 src/PeerStat.cc                    |  4 +--
 src/Request.cc                     |  2 +-
 src/RequestSlot.cc                 |  3 +-
 src/RequestSlot.h                  |  2 +-
 src/SegmentMan.cc                  |  4 +--
 src/SleepCommand.cc                |  4 +--
 src/SpeedCalc.cc                   | 14 ++++-----
 src/TimeBasedCommand.cc            |  6 ++--
 src/TimeSeedCriteria.cc            |  4 +--
 src/UTMetadataRequestTracker.h     |  2 +-
 src/UTPexExtensionMessage.cc       |  4 +--
 src/wallclock.cc                   | 49 ++++++++++++++++++++++++++++++
 src/wallclock.h                    |  7 +++--
 test/TimeSeedCriteriaTest.cc       |  4 +--
 test/UTPexExtensionMessageTest.cc  |  2 +-
 48 files changed, 181 insertions(+), 136 deletions(-)
 create mode 100644 src/wallclock.cc

diff --git a/src/AbstractCommand.cc b/src/AbstractCommand.cc
index 16f5f004..0b181060 100644
--- a/src/AbstractCommand.cc
+++ b/src/AbstractCommand.cc
@@ -85,7 +85,7 @@ AbstractCommand::AbstractCommand
  const SocketHandle& s,
  const SharedHandle<SocketRecvBuffer>& socketRecvBuffer,
  bool incNumConnection)
-  : Command(cuid), checkPoint_(global::wallclock),
+  : Command(cuid), checkPoint_(global::wallclock()),
     timeout_(requestGroup->getTimeout()),
     requestGroup_(requestGroup),
     req_(req), fileEntry_(fileEntry), e_(e), socket_(s),
@@ -93,7 +93,7 @@ AbstractCommand::AbstractCommand
     checkSocketIsReadable_(false), checkSocketIsWritable_(false),
     nameResolverCheck_(false),
     incNumConnection_(incNumConnection),
-    serverStatTimer_(global::wallclock)
+    serverStatTimer_(global::wallclock())
 {
   if(socket_ && socket_->isOpen()) {
     setReadCheckSocket(socket_);
@@ -184,8 +184,8 @@ bool AbstractCommand::execute() {
       if(req_ && fileEntry_->getLength() > 0 &&
          e_->getRequestGroupMan()->getMaxOverallDownloadSpeedLimit() == 0 &&
          requestGroup_->getMaxDownloadSpeedLimit() == 0 &&
-         serverStatTimer_.difference(global::wallclock) >= 10) {
-        serverStatTimer_ = global::wallclock;
+         serverStatTimer_.difference(global::wallclock()) >= 10) {
+        serverStatTimer_ = global::wallclock();
         std::vector<std::pair<size_t, std::string> > usedHosts;
         if(getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) {
           getDownloadEngine()->getRequestGroupMan()->getUsedHosts(usedHosts);
@@ -209,7 +209,7 @@ bool AbstractCommand::execute() {
 #endif // ENABLE_ASYNC_DNS
        (!checkSocketIsReadable_ && !checkSocketIsWritable_ &&
         !nameResolverCheck_)) {
-      checkPoint_ = global::wallclock;
+      checkPoint_ = global::wallclock();
       if(getPieceStorage()) {
         if(!req_ || req_->getMaxPipelinedRequest() == 1 ||
            // Why the following condition is necessary? That's because
@@ -263,7 +263,7 @@ bool AbstractCommand::execute() {
       throw DL_RETRY_EX(fmt(MSG_NETWORK_PROBLEM,
                             socket_->getSocketError().c_str()));
     } else {
-      if(checkPoint_.difference(global::wallclock) >= timeout_) {
+      if(checkPoint_.difference(global::wallclock()) >= timeout_) {
         // timeout triggers ServerStat error state.
         SharedHandle<ServerStat> ss =
           e_->getRequestGroupMan()->getOrCreateServerStat(req_->getHost(),
@@ -339,7 +339,7 @@ bool AbstractCommand::execute() {
       tryReserved();
       return true;
     } else {
-      Timer wakeTime(global::wallclock);
+      Timer wakeTime(global::wallclock());
       wakeTime.advance(getOption()->getAsInt(PREF_RETRY_WAIT));
       req_->setWakeTime(wakeTime);
       return prepareForRetry(0);
diff --git a/src/ActivePeerConnectionCommand.cc b/src/ActivePeerConnectionCommand.cc
index c07c7354..d2b54c81 100644
--- a/src/ActivePeerConnectionCommand.cc
+++ b/src/ActivePeerConnectionCommand.cc
@@ -79,8 +79,8 @@ bool ActivePeerConnectionCommand::execute() {
   if(btRuntime_->isHalt()) {
     return true;
   }
-  if(checkPoint_.difference(global::wallclock) >= interval_) {
-    checkPoint_ = global::wallclock;
+  if(checkPoint_.difference(global::wallclock()) >= interval_) {
+    checkPoint_ = global::wallclock();
     TransferStat tstat = requestGroup_->calculateStat();
     const unsigned int maxDownloadLimit =
       requestGroup_->getMaxDownloadSpeedLimit();
diff --git a/src/BtLeecherStateChoke.cc b/src/BtLeecherStateChoke.cc
index 125657fe..41a2ab45 100644
--- a/src/BtLeecherStateChoke.cc
+++ b/src/BtLeecherStateChoke.cc
@@ -57,7 +57,7 @@ BtLeecherStateChoke::PeerEntry::PeerEntry(const SharedHandle<Peer>& peer):
   // peer must be interested to us and sent block in the last 30 seconds
   regularUnchoker_
   (peer->peerInterested() &&
-   peer->getLastDownloadUpdate().difference(global::wallclock) < 30) {}
+   peer->getLastDownloadUpdate().difference(global::wallclock()) < 30) {}
 
 BtLeecherStateChoke::PeerEntry::PeerEntry(const PeerEntry& c)
   : peer_(c.peer_),
@@ -208,7 +208,7 @@ BtLeecherStateChoke::executeChoke
 (const std::vector<SharedHandle<Peer> >& peerSet)
 {
   A2_LOG_INFO(fmt("Leecher state, %d choke round started", round_));
-  lastRound_ = global::wallclock;
+  lastRound_ = global::wallclock();
 
   std::vector<PeerEntry> peerEntries;
   std::transform(peerSet.begin(), peerSet.end(),
diff --git a/src/BtSeederStateChoke.cc b/src/BtSeederStateChoke.cc
index c0c8284a..724ac17a 100644
--- a/src/BtSeederStateChoke.cc
+++ b/src/BtSeederStateChoke.cc
@@ -57,7 +57,7 @@ BtSeederStateChoke::PeerEntry::PeerEntry
   peer_(peer),
   outstandingUpload_(peer->countOutstandingUpload()),
   lastAmUnchoking_(peer->getLastAmUnchoking()),
-  recentUnchoking_(lastAmUnchoking_.difference(global::wallclock) < TIME_FRAME),
+  recentUnchoking_(lastAmUnchoking_.difference(global::wallclock()) < TIME_FRAME),
   uploadSpeed_(peer->calculateUploadSpeed())
 {}
 
@@ -166,7 +166,7 @@ BtSeederStateChoke::executeChoke
 (const std::vector<SharedHandle<Peer> >& peerSet)
 {
   A2_LOG_INFO(fmt("Seeder state, %d choke round started", round_));
-  lastRound_ = global::wallclock;
+  lastRound_ = global::wallclock();
 
   std::vector<PeerEntry> peerEntries;
 
diff --git a/src/BtStopDownloadCommand.cc b/src/BtStopDownloadCommand.cc
index d488ce1e..c0cb922a 100644
--- a/src/BtStopDownloadCommand.cc
+++ b/src/BtStopDownloadCommand.cc
@@ -60,7 +60,7 @@ void BtStopDownloadCommand::preProcess()
   if(btRuntime_->isHalt() || pieceStorage_->downloadFinished()) {
     enableExit();
   }
-  if(checkPoint_.difference(global::wallclock) >= timeout_) {
+  if(checkPoint_.difference(global::wallclock()) >= timeout_) {
     A2_LOG_NOTICE(fmt("GID#%s Stop downloading torrent due to"
                       " --bt-stop-timeout option.",
                       util::itos(requestGroup_->getGID()).c_str()));
@@ -73,7 +73,7 @@ void BtStopDownloadCommand::preProcess()
 void BtStopDownloadCommand::process()
 {
   if(requestGroup_->calculateStat().getDownloadSpeed() > 0) {
-    checkPoint_ = global::wallclock;
+    checkPoint_ = global::wallclock();
   }
 }
 
diff --git a/src/ConsoleStatCalc.cc b/src/ConsoleStatCalc.cc
index 5710b184..49def6bf 100644
--- a/src/ConsoleStatCalc.cc
+++ b/src/ConsoleStatCalc.cc
@@ -248,10 +248,10 @@ ConsoleStatCalc::ConsoleStatCalc(time_t summaryInterval, bool humanReadable):
 void
 ConsoleStatCalc::calculateStat(const DownloadEngine* e)
 {
-  if(cp_.differenceInMillis(global::wallclock)+A2_DELTA_MILLIS < 1000) {
+  if(cp_.differenceInMillis(global::wallclock())+A2_DELTA_MILLIS < 1000) {
     return;
   }
-  cp_ = global::wallclock;
+  cp_ = global::wallclock();
   const SizeFormatter& sizeFormatter = *sizeFormatter_.get();
 
 #ifdef __MINGW32__
@@ -278,9 +278,9 @@ ConsoleStatCalc::calculateStat(const DownloadEngine* e)
   std::ostringstream o;
   if(e->getRequestGroupMan()->countRequestGroup() > 0) {
     if((summaryInterval_ > 0) &&
-       lastSummaryNotified_.differenceInMillis(global::wallclock)+
+       lastSummaryNotified_.differenceInMillis(global::wallclock())+
        A2_DELTA_MILLIS >= summaryInterval_*1000) {
-      lastSummaryNotified_ = global::wallclock;
+      lastSummaryNotified_ = global::wallclock();
       printProgressSummary(e->getRequestGroupMan()->getRequestGroups(), cols, e,
                            sizeFormatter);
       global::cout->write("\n");
diff --git a/src/CreateRequestCommand.cc b/src/CreateRequestCommand.cc
index 9fe997e6..21edc397 100644
--- a/src/CreateRequestCommand.cc
+++ b/src/CreateRequestCommand.cc
@@ -98,7 +98,7 @@ bool CreateRequestCommand::executeInternal()
     // so use it here.
     throw DL_ABORT_EX2("No URI available.",
                        getRequestGroup()->getLastErrorCode());
-  } else if(getRequest()->getWakeTime() > global::wallclock) {
+  } else if(getRequest()->getWakeTime() > global::wallclock()) {
     A2_LOG_DEBUG("This request object is still sleeping.");
     getFileEntry()->poolRequest(getRequest());
     getDownloadEngine()->addCommand(this);
diff --git a/src/DHTBucket.cc b/src/DHTBucket.cc
index 04d2bb30..75330be4 100644
--- a/src/DHTBucket.cc
+++ b/src/DHTBucket.cc
@@ -57,7 +57,7 @@ DHTBucket::DHTBucket
  const SharedHandle<DHTNode>& localNode)
   : prefixLength_(prefixLength),
     localNode_(localNode),
-    lastUpdated_(global::wallclock)
+    lastUpdated_(global::wallclock())
 {
   memcpy(max_, max, DHT_ID_LENGTH);
   memcpy(min_, min, DHT_ID_LENGTH);
@@ -66,7 +66,7 @@ DHTBucket::DHTBucket
 DHTBucket::DHTBucket(const SharedHandle<DHTNode>& localNode)
   : prefixLength_(0),
     localNode_(localNode),
-    lastUpdated_(global::wallclock)
+    lastUpdated_(global::wallclock())
 {
   memset(max_, 0xffu, DHT_ID_LENGTH);
   memset(min_, 0, DHT_ID_LENGTH);
@@ -249,12 +249,12 @@ bool DHTBucket::operator==(const DHTBucket& bucket) const
 bool DHTBucket::needsRefresh() const
 {
   return nodes_.size() < K ||
-    lastUpdated_.difference(global::wallclock) >= DHT_BUCKET_REFRESH_INTERVAL;
+    lastUpdated_.difference(global::wallclock()) >= DHT_BUCKET_REFRESH_INTERVAL;
 }
 
 void DHTBucket::notifyUpdate()
 {
-  lastUpdated_ = global::wallclock;
+  lastUpdated_ = global::wallclock();
 }
 
 namespace {
diff --git a/src/DHTGetPeersCommand.cc b/src/DHTGetPeersCommand.cc
index 25eab93f..d19a00c5 100644
--- a/src/DHTGetPeersCommand.cc
+++ b/src/DHTGetPeersCommand.cc
@@ -90,7 +90,7 @@ bool DHTGetPeersCommand::execute()
   if(btRuntime_->isHalt()) {
     return true;
   }
-  time_t elapsed = lastGetPeerTime_.difference(global::wallclock);
+  time_t elapsed = lastGetPeerTime_.difference(global::wallclock());
   if(!task_ &&
      (elapsed >= GET_PEER_INTERVAL ||
       (((btRuntime_->lessThanMinPeers() &&
@@ -109,7 +109,7 @@ bool DHTGetPeersCommand::execute()
     taskQueue_->addPeriodicTask2(task_);
   } else if(task_ && task_->finished()) {
     A2_LOG_DEBUG("task finished detected");
-    lastGetPeerTime_ = global::wallclock;
+    lastGetPeerTime_ = global::wallclock();
     if(numRetry_ < MAX_RETRIES &&
        (btRuntime_->getMaxPeers() == 0 ||
         btRuntime_->getMaxPeers() > peerStorage_->countPeer())) {
diff --git a/src/DHTMessageTrackerEntry.cc b/src/DHTMessageTrackerEntry.cc
index 86b1153b..59ad4322 100644
--- a/src/DHTMessageTrackerEntry.cc
+++ b/src/DHTMessageTrackerEntry.cc
@@ -49,7 +49,7 @@ DHTMessageTrackerEntry::DHTMessageTrackerEntry(const SharedHandle<DHTMessage>& s
   transactionID_(sentMessage->getTransactionID()),
   messageType_(sentMessage->getMessageType()),
   callback_(callback),
-  dispatchedTime_(global::wallclock),
+  dispatchedTime_(global::wallclock()),
   timeout_(timeout)
 {}
 
@@ -57,7 +57,7 @@ DHTMessageTrackerEntry::~DHTMessageTrackerEntry() {}
 
 bool DHTMessageTrackerEntry::isTimeout() const
 {
-  return dispatchedTime_.difference(global::wallclock) >= timeout_;
+  return dispatchedTime_.difference(global::wallclock()) >= timeout_;
 }
 
 void DHTMessageTrackerEntry::extendTimeout()
@@ -81,7 +81,7 @@ bool DHTMessageTrackerEntry::match(const std::string& transactionID, const std::
 
 int64_t DHTMessageTrackerEntry::getElapsedMillis() const
 {
-  return dispatchedTime_.differenceInMillis(global::wallclock);
+  return dispatchedTime_.differenceInMillis(global::wallclock());
 }
 
 } // namespace aria2
diff --git a/src/DHTMessageTrackerEntry.h b/src/DHTMessageTrackerEntry.h
index 524fd17d..d9c7f96d 100644
--- a/src/DHTMessageTrackerEntry.h
+++ b/src/DHTMessageTrackerEntry.h
@@ -42,7 +42,6 @@
 #include "SharedHandle.h"
 #include "DHTConstants.h"
 #include "TimerA2.h"
-#include "wallclock.h"
 
 namespace aria2 {
 
diff --git a/src/DHTNode.cc b/src/DHTNode.cc
index 02f7b7dd..b04959ae 100644
--- a/src/DHTNode.cc
+++ b/src/DHTNode.cc
@@ -92,7 +92,7 @@ bool DHTNode::isBad() const
 bool DHTNode::isQuestionable() const
 {
   return !isBad() &&
-    lastContact_.difference(global::wallclock) >= DHT_NODE_CONTACT_INTERVAL;
+    lastContact_.difference(global::wallclock()) >= DHT_NODE_CONTACT_INTERVAL;
 }
 
 void DHTNode::markGood()
@@ -107,7 +107,7 @@ void DHTNode::markBad()
 
 void DHTNode::updateLastContact()
 {
-  lastContact_ = global::wallclock;
+  lastContact_ = global::wallclock();
 }
 
 void DHTNode::timeout()
diff --git a/src/DHTPeerAnnounceEntry.cc b/src/DHTPeerAnnounceEntry.cc
index 53661c57..3fe0a470 100644
--- a/src/DHTPeerAnnounceEntry.cc
+++ b/src/DHTPeerAnnounceEntry.cc
@@ -75,7 +75,7 @@ public:
 
   bool operator()(const PeerAddrEntry& entry) const
   {
-    if(entry.getLastUpdated().difference(global::wallclock) >= timeout_) {
+    if(entry.getLastUpdated().difference(global::wallclock()) >= timeout_) {
       return true;
     } else {
       return false;
@@ -107,7 +107,7 @@ void DHTPeerAnnounceEntry::getPeers
 
 void DHTPeerAnnounceEntry::notifyUpdate()
 {
-  lastUpdated_ = global::wallclock;
+  lastUpdated_ = global::wallclock();
 }
 
 } // namespace aria2
diff --git a/src/DHTPeerAnnounceStorage.cc b/src/DHTPeerAnnounceStorage.cc
index d5530c9a..8fb35013 100644
--- a/src/DHTPeerAnnounceStorage.cc
+++ b/src/DHTPeerAnnounceStorage.cc
@@ -145,7 +145,7 @@ void DHTPeerAnnounceStorage::announcePeer()
   for(std::deque<SharedHandle<DHTPeerAnnounceEntry> >::iterator i =
         entries_.begin(), eoi = entries_.end(); i != eoi; ++i) {
     if((*i)->getLastUpdated().
-       difference(global::wallclock) >= DHT_PEER_ANNOUNCE_INTERVAL) {
+       difference(global::wallclock()) >= DHT_PEER_ANNOUNCE_INTERVAL) {
       (*i)->notifyUpdate();
       SharedHandle<DHTTask> task =
         taskFactory_->createPeerAnnounceTask((*i)->getInfoHash());
diff --git a/src/DefaultBtAnnounce.cc b/src/DefaultBtAnnounce.cc
index 0f0efa86..c1c35bb9 100644
--- a/src/DefaultBtAnnounce.cc
+++ b/src/DefaultBtAnnounce.cc
@@ -79,7 +79,7 @@ bool DefaultBtAnnounce::isDefaultAnnounceReady() {
   return
     (trackers_ == 0 &&
      prevAnnounceTimer_.
-     difference(global::wallclock) >= (userDefinedInterval_==0?
+     difference(global::wallclock()) >= (userDefinedInterval_==0?
                                        minInterval_:userDefinedInterval_) &&
      !announceList_.allTiersFailed());
 }
@@ -210,7 +210,7 @@ bool DefaultBtAnnounce::isAllAnnounceFailed() {
 }
 
 void DefaultBtAnnounce::resetAnnounce() {
-  prevAnnounceTimer_ = global::wallclock;
+  prevAnnounceTimer_ = global::wallclock();
   announceList_.resetTier();
 }
 
diff --git a/src/DefaultBtInteractive.cc b/src/DefaultBtInteractive.cc
index a4017e8c..b70bb330 100644
--- a/src/DefaultBtInteractive.cc
+++ b/src/DefaultBtInteractive.cc
@@ -84,12 +84,12 @@ DefaultBtInteractive::DefaultBtInteractive
     metadataGetMode_(false),
     localNode_(0),
     allowedFastSetSize_(10),
-    haveTimer_(global::wallclock),
-    keepAliveTimer_(global::wallclock),
-    floodingTimer_(global::wallclock),
-    inactiveTimer_(global::wallclock),
-    pexTimer_(global::wallclock),
-    perSecTimer_(global::wallclock),
+    haveTimer_(global::wallclock()),
+    keepAliveTimer_(global::wallclock()),
+    floodingTimer_(global::wallclock()),
+    inactiveTimer_(global::wallclock()),
+    pexTimer_(global::wallclock()),
+    perSecTimer_(global::wallclock()),
     keepAliveInterval_(120),
     utPexEnabled_(false),
     dhtEnabled_(false),
@@ -161,8 +161,8 @@ BtMessageHandle DefaultBtInteractive::receiveAndSendHandshake() {
 void DefaultBtInteractive::doPostHandshakeProcessing() {
   // Set time 0 to haveTimer to cache http/ftp download piece completion
   haveTimer_.reset(0);
-  keepAliveTimer_ = global::wallclock;
-  floodingTimer_ = global::wallclock;
+  keepAliveTimer_ = global::wallclock();
+  floodingTimer_ = global::wallclock();
   pexTimer_.reset(0);
   if(peer_->isExtendedMessagingEnabled()) {
     addHandshakeExtendedMessageToQueue();
@@ -247,7 +247,7 @@ void DefaultBtInteractive::decideChoking() {
 void DefaultBtInteractive::checkHave() {
   std::vector<size_t> indexes;
   pieceStorage_->getAdvertisedPieceIndexes(indexes, cuid_, haveTimer_);
-  haveTimer_ = global::wallclock;
+  haveTimer_ = global::wallclock();
   if(indexes.size() >= 20) {
     if(peer_->isFastExtensionEnabled() &&
        pieceStorage_->allDownloadFinished()) {
@@ -264,10 +264,10 @@ void DefaultBtInteractive::checkHave() {
 }
 
 void DefaultBtInteractive::sendKeepAlive() {
-  if(keepAliveTimer_.difference(global::wallclock) >= keepAliveInterval_) {
+  if(keepAliveTimer_.difference(global::wallclock()) >= keepAliveInterval_) {
     dispatcher_->addMessageToQueue(messageFactory_->createKeepAliveMessage());
     dispatcher_->sendMessages();
-    keepAliveTimer_ = global::wallclock;
+    keepAliveTimer_ = global::wallclock();
   }
 }
 
@@ -308,7 +308,7 @@ size_t DefaultBtInteractive::receiveMessages() {
       peerStorage_->updateTransferStatFor(peer_);
       // pass through
     case BtRequestMessage::ID:
-      inactiveTimer_ = global::wallclock;
+      inactiveTimer_ = global::wallclock();
       break;
     }
   }
@@ -422,20 +422,20 @@ void DefaultBtInteractive::sendPendingMessage() {
 
 void DefaultBtInteractive::detectMessageFlooding() {
   if(floodingTimer_.
-     difference(global::wallclock) >= FLOODING_CHECK_INTERVAL) {
+     difference(global::wallclock()) >= FLOODING_CHECK_INTERVAL) {
     if(floodingStat_.getChokeUnchokeCount() >= 2 ||
        floodingStat_.getKeepAliveCount() >= 2) {
       throw DL_ABORT_EX(EX_FLOODING_DETECTED);
     } else {
       floodingStat_.reset();
     }
-    floodingTimer_ = global::wallclock;
+    floodingTimer_ = global::wallclock();
   }
 }
 
 void DefaultBtInteractive::checkActiveInteraction()
 {
-  time_t inactiveTime = inactiveTimer_.difference(global::wallclock);
+  time_t inactiveTime = inactiveTimer_.difference(global::wallclock());
   // To allow aria2 to accept mutially interested peer, disconnect unintersted
   // peer.
   {
@@ -471,7 +471,7 @@ void DefaultBtInteractive::checkActiveInteraction()
 void DefaultBtInteractive::addPeerExchangeMessage()
 {
   if(pexTimer_.
-     difference(global::wallclock) >= UTPexExtensionMessage::DEFAULT_INTERVAL) {
+     difference(global::wallclock()) >= UTPexExtensionMessage::DEFAULT_INTERVAL) {
     UTPexExtensionMessageHandle m
       (new UTPexExtensionMessage(peer_->getExtensionMessageID("ut_pex")));
 
@@ -497,7 +497,7 @@ void DefaultBtInteractive::addPeerExchangeMessage()
 
     BtMessageHandle msg = messageFactory_->createBtExtendedMessage(m);
     dispatcher_->addMessageToQueue(msg);
-    pexTimer_ = global::wallclock;
+    pexTimer_ = global::wallclock();
   }
 }
 
@@ -517,8 +517,8 @@ void DefaultBtInteractive::doInteractionProcessing() {
         utMetadataRequestFactory_->create(requests, num, pieceStorage_);
         dispatcher_->addMessageToQueue(requests);
       }
-      if(perSecTimer_.difference(global::wallclock) >= 1) {
-        perSecTimer_ = global::wallclock;
+      if(perSecTimer_.difference(global::wallclock()) >= 1) {
+        perSecTimer_ = global::wallclock();
         // Drop timeout request after queuing message to give a chance
         // to other connection to request piece.
         std::vector<size_t> indexes =
@@ -537,8 +537,8 @@ void DefaultBtInteractive::doInteractionProcessing() {
     checkActiveInteraction();
     decideChoking();
     detectMessageFlooding();
-    if(perSecTimer_.difference(global::wallclock) >= 1) {
-      perSecTimer_ = global::wallclock;
+    if(perSecTimer_.difference(global::wallclock()) >= 1) {
+      perSecTimer_ = global::wallclock();
       dispatcher_->checkRequestSlotAndDoNecessaryThing();
     }
     checkHave();
diff --git a/src/DefaultPeerStorage.cc b/src/DefaultPeerStorage.cc
index c06c262d..900a6b33 100644
--- a/src/DefaultPeerStorage.cc
+++ b/src/DefaultPeerStorage.cc
@@ -246,10 +246,10 @@ TransferStat calculateStatFor(const SharedHandle<Peer>& peer)
 TransferStat DefaultPeerStorage::calculateStat()
 {
   TransferStat stat;
-  if(lastTransferStatMapUpdated_.differenceInMillis(global::wallclock)+
+  if(lastTransferStatMapUpdated_.differenceInMillis(global::wallclock())+
      A2_DELTA_MILLIS >= 250) {
     A2_LOG_DEBUG("Updating TransferStat of PeerStorage");
-    lastTransferStatMapUpdated_ = global::wallclock;
+    lastTransferStatMapUpdated_ = global::wallclock();
     peerTransferStatMap_.clear();
     std::vector<SharedHandle<Peer> > activePeers;
     getActivePeers(activePeers);
@@ -358,10 +358,10 @@ bool DefaultPeerStorage::chokeRoundIntervalElapsed()
   const time_t CHOKE_ROUND_INTERVAL = 10;
   if(pieceStorage_->downloadFinished()) {
     return seederStateChoke_->getLastRound().
-      difference(global::wallclock) >= CHOKE_ROUND_INTERVAL;
+      difference(global::wallclock()) >= CHOKE_ROUND_INTERVAL;
   } else {
     return leecherStateChoke_->getLastRound().
-      difference(global::wallclock) >= CHOKE_ROUND_INTERVAL;
+      difference(global::wallclock()) >= CHOKE_ROUND_INTERVAL;
   }
 }
 
diff --git a/src/DefaultPieceStorage.cc b/src/DefaultPieceStorage.cc
index eedce97f..82fe0bd6 100644
--- a/src/DefaultPieceStorage.cc
+++ b/src/DefaultPieceStorage.cc
@@ -655,7 +655,7 @@ size_t DefaultPieceStorage::getPieceLength(size_t index)
 
 void DefaultPieceStorage::advertisePiece(cuid_t cuid, size_t index)
 {
-  HaveEntry entry(cuid, index, global::wallclock);
+  HaveEntry entry(cuid, index, global::wallclock());
   haves_.push_front(entry);
 }
 
@@ -686,7 +686,7 @@ public:
   FindElapsedHave(time_t elapsed):elapsed(elapsed) {}
 
   bool operator()(const HaveEntry& have) {
-    if(have.getRegisteredTime().difference(global::wallclock) >= elapsed) {
+    if(have.getRegisteredTime().difference(global::wallclock()) >= elapsed) {
       return true;
     } else {
       return false;
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
index f4a76267..498309e0 100644
--- a/src/DownloadCommand.cc
+++ b/src/DownloadCommand.cc
@@ -271,7 +271,7 @@ bool DownloadCommand::executeInternal() {
 void DownloadCommand::checkLowestDownloadSpeed() const
 {
   if(lowestDownloadSpeedLimit_ > 0 &&
-     peerStat_->getDownloadStartTime().difference(global::wallclock) >=
+     peerStat_->getDownloadStartTime().difference(global::wallclock()) >=
      startupIdleTime_) {
     unsigned int nowSpeed = peerStat_->calculateDownloadSpeed();
     if(nowSpeed <= lowestDownloadSpeedLimit_) {
diff --git a/src/DownloadContext.cc b/src/DownloadContext.cc
index beabd090..b73845fe 100644
--- a/src/DownloadContext.cc
+++ b/src/DownloadContext.cc
@@ -75,13 +75,13 @@ DownloadContext::~DownloadContext() {}
 
 void DownloadContext::resetDownloadStartTime()
 {
-  downloadStartTime_ = global::wallclock;
+  downloadStartTime_ = global::wallclock();
   downloadStopTime_.reset(0);
 }
 
 void DownloadContext::resetDownloadStopTime()
 {
-  downloadStopTime_ = global::wallclock;
+  downloadStopTime_ = global::wallclock();
 }
 
 int64_t DownloadContext::calculateSessionTime() const
diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc
index a18e36ad..218c6484 100644
--- a/src/DownloadEngine.cc
+++ b/src/DownloadEngine.cc
@@ -65,6 +65,7 @@
 #include "BtProgressInfoFile.h"
 #include "DownloadContext.h"
 #include "fmt.h"
+#include "wallclock.h"
 #ifdef ENABLE_BITTORRENT
 # include "BtRegistry.h"
 #endif // ENABLE_BITTORRENT
@@ -73,10 +74,6 @@ namespace aria2 {
 
 namespace global {
 
-// Global clock, this clock is reseted before executeCommand() call to
-// reduce the call gettimeofday() system call.
-Timer wallclock;
-
 // 0 ... running
 // 1 ... stop signal detected
 // 2 ... stop signal processed by DownloadEngine
@@ -146,12 +143,12 @@ void DownloadEngine::run()
   Timer cp;
   cp.reset(0);
   while(!commands_.empty() || !routineCommands_.empty()) {
-    global::wallclock.reset();
+    global::wallclock().reset();
     calculateStatistics();
-    if(cp.differenceInMillis(global::wallclock)+A2_DELTA_MILLIS >=
+    if(cp.differenceInMillis(global::wallclock())+A2_DELTA_MILLIS >=
        refreshInterval_) {
       refreshInterval_ = DEFAULT_REFRESH_INTERVAL;
-      cp = global::wallclock;
+      cp = global::wallclock();
       executeCommand(commands_, Command::STATUS_ALL);
     } else {
       executeCommand(commands_, Command::STATUS_ACTIVE);
@@ -288,10 +285,10 @@ void DownloadEngine::poolSocket(const std::string& key,
   std::multimap<std::string, SocketPoolEntry>::value_type p(key, entry);
   socketPool_.insert(p);
 
-  if(lastSocketPoolScan_.difference(global::wallclock) >= 60) {
+  if(lastSocketPoolScan_.difference(global::wallclock()) >= 60) {
     std::multimap<std::string, SocketPoolEntry> newPool;
     A2_LOG_DEBUG("Scaning SocketPool and erasing timed out entry.");
-    lastSocketPoolScan_ = global::wallclock;
+    lastSocketPoolScan_ = global::wallclock();
     for(std::multimap<std::string, SocketPoolEntry>::iterator i =
           socketPool_.begin(), eoi = socketPool_.end(); i != eoi; ++i) {
       if(!(*i).second.isTimeout()) {
@@ -497,7 +494,7 @@ DownloadEngine::SocketPoolEntry::~SocketPoolEntry() {}
 
 bool DownloadEngine::SocketPoolEntry::isTimeout() const
 {
-  return registeredTime_.difference(global::wallclock) >= timeout_;
+  return registeredTime_.difference(global::wallclock()) >= timeout_;
 }
 
 cuid_t DownloadEngine::newCUID()
diff --git a/src/FileAllocationCommand.cc b/src/FileAllocationCommand.cc
index 84e28e06..7b7b10b7 100644
--- a/src/FileAllocationCommand.cc
+++ b/src/FileAllocationCommand.cc
@@ -70,7 +70,7 @@ bool FileAllocationCommand::executeInternal()
   if(fileAllocationEntry_->finished()) {
     A2_LOG_DEBUG
       (fmt(MSG_ALLOCATION_COMPLETED,
-           static_cast<long int>(timer_.difference(global::wallclock)),
+           static_cast<long int>(timer_.difference(global::wallclock())),
            util::itos(getRequestGroup()->getTotalLength(), true).c_str()));
     getDownloadEngine()->getFileAllocationMan()->dropPickedEntry();
     
diff --git a/src/FileEntry.cc b/src/FileEntry.cc
index 5ca1d23b..379be62a 100644
--- a/src/FileEntry.cc
+++ b/src/FileEntry.cc
@@ -174,13 +174,13 @@ FileEntry::getRequest
     }
   } else {
     // Skip Request object if it is still
-    // sleeping(Request::getWakeTime() < global::wallclock).  If all
+    // sleeping(Request::getWakeTime() < global::wallclock()).  If all
     // pooled objects are sleeping, return first one.  Caller should
     // inspect returned object's getWakeTime().
     std::deque<SharedHandle<Request> >::iterator i = requestPool_.begin();
     std::deque<SharedHandle<Request> >::iterator eoi = requestPool_.end();
     for(; i != eoi; ++i) {
-      if((*i)->getWakeTime() <= global::wallclock) {
+      if((*i)->getWakeTime() <= global::wallclock()) {
         break;
       }
     }
@@ -200,7 +200,7 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
 {
   const int startupIdleTime = 10;
   if(requestPool_.empty() ||
-     lastFasterReplace_.difference(global::wallclock) < startupIdleTime) {
+     lastFasterReplace_.difference(global::wallclock()) < startupIdleTime) {
     return SharedHandle<Request>();
   }
   const SharedHandle<PeerStat>& fastest = requestPool_.front()->getPeerStat();
@@ -211,13 +211,13 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
   // TODO hard coded value. See PREF_STARTUP_IDLE_TIME
   if(!basestat ||
      (basestat->getDownloadStartTime().
-      difference(global::wallclock) >= startupIdleTime &&
+      difference(global::wallclock()) >= startupIdleTime &&
       fastest->getAvgDownloadSpeed()*0.8 > basestat->calculateDownloadSpeed())){
     // TODO we should consider that "fastest" is very slow.
     SharedHandle<Request> fastestRequest = requestPool_.front();
     requestPool_.pop_front();
     inFlightRequests_.push_back(fastestRequest);
-    lastFasterReplace_ = global::wallclock;
+    lastFasterReplace_ = global::wallclock();
     return fastestRequest;
   }
   return SharedHandle<Request>();
@@ -231,7 +231,7 @@ FileEntry::findFasterRequest
 {
   const int startupIdleTime = 10;
   const unsigned int SPEED_THRESHOLD = 20*1024;
-  if(lastFasterReplace_.difference(global::wallclock) < startupIdleTime) {
+  if(lastFasterReplace_.difference(global::wallclock()) < startupIdleTime) {
     return SharedHandle<Request>();
   }
   std::vector<std::string> inFlightHosts;
@@ -280,7 +280,7 @@ FileEntry::findFasterRequest
     uris_.erase(std::find(uris_.begin(), uris_.end(), uri));
     spentUris_.push_back(uri);
     inFlightRequests_.push_back(fastestRequest);
-    lastFasterReplace_ = global::wallclock;
+    lastFasterReplace_ = global::wallclock();
     return fastestRequest;
   }
   A2_LOG_DEBUG("No faster server found.");
diff --git a/src/FtpFinishDownloadCommand.cc b/src/FtpFinishDownloadCommand.cc
index 9b40e024..208fb79f 100644
--- a/src/FtpFinishDownloadCommand.cc
+++ b/src/FtpFinishDownloadCommand.cc
@@ -77,7 +77,7 @@ bool FtpFinishDownloadCommand::execute()
   }
   try {
     if(readEventEnabled() || hupEventEnabled()) {
-      getCheckPoint() = global::wallclock;
+      getCheckPoint() = global::wallclock();
       unsigned int status = ftpConnection_->receiveResponse();
       if(status == 0) {
         getDownloadEngine()->addCommand(this);
@@ -95,7 +95,7 @@ bool FtpFinishDownloadCommand::execute()
         A2_LOG_INFO(fmt("CUID#%lld - Bad status for transfer complete.",
                         getCuid()));
       }
-    } else if(getCheckPoint().difference(global::wallclock) >= getTimeout()) {
+    } else if(getCheckPoint().difference(global::wallclock()) >= getTimeout()) {
       A2_LOG_INFO(fmt("CUID#%lld - Timeout before receiving transfer complete.",
                       getCuid()));
     } else {
diff --git a/src/HttpServerBodyCommand.cc b/src/HttpServerBodyCommand.cc
index e8c063e5..71b20a7b 100644
--- a/src/HttpServerBodyCommand.cc
+++ b/src/HttpServerBodyCommand.cc
@@ -201,7 +201,7 @@ bool HttpServerBodyCommand::execute()
     if(socket_->isReadable(0) ||
        !httpServer_->getSocketRecvBuffer()->bufferEmpty() ||
        httpServer_->getContentLength() == 0) {
-      timeoutTimer_ = global::wallclock;
+      timeoutTimer_ = global::wallclock();
 
       if(httpServer_->receiveBody()) {
         std::string reqPath = httpServer_->getRequestPath();
@@ -280,7 +280,7 @@ bool HttpServerBodyCommand::execute()
         return false;
       } 
     } else {
-      if(timeoutTimer_.difference(global::wallclock) >= 30) {
+      if(timeoutTimer_.difference(global::wallclock()) >= 30) {
         A2_LOG_INFO("HTTP request body timeout.");
         return true;
       } else {
diff --git a/src/HttpServerCommand.cc b/src/HttpServerCommand.cc
index 1fde0844..8306ad15 100644
--- a/src/HttpServerCommand.cc
+++ b/src/HttpServerCommand.cc
@@ -109,7 +109,7 @@ bool HttpServerCommand::execute()
   try {
     if(socket_->isReadable(0) ||
        !httpServer_->getSocketRecvBuffer()->bufferEmpty()) {
-      timeoutTimer_ = global::wallclock;
+      timeoutTimer_ = global::wallclock();
       SharedHandle<HttpHeader> header;
 
       header = httpServer_->receiveRequest();
@@ -144,7 +144,7 @@ bool HttpServerCommand::execute()
       e_->setNoWait(true);
       return true;
     } else {
-      if(timeoutTimer_.difference(global::wallclock) >= 30) {
+      if(timeoutTimer_.difference(global::wallclock()) >= 30) {
         A2_LOG_INFO("HTTP request timeout.");
         return true;
       } else {
diff --git a/src/HttpServerResponseCommand.cc b/src/HttpServerResponseCommand.cc
index d5ffab65..a44560e7 100644
--- a/src/HttpServerResponseCommand.cc
+++ b/src/HttpServerResponseCommand.cc
@@ -91,7 +91,7 @@ bool HttpServerResponseCommand::execute()
     }
     return true;
   } else {
-    if(timeoutTimer_.difference(global::wallclock) >= 10) {
+    if(timeoutTimer_.difference(global::wallclock()) >= 10) {
       A2_LOG_INFO(fmt("CUID#%lld - HttpServer: Timeout while trasmitting"
                       " response.",
                       getCuid()));
diff --git a/src/LpdMessageDispatcher.cc b/src/LpdMessageDispatcher.cc
index ba2bbdf7..fcbfd2b3 100644
--- a/src/LpdMessageDispatcher.cc
+++ b/src/LpdMessageDispatcher.cc
@@ -93,12 +93,12 @@ bool LpdMessageDispatcher::sendMessage()
 
 bool LpdMessageDispatcher::isAnnounceReady() const
 {
-  return timer_.difference(global::wallclock) >= interval_;
+  return timer_.difference(global::wallclock()) >= interval_;
 }
 
 void LpdMessageDispatcher::resetAnnounceTimer()
 {
-  timer_ = global::wallclock;
+  timer_ = global::wallclock();
 }
 
 namespace bittorrent {
diff --git a/src/Makefile.am b/src/Makefile.am
index 67833bf9..c3c47b7c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -194,7 +194,7 @@ SRCS =  Socket.h\
 	bitfield.cc bitfield.h\
 	CreateRequestCommand.cc CreateRequestCommand.h\
 	error_code.h\
-	wallclock.h\
+	wallclock.cc wallclock.h\
 	download_helper.cc download_helper.h\
 	MetadataInfo.cc MetadataInfo.h\
 	SessionSerializer.cc SessionSerializer.h\
diff --git a/src/Peer.cc b/src/Peer.cc
index 73d35f91..0423bfeb 100644
--- a/src/Peer.cc
+++ b/src/Peer.cc
@@ -50,7 +50,7 @@ namespace aria2 {
 Peer::Peer(std::string ipaddr, uint16_t port, bool incoming):
   ipaddr_(ipaddr),
   port_(port),
-  firstContactTime_(global::wallclock),
+  firstContactTime_(global::wallclock()),
   badConditionStartTime_(0),
   seeder_(false),
   res_(0),
@@ -326,13 +326,13 @@ void Peer::setAllBitfield() {
 
 void Peer::startBadCondition()
 {
-  badConditionStartTime_ = global::wallclock;
+  badConditionStartTime_ = global::wallclock();
 }
 
 bool Peer::isGood() const
 {
   return badConditionStartTime_.
-    difference(global::wallclock) >= BAD_CONDITION_INTERVAL;
+    difference(global::wallclock()) >= BAD_CONDITION_INTERVAL;
 }
 
 uint8_t Peer::getExtensionMessageID(const std::string& name) const
diff --git a/src/PeerAbstractCommand.cc b/src/PeerAbstractCommand.cc
index 63ec031e..e1541d68 100644
--- a/src/PeerAbstractCommand.cc
+++ b/src/PeerAbstractCommand.cc
@@ -55,7 +55,7 @@ PeerAbstractCommand::PeerAbstractCommand
  DownloadEngine* e,
  const SocketHandle& s)
  : Command(cuid),
-   checkPoint_(global::wallclock),
+   checkPoint_(global::wallclock()),
    // TODO referring global option
    timeout_(e->getOption()->getAsInt(PREF_BT_TIMEOUT)),
    e_(e),
@@ -93,13 +93,13 @@ bool PeerAbstractCommand::execute()
        (checkSocketIsReadable_ && readEventEnabled()) ||
        (checkSocketIsWritable_ && writeEventEnabled()) ||
        hupEventEnabled()) {
-      checkPoint_ = global::wallclock;
+      checkPoint_ = global::wallclock();
     } else if(errorEventEnabled()) {
       throw DL_ABORT_EX
         (fmt(MSG_NETWORK_PROBLEM,
              socket_->getSocketError().c_str()));
     }
-    if(checkPoint_.difference(global::wallclock) >= timeout_) {
+    if(checkPoint_.difference(global::wallclock()) >= timeout_) {
       throw DL_ABORT_EX(EX_TIME_OUT);
     }
     return executeInternal();
@@ -190,7 +190,7 @@ void PeerAbstractCommand::setNoCheck(bool check)
 
 void PeerAbstractCommand::updateKeepAlive()
 {
-  checkPoint_ = global::wallclock;
+  checkPoint_ = global::wallclock();
 }
 
 void PeerAbstractCommand::createSocket()
diff --git a/src/PeerAddrEntry.cc b/src/PeerAddrEntry.cc
index 087bf118..ee68c7c8 100644
--- a/src/PeerAddrEntry.cc
+++ b/src/PeerAddrEntry.cc
@@ -62,7 +62,7 @@ PeerAddrEntry& PeerAddrEntry::operator=(const PeerAddrEntry& c)
 
 void PeerAddrEntry::notifyUpdate()
 {
-  lastUpdated_ = global::wallclock;
+  lastUpdated_ = global::wallclock();
 }
 
 bool PeerAddrEntry::operator==(const PeerAddrEntry& entry) const
diff --git a/src/PeerSessionResource.cc b/src/PeerSessionResource.cc
index f8141d33..790f1148 100644
--- a/src/PeerSessionResource.cc
+++ b/src/PeerSessionResource.cc
@@ -70,7 +70,7 @@ void PeerSessionResource::amChoking(bool b)
 {
   amChoking_ = b;
   if(!b) {
-    lastAmUnchoking_ = global::wallclock;
+    lastAmUnchoking_ = global::wallclock();
   }
 }
 
@@ -256,7 +256,7 @@ void PeerSessionResource::updateDownloadLength(size_t bytes)
 {
   peerStat_.updateDownloadLength(bytes);
 
-  lastDownloadUpdate_ = global::wallclock;
+  lastDownloadUpdate_ = global::wallclock();
 }
 
 uint64_t PeerSessionResource::getCompletedLength() const
diff --git a/src/PeerStat.cc b/src/PeerStat.cc
index 6aa19497..1a060a90 100644
--- a/src/PeerStat.cc
+++ b/src/PeerStat.cc
@@ -43,7 +43,7 @@ PeerStat::PeerStat
   : cuid_(cuid),
     hostname_(hostname),
     protocol_(protocol),
-    downloadStartTime_(global::wallclock),
+    downloadStartTime_(global::wallclock()),
     status_(PeerStat::IDLE),
     avgDownloadSpeed_(0),
     avgUploadSpeed_(0),
@@ -113,7 +113,7 @@ void PeerStat::reset()
 {
   downloadSpeed_.reset();
   uploadSpeed_.reset();
-  downloadStartTime_ = global::wallclock;
+  downloadStartTime_ = global::wallclock();
   status_ = PeerStat::IDLE;
 }
 
diff --git a/src/Request.cc b/src/Request.cc
index a70f370e..d611cb24 100644
--- a/src/Request.cc
+++ b/src/Request.cc
@@ -68,7 +68,7 @@ Request::Request():
   ipv6LiteralAddress_(false),
   removalRequested_(false),
   connectedPort_(0),
-  wakeTime_(global::wallclock)
+  wakeTime_(global::wallclock())
 {}
 
 Request::~Request() {}
diff --git a/src/RequestSlot.cc b/src/RequestSlot.cc
index 557fc5ab..c39381fe 100644
--- a/src/RequestSlot.cc
+++ b/src/RequestSlot.cc
@@ -33,7 +33,6 @@
  */
 /* copyright --> */
 #include "RequestSlot.h"
-#include "wallclock.h"
 
 namespace aria2 {
 
@@ -44,7 +43,7 @@ void RequestSlot::setDispatchedTime(time_t sec) {
 }
 
 bool RequestSlot::isTimeout(time_t timeoutSec) const {
-  return dispatchedTime_.difference(global::wallclock) >= timeoutSec;
+  return dispatchedTime_.difference(global::wallclock()) >= timeoutSec;
 }
 
 bool RequestSlot::isNull(const RequestSlot& requestSlot) {
diff --git a/src/RequestSlot.h b/src/RequestSlot.h
index b8d219dd..1ce43fbe 100644
--- a/src/RequestSlot.h
+++ b/src/RequestSlot.h
@@ -71,7 +71,7 @@ public:
   
   RequestSlot(size_t index, uint32_t begin, size_t length, size_t blockIndex,
               const SharedHandle<Piece>& piece = SharedHandle<Piece>()):
-    dispatchedTime_(global::wallclock),
+    dispatchedTime_(global::wallclock()),
     index_(index), begin_(begin), length_(length), blockIndex_(blockIndex),
     piece_(piece) {}
 
diff --git a/src/SegmentMan.cc b/src/SegmentMan.cc
index 7fb65b38..a8fe2efb 100644
--- a/src/SegmentMan.cc
+++ b/src/SegmentMan.cc
@@ -409,9 +409,9 @@ void SegmentMan::updateFastestPeerStat(const SharedHandle<PeerStat>& peerStat)
 unsigned int SegmentMan::calculateDownloadSpeed()
 {
   unsigned int speed = 0;
-  if(lastPeerStatDlspdMapUpdated_.differenceInMillis(global::wallclock)+
+  if(lastPeerStatDlspdMapUpdated_.differenceInMillis(global::wallclock())+
      A2_DELTA_MILLIS >= 250){
-    lastPeerStatDlspdMapUpdated_ = global::wallclock;
+    lastPeerStatDlspdMapUpdated_ = global::wallclock();
     peerStatDlspdMap_.clear();
     for(std::vector<SharedHandle<PeerStat> >::const_iterator i =
           peerStats_.begin(), eoi = peerStats_.end(); i != eoi; ++i) {
diff --git a/src/SleepCommand.cc b/src/SleepCommand.cc
index a7a1c5f5..a3ace47e 100644
--- a/src/SleepCommand.cc
+++ b/src/SleepCommand.cc
@@ -43,7 +43,7 @@ SleepCommand::SleepCommand(cuid_t cuid, DownloadEngine* e,
                            RequestGroup* requestGroup,
                            Command* nextCommand, time_t wait):
   Command(cuid), engine_(e), requestGroup_(requestGroup),
-  nextCommand_(nextCommand), wait_(wait), checkPoint_(global::wallclock) {}
+  nextCommand_(nextCommand), wait_(wait), checkPoint_(global::wallclock()) {}
 
 SleepCommand::~SleepCommand() {
   delete nextCommand_;
@@ -52,7 +52,7 @@ SleepCommand::~SleepCommand() {
 bool SleepCommand::execute() {
   if(requestGroup_->downloadFinished() || requestGroup_->isHaltRequested()) {
     return true;
-  } else if(checkPoint_.differenceInMillis(global::wallclock)+A2_DELTA_MILLIS
+  } else if(checkPoint_.differenceInMillis(global::wallclock())+A2_DELTA_MILLIS
             >= wait_*1000) {
     engine_->addCommand(nextCommand_);
     nextCommand_ = 0;
diff --git a/src/SpeedCalc.cc b/src/SpeedCalc.cc
index 02b04801..c792df9e 100644
--- a/src/SpeedCalc.cc
+++ b/src/SpeedCalc.cc
@@ -52,17 +52,17 @@ SpeedCalc::SpeedCalc():sw_(0), maxSpeed_(0), prevSpeed_(0),
 
 void SpeedCalc::reset() {
   std::fill(&lengthArray_[0], &lengthArray_[2], 0);
-  std::fill(&cpArray_[0], &cpArray_[2], global::wallclock);
+  std::fill(&cpArray_[0], &cpArray_[2], global::wallclock());
   sw_ = 0;
   maxSpeed_ = 0;
   prevSpeed_ = 0;
-  start_ = global::wallclock;
+  start_ = global::wallclock();
   accumulatedLength_ = 0;
   nextInterval_ = CHANGE_INTERVAL_SEC;
 }
 
 unsigned int SpeedCalc::calculateSpeed() {
-  int64_t milliElapsed = cpArray_[sw_].differenceInMillis(global::wallclock);
+  int64_t milliElapsed = cpArray_[sw_].differenceInMillis(global::wallclock());
   if(milliElapsed) {
     unsigned int speed = lengthArray_[sw_]*1000/milliElapsed;
     prevSpeed_ = speed;
@@ -86,7 +86,7 @@ void SpeedCalc::update(size_t bytes) {
 }
 
 bool SpeedCalc::isIntervalOver() const {
-  return nextInterval_ <= cpArray_[sw_].difference(global::wallclock);
+  return nextInterval_ <= cpArray_[sw_].difference(global::wallclock());
 }
 
 bool SpeedCalc::isIntervalOver(int64_t milliElapsed) const
@@ -96,14 +96,14 @@ bool SpeedCalc::isIntervalOver(int64_t milliElapsed) const
 
 void SpeedCalc::changeSw() {
   lengthArray_[sw_] = 0;
-  cpArray_[sw_] = global::wallclock;
+  cpArray_[sw_] = global::wallclock();
   sw_ ^= 0x01u;
   nextInterval_ =
-    cpArray_[sw_].difference(global::wallclock)+CHANGE_INTERVAL_SEC;
+    cpArray_[sw_].difference(global::wallclock())+CHANGE_INTERVAL_SEC;
 }
 
 unsigned int SpeedCalc::calculateAvgSpeed() const {
-  uint64_t milliElapsed = start_.differenceInMillis(global::wallclock);
+  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/TimeBasedCommand.cc b/src/TimeBasedCommand.cc
index 78891c00..50d1ff03 100644
--- a/src/TimeBasedCommand.cc
+++ b/src/TimeBasedCommand.cc
@@ -42,7 +42,7 @@ TimeBasedCommand::TimeBasedCommand(cuid_t cuid, DownloadEngine* e,
                                    time_t interval,
                                    bool routineCommand):
   Command(cuid), e_(e),exit_(false), interval_(interval),
-  routineCommand_(routineCommand), checkPoint_(global::wallclock) {}
+  routineCommand_(routineCommand), checkPoint_(global::wallclock()) {}
 
 TimeBasedCommand::~TimeBasedCommand() {}
 
@@ -52,8 +52,8 @@ bool TimeBasedCommand::execute()
   if(exit_) {
     return true;
   }
-  if(checkPoint_.difference(global::wallclock) >= interval_) {
-    checkPoint_ = global::wallclock;
+  if(checkPoint_.difference(global::wallclock()) >= interval_) {
+    checkPoint_ = global::wallclock();
     process();
     if(exit_) {
       return true;
diff --git a/src/TimeSeedCriteria.cc b/src/TimeSeedCriteria.cc
index eb46e1cc..5c2a1d6c 100644
--- a/src/TimeSeedCriteria.cc
+++ b/src/TimeSeedCriteria.cc
@@ -43,12 +43,12 @@ TimeSeedCriteria::~TimeSeedCriteria() {}
 
 void TimeSeedCriteria::reset()
 {
-  watch_ = global::wallclock;
+  watch_ = global::wallclock();
 }
 
 bool TimeSeedCriteria::evaluate()
 {
-  return watch_.difference(global::wallclock) >= duration_;
+  return watch_.difference(global::wallclock()) >= duration_;
 }
 
 } // namespace aria2
diff --git a/src/UTMetadataRequestTracker.h b/src/UTMetadataRequestTracker.h
index 5ba719b5..659fa80c 100644
--- a/src/UTMetadataRequestTracker.h
+++ b/src/UTMetadataRequestTracker.h
@@ -54,7 +54,7 @@ private:
 
     bool elapsed(time_t t) const
     {
-      return dispatchedTime_.difference(global::wallclock) >= t;
+      return dispatchedTime_.difference(global::wallclock()) >= t;
     }
 
     bool operator==(const RequestEntry& e) const
diff --git a/src/UTPexExtensionMessage.cc b/src/UTPexExtensionMessage.cc
index d04a3577..d530cd16 100644
--- a/src/UTPexExtensionMessage.cc
+++ b/src/UTPexExtensionMessage.cc
@@ -134,7 +134,7 @@ void UTPexExtensionMessage::doReceivedAction()
 bool UTPexExtensionMessage::addFreshPeer(const SharedHandle<Peer>& peer)
 {
   if(!peer->isIncomingPeer() &&
-     peer->getFirstContactTime().difference(global::wallclock) < interval_) {
+     peer->getFirstContactTime().difference(global::wallclock()) < interval_) {
     freshPeers_.push_back(peer);
     return true;
   } else {
@@ -151,7 +151,7 @@ bool UTPexExtensionMessage::addDroppedPeer(const SharedHandle<Peer>& peer)
 {
   if(!peer->isIncomingPeer() &&
      peer->getBadConditionStartTime().
-     difference(global::wallclock) < interval_) {
+     difference(global::wallclock()) < interval_) {
     droppedPeers_.push_back(peer);
     return true;
   } else {
diff --git a/src/wallclock.cc b/src/wallclock.cc
new file mode 100644
index 00000000..4b43b720
--- /dev/null
+++ b/src/wallclock.cc
@@ -0,0 +1,49 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2011 Tatsuhiro Tsujikawa
+ *
+ * This program 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 program 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 program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#include "wallclock.h"
+
+namespace aria2 {
+
+namespace global {
+
+Timer& wallclock()
+{
+  static Timer* t = new Timer();
+  return *t;
+}
+
+} // namespace global
+
+} // namespace aria2
diff --git a/src/wallclock.h b/src/wallclock.h
index 759c2768..8d9d0a7e 100644
--- a/src/wallclock.h
+++ b/src/wallclock.h
@@ -2,7 +2,7 @@
 /*
  * aria2 - The high speed download utility
  *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
+ * Copyright (C) 2011 Tatsuhiro Tsujikawa
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,8 +38,9 @@ namespace aria2 {
 
 namespace global {
 
-// wallclock is defined in DownloadEngine.cc
-extern Timer wallclock;
+// Global clock, this clock is reseted before executeCommand() call to
+// reduce the call gettimeofday() system call.
+Timer& wallclock();
 
 } // namespace global
 
diff --git a/test/TimeSeedCriteriaTest.cc b/test/TimeSeedCriteriaTest.cc
index 38d06971..cc46b77b 100644
--- a/test/TimeSeedCriteriaTest.cc
+++ b/test/TimeSeedCriteriaTest.cc
@@ -22,8 +22,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION(TimeSeedCriteriaTest);
 
 void TimeSeedCriteriaTest::testEvaluate() {
   TimeSeedCriteria cri(1);
-  global::wallclock.reset();
-  global::wallclock.advance(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 3feb33ec..09a8b157 100644
--- a/test/UTPexExtensionMessageTest.cc
+++ b/test/UTPexExtensionMessageTest.cc
@@ -35,7 +35,7 @@ public:
   void setUp()
   {
     peerStorage_.reset(new MockPeerStorage());
-    global::wallclock.reset();
+    global::wallclock().reset();
   }
 
   void testGetExtensionMessageID();