mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
[179102] Re-aligned plugin and package names to confirm with Eclipse policy.
This commit is contained in:
parent
a12a4967e3
commit
65ce6ccf37
22 changed files with 2099 additions and 0 deletions
7
plugins/org.eclipse.dd.doc.dsf/.cvsignore
Normal file
7
plugins/org.eclipse.dd.doc.dsf/.cvsignore
Normal file
|
@ -0,0 +1,7 @@
|
|||
+index
|
||||
+javadoc.link.location
|
||||
+reference
|
||||
+build.xml
|
||||
+org.eclipse.dd.dsf.doc_1.0.0.jar
|
||||
+temp.convert.txt
|
||||
+temp.options.txt
|
22
plugins/org.eclipse.dd.doc.dsf/.project
Normal file
22
plugins/org.eclipse.dd.doc.dsf/.project
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.dd.doc.dsf</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
8
plugins/org.eclipse.dd.doc.dsf/META-INF/MANIFEST.MF
Normal file
8
plugins/org.eclipse.dd.doc.dsf/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,8 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Debug Services Framework Documentation
|
||||
Bundle-Vendor: Eclipse.org
|
||||
Bundle-SymbolicName: org.eclipse.dd.doc.dsf;singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Localization: plugin
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
28
plugins/org.eclipse.dd.doc.dsf/about.html
Normal file
28
plugins/org.eclipse.dd.doc.dsf/about.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body lang="EN-US">
|
||||
<h2>About This Content</h2>
|
||||
|
||||
<p>June 5, 2007</p>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
|
||||
indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
|
||||
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||
|
||||
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
|
||||
being redistributed by another party ("Redistributor") and different terms and conditions may
|
||||
apply to your use of any object code in the Content. Check the Redistributor's license that was
|
||||
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
|
||||
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
|
||||
and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
1
plugins/org.eclipse.dd.doc.dsf/book.css
Normal file
1
plugins/org.eclipse.dd.doc.dsf/book.css
Normal file
|
@ -0,0 +1 @@
|
|||
@import "../PRODUCT_PLUGIN/book.css";
|
21
plugins/org.eclipse.dd.doc.dsf/build.properties
Normal file
21
plugins/org.eclipse.dd.doc.dsf/build.properties
Normal file
|
@ -0,0 +1,21 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2000, 2006 IBM Corporation and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Wind River Systems, Inc. - initial API and implementation
|
||||
###############################################################################
|
||||
bin.includes = META-INF/,\
|
||||
about.html,\
|
||||
notices.html,\
|
||||
plugin.properties,\
|
||||
plugin.xml,\
|
||||
toc.xml,\
|
||||
docs/,\
|
||||
book.css,\
|
||||
schema.css
|
||||
customBuildCallbacks = customBuildCallbacks.xml
|
||||
|
141
plugins/org.eclipse.dd.doc.dsf/buildDoc.xml
Normal file
141
plugins/org.eclipse.dd.doc.dsf/buildDoc.xml
Normal file
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="DSF Doc Build" default="all" basedir=".">
|
||||
|
||||
<property name="javadoc.link.location" value="${basedir}/javadoc.link.location"/>
|
||||
|
||||
<target name="init">
|
||||
<available file="${basedir}/index" property="index.present" />
|
||||
<path id="path_bootclasspath">
|
||||
<fileset dir="${java.home}/lib">
|
||||
<include name="*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
<property name="bootclasspath" refid="path_bootclasspath"/>
|
||||
<condition property="safeBaseLocation"
|
||||
value="${baseLocation}"
|
||||
else="${eclipse.home}">
|
||||
<isset property="baseLocation"/>
|
||||
</condition>
|
||||
<delete dir="${javadoc.link.location}" />
|
||||
</target>
|
||||
|
||||
<target name="computeClasspath" unless="javadoc.classpath">
|
||||
<!-- Construct the javadoc classpath and store it in a property. -->
|
||||
<echo level="info" message="Computing classpath ..."/>
|
||||
<!-- Add platform dependencies required by your plug-in here.
|
||||
Note that this pattern expects Eclipse to have
|
||||
been installed into the platform directory structure, as is
|
||||
the case during the build. -->
|
||||
<patternset id="platform.classpath.pattern">
|
||||
<include name="**/org.eclipse.ui*.jar"/>
|
||||
<include name="**/org.eclipse.ui*/**/*.jar"/>
|
||||
<include name="**/org.eclipse.core*.jar"/>
|
||||
<include name="**/org.eclipse.debug.core*.jar"/>
|
||||
<include name="**/org.eclipse.equinox*.jar"/>
|
||||
<include name="**/org.eclipse.equinox*/**/*.jar"/>
|
||||
<include name="**/org.eclipse.core*/**/*.jar"/>
|
||||
<include name="**/org.eclipse.debug.ui*.jar"/>
|
||||
<include name="**/org.eclipse.swt*.jar"/>
|
||||
<include name="**/org.eclipse.swt*/**/*.jar"/>
|
||||
<include name="**/org.eclipse.osgi*.jar"/>
|
||||
<include name="**/org.eclipse.osgi*/**/*.jar"/>
|
||||
<include name="**/org.eclipse.jface*.jar"/>
|
||||
<include name="**/org.eclipse.jface*/**/*.jar"/>
|
||||
<include name="**/org.junit*.jar"/>
|
||||
<include name="**/org.junit*/**/*.jar"/>
|
||||
</patternset>
|
||||
<pathconvert property="javadoc.classpath">
|
||||
<path>
|
||||
<fileset dir="${safeBaseLocation}">
|
||||
<patternset refid="platform.classpath.pattern"/>
|
||||
</fileset>
|
||||
</path>
|
||||
</pathconvert>
|
||||
<echo level="info" message="Done computing classpath."/>
|
||||
<echo level="debug" message="Bootclasspath is: ${bootclasspath}"/>
|
||||
<echo level="debug" message="Classpath is: ${javadoc.classpath}"/>
|
||||
</target>
|
||||
|
||||
<target name="extractLinks">
|
||||
<mkdir dir="${javadoc.link.location}"/>
|
||||
<patternset id="package.list">
|
||||
<include name="**/package-list"/>
|
||||
</patternset>
|
||||
<!-- We only need the package-list files out of these -->
|
||||
<echo message="${javadoc.link.location}"/>
|
||||
<echo message="${safeBaseLocation}"/>
|
||||
<unzip dest="${javadoc.link.location}/platform/">
|
||||
<patternset refid="package.list"/>
|
||||
<fileset dir="${safeBaseLocation}/plugins">
|
||||
<include name="org.eclipse.dd.dsf.doc.jar"/>
|
||||
</fileset>
|
||||
</unzip>
|
||||
</target>
|
||||
|
||||
<target name="all" depends="init" unless="index.present">
|
||||
<antcall target="convertSchemaToHtml" />
|
||||
<antcall target="generateJavadoc" />
|
||||
<antcall target="build.index" />
|
||||
</target>
|
||||
|
||||
<target name="build.index" description="Builds search index for the plug-in: org.eclipse.dd.dsf.doc" if="eclipse.running">
|
||||
<help.buildHelpIndex manifest="${basedir}/plugin.xml" destination="${basedir}" />
|
||||
</target>
|
||||
|
||||
<target name="convertSchemaToHtml" if="eclipse.running">
|
||||
<property name="dest" value="reference/extension-points" />
|
||||
<record name="${basedir}/temp.convert.txt" action="start" />
|
||||
<pde.convertSchemaToHTML manifest="../org.eclipse.dd.dsf/plugin.xml" destination="${dest}" />
|
||||
<pde.convertSchemaToHTML manifest="../org.eclipse.dd.dsf.examples/plugin.xml" destination="${dest}" />
|
||||
<pde.convertSchemaToHTML manifest="../org.eclipse.dd.dsf.examples/plugin.xml" destination="${dest}" />
|
||||
<record name="${basedir}/temp.convert.txt" action="stop" />
|
||||
</target>
|
||||
|
||||
<target name="getJavadocPath">
|
||||
<available file="${java.home}/../bin/javadoc.exe" property="javadoc" value="${java.home}/../bin/javadoc.exe" />
|
||||
<available file="${java.home}/../bin/javadoc" property="javadoc" value="${java.home}/../bin/javadoc" />
|
||||
<available file="/usr/bin/javadoc" property="javadoc" value="/usr/bin/javadoc" />
|
||||
</target>
|
||||
|
||||
<target name="generateJavadoc" depends="getJavadocPath,extractLinks,computeClasspath" if="javadoc">
|
||||
<property name="optionsFile" value="temp.options.txt" />
|
||||
<copy file="options.txt" tofile="${optionsFile}" overwrite="true" />
|
||||
|
||||
<condition property="argsListDelimiter" value=":">
|
||||
<os family="unix" />
|
||||
</condition>
|
||||
<condition property="argsListDelimiter" value=";">
|
||||
<os family="windows" />
|
||||
</condition>
|
||||
|
||||
<replaceregexp file="${basedir}/${optionsFile}" flags="g" match="(\r\n?|\n);" replace="${argsListDelimiter}" />
|
||||
<replace file="${basedir}/${optionsFile}" token="@rt@" value="${bootclasspath}${argsListDelimiter}${javadoc.classpath}" />
|
||||
<replace file="${basedir}/${optionsFile}" token="@baseLocation@" value="${safeBaseLocation}" />
|
||||
<replace file="${basedir}/${optionsFile}" token="@javadoc.link.location@" value="${javadoc.link.location}" />
|
||||
|
||||
<!--scrub isv plugin directories of any preexisting api doc content-->
|
||||
<delete dir="reference/api" />
|
||||
<mkdir dir="reference/api" />
|
||||
|
||||
<echo message="sep = ${argsListDelimiter}"/>
|
||||
<echo message="javadoc = ${javadoc}"/>
|
||||
<exec dir="." executable="${javadoc}" output="temp.bin.log">
|
||||
<arg line="@${basedir}/${optionsFile} -J-Xmx1000M" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
157
plugins/org.eclipse.dd.doc.dsf/customBuildCallbacks.xml
Normal file
157
plugins/org.eclipse.dd.doc.dsf/customBuildCallbacks.xml
Normal file
|
@ -0,0 +1,157 @@
|
|||
<!-- ===================================================================== -->
|
||||
<!-- Custom targets called from a project's generated build.xml -->
|
||||
<!-- Set customBuildCallbacks=<path/to/this/file> in your build.properties.-->
|
||||
<!-- ===================================================================== -->
|
||||
<project name="Build specific targets and properties" default="noDefault">
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Default target -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="noDefault">
|
||||
<echo message="This file must be called with explicit targets" />
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the target build.jars -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- build.result.folder - folder to contain the build results -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="pre.build.jars">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the target build.jars -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- build.result.folder - folder to contain the build results -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="post.build.jars">
|
||||
<ant antfile="buildDoc.xml" />
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the target build.sources -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- build.result.folder - folder to contain the build results -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="pre.build.sources">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the target build.sources -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- build.result.folder - folder to contain the build results -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="post.build.sources">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the compilation target <name> -->
|
||||
<!-- Substitute "name" with the name of the compilation target, eg @dot -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- source.foldern : n = 1 ... N, the source folders -->
|
||||
<!-- target.folder : where the results of the compilation go -->
|
||||
<!-- <name>.classpath : name = name of the compilation target. A -->
|
||||
<!-- reference to the classpath structure. -->
|
||||
<!-- ===================================================================== -->
|
||||
<!--
|
||||
<target name="pre.compileTarget.jar">
|
||||
</target>
|
||||
-->
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after compilation but before jaring -->
|
||||
<!-- Substitute "name" with the name of the compilation target, eg @dot -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- source.foldern : n = 1 ... N, the source folders -->
|
||||
<!-- target.folder : where the results of the compilation go -->
|
||||
<!-- <name>.classpath : name = name of the compilation target. A -->
|
||||
<!-- reference to the classpath structure. -->
|
||||
<!-- ===================================================================== -->
|
||||
<!--
|
||||
<target name="post.compile.compileTarget.jar">
|
||||
</target>
|
||||
-->
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the compilation target <name> -->
|
||||
<!-- Substitute "name" with the name of the compilation target, eg @dot -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- jar.location - the location of the compilation results -->
|
||||
<!-- <name>.classpath : name = name of the compilation target. A -->
|
||||
<!-- reference to the classpath structure. -->
|
||||
<!-- ===================================================================== -->
|
||||
<!--
|
||||
<target name="post.compileTarget.jar">
|
||||
</target>
|
||||
-->
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the target gather.bin.parts -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- base.dir - root of the project -->
|
||||
<!-- build.result.folder - folder containing the build results -->
|
||||
<!-- target.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="pre.gather.bin.parts">
|
||||
|
||||
</target>
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the target gather.bin.parts -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- base.dir - root of the project -->
|
||||
<!-- build.result.folder - folder containing the build results -->
|
||||
<!-- target.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="post.gather.bin.parts">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the target gather.sources -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- destination.temp.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="pre.gather.sources">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the target gather.sources -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- destination.temp.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="post.gather.sources">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the target gather.logs -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- destination.temp.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="pre.gather.logs">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the target gather.logs -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- destination.temp.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="post.gather.logs">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do before the target clean -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- destination.temp.folder - destination folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="pre.clean">
|
||||
</target>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Steps to do after the target clean -->
|
||||
<!-- Available parameters : -->
|
||||
<!-- plugin.destination - final destination of the build -->
|
||||
<!-- build.result.folder - results of the compilation -->
|
||||
<!-- temp.folder - temporary folder -->
|
||||
<!-- ===================================================================== -->
|
||||
<target name="post.clean">
|
||||
</target>
|
||||
</project>
|
BIN
plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png
Normal file
BIN
plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
432
plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html
Normal file
432
plugins/org.eclipse.dd.doc.dsf/docs/dsf_concurrency_model.html
Normal file
|
@ -0,0 +1,432 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1"
|
||||
http-equiv="content-type">
|
||||
<title>DSF Concurrency Model</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>DSF Concurrency Model</h2>
|
||||
<h3>
|
||||
</h3>
|
||||
<p class="MsoNormal" style="line-height: normal;"><b><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Version
|
||||
1.0<br>
|
||||
Pawel Piech<br>
|
||||
© 2006, Wind River Systems.<span style=""> </span>Release
|
||||
under EPL version 1.0.</span></b><b><span
|
||||
style="font-size: 18pt; font-family: "Times New Roman";"><o:p></o:p></span></b></p>
|
||||
<h3>Introduction</h3>
|
||||
Providing a solution to concurrency problems is the primary design goal
|
||||
of DSF. To that end DSF imposes a rather draconian
|
||||
restriction on services that use it: <span style="font-weight: bold;">1)
|
||||
All service interface methods must be called using a single designated
|
||||
dispatch thread, unless explicitly stated otherwise, 2) The dispatch
|
||||
thread should never be used to make a blocking call (a call that waits
|
||||
on I/O or a call that makes a long-running computation). </span>What
|
||||
the first restriction effectively means, is that the dispatch thread
|
||||
becomes a global "lock" that all DSF services in a given session
|
||||
share with each other, and which controls access to most of services'
|
||||
shared data. It's important to note that <span
|
||||
style="font-weight: bold;">multi-threading is still allowed</span>
|
||||
within individual service implementation. but when crossing the service
|
||||
interface boundaries, only the dispatch thread can be used. The
|
||||
second restriction just ensures that the performance of the whole
|
||||
system is not killed by one service that needs to read a huge file over
|
||||
the network. Another way of looking at it is that the
|
||||
service implementations practice co-operative multi-threading using the
|
||||
single dispatch thread.<br>
|
||||
<br>
|
||||
There are a couple of obvious side effects that result from this rule:<br>
|
||||
<ol>
|
||||
<li>When executing within the dispatch thread, the state of the
|
||||
services is guaranteed not to change. This means that
|
||||
thread-defensive programming techniques, such as making duplicates of
|
||||
lists before iterating over them, are not necessary. Also it's
|
||||
possible to implement much more complicated logic which polls the state
|
||||
of many objects, without the worry about dead-locks.</li>
|
||||
<li>Whenever a blocking operation needs to be performed, it must be
|
||||
done using an asynchronous method. By the time the operation is
|
||||
completed, and the caller regains the dispatch thread, this caller may
|
||||
need to retest the relevant state of the system, because it could
|
||||
change completely while the asynchronous operation was executing.</li>
|
||||
</ol>
|
||||
<h3>The Mechanics</h3>
|
||||
<h4><span style="font-family: monospace;">java.util.concurrent.ExecutorService</span><br>
|
||||
</h4>
|
||||
DSF builds on the vast array of tools added in Java 5.0's
|
||||
java.util.concurrent package (see <a
|
||||
href="http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/index.html">http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/index.html</a>
|
||||
for details), where the most important is the <a
|
||||
style="font-family: monospace;"
|
||||
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html">ExecutorService</a>
|
||||
interface. <span style="font-family: monospace;">ExecutorService
|
||||
</span>is a formal interface for submitting <span
|
||||
style="font-family: monospace;">Runnable</span> objects that will be
|
||||
executed according to executor's rules, which could be to execute the
|
||||
<span style="font-family: monospace;">Runnable </span>immediately,
|
||||
within a thread pool, using a display thread,
|
||||
etc. For DSF, the main rule for executors is that they have
|
||||
to use a single thread to execute the runnable and that the runnables
|
||||
be executed in the order that they were submitted. To give the
|
||||
DSF clients and services a method for checking whether they are
|
||||
being called on the dispatch thread, we extended the <span
|
||||
style="font-family: monospace;">ExecutorService
|
||||
</span>interface as such:<br>
|
||||
<pre>public interface DsfExecutor extends ScheduledExecutorService<br>{<br> /**<br> * Checks if the thread that this method is called in is the same as the<br> * executor's dispatch thread.<br> * @return true if in DSF executor's dispatch thread<br> */<br> public boolean isInExecutorThread();<br>}<br></pre>
|
||||
<h4><a
|
||||
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html"><span
|
||||
style="font-family: monospace;">java.lang.concurrent.Future</span></a>
|
||||
vs <a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/concurrent/Done.html"><span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.concurrent.Done</span></a></h4>
|
||||
The <span style="font-family: monospace;">Done </span>object
|
||||
encapsulates the return value of an asynchronous call in DSF. It
|
||||
is actually merely a <span style="font-family: monospace;">Runnable </span>with
|
||||
an attached <span style="font-family: monospace;">org.eclipse.core.runtime.IStatus</span>
|
||||
object , but it can be extended by the services or clients to hold
|
||||
whatever additional data is needed. Typical pattern in how
|
||||
the <span style="font-family: monospace;">Done </span>object is used,
|
||||
is as follows:<br>
|
||||
<pre>Service:<br> public class Service {<br> void asyncMethod(Done done) {<br> new Job() {<br> public void run() {<br> // perform calculation <br> ... <br> done.setStatus(new Status(IStatus.ERROR, ...));<br> fExecutor.execute(done);<br> }<br> }.schedule();<br> }<br> }<br><br>Client:<br> ...<br> Service service = new Service();<br> final String clientData = "xyz";<br> ...<br> service.asynMethod(new Done() {<br> public void run() {<br> if (getStatus().isOK()) {<br> // Handle return data<br> ...<br> } else {<br> // Handle error<br> ...<br> }<br> }<br> }<br></pre>
|
||||
The service performs the asynchronous operation a background thread,
|
||||
but
|
||||
it can still submit the <span style="font-family: monospace;">Done </span>runnable
|
||||
with the executor. In other words, the <span
|
||||
style="font-family: monospace;">Done</span> and other runnables can be
|
||||
submitted from any thread, but will always execute in the single
|
||||
dispatch thread. Also if the implementation of the <span
|
||||
style="font-family: monospace;">asyncMethod()</span> is non-blocking,
|
||||
it does not need to start a job, it could just perform the operation in
|
||||
the dispatch thread. On the client side, care has to be taken to
|
||||
save appropriate state before the asynchronous method is called,
|
||||
because by the time the <span style="font-family: monospace;">Done </span>is
|
||||
executed, the client state may change.<br>
|
||||
<br>
|
||||
The <span style="font-family: monospace;">java.lang.concurrent</span>
|
||||
package
|
||||
doesn't already have a <span style="font-family: monospace;">Done</span>,
|
||||
because the generic concurrent
|
||||
package is geared more towards large thread pools, where clients submit
|
||||
tasks to be run in a style similar to Eclipse's Jobs, rather than using
|
||||
the single dispatch thread model of DSF. To this end<span
|
||||
style="font-family: monospace;">,</span> the
|
||||
concurrent package does have an equivalent object, <a
|
||||
style="font-family: monospace;"
|
||||
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html">Future</a>.
|
||||
<span style="font-family: monospace;">Future </span>has methods that
|
||||
allows the client to call the <span style="font-family: monospace;">get()</span>
|
||||
method, and block while waiting for a result, and for this reason it
|
||||
cannot
|
||||
be used from the dispatch thread. But it can be used, in a
|
||||
limited way, by clients which are running on background thread that
|
||||
still
|
||||
need to retrieve data from <span style="text-decoration: underline;">synchronous</span>
|
||||
DSF methods. In this case the code might look like the
|
||||
following:<br>
|
||||
<pre>Service:<br> public class Service {<br> int syncMethod() {<br> // perform calculation<br> ...<br> return result;<br> }<br> }<br><br>Client:<br> ...<br> DsfExecutor executor = new DsfExecutor();<br> final Service service = new Service(executor);<br> Future<Integer> future = executor.submit(new Callable<Integer>() {<br> Integer call() {<br> return service.syncMethod();<br> }<br> });<br> int result = future.get();<br></pre>
|
||||
The biggest drawback to using <span style="font-family: monospace;">Future
|
||||
</span>with DSF services, is that it does not work with
|
||||
asynchronous methods. This is because the <a
|
||||
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Callable.html#call%28%29"><span
|
||||
style="font-family: monospace;">Callable.call()</span></a>
|
||||
implementation
|
||||
has to return a value within a single dispatch cycle. To get
|
||||
around this, DSF has an additional object called <span
|
||||
style="font-family: monospace;">DsfQuery</span>, which works like a <span
|
||||
style="font-family: monospace;">Future </span>combined with a <span
|
||||
style="font-family: monospace;">Callable</span>, but allows the
|
||||
implementation to make multiple dispatches before setting the return
|
||||
value to the client. The <span style="font-family: monospace;">DsfQuery<span
|
||||
style="font-family: monospace;"> object works as follows:<br>
|
||||
</span></span>
|
||||
<ol>
|
||||
<li>Client creates the query object with its own implementation of <span
|
||||
style="font-family: monospace;">DsfQuery.execute()</span>.<br>
|
||||
</li>
|
||||
<li>Client calls the <span style="font-family: monospace;">DsfQuery.get()</span>
|
||||
method on non-dispatch thread, and blocks.</li>
|
||||
<li>The query is queued with the executor, and eventually the <span
|
||||
style="font-family: monospace;">DsfQuery.execute()</span> method is
|
||||
called on the dispatch thread.</li>
|
||||
<li>The query <span style="font-family: monospace;">DsfQuery.execute()</span>
|
||||
calls synchronous and asynchronous methods that are needed to do its
|
||||
job.</li>
|
||||
<li>The query code calls <span style="font-family: monospace;">DsfQuery.done()</span>
|
||||
method with the result.</li>
|
||||
<li>The <span style="font-family: monospace;">DsfQuery.get()</span>
|
||||
method un-blocks and returns the result to the client.<br>
|
||||
</li>
|
||||
</ol>
|
||||
<h3><a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/examples/concurrent/package-summary.html">Slow
|
||||
Data Provider Example</a></h3>
|
||||
The point of DSF concurrency can be most easily explained through
|
||||
a practical example. Suppose there is a viewer which needs to
|
||||
show data that originates from a remote "provider". There is a
|
||||
considerable delay in transmitting the data to and from the provider,
|
||||
and some delay in processing the data. The viewer is a
|
||||
lazy-loading table, which means that it request information only about
|
||||
items that are visible on the screen, and as the table is scrolled, new
|
||||
requests for data are generated. The diagram below illustrates
|
||||
the
|
||||
logical relationship between components:<br>
|
||||
<br>
|
||||
.<img alt="" title="Slow Data Provider Diagram"
|
||||
src="dsf_concurrency_model-1.png" style="width: 636px; height: 128px;"><br>
|
||||
<p>In detail, these components look like this:<span
|
||||
style="text-decoration: underline;"></span></p>
|
||||
<p><span style="text-decoration: underline;"></span></p>
|
||||
<span style="text-decoration: underline;">Table Viewer</span><br>
|
||||
<p>The table viewer is the standard
|
||||
<span style="font-family: monospace;">org.eclipse.jface.viewers.TableViewer</span>,
|
||||
created with <span style="font-family: monospace;">SWT.VIRTUAL</span>
|
||||
flag. It has an associated content
|
||||
provider, SlowDataProviderContentProvider) which handles all the
|
||||
interactions with the data provider. The lazy content provider
|
||||
operates in a very simple cycle:</p>
|
||||
<ol>
|
||||
<li>Table viewer tells content provider that the input has changed by
|
||||
calling <span style="font-family: monospace;">IContentProvider.inputChanged()</span>.
|
||||
This means that the content provider has to query initial state of the
|
||||
data.</li>
|
||||
<li>Next the content provider tells the viewer how many elements
|
||||
there are, by calling <span style="font-family: monospace;">TableViewer.setItemCount()</span>.</li>
|
||||
<li>At this point, the table resizes, and it requests data values for
|
||||
items that are visible. So for each visible item it calls: <span
|
||||
style="font-family: monospace;">ILazyContentProvider.updateElement()</span>.</li>
|
||||
<li>After calculating the value, the content provider tells the table
|
||||
what the value is, by calling <span style="font-family: monospace;">TableViewer.replace().</span></li>
|
||||
<li>If the data ever changes, the content provider tells the table to
|
||||
rerequest the data, by calling <span style="font-family: monospace;">TableViewer.clear()</span>.</li>
|
||||
</ol>
|
||||
Table viewer operates in the
|
||||
SWT display thread, which means that the content provider must switch
|
||||
from the display thread to the DSF dispatch thread, whenever it is
|
||||
called by the table viewer, as in the example below:<br>
|
||||
<pre> public void updateElement(final int index) {<br> assert fTableViewer != null;<br> if (fDataProvider == null) return;<br><br> fDataProvider.getExecutor().execute(<br> new Runnable() { public void run() {<br> // Must check again, in case disposed while redispatching.<br> if (fDataProvider == null) return;<br> <br> queryItemData(index);<br> }});<br> }<br></pre>
|
||||
Likewise, when the content provider calls the table viewer, it also has
|
||||
to switch back into the display thread as in following example, when
|
||||
the content provider receives an event from the data provider, that an
|
||||
item value has changed.<br>
|
||||
<pre> public void dataChanged(final Set<Integer> indexes) {<br> // Check for dispose.<br> if (fDataProvider == null) return;<br><br> // Clear changed items in table viewer.<br> if (fTableViewer != null) {<br> final TableViewer tableViewer = fTableViewer;<br> tableViewer.getTable().getDisplay().asyncExec(<br> new Runnable() { public void run() {<br> // Check again if table wasn't disposed when <br> // switching to the display thread.<br> if (tableViewer.getTable().isDisposed()) return; // disposed<br> for (Integer index : indexes) {<br> tableViewer.clear(index);<br> }<br> }});<br> }<br> }<br></pre>
|
||||
All of this switching back and forth between threads makes the code
|
||||
look a lot more complicated than it really is, and it takes some
|
||||
getting used to, but this is the price to be paid for multi-threading.
|
||||
Whether the participants use semaphores or the dispatch thread, the
|
||||
logic is equally complicated, and we believe that using a single
|
||||
dispatch thread, makes the synchronization very explicit and thus less
|
||||
error-prone.<br>
|
||||
<p><span style="text-decoration: underline;">Data Provider Service</span></p>
|
||||
<p>The data provider service interface, <span
|
||||
style="font-family: monospace;">DataProvider</span>, is very similar
|
||||
to that of the lazy content provider. It has methods to: </p>
|
||||
<ul>
|
||||
<li>get item count</li>
|
||||
<li>get a value for given item</li>
|
||||
<li>register as listener for changes in data count and data values</li>
|
||||
</ul>
|
||||
But this is a DSF interface, and all methods must be called on the
|
||||
service's dispatch thread. For this reason, the <span
|
||||
style="font-family: monospace;">DataProvider </span>interface returns
|
||||
an instance of <span style="font-family: monospace;">DsfExecutor</span>,
|
||||
which must be used with the interface.<br>
|
||||
<p><span style="text-decoration: underline;">Slow Data Provider</span></p>
|
||||
<p>The data provider is actually implemented as a thread which is an
|
||||
inner class of <span style="font-family: monospace;">SlowDataProvider</span>
|
||||
service. The provider thread
|
||||
communicates with the service by reading Request objects from a shared
|
||||
queue, and by posting Runnable objects directly to the <span
|
||||
style="font-family: monospace;">DsfExecutor</span> but
|
||||
with a simulated transmission delay. Separately, an additional
|
||||
flag is also used to control the shutdown of the provider thread.</p>
|
||||
To simulate a real back end, the data provider randomly invalidates a
|
||||
set of items and notifies the listeners to update themselves. It
|
||||
also periodically invalidates the whole table and forces the clients to
|
||||
requery all items.<br>
|
||||
<h4>Data and Control Flow<br>
|
||||
</h4>
|
||||
This can be described in following steps:<br>
|
||||
<ol>
|
||||
<li>The table viewer requests data for an item at a given index (<span
|
||||
style="font-family: monospace;">SlowDataProviderContentProvider.updateElement</span>).<br>
|
||||
</li>
|
||||
<li>The table viewer's content provider executes a <span
|
||||
style="font-family: monospace;">Runnable </span>in the DSF
|
||||
dispatch thread and calls the data provider interface (<span
|
||||
style="font-family: monospace;">SlowDataProviderContentProvider.queryItemData</span>).</li>
|
||||
<li>Data provider service creates a Request object, and files it in a
|
||||
queue (<span style="font-family: monospace;">SlowDataProvider.getItem</span>).</li>
|
||||
<li>Data provider thread de-queues the Request object and acts on it,
|
||||
calculating the value (<span style="font-family: monospace;">ProviderThread.processItemRequest</span>).</li>
|
||||
<li>Data provider thread schedules the calculation result to be
|
||||
posted with DSF executor (<span style="font-family: monospace;">SlowDataProvider.java:185</span>).</li>
|
||||
<li>The Done callback sets the result data in the table viewer (<span
|
||||
style="font-family: monospace;">SlowDataProviderContentProvider.java:167</span>).<br>
|
||||
</li>
|
||||
</ol>
|
||||
<h4>Running the example and full sources</h4>
|
||||
This example is implemented in the <span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.examples</span>
|
||||
plugin, in the <span style="font-family: monospace;">org.eclipse.dd.dsf.examples.concurrent</span>
|
||||
package. <br>
|
||||
<br>
|
||||
To run the example:<br>
|
||||
<ol>
|
||||
<li>Build the test plugin (along with the <span
|
||||
style="font-family: monospace;">org.eclipse.dsdp.DSF plugin</span>)
|
||||
and launch the PDE. <br>
|
||||
</li>
|
||||
<li>Make sure to add the <span style="font-style: italic;">DSF
|
||||
Tests</span> action set to your current perspective.</li>
|
||||
<li>From the main menu, select <span style="font-style: italic;">DSF
|
||||
Tests -> Slow Data Provider</span>.</li>
|
||||
<li>A dialog will open and after a delay it will populate with data.</li>
|
||||
<li>Scroll and resize dialog and observe the update behavior.</li>
|
||||
</ol>
|
||||
<h4>Initial Notes<br>
|
||||
</h4>
|
||||
This example is supposed to be representative of a typical embedded
|
||||
debugger design problem. Embedded debuggers are often slow in
|
||||
retrieving and processing data, and can sometimes be accessed through a
|
||||
relatively slow data channel, such as serial port or JTAG
|
||||
connection. But as such, this basic example presents a couple
|
||||
of major usability problems<br>
|
||||
<ol>
|
||||
<li>The data provider service interface mirrors the table's content
|
||||
provider interface, in that it has a method to retrieve a single piece
|
||||
of data at a time. The result of this is visible to the user as
|
||||
lines of data are filled in one-by-one in the table. However,
|
||||
most debugger back ends are in fact capable of retrieving data in
|
||||
batches and are much more efficient at it than retrieving data items
|
||||
one-by-one.</li>
|
||||
<li>When scrolling quickly through the table, the requests are
|
||||
generated by the table viewer for items which are quickly scrolled out
|
||||
of view, but the service still queues them up and calculates them in
|
||||
the order they were received. As a result, it takes a very long
|
||||
time for the table to be populated with data at the location where the
|
||||
user is looking. <br>
|
||||
</li>
|
||||
</ol>
|
||||
These two problems are very common in creating UI for embedded
|
||||
debugging, and there are common patterns which can be used to solve
|
||||
these problems in DSF services. <br>
|
||||
<h3>Coalescing</h3>
|
||||
Coalescing many single-item requests into fewer multi-item requests is
|
||||
the surest way to improve performance in communication with a remote
|
||||
debugger, although it's not necessarily the simplest. There are
|
||||
two basic patterns in which coalescing is achieved:<br>
|
||||
<ol>
|
||||
<li>The back end provides an interface for retrieving data in large
|
||||
chunks. So when the service implementation receives a request for
|
||||
a single item, it retrieves a whole chunk of data, returns the single
|
||||
item, and stores the rest of the data in a local cache.</li>
|
||||
<li>The back end providers an interface for retrieving data in
|
||||
variable size chunks. When the service implementation receives a
|
||||
request for a single item, it buffers the request, and waits for other
|
||||
requests to come in. After a delay, the service clears the buffer
|
||||
and submits a request for the combined items to the data provider.</li>
|
||||
</ol>
|
||||
In practice, a combination of the two patterns is needed, but for
|
||||
purpose of an example, we implemented the second pattern in the
|
||||
"Input-Coalescing Slow Data Provider" (<span
|
||||
style="font-family: monospace;">InputCoalescingSlowDataProvider.java</span>).
|
||||
<br>
|
||||
<p><span style="text-decoration: underline;">Input Buffer</span></p>
|
||||
<p>The main feature of this pattern is a buffer for holding the
|
||||
requests before sending them to the data provider. In this
|
||||
example the user requests are buffered in two arrays: <span
|
||||
style="font-family: monospace;">fGetItemIndexesBuffer</span> and <span
|
||||
style="font-family: monospace;">fGetItemDonesBuffer</span>. The
|
||||
<span style="font-family: monospace;">DataProvider.getItem()</span>
|
||||
implementation is changed as follows:</p>
|
||||
<pre> public void getItem(final int index, final GetDataDone<String> done) {<br> // Schedule a buffer-servicing call, if one is needed.<br> if (fGetItemIndexesBuffer.isEmpty()) {<br> fExecutor.schedule(<br> new Runnable() { public void run() {<br> fileBufferedRequests();<br> }},<br> COALESCING_DELAY_TIME, <br> TimeUnit.MILLISECONDS);<br> }<br> <br> // Add the call data to the buffer. <br> // Note: it doesn't matter that the items were added to the buffer <br> // after the buffer-servicing request was scheduled. This is because<br> // the buffers are guaranteed not to be modified until this dispatch<br> // cycle is over.<br> fGetItemIndexesBuffer.add(index);<br> fGetItemDonesBuffer.add(done);<br> } <br><br></pre>
|
||||
And method that services the buffer looks like this:<br>
|
||||
<pre> public void fileBufferedRequests() { <br> // Remove a number of getItem() calls from the buffer, and combine them<br> // into a request.<br> int numToCoalesce = Math.min(fGetItemIndexesBuffer.size(), COALESCING_COUNT_LIMIT);<br> final ItemRequest request = new ItemRequest(new Integer[numToCoalesce], new GetDataDone[numToCoalesce]); <br> for (int i = 0; i < numToCoalesce; i++) {<br> request.fIndexes[i] = fGetItemIndexesBuffer.remove(0);<br> request.fDones[i] = fGetItemDonesBuffer.remove(0);<br> }<br><br> // Queue the coalesced request, with the appropriate transmission delay.<br> fQueue.add(request);<br> <br> // If there are still calls left in the buffer, execute another <br> // buffer-servicing call, but without any delay.<br> if (!fGetItemIndexesBuffer.isEmpty()) {<br> fExecutor.execute(new Runnable() { public void run() {<br> fileBufferedRequests();<br> }});<br> }<br> }<br></pre>
|
||||
The most interesting feature of this implementation is the fact that
|
||||
there are no semaphores anywhere to control access to the input
|
||||
buffers. Even though the buffers are serviced with a delay and
|
||||
multiple clients can call the <span style="font-family: monospace;">getItem()</span>
|
||||
method, the use of a single
|
||||
dispatch thread prevents any race conditions that could corrupt the
|
||||
buffer data. In real-world implementations, the buffers and
|
||||
caches that need to be used are far more sophisticated with much more
|
||||
complicated logic, and this is where managing access to them using the
|
||||
dispatch thread is ever more important.<br>
|
||||
<h3>Cancellability</h3>
|
||||
<p><span style="text-decoration: underline;">Table Viewer</span></p>
|
||||
<p><span style="text-decoration: underline;"></span></p>
|
||||
Unlike coalescing, which can be implemented entirely within the
|
||||
service, cancellability requires that the client be modified as well
|
||||
to take advantage of this capability. For the table viewer
|
||||
content provider, this means that additional features have to be
|
||||
added. In <span style="font-family: monospace;">CancellingSlowDataProviderContentProvider.java</span>
|
||||
<span style="font-family: monospace;">ILazyContentProvider.updateElement()</span>
|
||||
was changes as follows:<br>
|
||||
<pre> public void updateElement(final int index) {<br> assert fTableViewer != null;<br> if (fDataProvider == null) return;<br> <br> // Calculate the visible index range.<br> final int topIdx = fTableViewer.getTable().getTopIndex();<br> final int botIdx = topIdx + getVisibleItemCount(topIdx);<br> <br> fCancelCallsPending.incrementAndGet();<br> fDataProvider.getExecutor().execute(<br> new Runnable() { public void run() {<br> // Must check again, in case disposed while redispatching.<br> if (fDataProvider == null || fTableViewer.getTable().isDisposed()) return;<br> if (index >= topIdx && index <= botIdx) {<br> queryItemData(index);<br> }<br> cancelStaleRequests(topIdx, botIdx);<br> }});<br> }<br></pre>
|
||||
Now the client keeps track of the requests it made to the service in <span
|
||||
style="font-family: monospace;">fItemDataDones</span>, and above, <span
|
||||
style="font-family: monospace;">cancelStaleRequests()</span> iterates
|
||||
through all the outstanding requests and cancels the ones that are no
|
||||
longer in the visible range.<br>
|
||||
<p><span style="text-decoration: underline;">Data Provider Service<span
|
||||
style="text-decoration: underline;"></span></span></p>
|
||||
<p><span style="text-decoration: underline;"><span
|
||||
style="text-decoration: underline;"></span></span></p>
|
||||
<p>The data provider implementation
|
||||
(<span style="font-family: monospace;">CancellableInputCoalescingSlowDataProvider.java</span>),
|
||||
builds on top of the
|
||||
coalescing data provider. To make the canceling feature useful,
|
||||
the data provider service has to limit the size of the request
|
||||
queue. This is because in this example which simulates
|
||||
communication with a target and once requests are filed into the
|
||||
request
|
||||
queue, they cannot be canceled, just like a client can't cancel
|
||||
request once it sends them over a socket. So instead, if a flood
|
||||
of <span style="font-family: monospace;">getItem()</span>
|
||||
calls comes in, the service has to hold most of them in the coalescing
|
||||
buffer in case the client decides to cancel them. Therefore the
|
||||
<span style="font-family: monospace;">fileBufferedRequests()</span>
|
||||
method includes a simple check before servicing
|
||||
the buffer, and if the request queue is full, the buffer servicing call
|
||||
is delayed.</p>
|
||||
<pre> if (fQueue.size() >= REQUEST_QUEUE_SIZE_LIMIT) {<br> if (fGetItemIndexesBuffer.isEmpty()) {<br> fExecutor.schedule(<br> new Runnable() { public void run() {<br> fileBufferedRequests();<br> }},<br> REQUEST_BUFFER_FULL_RETRY_DELAY, <br> TimeUnit.MILLISECONDS);<br> }<br> return;<br> } <br></pre>
|
||||
Beyond this change, the only other significant change is that before
|
||||
the requests are queued, they are checked for cancellation.<br>
|
||||
<h3>Final Notes<br>
|
||||
</h3>
|
||||
The example given here is fairly simplistic, and chances are that the
|
||||
same example could be implemented using semaphores and free threading
|
||||
with perhaps fewer lines of code. But what we have found is that
|
||||
as the problem gets bigger, the amount of
|
||||
features in the data provider increases, the state of the
|
||||
communication protocol gets more complicated, and the number of modules
|
||||
needed in the service layer increases, using free threading and
|
||||
semaphores does not safely scale. Using a dispatch thread for
|
||||
synchronization certainly doesn't make the inherent problems of the
|
||||
system less complicated, but it does help eliminate the race conditions
|
||||
and deadlocks from the overall system.<br>
|
||||
<p>Coalescing and Cancellability are both optimizations. Neither
|
||||
of these optimizations affected the original interface of the service,
|
||||
and one of them only needed a service-side modification. But as
|
||||
with all optimizations, it is often better to first make sure that the
|
||||
whole system is working correctly and then add optimizations where they
|
||||
can make the biggest difference in user experience. </p>
|
||||
<p>The above examples of optimizations can take many forms, and as
|
||||
mentioned with coalescing, caching data that is retrieved from the data
|
||||
provider is the most common form of data coalescing. For
|
||||
cancellation, many services in DSF build on top of other services,
|
||||
which means that even a low-level service can cause a higher
|
||||
level service to retrieve data, while another event might cause it to
|
||||
cancel those requests. The perfect example of this is a Variables
|
||||
service, which is responsible for calculating the value of expressions
|
||||
shown in the Variables view. The Variables service reacts to the
|
||||
Run Control service, which issues a suspended event and then requests a
|
||||
set of variables to be evaluated by the debugger back end. But as
|
||||
soon as a resumed event is issued by Run Control, the Variables service
|
||||
needs to cancel the pending evaluation requests.<br>
|
||||
</p>
|
||||
<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
286
plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html
Normal file
286
plugins/org.eclipse.dd.doc.dsf/docs/dsf_data_model.html
Normal file
|
@ -0,0 +1,286 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1"
|
||||
http-equiv="content-type">
|
||||
<title>DSF Data Model</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>DSF Data Model</h2>
|
||||
<b><span style="font-size: 12pt; font-family: "Times New Roman";">Version
|
||||
1.0<br>
|
||||
Pawel Piech<br>
|
||||
© 2006, Wind River Systems.<span style=""> </span>Release
|
||||
under EPL version 1.0.</span></b>
|
||||
<h3>Overview</h3>
|
||||
<p>The data model aspect of DSF is only partially complete as compared
|
||||
to the Concurrency and Services Models. The goals for its design
|
||||
are:<br>
|
||||
</p>
|
||||
<ol>
|
||||
<li><span style="font-style: italic;">Separate the structure of the
|
||||
data in the services from the model used for presentation in views.</span>
|
||||
This seems like a basic model-viewer separation, which is something
|
||||
that we theoretically have already. But in reality the current
|
||||
platform debug model APIs closely correspond to how the data is
|
||||
laid out in debug views, and even with the flexible hierarchy views it
|
||||
is
|
||||
difficult to provide alternative layouts.</li>
|
||||
<li><span style="font-style: italic;">Allow for a modular
|
||||
implementation of services that contribute to the data model.</span>
|
||||
<br>
|
||||
</li>
|
||||
<li><span style="font-style: italic;">Perform well with large
|
||||
data sets.</span></li>
|
||||
<li><span style="font-style: italic;">Make the data model interfaces
|
||||
convenient to use by other services as well as by views.</span>
|
||||
Some interim designs of DSF data model APIs were very well suited for
|
||||
populating views (though asynchronous) content and label provider, but
|
||||
were very difficult to use for other purposes, such as by another
|
||||
service, or a client that creates a dialog. This led to services
|
||||
implementing two sets of interfaces for the same data, which was more
|
||||
expensive to develop and maintain.<br>
|
||||
</li>
|
||||
<li><span style="font-style: italic;">Allow for easy changes to the
|
||||
layout of data in views.</span> This is from the point of view of
|
||||
a debugger implementer that would like to modify the standard layout of
|
||||
debugger data. <br>
|
||||
</li>
|
||||
<li><span style="font-style: italic;">Allow the users to modify the
|
||||
layout of data in views.</span> And this is a logical extension
|
||||
of the previous goal.</li>
|
||||
</ol>
|
||||
<p> </p>
|
||||
That's a pretty ambitious set of goals to keep in mind, which partly
|
||||
explains why the design is not fully complete yet. In particular,
|
||||
the last goal doesn't have any implementation at this point. But
|
||||
other than that the, we believe that our current design mostly
|
||||
meets the other goals. It remains to be seen how well it will
|
||||
hold up
|
||||
beyond a prototype implementation.<br>
|
||||
<p>The DSF data model is divided into two parts: a non-UI part that
|
||||
helps services expose data in a consistent form, and a UI part that
|
||||
helps viewers present the data. They are described separately in
|
||||
the two sections below.<br>
|
||||
</p>
|
||||
<h3>Timers Example</h3>
|
||||
<p>A <a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/examples/timers/package-summary.html">"timers
|
||||
example"</a> is included with the DSF plugins which
|
||||
demonstrates the use of data model and view model
|
||||
APIs. It is probably much easier to digest this document
|
||||
when referring to this example for usage.<br>
|
||||
</p>
|
||||
<h3>Data Model API (<a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/model/package-summary.html"><span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.model</span></a>)<br>
|
||||
</h3>
|
||||
As stated before, the aim of this API is to allow services to provide
|
||||
data with just enough common information, so that it can be easily
|
||||
presented in the view, but with a simple enough design, so that the
|
||||
data can be accessed by non-viewer clients. The type of data in
|
||||
services can vary greatly from service to service, some data for
|
||||
example:<br>
|
||||
<ul>
|
||||
<li>service data might be extremely large and thus may only be
|
||||
retrieved from a back end process in small chunks, while some service
|
||||
data might be always stored locally in the service<br>
|
||||
</li>
|
||||
<li>data might take a very long time to retrieve, or it could be
|
||||
instantaneous<br>
|
||||
</li>
|
||||
<li>some services might support canceling of the request while it is
|
||||
being processed, while other services might not<br>
|
||||
</li>
|
||||
<li>some data may change very frequently, other data may not change
|
||||
at all<br>
|
||||
</li>
|
||||
</ul>
|
||||
The data model API tries to find a common denominator for these
|
||||
divergent properties and imposes the following restrictions:<br>
|
||||
<ol>
|
||||
<li>Each "chunk" of data that comes from a service has a
|
||||
corresponding <span style="font-family: monospace;">IDataModelContext </span>(Data Model Context)
|
||||
object.<br>
|
||||
</li>
|
||||
<li>The DM-Context objects are to be generated by the data model services (<span
|
||||
style="font-family: monospace;">IDataModelService</span>) with either
|
||||
synchronous or asynchronous methods, and taking whatever arguments are
|
||||
needed. Put differently, how DM-Contexts are created is up to the
|
||||
service.</li>
|
||||
<li>The service will provide a method for retrieving each "chunk" of
|
||||
model data (<span style="font-family: monospace;">IDataModelData</span>)
|
||||
using a method that requires no other arguments besides the DM-Contexts.</li>
|
||||
</ol>
|
||||
<h4>DM-Context (<span style="font-family: monospace;">IMContext</span>)<br>
|
||||
</h4>
|
||||
The DM-Contexts are the most
|
||||
important part of this design, so they warrant a closer look. The
|
||||
interface is listed below:<br>
|
||||
<pre> public interface IDataModelContext<V extends IDataModelData> extends IAdaptable {<br> public String getSessionId();<br> public String getServiceFilter();<br> public IDataModelContext[] getParents();<br> }<br></pre>
|
||||
First of all the object extends <span style="font-family: monospace;">IAdaptable</span>,
|
||||
which allows clients to use these objects as handles that are stored
|
||||
with UI components. However the implementation of <span
|
||||
style="font-family: monospace;">IDataModelData.getAdapter()</span>
|
||||
presents a particular challenge. If the standard platform method
|
||||
of retrieving an adapter is used (<span style="font-family: monospace;">PlatformObject.getAdapter()</span>),
|
||||
then there can only be one adapter registered for a given DM-Context class,
|
||||
which has to be shared by all the DSF sessions that are running
|
||||
concurrently. Thus one debugger that implements a <span
|
||||
style="font-family: monospace;">IStack.IFrameDMContext</span>, would have to
|
||||
have the same instance of<span style="font-family: monospace;">
|
||||
IAsynchronousLabelAdapter</span> as another debugger implementation
|
||||
that is running at the same time. To overcome this problem, DSF
|
||||
provides a method for registering adapters with a session using <span
|
||||
style="font-family: monospace;">DsfSession.registerModelAdapter()</span>,
|
||||
instead of with the platform (<span style="font-family: monospace;">Platform.getAdapterManager().registerAdapters()</span>).
|
||||
<br>
|
||||
<p>The <span style="font-family: monospace; font-weight: bold;">getSessionId()</span>
|
||||
method serves two purposes. First, it allows the
|
||||
<span style="font-family: monospace;">IAdapter.getAdapter()</span>
|
||||
implementation to work as described above. Second, it allows clients to
|
||||
access the correct dispatch thread (<span
|
||||
style="font-family: monospace;">DsfSession.getSession(id).getExecutor()</span>)
|
||||
for calling the service that the DM-Context originated from. <br>
|
||||
</p>
|
||||
<p>The <span style="font-family: monospace; font-weight: bold;">getServiceFilter()</span>
|
||||
method is actually included to allow future development. It is
|
||||
intended to allow the client to precisely identify the service that
|
||||
the DM-Context originated from, without having to examine the exact class type
|
||||
of the DM-Context. But this functionality will not really be needed
|
||||
until we start writing generic/data-driven clients.<br>
|
||||
</p>
|
||||
<p>The <span style="font-family: monospace; font-weight: bold;">getParents()</span>
|
||||
method allows the DM-Context to be connected together into something that can
|
||||
be considered a "model". Of course, most debugger data objects,
|
||||
require the context of other objects in order to make sense: stack
|
||||
frame is meaningless without the thread, debug symbols belong to a
|
||||
module, which belongs to a process, etc. In other words, there is
|
||||
some natural hierarchy to the data in debug services which needs to be
|
||||
accessible through the data model APIs. This hierarchy may be the
|
||||
same hierarchy that is to be shown in some debug views, but it doesn't
|
||||
have to be. More importantly, this hierarchy should allow for a
|
||||
clean separation of debug services, and for a clear dependency graph
|
||||
between these services. </p>
|
||||
<h3>View Model API (<a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/ui/model/package-summary.html"><span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.ui.model</span></a>)<br>
|
||||
</h3>
|
||||
This is the component which allows the DSF data model to be presented
|
||||
in
|
||||
the views with different/configurable layouts. It is tightly
|
||||
integrated with the recently added (and still provisional)
|
||||
flexible-hierarchy viewers in the <span style="font-family: monospace;">org.eclipse.debug.ui</span>
|
||||
plugin (see EclipseCon 2006 <a
|
||||
href="http://www.eclipsecon.org/2006/Sub.do?id=31">presentation</a>
|
||||
for more details). Actually, the platform flexible hierarchy
|
||||
framework already provides all the adapter interfaces needed to present
|
||||
the DSF data model in the viewers, and it is possible to do
|
||||
that. However the flexible hierarchy views were not specifically
|
||||
designed for DSF, and there are a few ugly patterns that emerge when
|
||||
using them with DSF data model interfaces directly:<br>
|
||||
<ul>
|
||||
<li>Because of the nature of IAdaptable pattern, the flexible
|
||||
hierarchy label and content adapters have to have a single instance
|
||||
that works for all views that the objects appear in. This leads
|
||||
to a lot of if-else statements, which make the implementation difficult
|
||||
to follow.<br>
|
||||
</li>
|
||||
<li>There is a single adapter for all DSF data model elements in the
|
||||
tree (from the same session), so the adapters have even more if-else
|
||||
statements to handle the different elements in the viewer.</li>
|
||||
<li>Most of DSF adapter work needs to be performed in the dispatch
|
||||
thread, so each handler starts with a re-dispatch call.</li>
|
||||
<li>In all of this, the logic which determines the hierarchy of
|
||||
elements in the viewer is very hard to follow.</li>
|
||||
</ul>
|
||||
The view model API tries to address these issues in the following way:<br>
|
||||
<ol>
|
||||
<li>It divides the adapter work for different views in separate <span
|
||||
style="font-family: monospace;">ViewModelProvider</span> objects.</li>
|
||||
<li>It defines the view layout in an object-oriented manner using the
|
||||
<span style="font-family: monospace;">IViewModelLayoutNode</span>
|
||||
objects.</li>
|
||||
<li>It consolidates the logic of switching to dispatch thread in one
|
||||
place, and allows the <span style="font-family: monospace;">ViewModelProvider</span>
|
||||
objects to work only in dispatch thread.<br>
|
||||
</li>
|
||||
</ol>
|
||||
<h4><span style="font-family: monospace;">IViewModelLayoutNode</span></h4>
|
||||
The core of the logic in this design lies in the implementation of the <span
|
||||
style="font-family: monospace;">IViewModelLayoutNode</span> objects.
|
||||
This interface is listed below:<br>
|
||||
<pre>public interface IViewModelLayoutNode {<br> public IViewModelLayoutNode[] getChildNodes();<br> public void hasElements(IViewModelContext parentVmc, GetDataDone<Boolean> done);<br> public void getElements(final IViewModelContext parentVmc, GetDataDone<IViewModelContext[]> done);<br> public void retrieveLabel(IViewModelContext vmc, final ILabelRequestMonitor result);<br> public boolean hasDeltaFlags(IDataModelEvent e);<br> public void buildDelta(IDataModelEvent e, ViewModelDelta parent, Done done);<br> public void sessionDispose();<br>}<br></pre>
|
||||
The <span style="font-family: monospace; font-weight: bold;">getChildNodes()</span>
|
||||
method allows these layout nodes to be combined into a tree structure,
|
||||
which mimics the layout of elements in the view. What the
|
||||
children are depends on the implementation, some may be configurable
|
||||
and
|
||||
some may be fixed.<br>
|
||||
<br>
|
||||
The <span style="font-family: monospace; font-weight: bold;">hasElements()</span>
|
||||
and <span style="font-family: monospace; font-weight: bold;">getElements()</span>
|
||||
methods generate the actual elements that will appear in the
|
||||
view. The methods are analogous to the flexible hierarchy API
|
||||
methods: <span style="font-family: monospace;">IAsynchronousContentAdapter.isContainer()</span>
|
||||
and <span style="font-family: monospace;">IAsynchronousContentAdapter.retrieveChildren()</span>
|
||||
and are pretty straightforward to implement. Also <span
|
||||
style="font-weight: bold; font-family: monospace;">retrieveLabel()</span>
|
||||
is directly analogous to
|
||||
IAsynchronousLabelAdapter.retrieveLabel(). <br>
|
||||
<br>
|
||||
The <span style="font-family: monospace; font-weight: bold;">hasDeltaFlags()</span>
|
||||
and <span style="font-weight: bold; font-family: monospace;">buildDelta()</span>
|
||||
are used to generate model deltas in response to service events. These
|
||||
are discussed in the next section.<br>
|
||||
<br>
|
||||
Finally, in most cases the elements in the views correspond
|
||||
directly to an <span style="font-family: monospace;">IDataModelContext</span>
|
||||
(DM-Context) objects of a specific type. In those cases, the <span
|
||||
style="font-family: monospace;">DMContextVMLayoutNode</span>
|
||||
abstract class implements the common functionality in that pattern.<br>
|
||||
<h4>Model deltas</h4>
|
||||
The <span style="font-family: monospace;">hasDeltaFlags()</span> and <span
|
||||
style="font-family: monospace;">buildDelta()</span> methods are used
|
||||
to implement the <span style="font-family: monospace;">IModelProxy </span>adapter,
|
||||
and are the most tricky aspect of this design. The difficulty is
|
||||
that the flexible hierarchy views require that the <span
|
||||
style="font-family: monospace;">IModelProxy </span>translate data
|
||||
model-specific events, into generic model deltas that can be
|
||||
interpreted by the viewer. The deltas (<span
|
||||
style="font-family: monospace;">IModelDelta</span>) are tree
|
||||
structures which are supposed to mirror the structure of nodes in the
|
||||
tree, and which contain flags that tell the viewer what has changed in
|
||||
the view and how.<a href="#Asterix">*</a> This means that if the
|
||||
model proxy receives an event for some <span
|
||||
style="font-family: monospace;">IDataModelContext</span> (DM-Context) object,
|
||||
it needs to know if this object is in the viewer's tree, and what is
|
||||
the full path (or paths) that leads to this object. <br>
|
||||
<p>The model delta is generated by first calling the top layout node's <span
|
||||
style="font-family: monospace;">hasDeltaFlags()</span> with the
|
||||
received event, which then can either return <span
|
||||
style="font-family: monospace;">true </span>or ask any of its
|
||||
children if they have deltas (which in turn returns true or calls its
|
||||
children, etc). If a node returns <span
|
||||
style="font-family: monospace;">true </span>for <span
|
||||
style="font-family: monospace;">hasDeltaFlags()</span>, then the
|
||||
asynchronous <span style="font-family: monospace;">buildDelta()</span>
|
||||
is called with the event and a parent delta node, to generate the delta
|
||||
elements and flags for its node. Once the layout node generates
|
||||
its delta objects, it still needs to call its children, which in turn
|
||||
add their delta information, and so on.<br>
|
||||
</p>
|
||||
<p><a name="Asterix"></a>* It's not strictly true that a full path to
|
||||
an element always has to be present for model delta's to work. If
|
||||
the full path is not present, the viewer will try to find the element
|
||||
using an internal map that it keeps of all of the elements it
|
||||
knows.
|
||||
But since the viewer is lazy loading, it is possible (and likely) that
|
||||
the element affected by an event is not even known to the viewer at
|
||||
time of the event, and for some delta actions, <span
|
||||
style="font-family: monospace;">IModelDelta.SELECT</span> and <span
|
||||
style="font-family: monospace;">IModelDelta.EXPAND</span>, this is not
|
||||
acceptable.<br>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
135
plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html
Normal file
135
plugins/org.eclipse.dd.doc.dsf/docs/dsf_mi_instructions.html
Normal file
|
@ -0,0 +1,135 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1"
|
||||
http-equiv="content-type">
|
||||
<title>GDB/MI Debugger on top of DSF - Instructions</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>GDB/MI Debugger implementation based on DSF</h2>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">
|
||||
<h3>Buiding and Running Instructions<br>
|
||||
</h3>
|
||||
<h4>To build:</h4>
|
||||
<ol>
|
||||
<li>Install the latest milestone of Eclipse 3.3 SDK</li>
|
||||
<li>Install the latest milestone of CDT 4.0</li>
|
||||
<li>Install and configure gdb (cygwin on windows)</li>
|
||||
<li>Check out following projects from<a
|
||||
href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.dd.dsf/plugins/?cvsroot=DSDP_Project">
|
||||
<span class="moz-txt-slash"><span class="moz-txt-tag">/</span>cvsroot/dsdp/org.eclipse.dd.dsf/plugins
|
||||
</span></a></li>
|
||||
<ul>
|
||||
<li>org.eclipse.dd.dsf </li>
|
||||
<li>org.eclipse.dd.dsf.ui </li>
|
||||
<li>org.eclipse.dd.dsf.debug </li>
|
||||
<li>org.eclipse.dd.dsf.debug.ui </li>
|
||||
<li>org.eclipse.dd.dsf.mi.core </li>
|
||||
<li>org.eclipse.dd.dsf.mi.ui.</li>
|
||||
</ul>
|
||||
</ol>
|
||||
<h4>To run:</h4>
|
||||
<ol>
|
||||
<li>Create a new "Managed make build project" called "hello".</li>
|
||||
<li>Create a simple hello.c source file:</li>
|
||||
</ol>
|
||||
<div style="margin-left: 40px;">
|
||||
<pre>#include <stdio.h><br>int main(void) {<br> printf("Hello world");<br>}<br></pre>
|
||||
</div>
|
||||
<ol start="3">
|
||||
<li>Build the project.<br>
|
||||
</li>
|
||||
<li>Create a new "DSF C/C++ Local Application" launch
|
||||
configuration (one with the pink icon) and set the executable and entry
|
||||
point to "main"<br>
|
||||
</li>
|
||||
<li>Launch and step through.</li>
|
||||
<li>If the "source not found" page appears, the a path mapping needs
|
||||
to be created. This is an issue with latest cygwin gdb.<br>
|
||||
</li>
|
||||
<ol>
|
||||
<li>Click on the "Edit source lookup" button in the editor, or
|
||||
right click on the launch node in Debug View and select "Edit source
|
||||
lookup"</li>
|
||||
<li>Click on the "Add..." button</li>
|
||||
<li>Select "Path Mapping" and click OK.<br>
|
||||
</li>
|
||||
<li>Select the new "Path Mapping" source container and click the
|
||||
"Edit..." button.</li>
|
||||
<li>Once again, click the "Add..." button to create a mapping.</li>
|
||||
<li>Enter the path to map from. Look at the stack frame label
|
||||
in Debug view, if the filename is something like
|
||||
"/cygdrive/c/workspace/hello/hello.c", enter the path to the first real
|
||||
directory "/cygdrive/c/workspace".</li>
|
||||
<li>Enter the correct path to the directory entered above, in the
|
||||
file system. In example above, it would be "C:\workspace".</li>
|
||||
<li>Click OK three times and you'll be back in Kansas.... ehm Debug
|
||||
view that is.</li>
|
||||
<li>If the source doesn't show up right away, try stepping once.</li>
|
||||
</ol>
|
||||
</ol>
|
||||
<hr style="width: 100%; height: 2px;">
|
||||
<h3>Supported Platforms<br>
|
||||
</h3>
|
||||
Currently only Windows with <a
|
||||
href="http://www.cygwin.com/mirrors.html">cygwin</a> GDB is supported.
|
||||
<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">
|
||||
<h3>Current Features<br>
|
||||
</h3>
|
||||
<ul>
|
||||
<li>Launching</li>
|
||||
<ul>
|
||||
<li>The "DSF C/C++Local Application" is the standard CDT launch
|
||||
configuration minus some of the features. <br>
|
||||
</li>
|
||||
<li>What is NOT working here is <br>
|
||||
</li>
|
||||
<ul>
|
||||
<li>Debugger tab: the selection of debugger back ends (gdb/mi,
|
||||
Cygwin gdb debugger, etc.), tThe implementation is currently hard-wired
|
||||
for Cygwin,</li>
|
||||
<li>Debugger tab: Debugger Options section</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<li>Debug view</li>
|
||||
<ul>
|
||||
<li>Single thread debugging only.</li>
|
||||
<li>Terminating<br>
|
||||
</li>
|
||||
<li>Stepping <br>
|
||||
</li>
|
||||
<li>Resume/Suspend<br>
|
||||
</li>
|
||||
</ul>
|
||||
<li>Console support<br>
|
||||
</li>
|
||||
<ul>
|
||||
<li>GDB process output</li>
|
||||
<li>NO user process console support<br>
|
||||
</li>
|
||||
</ul>
|
||||
<li>Breakpoints</li>
|
||||
<ul>
|
||||
<li>Basic CDT breakpoint support implemented</li>
|
||||
<ul>
|
||||
<li>no filtering support, <br>
|
||||
</li>
|
||||
<li>no advanced options (hardware, temporary, etc)</li>
|
||||
<li>no watchpoints <br>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<li>Variables</li>
|
||||
<ul>
|
||||
<li>not yet<br>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">Updated Aug 25th, 2006<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
BIN
plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png
Normal file
BIN
plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-2.png
Normal file
BIN
plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
363
plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html
Normal file
363
plugins/org.eclipse.dd.doc.dsf/docs/dsf_services_model.html
Normal file
|
@ -0,0 +1,363 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1"
|
||||
http-equiv="content-type">
|
||||
<title>DSF Services Model</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>DSF Services Model</h2>
|
||||
<br>
|
||||
<b><span style="font-size: 12pt; font-family: "Times New Roman";">Version
|
||||
1.0<br>
|
||||
Pawel Piech <br>
|
||||
</span></b><b><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">© 2006,
|
||||
Wind River Systems.<span style=""> </span>Release under EPL
|
||||
version 1.0.</span></b><b><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";"><br style="">
|
||||
</span></b>
|
||||
<p>Debugger Services Framework (DSF) is primarily a service framework
|
||||
defining rules for how
|
||||
services should be registered, discovered, organized into functional
|
||||
groups, communicated with, and started/ended. These rules help to
|
||||
organize the services into a functional system that efficiently
|
||||
abstracts various debugger back end capabilities. </p>
|
||||
<p>DSF services build on top of the OSGI services framework, so
|
||||
it's important to understand OSGI services before looking at DSF
|
||||
itself. For an overview of OSGI including services, see the <a
|
||||
href="http://eclipsezilla.eclipsecon.org/php/attachment.php?bugid=185">presentation
|
||||
on OSGI from EclipseCon 2006</a>. For detailed information, see
|
||||
OSGI javadocs, primarily: <a style="font-family: monospace;"
|
||||
href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/framework/package-summary.html">org.osgi.framework</a><a
|
||||
style="font-family: monospace;"
|
||||
href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/framework/ServiceRegistration.html">ServiceRegistration</a>,
|
||||
<a
|
||||
href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/framework/BundleContext.html"><span
|
||||
style="font-family: monospace;">BundleContext</span></a>, <a
|
||||
href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/framework/BundleContext.html"><span
|
||||
style="font-family: monospace;">ServiceReference</span></a>, <a
|
||||
href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/framework/Filter.html"><span
|
||||
style="font-family: monospace;">Filter</span></a>, and <a
|
||||
style="font-family: monospace;"
|
||||
href="http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/util/tracker/ServiceTracker.html">ServiceTracker</a>.
|
||||
</p>
|
||||
<h3>Services<br>
|
||||
</h3>
|
||||
In OSGI any class can be registered as a service. In DSF,
|
||||
Services must implement the <a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/service/IDsfService.html"><span
|
||||
style="font-family: monospace;">IDsfService</span></a>
|
||||
interface, which requires that the service
|
||||
provide:<br>
|
||||
<ol>
|
||||
<li>Access to the <span style="font-family: monospace;">DsfExecutor </span>that
|
||||
has to be used to access service methods.</li>
|
||||
<li>Full list of properties used to uniquely identify the service in
|
||||
OSGI.</li>
|
||||
<li>Startup and shutdown methods.</li>
|
||||
</ol>
|
||||
For the first two items, a service must use the data it received from
|
||||
its constructor. For the third item, a service must register and
|
||||
unregister itself with OSGI. But beyond that, this is all that
|
||||
services have in common, everything else is up to the specific service
|
||||
interface.<br>
|
||||
<h3>Sessions (<a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/service/DsfSession.html"><span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.service.DsfSession</span></a>)<br>
|
||||
</h3>
|
||||
DSF services are organized into logical groups, called
|
||||
sessions. Sessions are only necessary because we want multiple
|
||||
instances of systems built with DSF services to run at the same
|
||||
time This is because there is only a single OSGI service
|
||||
registry, so if multiple services are registered with a given class
|
||||
name, OSGI will not be able to distinguish between the two based on the
|
||||
class name alone. So there is an additional property which is
|
||||
used by every DSF service when registering with OSGI, <span
|
||||
style="font-family: monospace;">IDsfService.PROP_SESSION_ID</span>.
|
||||
<br>
|
||||
<p>A <span style="font-family: monospace;">Session</span> object
|
||||
(TODO: link javadoc) has the following data associated with it:<br>
|
||||
</p>
|
||||
<ul>
|
||||
<li><span style="text-decoration: underline;">Session ID</span> - A <span
|
||||
style="font-family: monospace;">String</span> object that is unique
|
||||
among all other sessions. Its ID is used by services as the <span
|
||||
style="font-family: monospace;">IDsfService.PROP_SESSION_ID</span>
|
||||
property, and it is used by the client to obtain the <span
|
||||
style="font-family: monospace;">Session</span> object instance.</li>
|
||||
<li><span style="font-family: monospace; text-decoration: underline;">DsfExecutor</span>
|
||||
- Each session has a single executor. This means that all the
|
||||
services in a single session share the same executor and dispatch
|
||||
thread, and conversely it means that when operating in the dispatch
|
||||
thread, the state of all the services in a session will remain the same
|
||||
until the end of a dispatch. Note: multiple sessions <span
|
||||
style="font-style: italic;">could</span> share the same <span
|
||||
style="font-family: monospace;">DsfExecutor</span>.</li>
|
||||
<li><span style="text-decoration: underline;">Service startup counter</span>
|
||||
- An integer counter which is read and incremented by every service
|
||||
that is started in a session. This counter is used to determine
|
||||
the dependency order among services, which is used by events.</li>
|
||||
<li><span style="text-decoration: underline;">Event listener list</span>
|
||||
- This will be covered in the "Events" section.</li>
|
||||
<li><span style="text-decoration: underline;">Adapter list</span> - A
|
||||
list of adapters, providing functionality analogous to runtime's <span
|
||||
style="font-family: monospace;">org.eclipse.core.internal.runtime.AdapterManager</span>.
|
||||
Sessions need to manage their own lists of adapters, so that <span
|
||||
style="font-family: monospace;">IAdapter</span> objects which
|
||||
originate from DSF services can provider different adapters, based
|
||||
on the session that they originate from. This feature is covered
|
||||
in detail in the "DSF Data Model" document.<br>
|
||||
</li>
|
||||
</ul>
|
||||
<p>The Session class also has a number of static features used to
|
||||
manage Session objects:</p>
|
||||
<ul>
|
||||
<li><span style="text-decoration: underline;">Session ID counter</span>
|
||||
- Used to generate new session IDs.</li>
|
||||
<li><span style="text-decoration: underline;">Methods for starting
|
||||
and ending sessions</span> <br>
|
||||
</li>
|
||||
<li><span style="text-decoration: underline;">Session started/ended
|
||||
event listener list</span> - This allows clients to be notified when
|
||||
sessions are created or terminated, which is used mostly for clean-up
|
||||
purposes.<br>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Startup/Shutdown</h3>
|
||||
Managing the startup and shutdown process is often the most complicated
|
||||
aspect of modular systems. The details of how the startup and
|
||||
shutdown processes should be performed are also highly dependent on the
|
||||
specifics of the system and service implementations. To help
|
||||
with this, DSF provides two simple guidelines:<br>
|
||||
<ol>
|
||||
<li><span style="text-decoration: underline;">There should be a clear
|
||||
dependency tree of all services within a session</span> - When the
|
||||
dependencies between services are clearly defined, it is possible to
|
||||
bring-up and bring-down the services in an order that guarantees each
|
||||
running service can access all of the services that it depends on.</li>
|
||||
<li><span style="text-decoration: underline;">There needs to be a
|
||||
single point of control, which brings up and shuts down all the
|
||||
services.</span> - In other words, services should not initialize or
|
||||
shut-down themselves, based on some global event that they are all
|
||||
listening to. But rather an external piece of logic needs to be
|
||||
in charge of performing this operation.</li>
|
||||
</ol>
|
||||
The main implication of the first guideline, is that each service can
|
||||
get and hold onto references to other services, without having to
|
||||
repeatedly check, whether the service references are still valid.
|
||||
This is because if a given service is to be shut-down, all services
|
||||
that depend on this service will already have been shut down. The
|
||||
second guideline, simply ensures that startup and shutdown procedures
|
||||
are clear and easy to follow.<br>
|
||||
<h3><a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/service/DsfServicesTracker.html"><span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.service.DsfServicesTracker</span></a>
|
||||
vs <a
|
||||
href="http://help.eclipse.org/help31/topic/org.eclipse.platform.doc.isv/reference/osgi/org/osgi/util/tracker/ServiceTracker.html"><span
|
||||
style="font-family: monospace;">org.osgi.util.tracker.ServiceTracker</span></a></h3>
|
||||
OSGI methods for obtaining and tracking services can be rather
|
||||
complicated. To obtain a reference to a service, the client has
|
||||
to:<br>
|
||||
<ol>
|
||||
<li>Get a reference to a <span style="font-family: monospace;">BundleContext
|
||||
</span>object, which can be retrieved from the plugin class.</li>
|
||||
<li>Obtain a service reference object by calling <span
|
||||
style="font-family: monospace;">BundleContext.getServiceReference()</span>;</li>
|
||||
<li>Obtain an instance of the service by calling <span
|
||||
style="font-family: monospace;">BundleContext.getService(ServiceReference)</span>.</li>
|
||||
</ol>
|
||||
But worst of all, when the client is finished using the service, it has
|
||||
to call <span style="font-family: monospace;">BundleContext.ungetService(ServiceReference)</span>,
|
||||
because the bundle context counts the used references to a given
|
||||
service. All this paperwork is useful for services which manage
|
||||
their own life-cycle, and could be un-registered at any time. To
|
||||
make managing references to these kinds of services, OSGI provides a
|
||||
utility class, called <span style="font-family: monospace;">ServiceTracker</span>.
|
||||
<br>
|
||||
<p>For DSF services, the life cycle of the services is much more
|
||||
predictable, but the process of obtaining a reference to a service is
|
||||
just as onerous. DSF provides its own utility, which is
|
||||
separate from the <span style="font-family: monospace;">ServiceTracker</span>,
|
||||
named <span style="font-family: monospace;">DsfServicesTracker</span>.
|
||||
The differences between the two are listed in table below:<br>
|
||||
</p>
|
||||
<table style="width: 100%; text-align: left;" border="1" cellpadding="3"
|
||||
cellspacing="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th
|
||||
style="vertical-align: top; background-color: rgb(204, 204, 204); font-family: helvetica,arial,sans-serif;">Property<br>
|
||||
</th>
|
||||
<th
|
||||
style="vertical-align: top; background-color: rgb(204, 204, 204); font-family: helvetica,arial,sans-serif;">OSGI
|
||||
<span style="font-family: monospace;">ServiceTracker</span><br
|
||||
style="font-family: monospace;">
|
||||
</th>
|
||||
<th
|
||||
style="vertical-align: top; background-color: rgb(204, 204, 204); font-family: helvetica,arial,sans-serif;">DSF
|
||||
<span style="font-family: monospace;">DsfServicesTracker</span><br>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Number
|
||||
of services tracked<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">While
|
||||
not strictly limited, it is optimized for tracking services of a single
|
||||
class type, or more typically to track a single service reference.<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Designed
|
||||
to track services within a single DSF session. <br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">When
|
||||
are service references obtained<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Obtain
|
||||
references automatically as the services register themselves.<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Service
|
||||
references are obtained as requested by the client, and cached.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Synchronization<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Multi-thread
|
||||
accessible. <br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Can
|
||||
be accessed only on the session's dispatch thread.<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Clean-up<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Automatically
|
||||
un-gets references for services that are shut down.<br>
|
||||
</td>
|
||||
<td
|
||||
style="vertical-align: top; font-family: helvetica,arial,sans-serif;">Client
|
||||
must listen to session events, and clean up as needed.<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Both trackers are useful. Service implementations that depend
|
||||
on a number of other services are most likely to use DSF <span
|
||||
style="font-family: monospace;">ServicesTracker</span>, while some
|
||||
clients, which use a single service may find OSGI <span
|
||||
style="font-family: monospace;">ServiceTracker </span>more suitable.<br>
|
||||
</p>
|
||||
<h3>Events</h3>
|
||||
Events are the most un-conventional component of the services package
|
||||
and probably most likely to need modifications to the design by the
|
||||
community. The design goal of
|
||||
the event system is to allow a hierarchy of event classes, where a
|
||||
listener could register itself for a specific event class or for all
|
||||
events which derive from a base class. The use case for this
|
||||
behavior is in the data model, where we would like to have the ability
|
||||
to capture all model-related events with a generic listener while at
|
||||
the same time allowing for services to fully use class types. <br>
|
||||
<p>The event model is made up of the following components:<br>
|
||||
</p>
|
||||
<ul>
|
||||
<li><span style="font-weight: bold;"><span
|
||||
style="font-family: monospace;">DsfServiceEventHandler </span>annotation</span>
|
||||
- This is the only indicator that a given method is an event
|
||||
listener. The class with the event handler doesn't have to
|
||||
implement any interfaces, but it must be public, which is a big
|
||||
drawback.</li>
|
||||
<li><span style="font-weight: bold;"><span
|
||||
style="font-family: monospace;">Session.addServiceEventListener</span>,
|
||||
<span style="font-family: monospace;">Session.removeServiceEventListener</span>
|
||||
methods</span> - These methods allow clients to register for an event
|
||||
based on an event class and a service filter, where the filter can be
|
||||
used to uniquely identify a service in case of services with multiple
|
||||
instances of same class.</li>
|
||||
<li><span style="font-weight: bold;"><span
|
||||
style="font-family: monospace;">Session.dispatchEvent</span> method -</span>
|
||||
This is the method that actually dispatches the event to the
|
||||
listeners.
|
||||
The method must be called by a service that generates the event.</li>
|
||||
</ul>
|
||||
There are only a few more notes about the events mechanism:<br>
|
||||
<ol>
|
||||
<li>The event is always dispatched in its own <span
|
||||
style="font-family: monospace;">Runnable</span> submitted to
|
||||
the session's <span style="font-family: monospace;">DsfExecutor</span>.</li>
|
||||
<li>There is a slight convenience for clients not to have to register
|
||||
for each type of event separately.</li>
|
||||
<li>There is a slight inconvenience for clients, because anonymous
|
||||
classes cannot be used as listeners, due to the public class
|
||||
requirement.</li>
|
||||
</ol>
|
||||
<h3>Debugger Services (<a
|
||||
href="http://dsdp.eclipse.org/help/latest/topic/org.eclipse.dd.dsf.doc/reference/api/org/eclipse/dd/dsf/debug/package-summary.html"><span
|
||||
style="font-family: monospace;">org.eclipse.dd.dsf.debug</span></a>)<br>
|
||||
</h3>
|
||||
DSF framework includes a set of service interfaces for a typical
|
||||
debugger implementation. Functionally, they are pretty much
|
||||
equivalent to the platform debug interfaces, but they are structured in
|
||||
a way that allows a debugger to implement only some of them. In
|
||||
order for the startup and shutdown process to work effectively, the
|
||||
dependencies between services need to be clearly defined. The
|
||||
dependencies between the main service interfaces are shown in the graph
|
||||
below:<br>
|
||||
<img alt="" title="Debugger Services Dependencies"
|
||||
src="dsf_services_model-1.png" style="width: 720px; height: 540px;"><br>
|
||||
<p>It's also important to realize that it's unlikely that a single
|
||||
hierarchy of interfaces will adequately fit all the various debugger
|
||||
use cases, and it is likely that some interfaces will be needed which
|
||||
partially duplicate functionality found in other interfaces.
|
||||
An example of this in the proposed interface set are the interfaces
|
||||
which are used to initiate a debugging session. The <span
|
||||
style="font-family: monospace;">INativeProcesses</span> service is
|
||||
intended as the simple abstraction for native debuggers, where a
|
||||
debugger only needs an existing host process ID or an executable image
|
||||
name. Based on this a <span style="font-family: monospace;">INativeProcess</span>
|
||||
debugger implementation should be able to initiate a debugging session,
|
||||
and return run-control, memory, and symbol contexts that are required
|
||||
to carry out debugging operations. By comparison, <span
|
||||
style="font-family: monospace;">IOS</span> and <span
|
||||
style="font-family: monospace;">ITarget</span> are generic interfaces
|
||||
which allow clients to manage multiple target definitions, to
|
||||
examine a wide array of OS objects, and to attach a debugger to a
|
||||
process or some other debuggable entity. <br>
|
||||
<img alt="" title="Process Managment Services"
|
||||
src="dsf_services_model-2.png" style="width: 720px; height: 540px;"><br>
|
||||
</p>
|
||||
<h4>Disclaimer</h4>
|
||||
Drafting large APIs that are intended to have many implementations and
|
||||
by clients is a notoriously difficult task. It is
|
||||
impossible to expect that a first draft of such interfaces will not
|
||||
require changes, and only time and multiple successful implementation
|
||||
can validate them. While we can draw upon many examples of
|
||||
debugger
|
||||
APIs in Eclipse in and our commercial debugger, this is a new API with
|
||||
a
|
||||
prototype that exercises only a small portion of its interfaces.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
315
plugins/org.eclipse.dd.doc.dsf/docs/dsf_white_paper.html
Normal file
315
plugins/org.eclipse.dd.doc.dsf/docs/dsf_white_paper.html
Normal file
|
@ -0,0 +1,315 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1"
|
||||
http-equiv="content-type">
|
||||
<title>DSF White Paper</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Debugger Services Framework (DSF) White Paper</h2>
|
||||
Version 1.0<br>
|
||||
Pawel Piech<br>
|
||||
© 2006, Wind River Systems. Release under EPL version 1.0.<br>
|
||||
<h3>Overview</h3>
|
||||
DSF is a service framework for implementing the model and communication
|
||||
layers of Eclipse debuggers. The framework itself is actually
|
||||
very small in terms of lines of code, because it mostly builds on top
|
||||
of existing standard frameworks of OSGI services and Java 5.0
|
||||
concurrency features. The value of DSF is the set of utilities,
|
||||
patterns, and guidelines that together help solve some of the more
|
||||
difficult problems we have with existing Eclipse debugger
|
||||
implementations.<br>
|
||||
<h3>Design goals</h3>
|
||||
<span style="font-size: 12pt; font-family: times new roman,times,serif;">The
|
||||
primary design goal is to overcome the problems with
|
||||
existing Eclipse debuggers. These problems are:<o:p></o:p></span>
|
||||
<ol start="1" type="1">
|
||||
<li class="MsoNormal"
|
||||
style="line-height: normal; font-family: times new roman,times,serif;"><span
|
||||
style="font-size: 12pt;">Poor performance when debugging a remote
|
||||
target (over a slow connection).<o:p></o:p></span></li>
|
||||
<ul style="font-family: times new roman,times,serif;" type="circle">
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt;">Synchronous debugger communication, which
|
||||
results in poor throughput of data.<o:p></o:p></span></li>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt;">Amount of data that is retrieved from target
|
||||
is based on the data model, rather than on what's visible to the user
|
||||
on the screen.<o:p></o:p></span></li>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt;">No ability to filter, or to choose update
|
||||
policies, which could allow user to control what is retrieved from the
|
||||
target.<o:p></o:p></span></li>
|
||||
</ul>
|
||||
<li class="MsoNormal"
|
||||
style="line-height: normal; font-family: times new roman,times,serif;"><span
|
||||
style="font-size: 12pt;">No modularity in APIs or debugger
|
||||
implementations.<o:p></o:p></span></li>
|
||||
<ul style="font-family: times new roman,times,serif;" type="circle">
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt;">Specialized debuggers must use forking and
|
||||
duplication of common code to provide unique features.<o:p></o:p></span></li>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt;">Degenerate debuggers (with a subset of
|
||||
functionality of conventional debuggers) must implement a lot of
|
||||
interfaces that are meaningless to their users.</span><span
|
||||
class="MsoCommentReference"><span style="font-size: 8pt;"><!--[if !supportAnnotations]--><!--[endif]--><span
|
||||
style="display: none;"><span style=""> </span></span></span></span><span
|
||||
style="font-size: 12pt;"><o:p></o:p></span></li>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt;">It's difficult to modify or selectively
|
||||
replace interfaces, because all interfaces have references to each
|
||||
other.</span><span class="MsoCommentReference"><span
|
||||
style="font-size: 8pt;"><!--[if !supportAnnotations]--><!--[endif]--><span
|
||||
style="display: none;"><span style=""> </span></span></span></span><span
|
||||
style="font-size: 12pt;"><o:p></o:p></span></li>
|
||||
</ul>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";"><span
|
||||
style="font-family: times new roman,times,serif;">Difficulty in
|
||||
customizing data presentation for different types of debugging.</span></span></li>
|
||||
</ol>
|
||||
<h3>Features</h3>
|
||||
The DSF features described below, more-or-less correspond one-to-one to
|
||||
the problems in the Design Goals section. <br>
|
||||
<h4>Concurrency Model</h4>
|
||||
It may be a surprise that simply adopting a threading model would solve
|
||||
performance problems with debugger communication, but indirectly, it
|
||||
actually does. The primary reason for poor performance with
|
||||
remote targets in debuggers such as CDT is the synchronous nature of
|
||||
target communication. When a request is made at the UI level that
|
||||
results in a command being sent to the target, then the client thread
|
||||
is blocked while the command is being processed. After the result
|
||||
if finally retrieved, the client makes the next request for data and is
|
||||
blocked again. In this pattern the responsiveness of the UI is
|
||||
slow, yet the majority of this performance hit is due to the latency of
|
||||
the communication channel to the debugger back end. <br>
|
||||
<p>There is one major improvement to this pattern implemented in the
|
||||
platform already. The platform debugger views have been
|
||||
re-written so that they spin off a separate thread for each separable
|
||||
call to the debug model. The multiple threads each result in
|
||||
individual requests being sent to the target, and each thread is
|
||||
blocked waiting for the result. Overall the responsiveness of the
|
||||
view is improved because all the request threads execute in
|
||||
parallel. However, there is one obvious limitation of this
|
||||
approach: creating a lot of new threads, even when using a thread pool,
|
||||
is an expensive operation and can in itself degrade performance,
|
||||
therefore this solution doesn't scale well to programs that for example
|
||||
have thousands of threads, or threads, or variables.<br>
|
||||
</p>
|
||||
<p>There is also a more subtle limitation of using jobs. Most
|
||||
debuggers have a very lopsided performance characteristic, where it
|
||||
takes a long time to initiate a query for the target, but once a query
|
||||
is run, it takes relatively little extra time to retrieve larger
|
||||
amounts of data. Therefore, to better optimize the performance of
|
||||
communicating with a remote target, it is important to coalesce
|
||||
individual requests into queries for larger chunks of data. This
|
||||
is a rather complicated problem, mostly because the commands available
|
||||
in debugger back ends vary depending on the type of data being
|
||||
retrieved. Also different types of data require different types
|
||||
of coalescing. For example, where it might be possible to
|
||||
retrieve memory in arbitrarily sized chunks, registers may be
|
||||
retrievable only in groups. There is one thing all coalescing
|
||||
solutions will have in common, though: they need to convert the calls
|
||||
that are made to the service into objects, which can be compared,
|
||||
sorted, and pooled together. Management of such objects requires
|
||||
a lot of state information to be tracked by the service, and managing
|
||||
the cache of the request results requires even more state
|
||||
information. </p>
|
||||
<p>Managing a lot of state information, which coalescing optimization
|
||||
requires, is exceedingly difficult in a free multi-threaded
|
||||
environment. This is because the more state information there is
|
||||
in the system, the more semaphores are needed to avoid race conditions.
|
||||
The more semaphores are used, the greater the chance that deadlocks
|
||||
will occur. There are many methods for managing concurrency in
|
||||
systems with a lot of state information, and they all have some
|
||||
drawbacks. One such example is the Eclipse resource system use of
|
||||
<span style="font-family: monospace;">ISchedulingRule </span>and
|
||||
jobs. Unfortunately this this concurrency model would not work
|
||||
well for the debugger because the resource system has a clearly defined
|
||||
hierarchy to its data: Workspace/Projects/File, so it’s easy to lock a
|
||||
portion of the tree and still allow other clients to interact with
|
||||
it. For debugger services, the relationship between state data is
|
||||
not clearly defined and often very complicated, so if scheduling rules
|
||||
were applied in a debugger implementation they would likely degrade
|
||||
performance, because each request would probably need to lock the
|
||||
entire system.<br>
|
||||
</p>
|
||||
<p>For its concurrency model, DSF imposes a strict threading
|
||||
model. <span style="font-style: italic;">All services that make
|
||||
up a debugger implementation must talk to each other using a single
|
||||
dispatch thread, and no service can make a blocking call while in the
|
||||
dispatch thread.</span> Conceptually this rule can be interpreted
|
||||
as: all communication between services is accomplished by runnables in
|
||||
a thread pool, where the thread pool size is just one. The effect
|
||||
of this policy is that the dispatch thread acts as a single global
|
||||
semaphore, and when executing on the dispatch thread, a client or a
|
||||
service can perform arbitrarily complex operations, and can poll the
|
||||
sate of as many services as necessary without worrying about the state
|
||||
of the system changing concurrently. The single threading rule
|
||||
only applies to the service interfaces, and does not preclude
|
||||
multi-threading in the service implementations. In fact
|
||||
multi-threading is utilized more in this architecture because many
|
||||
blocking operations that would normally be performed on shared threads,
|
||||
possibly slowing the UI responsiveness, now need to be performed using
|
||||
background threads.<br>
|
||||
</p>
|
||||
<p>In summary, a restrictive threading model combined with asynchronous
|
||||
interfaces, is the DSF solution to communication performance problems
|
||||
because it allows debugger implementations to have highly complex logic
|
||||
that handles coalescing and cancelling of requests, intelligent caching
|
||||
of debugger requests, and other advanced features such as filtering and
|
||||
configurable update policies.</p>
|
||||
<h4>Services Model<br>
|
||||
</h4>
|
||||
<p class="MsoNormal"
|
||||
style="margin-bottom: 0.0001pt; line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Fortunately
|
||||
it's easier to see the connection between a
|
||||
services model and addressing modularity problems. <o:p></o:p></span></p>
|
||||
<p class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Most current
|
||||
debugger
|
||||
implementations don't make an effort to separate out different
|
||||
components that make
|
||||
up the data model and communication layers. It is true that UI
|
||||
components
|
||||
usually interact with clearly defined data model interfaces, and in
|
||||
case of CDT
|
||||
the data model is somewhat separated from the communication layer using
|
||||
the CDI
|
||||
interface. However within the CDT data model and communication
|
||||
layer
|
||||
interfaces, there are enough references between the various objects to
|
||||
make all
|
||||
of them essentially inter-dependent. Furthermore, in the
|
||||
implementation
|
||||
of these layers, components use internal knowledge of other
|
||||
components.
|
||||
This is perfectly acceptable if we assume that the debugger
|
||||
implementation is
|
||||
going to be used as a single module, and any extensions can be built on
|
||||
top of
|
||||
it. But, it is important that vendors be able to selectively pick
|
||||
and
|
||||
choose components which they would like to reuse "as is" and which
|
||||
components they would like to extend, modify, replace, or not use at
|
||||
all.
|
||||
In order to achieve that kind of modularity, a lot of design work has
|
||||
to go
|
||||
into interfaces not just between the major layers of implementation,
|
||||
but also
|
||||
between various components that make up these layers.<br>
|
||||
</span></p>
|
||||
<p class="MsoNormal" style="line-height: normal;"></p>
|
||||
<p class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">To help build
|
||||
a modular
|
||||
architecture, DSF builds on the OSGI services framework, by providing
|
||||
additional functionality of:<o:p></o:p></span></p>
|
||||
<ul>
|
||||
<li> organizing services into sessions,</li>
|
||||
<li>managing start-up and shut-down processes,</li>
|
||||
<li>managing events between services.</li>
|
||||
</ul>
|
||||
<p class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Additionally,
|
||||
DSF includes an
|
||||
initial draft of service interfaces designed to build a modular
|
||||
debugger
|
||||
implementation. These interfaces must be validated, and this can
|
||||
only be
|
||||
realistically accomplished by implementing several full-featured and
|
||||
diverse
|
||||
debuggers. We are seeking additional debug tool vendors from the
|
||||
community to port to these interfaces in addition to Wind River.<o:p></o:p></span></p>
|
||||
<h4>Data Model</h4>
|
||||
<p class="MsoNormal"
|
||||
style="margin-bottom: 0.0001pt; line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">The problems
|
||||
of the data model are perhaps less severe than
|
||||
problems of performance and modularity, but this is an area with a lot
|
||||
of room
|
||||
for innovation. We are used to thinking of the debug data model
|
||||
in a
|
||||
rather rigid terms, where there is a defined hierarchy of debug
|
||||
targets,
|
||||
threads, stack frames, variables, sub-expressions, etc. We are
|
||||
also used
|
||||
to seeing standard debug views of threads, stack frames, locals, and
|
||||
watch. These expectations seem to be pretty accurately reflected
|
||||
in the
|
||||
platform debug model, on top of which all of the current Eclipse
|
||||
debuggers are
|
||||
based. This is a problem for two reasons:<o:p></o:p></span></p>
|
||||
<ol start="1" type="1">
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">The direct
|
||||
references between different types of objects prevent the debug model
|
||||
implementation from being modular.<o:p></o:p></span></li>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Extensions to
|
||||
the debug model are limited to additions in functionality of the basic
|
||||
platform objects and some additional object types.<o:p></o:p></span></li>
|
||||
</ol>
|
||||
<p class="MsoNormal"
|
||||
style="margin-bottom: 0.0001pt; line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Fortunately
|
||||
in release 3.2, the Eclipse platform introduced
|
||||
a way to circumvent the standard platform model and to drive the
|
||||
content of
|
||||
most of the standard debugger views using a completely custom data
|
||||
model and a
|
||||
set of viewer adapters. DSF aims to take advantage of this new
|
||||
capability
|
||||
to address the above problems, as well as to provide the additional
|
||||
benefits
|
||||
of:<o:p></o:p></span></p>
|
||||
<ol start="3" type="1">
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Improving
|
||||
performance by using the DSF dispatch thread model and asynchronous
|
||||
methods.<o:p></o:p></span></li>
|
||||
<li class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Giving the
|
||||
user ability to fully customize at runtime the content and layout of
|
||||
debugger views.<o:p></o:p></span></li>
|
||||
</ol>
|
||||
<p class="MsoNormal"
|
||||
style="margin-bottom: 0.0001pt; line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">Points 1, 2,
|
||||
and 3 are a side effect of DSF's Threading
|
||||
Model and Services Model used in conjunction with the platform's
|
||||
flexible
|
||||
hierarchy interfaces. Point 4 is an innovative and exciting
|
||||
feature that
|
||||
naturally builds on top of the service model and flexible hierarchy.<span
|
||||
style=""> </span>In the first release of DSF to open source,
|
||||
we have not yet implemented the capability described in point 4.
|
||||
The
|
||||
design for this feature calls for data driven, configurable views,
|
||||
where the
|
||||
configuration data drives the content and label providers to retrieve
|
||||
appropriate information from the data model.<span style="">
|
||||
</span>On the service side, there needs to be a published data model
|
||||
schema and
|
||||
a query language interpreter, which will retrieve the data for clients.<span
|
||||
style=""> </span>We expect community discussion and design
|
||||
work to help solve this problem, and we intend to present
|
||||
implementations from
|
||||
our commercial product as one possible solution.<o:p></o:p></span></p>
|
||||
<p class="MsoNormal" style="line-height: normal;"><span
|
||||
style="font-size: 12pt; font-family: "Times New Roman";">One final
|
||||
point is that although the
|
||||
DSF data model is fundamentally different than the platform debug model
|
||||
and the
|
||||
CDT extensions, a DSF debugger could easily be adapted to provide any
|
||||
of these
|
||||
API’s. This may require considerable effort, especially for
|
||||
extensive
|
||||
API’s like CDI, but is desirable and necessary to support the existing
|
||||
CDT
|
||||
community.<o:p></o:p></span></p>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
22
plugins/org.eclipse.dd.doc.dsf/notices.html
Normal file
22
plugins/org.eclipse.dd.doc.dsf/notices.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta name="copyright" content="Copyright (c) Wind River Systems, Inc. and others 2000, 2006. This page is made available under license. For full details see the LEGAL in the documentation book that contains this page." >
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<LINK REL="STYLESHEET" HREF="book.css" CHARSET="ISO-8859-1" TYPE="text/css">
|
||||
<title>Legal Notices</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3>
|
||||
<a NAME="Notices"></a>Notices</h3>
|
||||
<p>
|
||||
The material in this guide is Copyright (c) Wind River Systems, Inc. and others 2000, 2006.
|
||||
</p>
|
||||
<p>
|
||||
<a href="about.html">Terms and conditions regarding the use of this guide.</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
35
plugins/org.eclipse.dd.doc.dsf/options.txt
Normal file
35
plugins/org.eclipse.dd.doc.dsf/options.txt
Normal file
|
@ -0,0 +1,35 @@
|
|||
-quiet
|
||||
-encoding "iso-8859-1"
|
||||
-charset "iso-8859-1"
|
||||
-sourcepath "../org.eclipse.dd.dsf/src
|
||||
;../org.eclipse.dd.dsf.ui/src
|
||||
;../org.eclipse.dd.dsf.examples/src
|
||||
-d reference/api
|
||||
-classpath @rt@
|
||||
-breakiterator
|
||||
-tag generated:X
|
||||
-tag lastgen:X
|
||||
-tag model:X
|
||||
-tag ordered:X
|
||||
-use
|
||||
-splitIndex
|
||||
-windowtitle "DSF API Specification"
|
||||
-doctitle "DSF API Specification"
|
||||
-header "<b>DSF</b>"
|
||||
-bottom "Copyright (c) Wind River Systems, Inc. and others 2000, 2006. All Rights Reserved."
|
||||
-group "DSF Core Packages" "org.eclipse.dd.dsf"
|
||||
-group "DSF UI Packages" "org.eclipse.dd.dsf.ui"
|
||||
-group "DSF Examples Packages" "org.eclipse.dd.dsf.examples"
|
||||
-link http://java.sun.com/j2se/1.5/docs/api
|
||||
-link http://bundles.osgi.org/javadoc/r4
|
||||
|
||||
org.eclipse.dd.dsf
|
||||
org.eclipse.dd.dsf.concurrent
|
||||
org.eclipse.dd.dsf.debug
|
||||
org.eclipse.dd.dsf.model
|
||||
org.eclipse.dd.dsf.service
|
||||
org.eclipse.dd.dsf.ui
|
||||
org.eclipse.dd.dsf.ui.model
|
||||
org.eclipse.dd.dsf.examples
|
||||
org.eclipse.dd.dsf.examples.concurrent
|
||||
org.eclipse.dd.dsf.examples.timers
|
13
plugins/org.eclipse.dd.doc.dsf/plugin.properties
Normal file
13
plugins/org.eclipse.dd.doc.dsf/plugin.properties
Normal file
|
@ -0,0 +1,13 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2006 Wind River Systems and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Wind River Systems - initial API and implementation
|
||||
###############################################################################
|
||||
pluginName=DSDP/DD Debugger Services Framework (DSF) Documentation
|
||||
providerName=Eclipse.org
|
||||
|
32
plugins/org.eclipse.dd.doc.dsf/plugin.xml
Normal file
32
plugins/org.eclipse.dd.doc.dsf/plugin.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.0"?>
|
||||
|
||||
<!-- ===================================================== -->
|
||||
<!-- Declare the documentation for the DSF Docs -->
|
||||
<!-- We will declare only one infoset (book) -->
|
||||
<!-- ===================================================== -->
|
||||
|
||||
<plugin>
|
||||
|
||||
|
||||
<!-- ============================================================================= -->
|
||||
<!-- Define primary TOC -->
|
||||
<!-- ============================================================================= -->
|
||||
|
||||
<extension point="org.eclipse.help.toc">
|
||||
<toc file="toc.xml" primary="true"/>
|
||||
<index path="index/"/>
|
||||
</extension>
|
||||
|
||||
<!-- ============================================================================= -->
|
||||
<!-- Define Javadoc locations -->
|
||||
<!-- ============================================================================= -->
|
||||
<extension point="org.eclipse.pde.core.javadoc">
|
||||
<javadoc path="reference/api">
|
||||
<plugin id="org.eclipse.dd.dsf" />
|
||||
<plugin id="org.eclipse.dd.dsf.ui" />
|
||||
<plugin id="org.eclipse.dd.dsf.examples" />
|
||||
</javadoc>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
66
plugins/org.eclipse.dd.doc.dsf/schema.css
Normal file
66
plugins/org.eclipse.dd.doc.dsf/schema.css
Normal file
|
@ -0,0 +1,66 @@
|
|||
H6.CaptionFigColumn#header {
|
||||
font-size:16px;
|
||||
display:inline
|
||||
}
|
||||
|
||||
P.Note#copyright {
|
||||
font-size: smaller;
|
||||
font-style: normal;
|
||||
color: #336699;
|
||||
display:inline;
|
||||
margin-top: 3.000000pt;
|
||||
margin-bottom: 11.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 0.000000pt;
|
||||
}
|
||||
|
||||
P.Code#dtd {
|
||||
color: #800000;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 10.000000pt;
|
||||
}
|
||||
|
||||
P.Code#dtdAttlist {
|
||||
color: #800000;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 20.000000pt;
|
||||
}
|
||||
|
||||
P.Code#tag {
|
||||
color: #000080;
|
||||
display:inline;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 0.000000pt;
|
||||
}
|
||||
|
||||
P.Code#cstring {
|
||||
color: #008000;
|
||||
display:inline;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 0.000000pt;
|
||||
}
|
||||
|
||||
.ConfigMarkup#elementDesc {
|
||||
color: black;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 10.000000pt;
|
||||
}
|
||||
|
||||
.ConfigMarkup#attlistDesc {
|
||||
color: black;
|
||||
margin-top: 0.000000pt;
|
||||
margin-bottom: 0.000000pt;
|
||||
margin-right: 0.000000pt;
|
||||
margin-left: 32.000000pt;
|
||||
}
|
||||
|
15
plugins/org.eclipse.dd.doc.dsf/toc.xml
Normal file
15
plugins/org.eclipse.dd.doc.dsf/toc.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?NLS TYPE="org.eclipse.help.toc"?>
|
||||
<!-- ============================================================================= -->
|
||||
<!-- Define the top level topics -->
|
||||
<!-- ============================================================================= -->
|
||||
|
||||
<toc label="DSF Design Documents">
|
||||
<topic label="DSF White Paper" href="docs/dsf_white_paper.html"/>
|
||||
<topic label="DSF Services Model" href="docs/dsf_services_model.html"/>
|
||||
<topic label="DSF Concurrency Model" href="docs/dsf_concurrency_model.html"/>
|
||||
<topic label="DSF Data Model" href="docs/dsf_data_model.html"/>
|
||||
<topic label="GDB/MI Debugger implementation based on DSF" href="docs/dsf_mi_instructions.html"/>
|
||||
<topic label="DSF API Reference All Packages" href="reference/api/overview-summary.html"/>
|
||||
<topic label="Legal" href="notices.html"/>
|
||||
</toc>
|
Loading…
Add table
Reference in a new issue