diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2010-01-18 19:36:41 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2010-01-18 19:36:41 +0000 |
commit | 7e46119759b7099c38f543bd38d0186b9806542f (patch) | |
tree | b31264c454e26566b2e70c2794b89d77f4e28c44 | |
parent | 42592c0083505777e8fb8e4bf09182528229a787 (diff) |
Remove excessive gettimeofday system calls
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12293 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/dns.h | 11 | ||||
-rw-r--r-- | include/inspircd.h | 15 | ||||
-rw-r--r-- | src/configreader.cpp | 2 | ||||
-rw-r--r-- | src/dns.cpp | 19 | ||||
-rw-r--r-- | src/inspircd.cpp | 61 | ||||
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_spanningtree/pong.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treeserver.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treeserver.h | 2 | ||||
-rw-r--r-- | src/socketengines/socketengine_epoll.cpp | 1 | ||||
-rw-r--r-- | src/socketengines/socketengine_kqueue.cpp | 1 | ||||
-rw-r--r-- | src/socketengines/socketengine_poll.cpp | 1 | ||||
-rw-r--r-- | src/socketengines/socketengine_ports.cpp | 1 | ||||
-rw-r--r-- | src/socketengines/socketengine_select.cpp | 1 | ||||
-rw-r--r-- | src/stats.cpp | 5 | ||||
-rw-r--r-- | src/userprocess.cpp | 8 | ||||
-rw-r--r-- | win/inspircd_win32wrapper.cpp | 4 | ||||
-rw-r--r-- | win/inspircd_win32wrapper.h | 3 |
18 files changed, 76 insertions, 79 deletions
diff --git a/include/dns.h b/include/dns.h index f79121ab3..3d326a69c 100644 --- a/include/dns.h +++ b/include/dns.h @@ -84,19 +84,12 @@ class CoreExport CachedQuery * @param res The result data, an IP or hostname * @param ttl The time-to-live value of the query result */ - CachedQuery(const std::string &res, unsigned int ttl) : data(res) - { - expires = time(NULL) + ttl; - } + CachedQuery(const std::string &res, unsigned int ttl); /** Returns the number of seconds remaining before this * cache item has expired and should be removed. */ - int CalcTTLRemaining() - { - int n = (int)expires - (int)time(NULL); - return (n < 0 ? 0 : n); - } + int CalcTTLRemaining(); }; /** DNS cache information. Holds IPs mapped to hostnames, and hostnames mapped to IPs. diff --git a/include/inspircd.h b/include/inspircd.h index 3d1abdee4..89f0a08ee 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -52,6 +52,7 @@ #include <map> #include <bitset> #include <set> +#include <time.h> #include "inspircd_config.h" #include "inspircd_version.h" #include "typedefs.h" @@ -222,7 +223,7 @@ class serverstats timeval LastCPU; /** Time last sample was read */ - timeval LastSampled; + timespec LastSampled; /** The constructor initializes all the counts to zero */ serverstats() @@ -282,11 +283,7 @@ class CoreExport InspIRCd /** The current time, updated in the mainloop */ - time_t TIME; - - /** The time that was recorded last time around the mainloop - */ - time_t OLDTIME; + struct timespec TIME; /** A 64k buffer used to read socket data into * NOTE: update ValidateNetBufferSize if you change this @@ -446,7 +443,11 @@ class CoreExport InspIRCd * it is much faster than calling time() directly. * @return The current time as an epoch value (time_t) */ - time_t Time(); + inline time_t Time() { return TIME.tv_sec; } + /** The fractional time at the start of this mainloop iteration (nanoseconds) */ + inline long Time_ns() { return TIME.tv_nsec; } + /** Update the current time. Don't call this unless you have reason to do so. */ + void UpdateTime(); /** Bind all ports specified in the configuration file. * @return The number of ports bound without error diff --git a/src/configreader.cpp b/src/configreader.cpp index c62973c89..156168bbe 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -872,7 +872,7 @@ void ConfigReaderThread::Finish() ServerInstance->Res->Rehash(); ServerInstance->ResetMaxBans(); Config->ApplyDisabledCommands(Config->DisabledCommands); - User* user = TheUserUID.empty() ? ServerInstance->FindNick(TheUserUID) : NULL; + User* user = ServerInstance->FindNick(TheUserUID); FOREACH_MOD(I_OnRehash, OnRehash(user)); ServerInstance->BuildISupport(); diff --git a/src/dns.cpp b/src/dns.cpp index ba1e8f2a4..dee83d3ac 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -147,6 +147,17 @@ class RequestTimeout : public Timer } }; +CachedQuery::CachedQuery(const std::string &res, unsigned int ttl) : data(res) +{ + expires = ServerInstance->Time() + ttl; +} + +int CachedQuery::CalcTTLRemaining() +{ + int n = expires - ServerInstance->Time(); + return (n < 0 ? 0 : n); +} + /* Allocate the processing buffer */ DNSRequest::DNSRequest(DNS* dns, int rid, const std::string &original) : dnsobj(dns) { @@ -1035,11 +1046,9 @@ void DNS::CleanResolvers(Module* module) unsigned long DNS::PRNG() { unsigned long val = 0; - timeval n; serverstats* s = ServerInstance->stats; - gettimeofday(&n,NULL); - val = (n.tv_usec ^ (getpid() ^ geteuid()) ^ ((this->currid++)) ^ s->statsAccept) + n.tv_sec; - val = val + (s->statsCollisions ^ s->statsDnsGood) - s->statsDnsBad; - val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv) - ServerInstance->ports.size(); + val = (rand() ^ this->currid++ ^ s->statsAccept) + ServerInstance->Time_ns(); + val += (s->statsCollisions ^ s->statsDnsGood) * s->statsDnsBad; + val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv); return val; } diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 8cead1c87..47f743df2 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -340,7 +340,8 @@ InspIRCd::InspIRCd(int argc, char** argv) : this->ConfigThread = NULL; // Initialise TIME - this->TIME = this->OLDTIME = this->startup_time = time(NULL); + clock_gettime(CLOCK_REALTIME, &TIME); + this->startup_time = TIME.tv_sec; // This must be created first, so other parts of Insp can use it while starting up this->Logs = new LogManager; @@ -375,7 +376,7 @@ InspIRCd::InspIRCd(int argc, char** argv) : this->Config->cmdline.argv = argv; this->Config->cmdline.argc = argc; - srand(this->TIME); + srand(TIME.tv_nsec ^ TIME.tv_sec); struct option longopts[] = { @@ -685,6 +686,11 @@ InspIRCd::InspIRCd(int argc, char** argv) : this->WritePID(Config->PID); } +void InspIRCd::UpdateTime() +{ + clock_gettime(CLOCK_REALTIME, &TIME); +} + int InspIRCd::Run() { /* See if we're supposed to be running the test suite rather than entering the mainloop */ @@ -695,6 +701,9 @@ int InspIRCd::Run() Exit(0); } + UpdateTime(); + time_t OLDTIME = TIME.tv_sec; + while (true) { #ifndef WIN32 @@ -718,53 +727,48 @@ int InspIRCd::Run() ConfigThread = NULL; } - /* time() seems to be a pretty expensive syscall, so avoid calling it too much. - * Once per loop iteration is pleanty. - */ - OLDTIME = TIME; - TIME = time(NULL); + UpdateTime(); /* Run background module timers every few seconds * (the docs say modules shouldnt rely on accurate * timing using this event, so we dont have to * time this exactly). */ - if (TIME != OLDTIME) + if (TIME.tv_sec != OLDTIME) { + OLDTIME = TIME.tv_sec; +#ifndef WIN32 + getrusage(RUSAGE_SELF, &ru); + stats->LastSampled = TIME; + stats->LastCPU = ru.ru_utime; +#else + WindowsIPC->Check(); +#endif + /* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */ - if (TIME < OLDTIME - 2) + if (TIME.tv_sec < OLDTIME - 2) { - SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME); + SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME.tv_sec); } - else if (TIME > OLDTIME + 2) + else if (TIME.tv_sec > OLDTIME + 2) { - SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME - OLDTIME); + SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME.tv_sec - OLDTIME); } - if ((TIME % 3600) == 0) + if ((TIME.tv_sec % 3600) == 0) { this->RehashUsersAndChans(); FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect()); } - Timers->TickTimers(TIME); + Timers->TickTimers(TIME.tv_sec); this->DoBackgroundUserStuff(); - if ((TIME % 5) == 0) + if ((TIME.tv_sec % 5) == 0) { - FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME)); + FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME.tv_sec)); SNO->FlushSnotices(); } -#ifndef WIN32 - /* Same change as in cmd_stats.cpp, use RUSAGE_SELF rather than '0' -- Om */ - if (!getrusage(RUSAGE_SELF, &ru)) - { - gettimeofday(&this->stats->LastSampled, NULL); - this->stats->LastCPU = ru.ru_utime; - } -#else - WindowsIPC->Check(); -#endif } /* Call the socket engine to wait on the active @@ -808,11 +812,6 @@ bool InspIRCd::AllModulesReportReady(LocalUser* user) return (res == MOD_RES_PASSTHRU); } -time_t InspIRCd::Time() -{ - return TIME; -} - void InspIRCd::SetSignal(int signal) { *mysig = signal; diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 4961d724b..18f399bbf 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -128,9 +128,7 @@ void ModuleSpanningTree::DoPingChecks(time_t curtime) * Cancel remote burst mode on any servers which still have it enabled due to latency/lack of data. * This prevents lost REMOTECONNECT notices */ - timeval t; - gettimeofday(&t, NULL); - long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000); + long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); for (server_hash::iterator i = Utils->serverlist.begin(); i != Utils->serverlist.end(); i++) { diff --git a/src/modules/m_spanningtree/pong.cpp b/src/modules/m_spanningtree/pong.cpp index dd82f7d86..9627da8c0 100644 --- a/src/modules/m_spanningtree/pong.cpp +++ b/src/modules/m_spanningtree/pong.cpp @@ -34,9 +34,7 @@ bool TreeSocket::LocalPong(const std::string &prefix, parameterlist ¶ms) if (ServerSource) { ServerSource->SetPingFlag(); - timeval t; - gettimeofday(&t, NULL); - long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000); + long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); ServerSource->rtt = ts - ServerSource->LastPingMsec; } } @@ -61,9 +59,7 @@ bool TreeSocket::LocalPong(const std::string &prefix, parameterlist ¶ms) if (ServerSource) { - timeval t; - gettimeofday(&t, NULL); - long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000); + long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); ServerSource->rtt = ts - ServerSource->LastPingMsec; ServerSource->SetPingFlag(); } diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp index d5c3927f9..00799aa8e 100644 --- a/src/modules/m_spanningtree/treeserver.cpp +++ b/src/modules/m_spanningtree/treeserver.cpp @@ -59,9 +59,7 @@ TreeServer::TreeServer(SpanningTreeUtilities* Util, std::string Name, std::strin Warned = false; rtt = 0; - timeval t; - gettimeofday(&t, NULL); - long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000); + long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); this->StartBurst = ts; ServerInstance->Logs->Log("m_spanningtree",DEBUG, "Started bursting at time %lu", ts); @@ -142,9 +140,7 @@ void TreeServer::FinishBurst() { FinishBurstInternal(); ServerInstance->XLines->ApplyLines(); - timeval t; - gettimeofday(&t, NULL); - long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000); + long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); unsigned long bursttime = ts - this->StartBurst; ServerInstance->SNO->WriteToSnoMask(Parent == Utils->TreeRoot ? 'l' : 'L', "Received end of netburst from \2%s\2 (burst time: %lu %s)", ServerName.c_str(), (bursttime > 10000 ? bursttime / 1000 : bursttime), (bursttime > 10000 ? "secs" : "msecs")); diff --git a/src/modules/m_spanningtree/treeserver.h b/src/modules/m_spanningtree/treeserver.h index 9520506ae..079b6535e 100644 --- a/src/modules/m_spanningtree/treeserver.h +++ b/src/modules/m_spanningtree/treeserver.h @@ -109,7 +109,7 @@ class TreeServer : public classbase */ time_t NextPingTime(); - /** Last ping time in microseconds, used to calculate round trip time + /** Last ping time in milliseconds, used to calculate round trip time */ unsigned long LastPingMsec; diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 11fa72072..96c3922f9 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -187,6 +187,7 @@ int EPollEngine::DispatchEvents() socklen_t codesize = sizeof(int); int errcode; int i = epoll_wait(EngineHandle, events, GetMaxFds() - 1, 1000); + ServerInstance->UpdateTime(); TotalEvents += i; diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index ca909ce3e..e7d7e4283 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -217,6 +217,7 @@ int KQueueEngine::DispatchEvents() ts.tv_sec = 1; int i = kevent(EngineHandle, NULL, 0, &ke_list[0], GetMaxFds(), &ts); + ServerInstance->UpdateTime(); TotalEvents += i; diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp index f30cd1fed..93463aea7 100644 --- a/src/socketengines/socketengine_poll.cpp +++ b/src/socketengines/socketengine_poll.cpp @@ -235,6 +235,7 @@ int PollEngine::DispatchEvents() socklen_t codesize = sizeof(int); int errcode; int processed = 0; + ServerInstance->UpdateTime(); if (i > 0) { diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index 43d958173..23a3c3a45 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -167,6 +167,7 @@ int PortsEngine::DispatchEvents() unsigned int nget = 1; // used to denote a retrieve request. int i = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time); + ServerInstance->UpdateTime(); // first handle an error condition if (i == -1) diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index 7bff4ff6d..795e844e6 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -119,6 +119,7 @@ int SelectEngine::DispatchEvents() tval.tv_usec = 0; sresult = select(FD_SETSIZE, &rfdset, &wfdset, &errfdset, &tval); + ServerInstance->UpdateTime(); /* Nothing to process this time around */ if (sresult < 1) diff --git a/src/stats.cpp b/src/stats.cpp index b295db4a5..b272e0b6b 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -194,11 +194,10 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results) results.push_back(sn+" 249 "+user->nick+" :Swaps: "+ConvToStr(R.ru_nswap)); results.push_back(sn+" 249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw)); - timeval tv; char percent[30]; - gettimeofday(&tv, NULL); - float n_elapsed = ((tv.tv_sec - this->stats->LastSampled.tv_sec) * 1000000 + tv.tv_usec - this->stats->LastSampled.tv_usec); + float n_elapsed = (ServerInstance->Time() - this->stats->LastSampled.tv_sec) * 1000000 + + (ServerInstance->Time_ns() - this->stats->LastSampled.tv_nsec) / 1000; float n_eaten = ((R.ru_utime.tv_sec - this->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - this->stats->LastCPU.tv_usec); float per = (n_eaten / n_elapsed) * 100; diff --git a/src/userprocess.cpp b/src/userprocess.cpp index 75cd8634a..ee9c75bc0 100644 --- a/src/userprocess.cpp +++ b/src/userprocess.cpp @@ -68,7 +68,7 @@ void InspIRCd::DoBackgroundUserStuff() switch (curr->registered) { case REG_ALL: - if (TIME > curr->nping) + if (Time() > curr->nping) { // This user didn't answer the last ping, remove them if (!curr->lastping) @@ -77,14 +77,14 @@ void InspIRCd::DoBackgroundUserStuff() char message[MAXBUF]; snprintf(message, MAXBUF, "Ping timeout: %ld second%s", (long)time, time > 1 ? "s" : ""); curr->lastping = 1; - curr->nping = TIME + curr->MyClass->GetPingTime(); + curr->nping = Time() + curr->MyClass->GetPingTime(); this->Users->QuitUser(curr, message); continue; } curr->Write("PING :%s",this->Config->ServerName.c_str()); curr->lastping = 0; - curr->nping = TIME +curr->MyClass->GetPingTime(); + curr->nping = Time() +curr->MyClass->GetPingTime(); } break; case REG_NICKUSER: @@ -97,7 +97,7 @@ void InspIRCd::DoBackgroundUserStuff() break; } - if (curr->registered != REG_ALL && (TIME > (curr->age + curr->MyClass->GetRegTimeout()))) + if (curr->registered != REG_ALL && (Time() > (curr->age + curr->MyClass->GetRegTimeout()))) { /* * registration timeout -- didnt send USER/NICK/HOST diff --git a/win/inspircd_win32wrapper.cpp b/win/inspircd_win32wrapper.cpp index 8291cd60d..d82c90a61 100644 --- a/win/inspircd_win32wrapper.cpp +++ b/win/inspircd_win32wrapper.cpp @@ -549,14 +549,14 @@ void FindDNS(std::string& server) ServerInstance->Logs->Log("CONFIG",DEFAULT,"<dns:server> set to '%s' as first active resolver in registry.", nameserver.c_str()); } -int gettimeofday(struct timeval * tv, void * tz) +int clock_gettime(int clock, struct timespec * tv) { if(tv == NULL) return -1; DWORD mstime = timeGetTime(); tv->tv_sec = time(NULL); - tv->tv_usec = (mstime - (tv->tv_sec * 1000)) * 1000; + tv->tv_usec = (mstime - (tv->tv_sec * 1000)) * 1000000; return 0; } diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h index 4397d2ad3..3f16280fd 100644 --- a/win/inspircd_win32wrapper.h +++ b/win/inspircd_win32wrapper.h @@ -193,7 +193,8 @@ CoreExport DIR * opendir(const char * path); CoreExport dirent * readdir(DIR * handle); CoreExport void closedir(DIR * handle); -CoreExport int gettimeofday(struct timeval * tv, void * tz); +const int CLOCK_REALTIME = 0; +CoreExport int clock_gettime(int clock, struct timespec * tv); /* Disable these stupid warnings.. */ #pragma warning(disable:4800) |