[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [cdt-dev] DSF executor thread consumes 100% cpu on terminate
|
> -----Original Message-----
> From: cdt-dev-bounces@xxxxxxxxxxx
> [mailto:cdt-dev-bounces@xxxxxxxxxxx] On Behalf Of Dave Korn
> Sent: Sunday, October 14, 2012 8:35 AM
> To: CDT General developers list.
> Subject: Re: [cdt-dev] DSF executor thread consumes 100% cpu
> on terminate
>
> On 13/10/2012 19:45, Dave Korn wrote:
> > Hi list,
> >
> > I've got a lightly-customised DSF-GDB (based on Helios
> and CDT 7.0.0) and
> > I'm seeing very strange behaviour when I click on the
> terminate button: for
> > anywhere between 10 and 30 seconds, the DSF executor thread
> goes bananas,
> > spinning wildly and hogging 100% cpu.
>
> I think I've figured it out, and AFAICT it should occur to everyone
> everywhere who terminates a debug session within the first 30
> seconds, before ...
>
> 211,390 DSF execution #807. Executor is (org.eclipse.cdt.dsf.gdb - 3)
> Executable detail:
> type = java.lang.Object
> instance =
> org.eclipse.cdt.dsf.gdb.service.GDBBackend$GDBProcessStep$3@1c9c38d
> submitted by #26 at:
> org.eclipse.cdt.dsf.gdb.service.GDBBackend$GDBProcessStep.init
> ialize(GDBBackend.java:552)
> org.eclipse.cdt.dsf.gdb.service.command.GDBControl$Initializat
> ionShutdownStep.execute(GDBControl.java:491)
> org.eclipse.cdt.dsf.concurrent.Sequence.executeStep(Sequence.java:443)
>
>
> ... this step executes. That, IIUC, is the 30-second timeout
> to make sure
> that GDB started running correctly.
More info on this here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=382496#c4
BTW I run jdk1.6.0_22 on Linux and I don't see my CPU go to 100%.
Maybe a different version of java will fix things for you?
Marc
>
> The actual problem is caused by (what I consider to be) a
> design flaw in the
> Java 1.6 ThreadPoolExecutor class. If there are scheduled
> tasks left on the
> queue when the thread enters the SHUTDOWN state,
> ThreadPoolExecutor.getTask
> busy loops waiting for them to come ready:
>
> Runnable getTask() {
> for (;;) {
> try {
> int state = runState;
> if (state > SHUTDOWN)
> return null;
> Runnable r;
> if (state == SHUTDOWN) // Help drain queue
> r = workQueue.poll();
> else if (poolSize > corePoolSize ||
> allowCoreThreadTimeOut)
> r = workQueue.poll(keepAliveTime,
> TimeUnit.NANOSECONDS);
> else
> r = workQueue.take();
> if (r != null)
> return r;
> if (workerCanExit()) {
> if (runState >= SHUTDOWN) // Wake up others
> interruptIdleWorkers();
> return null;
> }
> // Else retry
> } catch (InterruptedException ie) {
> // On interruption, re-check runState
> }
> }
> }
>
> The comment "Help drain queue" should really read "Help consume all
> available CPU time", because that's what it's going to do
> when there's still a
> task scheduled for some time in the future.
>
> I can see two possible solutions to this problem: one would
> be to change how
> we timeout GDB startup, by scheduling a task say once second
> in the future
> that checks if GDB has started successfully and reschedules
> itself one further
> second in the future if not, up to 30 times until startup
> succeeds or the
> retry count expires.
>
> The other way would be to re-implement
> ScheduledThreadPoolExecutor and
> ThreadPoolExecutor, from which the DefaultDsfExecutor
> inherits, and fix the
> behaviour of getTask to not eat CPU; looking at the GNU Classpath
> implementation, if the thread is shutting down and poll()
> returns null, it
> does a take() instead. That should avoid thrashing the CPU.
>
> Any suggestions for further solutions, or observations on
> advantages or
> disadvantages of the two proposed solutions would be welcome,
> or indeed
> corrections if I've misunderstood or missed anything out, but
> hopefully I'm
> good to go now. Thanks for listening while I think out loud!
>
> cheers,
> DaveK
>
>
> _______________________________________________
> cdt-dev mailing list
> cdt-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/cdt-dev
>