From: Bert Hubert Date: Wed, 1 Dec 2010 15:55:46 +0000 (+0000) Subject: add max-mthread-stack metric to measure maximum mthread stack usage - 34 kilobytes... X-Git-Tag: rec-3.3.1~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec6eacbc7b2dd5358b9f43bb456ad047e686f3eb;p=pdns add max-mthread-stack metric to measure maximum mthread stack usage - 34 kilobytes appears to be the maximum on x86-64 right now git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1745 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index 30db35b6b..0ccd7385f 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -192,6 +192,9 @@ templateint MTasker::waitEven if(val && d_waitstatus==Answer) *val=d_waitval; d_tid=w.tid; + if((char*)&w < d_threads[d_tid].highestStackSeen) { + d_threads[d_tid].highestStackSeen = (char*)&w; + } key=d_eventkey; return d_waitstatus; } @@ -202,7 +205,7 @@ templateint MTasker::waitEven templatevoid MTasker::yield() { d_runQueue.push(d_tid); - if(swapcontext(d_threads[d_tid] ,&d_kernel) < 0) { // give control to the kernel + if(swapcontext(d_threads[d_tid].context ,&d_kernel) < 0) { // give control to the kernel perror("swapcontext in yield"); exit(EXIT_FAILURE); } @@ -271,7 +274,7 @@ templatevoid MTasker::makeThread(tfunc_t *start, makecontext (uc, (void (*)(void))threadWrapper, 6, thispair.first, thispair.second, start, d_maxtid, valpair.first, valpair.second); - d_threads[d_maxtid]=uc; + d_threads[d_maxtid].context = uc; d_runQueue.push(d_maxtid++); // will run at next schedule invocation } @@ -290,7 +293,7 @@ templatebool MTasker::schedule(struct timeval* n { if(!d_runQueue.empty()) { d_tid=d_runQueue.front(); - if(swapcontext(&d_kernel, d_threads[d_tid])) { + if(swapcontext(&d_kernel, d_threads[d_tid].context)) { perror("swapcontext in schedule"); exit(EXIT_FAILURE); } @@ -299,8 +302,8 @@ templatebool MTasker::schedule(struct timeval* n return true; } if(!d_zombiesQueue.empty()) { - delete[] (char *)d_threads[d_zombiesQueue.front()]->uc_stack.ss_sp; - delete d_threads[d_zombiesQueue.front()]; + delete[] (char *)d_threads[d_zombiesQueue.front()].context->uc_stack.ss_sp; + delete d_threads[d_zombiesQueue.front()].context; d_threads.erase(d_zombiesQueue.front()); d_zombiesQueue.pop(); return true; @@ -369,11 +372,11 @@ templatevoid MTasker::getEvents(std::vector& } } - templatevoid MTasker::threadWrapper(uint32_t self1, uint32_t self2, tfunc_t *tf, int tid, uint32_t val1, uint32_t val2) { void* val = joinPtr(val1, val2); MTasker* self = (MTasker*) joinPtr(self1, self2); + self->d_threads[self->d_tid].startOfStack = self->d_threads[self->d_tid].highestStackSeen = (char*)&val; (*tf)(val); self->d_zombiesQueue.push(tid); @@ -388,3 +391,10 @@ templateint MTasker::getTid() { return d_tid; } + + +//! Returns the maximum stack usage so far of this MThread +templateunsigned int MTasker::getMaxStackUsage() +{ + return d_threads[d_tid].startOfStack - d_threads[d_tid].highestStackSeen; +} diff --git a/pdns/mtasker.hh b/pdns/mtasker.hh index 97354c903..226dbbf20 100644 --- a/pdns/mtasker.hh +++ b/pdns/mtasker.hh @@ -50,8 +50,14 @@ private: std::queue d_runQueue; std::queue d_zombiesQueue; + struct ThreadInfo + { + ucontext_t* context; + char* startOfStack; + char* highestStackSeen; + }; - typedef std::map mthreads_t; + typedef std::map mthreads_t; mthreads_t d_threads; int d_tid; int d_maxtid; @@ -66,7 +72,7 @@ public: EventKey key; ucontext_t *context; struct timeval ttd; - int tid; + int tid; }; typedef multi_index_container< @@ -99,6 +105,7 @@ public: bool noProcesses(); unsigned int numProcesses(); int getTid(); + unsigned int getMaxStackUsage(); private: static void threadWrapper(uint32_t self1, uint32_t self2, tfunc_t *tf, int tid, uint32_t val1, uint32_t val2); diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 537ee7bca..f6c2c015a 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -653,6 +653,8 @@ void startDoResolve(void *p) catch(...) { L<getMaxStackUsage(), g_stats.maxMThreadStackUsage); } void makeControlChannelSocket() diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index 077e4ab3d..8f196cc28 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -400,6 +400,7 @@ RecursorControlParser::RecursorControlParser() addGetStat("over-capacity-drops", &g_stats.overCapacityDrops); addGetStat("no-packet-error", &g_stats.noPacketError); addGetStat("dlg-only-drops", &SyncRes::s_nodelegated); + addGetStat("max-mthread-stack", &g_stats.maxMThreadStackUsage); addGetStat("negcache-entries", boost::bind(getNegCacheSize)); addGetStat("throttle-entries", boost::bind(getThrottleSize)); diff --git a/pdns/syncres.hh b/pdns/syncres.hh index e3249d209..a1e5d2a9c 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -477,6 +477,7 @@ struct RecursorStats uint64_t packetCacheHits; uint64_t noPacketError; time_t startupTime; + unsigned int maxMThreadStackUsage; }; //! represents a running TCP/IP client session