#include "global.h"
#include "types.h"
Include dependency graph for threads.h:
This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Compounds | |
class | ClassInfo |
class | MethodInfo |
class | ThreadInfo |
Functions | |
void | ThreadDump (const string &info, ThreadID caller) |
Variables | |
bool | HotSpot |
provides workaround for threading issue. More... |
|
Definition at line 205 of file threads.cpp. Referenced by BackgroundThread().
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 } |
|
provides workaround for threading issue.
|