#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.
|
1.2.8.1 written by Dimitri van Heesch,
© 1997-2001