Skip to main content

[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

Back to the top