Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

threads.cpp File Reference

#include "xdprof.h"

Include dependency graph for threads.cpp:

Include dependency graph

Go to the source code of this file.

Functions

char* FixNull (char *c)
 Returns "null" if c is null; c otherwise. More...

void ThreadDump (const string &info, ThreadID caller)

Variables

bool HotSpot = false
 provides workaround for threading issue. More...

char* const NullCharPointer = "null"
 The string "null". More...


Function Documentation

char * FixNull ( char * c ) [inline, static]
 

Returns "null" if c is null; c otherwise.

Parameters:
c   the character pointer

Definition at line 45 of file threads.cpp.

Referenced by ThreadInfo::ThreadInfo().

00046 {
00047     return (c == null) ? NullCharPointer : c;
00048 }

void ThreadDump ( const string & info,
ThreadID caller )
 

Definition at line 205 of file threads.cpp.

00206 {
00207     ostringstream output;
00208 
00209     Lock(threads_lock);
00210     Lock(methods_lock);
00211     Lock(output_lock);
00212 
00213     if (ShutdownRequested)
00214     {
00215     unsafe_debug("shutdown in ", "ThreadDump");
00216     Unlock(output_lock);
00217     Unlock(methods_lock);
00218     Unlock(threads_lock);
00219     return;
00220 
00221     }
00222 
00223 //if(false)
00224     CALL(DisableGC());
00225     
00226     ThreadMap::iterator t;
00227     set<ThreadID> SuspendedThreads;
00228 
00229     const char Endl = '\n';
00230 
00231     // suspend all threads
00232     for (t = Threads.begin(); t != Threads.end(); ++t)
00233     {
00234         ThreadID tid = t->first;
00235         jlong status = CALL(GetThreadStatus)(tid);
00236         if ((tid != caller) &&
00237             (
00238             ((status & (~JVMPI_THREAD_INTERRUPTED)) == JVMPI_THREAD_RUNNABLE) 
00239             ||      HotSpot
00240             )
00241             )
00242         {
00243             CALL(SuspendThread)(tid);   
00244             SuspendedThreads.insert(tid);
00245             unsafe_debug("Suspended ", tid);
00246         }
00247         else
00248         {
00249             unsafe_debug(tid, (long)status);
00250         }
00251     }
00252 
00253     unsafe_debug("#threads ", Threads.size());
00254     output << "// start_message; num threads: " << Threads.size() << Endl;
00255     output << Threads.size() << Endl;
00256     const int number_of_frames = 100;
00257 
00258     MethodSet methods_to_send;
00259     JVMPI_CallTrace trace;
00260     JVMPI_CallFrame tframes[number_of_frames];
00261     const JVMPI_CallFrame* f;
00262     for (t = Threads.begin(); t != Threads.end(); ++t)
00263     {
00264         const ThreadInfo& ti = t->second;
00265 
00266         output << "// start_thread " << t->first  << Endl;
00267         output << t->first << Endl; // threadid
00268     
00269         jint thread_status = CALL(GetThreadStatus)(t->first);
00270         output << ti.getShortInfo();
00271         output << ti.getStarted() << Endl;
00272         output << thread_status << Endl;    // thread status
00273 
00274 //      unsafe_debug(t->first, ti.getThreadName(), thread_status);
00275         
00276         trace.frames = tframes;
00277         trace.env_id = t->first;
00278 //assert(false);        
00279         CALL(GetCallTrace)(&trace, number_of_frames);
00280 
00281         unsafe_debug("num frames: ", trace.num_frames);
00282 
00283         output << "// num frames = " << trace.num_frames << Endl;
00284         output << trace.num_frames << Endl;
00285         
00286         // send each frame
00287         for (int i = 0; i < trace.num_frames; i++)
00288         {
00289             //output << "// start frame " << i << Endl;
00290             f = &trace.frames[i];
00291             
00292             output << f->method_id << ' ' << f->lineno << Endl; // send method_id lineno
00293             
00294             methods_to_send.insert(f->method_id);
00295         }
00296 
00297     }
00298 
00299     output << "// sending methods now, count=" << methods_to_send.size() << Endl;
00300     output << methods_to_send.size() << Endl;
00301     ClassSet classes_to_send;
00302     
00303     const MethodInfo * the_method;
00304     //const MethodMap::iterator
00305     MethodMap::iterator m;
00306     const MethodMap::iterator m_end = Methods.end();
00307     MethodMap::iterator mc_end = MethodCache.end(); // look in the cache
00308     const MethodSet::iterator mse =  methods_to_send.end();
00309     for(MethodSet::iterator mi = methods_to_send.begin(); mi != mse; ++mi)
00310     {
00311 
00312         m = MethodCache.find(*mi);
00313         if (m == mc_end)
00314         {
00315             // couldn't find, so load it and cache it
00316             m = Methods.find(*mi);
00317             
00318             //assert(m != Methods.end());
00319             if (m == m_end )
00320             {
00321                 jclassID cid = CALL(GetMethodClass(*mi));
00322                 unsafe_debug("Couldn't find ", *mi, cid);
00323                 unsafe_debug("perf Methods = ", Methods.size());
00324                 output << ends;
00325 //              unsafe_debug("output:: ", output.str());
00326                 
00327                 assert(m != Methods.end());
00328                 CALL(EnableGC());
00329                 Unlock(output_lock);
00330                 Unlock(methods_lock);
00331                 Unlock(threads_lock);
00332                 return;
00333             }       
00334                         
00335             MethodCache.insert(make_pair(*mi, m->second));
00336             mc_end = MethodCache.end();
00337         }
00338         //m = Methods.find(*mi);    //TODO: caching?
00339         assert(m != Methods.end());
00340         the_method = m->second;
00341 
00342         //classid methodid methodname methodsig
00343         output << the_method->getShortInfo() << Endl;
00344         unsafe_debug(the_method->getClassID(), the_method->getShortInfo());
00345         classes_to_send.insert(the_method->getClassID());
00346     }
00347 
00348     output << "// sending classes now, count=" << classes_to_send.size() << Endl;
00349     output << classes_to_send.size() << Endl;
00350     const ClassInfoMap::iterator end = ClassCache.end();
00351     ClassInfoMap::iterator c;
00352     const ClassSet::iterator cse = classes_to_send.end();
00353     for (ClassSet::iterator ci = classes_to_send.begin(); ci != cse; ++ci)
00354     {
00355         c = ClassCache.find(*ci);
00356         if (c == end)
00357         {
00358             c = Classes.find(*ci);
00359             ClassCache.insert(make_pair(*ci, c->second));
00360         }
00361         //c = Classes.find(*ci);    //TODO: caching?
00362         assert(c != Classes.end());
00363         // class_id class_name source_name
00364         //unsafe_debug("ci1", c->second.getShortInfo() );
00365         output << c->second.getShortInfo() << Endl;
00366     }
00367 
00368 
00369     output << "// end_message" << Endl;
00370     output << ends;
00371 
00372     // Restart all suspended threads; in reverse order.
00373     set<ThreadID>::reverse_iterator susIter;
00374     const set<ThreadID>::reverse_iterator stre = SuspendedThreads.rend();
00375     for (susIter = SuspendedThreads.rbegin(); susIter != stre; ++susIter)
00376     {
00377         CALL(ResumeThread(*susIter));
00378         unsafe_debug("Resumed", *susIter);
00379     }
00380 
00381 //if(false)
00382     CALL(EnableGC());
00383     Unlock(output_lock);
00384     Unlock(methods_lock);
00385     Unlock(threads_lock);
00386     //return;
00387     Lock(output_lock);
00388     const int chunk = 1024;
00389     const string s = output.str();
00390     const char* cp = s.c_str();
00391     // send in tiny chunks
00392 
00393 RecordPacket(info.size() + s.size());
00394 
00395     Send(info);
00396 
00397     for (string::size_type p = 0; p < (s.size()/chunk); p++)
00398     {
00399         Send(cp, chunk);
00400         cp += chunk;
00401     }
00402     Send(cp, strlen(cp));
00403     Unlock(output_lock);
00404     
00405     LeaveRelease;
00406     unsafe_debug("perf ", "");
00407     unsafe_debug("perf classes to send count", classes_to_send.size());
00408     unsafe_debug("perf Classes", Classes.size());
00409     unsafe_debug("perf ClassesCache", ClassCache.size());
00410     unsafe_debug("perf methods to send count", methods_to_send.size());
00411     unsafe_debug("perf MethodsCache = ", MethodCache.size());
00412     unsafe_debug("perf Methods = ", Methods.size());
00413 
00414 
00415     
00416     ofstream outtrace("network.txt");
00417     outtrace << info <<  s << endl;
00418 
00419     debug("message", s.size());
00420     debug(s);
00421 
00422 }


Variable Documentation

bool HotSpot = false
 

provides workaround for threading issue.

Definition at line 36 of file threads.cpp.

char *const NullCharPointer = "null" [static]
 

The string "null".

Definition at line 39 of file threads.cpp.


Generated at Sun Jun 24 20:58:08 2001 for xdprof by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001