[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
RE: [dsdp-dd-dev] Is there any need for a multi-Container MIimplementation?
|
Salut Frederic,
I was thinking that for tracking, it would be easier (as you mention)
to use a bug. I opened bug 223386 (because I couldn't find an existing one.)
https://bugs.eclipse.org/bugs/show_bug.cgi?id=223386
It would be very nice if you could attach your patches to that bug.
Thanks
Marc
-----Original Message-----
From: dsdp-dd-dev-bounces@xxxxxxxxxxx
[mailto:dsdp-dd-dev-bounces@xxxxxxxxxxx]On Behalf Of Frederic RISS
Sent: Thursday, March 20, 2008 1:32 PM
To: Device Debugging developer discussions
Subject: Re: [dsdp-dd-dev] Is there any need for a multi-Container
MIimplementation?
Le mardi 18 mars 2008 à 14:09 -0700, Pawel Piech a écrit :
> Marc Khouzam wrote:
> > Daniel is right that the CodeSourcery solution for Ericsson will use a
> > single GDB to handle multiple processes.
> > However, we will also connect to multiple cores (processor boards) as you do.
> > >From what I understand up to now, each of these processor boards, will have
> > its own GDB. Therefore, what you have done will be very applicable to Ericsson.
> >
> >
> I absolutely agree, we need to be able to handle both cases: where the
> multiple containers within a single GDB session and multiple GDB
> sessions. Hopefully we can work out the changes in APIs to support
> both cases, so your patches would be a very good start.
[ I'll be leaving tomorrow till the 1st of April. If you don't here back
from me rapidly, that's why :-)]
OK, here we go. If you prefer me to submit the patches to bugzilla,
please yell. As an example, here's how we modified CommandCache.java to
handle multiple Containers:
-------------------8<--------------------------------------------------
--- vendor/dsf/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java
+++ plugins/dsf/org.eclipse.dd.dsf.debug/src/org/eclipse/dd/dsf/debug/service/command/CommandCache.java
@@ -25,6 +25,7 @@
import org.eclipse.dd.dsf.datamodel.DMContexts;
import org.eclipse.dd.dsf.datamodel.IDMContext;
import org.eclipse.dd.dsf.debug.internal.DsfDebugPlugin;
+import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.dd.dsf.service.IDsfService;
/**
@@ -73,7 +74,7 @@
fCurrentRequestMonitors = new LinkedList<DataRequestMonitor<ICommandResult>>();
fCurrentRequestMonitors.add(rm);
fCoalescedCmd = null;
- fResetCounterStatus = fResetCounter;
+ fResetCounterStatus = getStatus(cmd.getContext()).fResetCounter;
}
public CommandStyle getCommandstyle() { return fCmdStyle; }
@@ -143,9 +144,24 @@
* when back into individual results from this command.
*/
- private boolean fIsTargetAvailable = true;
- private int fResetCounter = 0;
-
+ private class TopLevelContextStatus {
+ boolean fIsTargetAvailable = true;
+ int fResetCounter = 0;
+ }
+ private Map<IDMContext, TopLevelContextStatus> fTopLevelContexts = new HashMap<IDMContext, TopLevelContextStatus>();
+
+ private TopLevelContextStatus getStatus(IDMContext context) {
+ IContainerDMContext dmc = DMContexts.getAncestorOfType(context, IContainerDMContext.class);
+ TopLevelContextStatus status = fTopLevelContexts.get(dmc);
+
+ if (status == null) {
+ status = new TopLevelContextStatus();
+ fTopLevelContexts.put(dmc, status);
+ }
+
+ return status;
+ }
+
private ICommandControl fCommandControl;
private Map<IDMContext, HashMap<CommandInfo, CommandResultInfo>> fCachedContexts = new HashMap<IDMContext, HashMap<CommandInfo, CommandResultInfo>>();
@@ -267,7 +283,7 @@
/*
* Return an error if the target is available anymore.
*/
- if (!fIsTargetAvailable) {
+ if (!getStatus(context).fIsTargetAvailable) {
rm.setStatus(new Status(IStatus.ERROR, DsfDebugPlugin.PLUGIN_ID, IDsfService.INVALID_STATE, "Target not available.", null)); //$NON-NLS-1$
rm.done();
return;
@@ -449,24 +465,16 @@
*
* @param isAvailable Flag indicating whether target can be accessed.
*/
- public void setTargetAvailable(boolean isAvailable) {
- fIsTargetAvailable = isAvailable;
+ public void setTargetAvailable(IDMContext dmc, boolean isAvailable) {
+ getStatus(dmc).fIsTargetAvailable = isAvailable;
}
/**
* Retrieves current flag indicating target availability.
* @see #setTargetAvailable(boolean)
*/
- public boolean isTargetAvailable() {
- return fIsTargetAvailable;
- }
-
- /**
- * Clears the cache data.
- */
- public void reset() {
- fCachedContexts.clear();
- fResetCounter++;
+ public boolean isTargetAvailable(IDMContext dmc) {
+ return getStatus(dmc).fIsTargetAvailable;
}
public void commandRemoved(ICommand<? extends ICommandResult> command) {
@@ -520,14 +528,16 @@
}
}
}
-
+
/**
* Clears the cache entries for given context. Clears the whole cache if
* context parameter is null.
*/
- public void reset(IDMContext dmc) {
+ public void reset(IDMContext dmc) {
+ getStatus(dmc).fResetCounter++;
if (dmc == null) {
fCachedContexts.clear();
+ return;
}
for (Iterator<IDMContext> itr = fCachedContexts.keySet().iterator(); itr.hasNext();) {
IDMContext keyDmc = itr.next();
@@ -535,6 +545,6 @@
itr.remove();
}
}
- }
+ }
}
-------------------8<--------------------------------------------------
And here's how we adapted MIRunControl for this change (of course other
services need similar modifications, this is just to get the idea
through):
-------------------8<--------------------------------------------------
--- vendor/dsf/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java
+++ plugins/dsf/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/MIRunControl.java
@@ -310,7 +310,7 @@
@Override
public void shutdown(final RequestMonitor rm) {
getSession().removeServiceEventListener(this);
- fMICommandCache.reset();
+ fMICommandCache.reset(null);
super.shutdown(rm);
}
@@ -395,20 +395,20 @@
fSuspended = false;
fResumePending = false;
fStateChangeReason = e.getReason();
- fMICommandCache.setTargetAvailable(false);
+ fMICommandCache.setTargetAvailable(e.getDMContext(), false);
//fStateChangeTriggeringContext = e.getTriggeringContext();
if (e.getReason().equals(StateChangeReason.STEP)) {
fStepping = true;
} else {
- fMICommandCache.reset();
+ fMICommandCache.reset(e.getDMContext());
}
}
@DsfServiceEventHandler
public void eventDispatched(ContainerSuspendedEvent e) {
- fMICommandCache.setTargetAvailable(true);
- fMICommandCache.reset();
+ fMICommandCache.setTargetAvailable(e.getDMContext(), true);
+ fMICommandCache.reset(e.getDMContext());
fStateChangeReason = e.getReason();
fStateChangeTriggeringContext = e.getTriggeringContext();
fSuspended = true;
@@ -468,7 +468,7 @@
// Cygwin GDB will accept commands and execute them after the step
// which is not what we want, so mark the target as unavailable
// as soon as we send a resume command.
- fMICommandCache.setTargetAvailable(false);
+ fMICommandCache.setTargetAvailable(context, false);
MIExecContinue cmd = null;
if(context instanceof IContainerDMContext)
cmd = new MIExecContinue(context);
@@ -550,7 +550,7 @@
fResumePending = true;
fStepping = true;
- fMICommandCache.setTargetAvailable(false);
+ fMICommandCache.setTargetAvailable(context, false);
switch(stepType) {
case STEP_INTO:
fConnection.queueCommand(
@@ -650,7 +650,7 @@
if (canResume(context)) {
fResumePending = true;
- fMICommandCache.setTargetAvailable(false);
+ fMICommandCache.setTargetAvailable(context, false);
fConnection.queueCommand(new MIExecUntil(dmc, fileName + ":" + lineNo), //$NON-NLS-1$
new DataRequestMonitor<MIInfo>(
getExecutor(), rm) {
-------------------8<--------------------------------------------------
As you see, this is nearly trivial.
Some services (MIRegisters, MIStack, ...) have been modified in a way
similar to CommandCache in order to store per-Container state.
There're 2 dowsides I can see to this approach:
- IContainerDMContext is hard-coded as the top-level context
- it adds HashMap lookups to some code paths
So, what do you think?
Cheers,
Fred
_______________________________________________
dsdp-dd-dev mailing list
dsdp-dd-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/dsdp-dd-dev