dol: initial dol commit
authorSebastian <basti@sraa.de>
Mon, 25 Nov 2013 16:47:40 +0000 (17:47 +0100)
committerSebastian <basti@sraa.de>
Mon, 25 Nov 2013 16:47:40 +0000 (17:47 +0100)
This is the original, unchanged DOL source code as provided by
ETHZ. It is meant to be built with Ant.

537 files changed:
dol/.classpath [new file with mode: 0644]
dol/.project [new file with mode: 0644]
dol/build.xml [new file with mode: 0644]
dol/examples/arch/cell.xml [new file with mode: 0644]
dol/examples/arch/mparm.xml [new file with mode: 0644]
dol/examples/arch/rdt1.xml [new file with mode: 0644]
dol/examples/arch/rdt8.xml [new file with mode: 0644]
dol/examples/example1/example1.xml [new file with mode: 0644]
dol/examples/example1/map_1.xml [new file with mode: 0644]
dol/examples/example1/map_3.xml [new file with mode: 0644]
dol/examples/example1/map_mparm.xml [new file with mode: 0644]
dol/examples/example1/src/arraygen.c [new file with mode: 0644]
dol/examples/example1/src/arraygen.h [new file with mode: 0644]
dol/examples/example1/src/consumer.c [new file with mode: 0644]
dol/examples/example1/src/consumer.h [new file with mode: 0644]
dol/examples/example1/src/generator.c [new file with mode: 0644]
dol/examples/example1/src/generator.h [new file with mode: 0644]
dol/examples/example1/src/global.h [new file with mode: 0644]
dol/examples/example1/src/printarray.c [new file with mode: 0644]
dol/examples/example1/src/printarray.h [new file with mode: 0644]
dol/examples/example1/src/quicksort.c [new file with mode: 0644]
dol/examples/example1/src/quicksort.h [new file with mode: 0644]
dol/examples/example1/src/square.c [new file with mode: 0644]
dol/examples/example1/src/square.h [new file with mode: 0644]
dol/examples/example2/example2.xml [new file with mode: 0644]
dol/examples/example2/src/consumer.c [new file with mode: 0644]
dol/examples/example2/src/consumer.h [new file with mode: 0644]
dol/examples/example2/src/generator.c [new file with mode: 0644]
dol/examples/example2/src/generator.h [new file with mode: 0644]
dol/examples/example2/src/global.h [new file with mode: 0644]
dol/examples/example2/src/square.c [new file with mode: 0644]
dol/examples/example2/src/square.h [new file with mode: 0644]
dol/examples/example3/example3.xml [new file with mode: 0644]
dol/examples/example3/src/forward.c [new file with mode: 0644]
dol/examples/example3/src/forward.h [new file with mode: 0644]
dol/examples/example3/src/horizontal_consumer.c [new file with mode: 0644]
dol/examples/example3/src/horizontal_consumer.h [new file with mode: 0644]
dol/examples/example3/src/horizontal_generator.c [new file with mode: 0644]
dol/examples/example3/src/horizontal_generator.h [new file with mode: 0644]
dol/examples/example3/src/vertical_consumer.c [new file with mode: 0644]
dol/examples/example3/src/vertical_consumer.h [new file with mode: 0644]
dol/examples/example3/src/vertical_generator.c [new file with mode: 0644]
dol/examples/example3/src/vertical_generator.h [new file with mode: 0644]
dol/examples/example4/example4.xml [new file with mode: 0644]
dol/examples/example4/src/addmult.c [new file with mode: 0644]
dol/examples/example4/src/addmult.h [new file with mode: 0644]
dol/examples/example4/src/constants.h [new file with mode: 0644]
dol/examples/example4/src/consumer.c [new file with mode: 0644]
dol/examples/example4/src/consumer.h [new file with mode: 0644]
dol/examples/example4/src/generator.c [new file with mode: 0644]
dol/examples/example4/src/generator.h [new file with mode: 0644]
dol/examples/example5/example5.xml [new file with mode: 0644]
dol/examples/example5/fft_script.m [new file with mode: 0644]
dol/examples/example5/src/consumer.c [new file with mode: 0644]
dol/examples/example5/src/consumer.h [new file with mode: 0644]
dol/examples/example5/src/fft2.c [new file with mode: 0644]
dol/examples/example5/src/fft2.h [new file with mode: 0644]
dol/examples/example5/src/generator.c [new file with mode: 0644]
dol/examples/example5/src/generator.h [new file with mode: 0644]
dol/examples/example5/src/global.h [new file with mode: 0644]
dol/examples/example6/example6.xml [new file with mode: 0644]
dol/examples/example6/src/consumer.c [new file with mode: 0644]
dol/examples/example6/src/consumer.h [new file with mode: 0644]
dol/examples/example6/src/filter.c [new file with mode: 0644]
dol/examples/example6/src/filter.h [new file with mode: 0644]
dol/examples/example6/src/producer.c [new file with mode: 0644]
dol/examples/example6/src/producer.h [new file with mode: 0644]
dol/examples/example7/example7.xml [new file with mode: 0644]
dol/examples/example7/filter_script.m [new file with mode: 0644]
dol/examples/example7/src/consumer.c [new file with mode: 0644]
dol/examples/example7/src/consumer.h [new file with mode: 0644]
dol/examples/example7/src/filter.c [new file with mode: 0644]
dol/examples/example7/src/filter.h [new file with mode: 0644]
dol/examples/example7/src/global.h [new file with mode: 0644]
dol/examples/example7/src/producer.c [new file with mode: 0644]
dol/examples/example7/src/producer.h [new file with mode: 0644]
dol/examples/examplecell/cell.xml [new file with mode: 0644]
dol/examples/examplecell/examplecell.xml [new file with mode: 0644]
dol/examples/examplecell/mapping.xml [new file with mode: 0644]
dol/examples/examplecell/src/consumer.c [new file with mode: 0644]
dol/examples/examplecell/src/consumer.h [new file with mode: 0644]
dol/examples/examplecell/src/generator.c [new file with mode: 0644]
dol/examples/examplecell/src/generator.h [new file with mode: 0644]
dol/examples/examplecell/src/global.h [new file with mode: 0644]
dol/examples/examplecell/src/square.c [new file with mode: 0644]
dol/examples/examplecell/src/square.h [new file with mode: 0644]
dol/examples/exampleproducerconsumer/exampleproducerconsumer.xml [new file with mode: 0644]
dol/examples/exampleproducerconsumer/src/consumer.c [new file with mode: 0644]
dol/examples/exampleproducerconsumer/src/consumer.h [new file with mode: 0644]
dol/examples/exampleproducerconsumer/src/producer.c [new file with mode: 0644]
dol/examples/exampleproducerconsumer/src/producer.h [new file with mode: 0644]
dol/examples/examplesingleprocess/examplesingleprocess.xml [new file with mode: 0644]
dol/examples/examplesingleprocess/src/task.c [new file with mode: 0644]
dol/examples/examplesingleprocess/src/task.h [new file with mode: 0644]
dol/examples/examplewindowedfifo/examplewindowedfifo.xml [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/consumer.c [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/consumer.h [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/generator.c [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/generator.h [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/global.h [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/square.c [new file with mode: 0644]
dol/examples/examplewindowedfifo/src/square.h [new file with mode: 0644]
dol/examples/runexample.xml [new file with mode: 0644]
dol/examples/runprofiler.xml [new file with mode: 0644]
dol/examples/schema/architecture.xsd [new file with mode: 0644]
dol/examples/schema/createschemastex [new file with mode: 0644]
dol/examples/schema/generics.xsd [new file with mode: 0644]
dol/examples/schema/internal/architecture_internal.xsd [new file with mode: 0644]
dol/examples/schema/internal/mapping_internal.xsd [new file with mode: 0644]
dol/examples/schema/internal/processnetwork_internal.xsd [new file with mode: 0644]
dol/examples/schema/mapping.xsd [new file with mode: 0644]
dol/examples/schema/processnetwork.xsd [new file with mode: 0644]
dol/jars/jdom.jar [new file with mode: 0644]
dol/jars/xercesImpl.jar [new file with mode: 0644]
dol/src/MANIFEST.MF [new file with mode: 0644]
dol/src/docs/doxygen/doxygen.cfg [new file with mode: 0644]
dol/src/docs/doxygen/footer.html [new file with mode: 0644]
dol/src/docs/doxygen/header.html [new file with mode: 0644]
dol/src/dol.properties [new file with mode: 0644]
dol/src/dol/check/SanityCheck.java [new file with mode: 0644]
dol/src/dol/check/package.html [new file with mode: 0644]
dol/src/dol/datamodel/XmlTag.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/ArchiConnection.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/ArchiResource.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Architecture.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Configuration.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/HWChannel.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Memory.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Node.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Path.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/PortNode.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Processor.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/ReadPath.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/Variable.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/WritePath.java [new file with mode: 0644]
dol/src/dol/datamodel/architecture/package.html [new file with mode: 0644]
dol/src/dol/datamodel/mapping/Binding.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/CommunicationBinding.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/ComputationBinding.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/Configuration.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/MapResource.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/Mapping.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/Schedule.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/ScheduleEntry.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/SchedulingPolicy.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/Variable.java [new file with mode: 0644]
dol/src/dol/datamodel/mapping/package.html [new file with mode: 0644]
dol/src/dol/datamodel/package.html [new file with mode: 0644]
dol/src/dol/datamodel/pn/Channel.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Configuration.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Connection.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Port.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Process.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/ProcessNetwork.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/ProfilingConfiguration.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Resource.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Schedulable.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/SourceCode.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/Variable.java [new file with mode: 0644]
dol/src/dol/datamodel/pn/package.html [new file with mode: 0644]
dol/src/dol/helper/flattener/ArchFlattener.java [new file with mode: 0644]
dol/src/dol/helper/flattener/BugCatcher.java [new file with mode: 0644]
dol/src/dol/helper/flattener/DomDocumentParser.java [new file with mode: 0644]
dol/src/dol/helper/flattener/FlattenerHelper.java [new file with mode: 0644]
dol/src/dol/helper/flattener/MappingFlattener.java [new file with mode: 0644]
dol/src/dol/helper/flattener/PNFlattener.java [new file with mode: 0644]
dol/src/dol/helper/flattener/SaxDocumentParser.java [new file with mode: 0644]
dol/src/dol/helper/flattener/XMLFlattener.java [new file with mode: 0644]
dol/src/dol/helper/flattener/package.html [new file with mode: 0644]
dol/src/dol/helper/profiler/ChannelProfile.java [new file with mode: 0644]
dol/src/dol/helper/profiler/Constants.java [new file with mode: 0644]
dol/src/dol/helper/profiler/PNProfileSummarizer.java [new file with mode: 0644]
dol/src/dol/helper/profiler/PortProfile.java [new file with mode: 0644]
dol/src/dol/helper/profiler/ProcessProfile.java [new file with mode: 0644]
dol/src/dol/helper/profiler/ProfileParser.java [new file with mode: 0644]
dol/src/dol/helper/profiler/Profiler.java [new file with mode: 0644]
dol/src/dol/helper/profiler/Range.java [new file with mode: 0644]
dol/src/dol/helper/profiler/VSPLogFileProfiler.java [new file with mode: 0644]
dol/src/dol/helper/profiler/WorkloadAnnotator.java [new file with mode: 0644]
dol/src/dol/helper/profiler/package.html [new file with mode: 0644]
dol/src/dol/helper/validator/XMLValidator.java [new file with mode: 0644]
dol/src/dol/helper/validator/package.html [new file with mode: 0644]
dol/src/dol/main/Main.java [new file with mode: 0644]
dol/src/dol/main/Options.java [new file with mode: 0644]
dol/src/dol/main/UserInterface.java [new file with mode: 0644]
dol/src/dol/main/package.html [new file with mode: 0644]
dol/src/dol/parser/xml/XmlErrorHandler.java [new file with mode: 0644]
dol/src/dol/parser/xml/XmlParser.java [new file with mode: 0644]
dol/src/dol/parser/xml/archischema/ArchiXmlParser.java [new file with mode: 0644]
dol/src/dol/parser/xml/archischema/Xml2Archi.java [new file with mode: 0644]
dol/src/dol/parser/xml/archischema/package.html [new file with mode: 0644]
dol/src/dol/parser/xml/mapschema/MapXmlParser.java [new file with mode: 0644]
dol/src/dol/parser/xml/mapschema/Xml2Map.java [new file with mode: 0644]
dol/src/dol/parser/xml/mapschema/package.html [new file with mode: 0644]
dol/src/dol/parser/xml/package.html [new file with mode: 0644]
dol/src/dol/parser/xml/pnschema/PNXmlParser.java [new file with mode: 0644]
dol/src/dol/parser/xml/pnschema/Xml2PN.java [new file with mode: 0644]
dol/src/dol/parser/xml/pnschema/package.html [new file with mode: 0644]
dol/src/dol/util/ApplicationGenerator.java [new file with mode: 0644]
dol/src/dol/util/CheckXMLs.java [new file with mode: 0644]
dol/src/dol/util/CodePrintStream.java [new file with mode: 0644]
dol/src/dol/util/CodePrintString.java [new file with mode: 0644]
dol/src/dol/util/Copier.java [new file with mode: 0644]
dol/src/dol/util/JarCopier.java [new file with mode: 0644]
dol/src/dol/util/SchemaLocation.java [new file with mode: 0644]
dol/src/dol/util/Sed.java [new file with mode: 0644]
dol/src/dol/util/package.html [new file with mode: 0644]
dol/src/dol/visitor/ArchiVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/MapVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/PNVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/PipeAndFilterMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/PipeAndFilterModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/PipeAndFilterProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/PipeAndFilterVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Condition.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Condition.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Event.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Event.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Fifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Fifo.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Mutex.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Mutex.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/ProcessWrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/ProcessWrapper.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Scheduler.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/Scheduler.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/WindowedFifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/WindowedFifo.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/dolSupport.cpp [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/lib/dolSupport.h [new file with mode: 0644]
dol/src/dol/visitor/PipeAndFilter/package.html [new file with mode: 0644]
dol/src/dol/visitor/Visitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/CbeBuildFileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/CbeConstantVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/CbeMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/CbeModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/CbeProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/CbeVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/ProcessFifo.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/ProcessWrapper.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/ProcessWrapperHelp.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/ProcessWrapperPPE.c [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/common.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/common_ppu.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/estimation.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/free_align.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/malloc_align.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/ppu_main.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/lib/ppu_main_workloop.h [new file with mode: 0644]
dol/src/dol/visitor/cbe/template/ppu_process_wrapper_template.c [new file with mode: 0644]
dol/src/dol/visitor/cbe/template/spu_process_wrapper_template.c [new file with mode: 0644]
dol/src/dol/visitor/cell/CellBuildFileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellConstantVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellMapping.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellPPEVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellSPEVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/CellVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/common.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/estimation.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/free_align.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/malloc_align.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/FastCommunication.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/FastCommunication.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/Fifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/Fifo.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/ProcessWrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/ProcessWrapper.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/WindowedFifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/WindowedFifo.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/common.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/common_ppu.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/dolSupport.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu/dolSupport.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/ppu_main.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/pt/lc-addrlabels.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/pt/lc-switch.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/pt/lc.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/pt/pt-sem.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/pt/pt.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/FastCommunication.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/FastCommunication.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/Fifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/Fifo.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/WindowedFifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/WindowedFifo.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/common.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/dolSupport.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/dolSupport.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/proc_wrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu/proc_wrapper.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu_mfcio_ext.h [new file with mode: 0644]
dol/src/dol/visitor/cell/lib/spu_os.h [new file with mode: 0644]
dol/src/dol/visitor/cell/template/spu_process_wrapper_template.cpp [new file with mode: 0644]
dol/src/dol/visitor/cell/template/spu_process_wrapper_template.h [new file with mode: 0644]
dol/src/dol/visitor/dot/ArchDotVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/dot/MapDotVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/dot/PNDotVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/dot/package.html [new file with mode: 0644]
dol/src/dol/visitor/hds/HdsMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hds/HdsModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hds/HdsProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hds/HdsVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/Fifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/Fifo.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/Performance_Extraction.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/Performance_Extraction.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/ProcessWrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/ProcessWrapper.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/WindowedFifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/WindowedFifo.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/dolSupport.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/dolSupport.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/dol_sched_if.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/functional_trace.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/functional_trace.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/trace.h [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/xmlParser.cpp [new file with mode: 0644]
dol/src/dol/visitor/hds/lib/xmlParser.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdModuleArchVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdModulePNVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdScriptVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/HdsdVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/hdsd/lib/dol.c [new file with mode: 0644]
dol/src/dol/visitor/hdsd/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/lib/dol_sched_if.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/lib/simple_fifo.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm_if.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_state.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_wrapper_if.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_base.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_base.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_busy.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_busy.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_fail.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_fail.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_failed.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_failed.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_idle.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_idle.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_init.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_init.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_term_req.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_term_req.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminate.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminate.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminated.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminated.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time_req.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time_req.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_base.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_base.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_busy.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_busy.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_done.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_done.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_fail.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_fail.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_failed.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_failed.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_idle.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_idle.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_init.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_init.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_term_ack.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_term_ack.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_terminated.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_terminated.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time_ack.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time_ack.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_base.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_base.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_busy.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_busy.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_done.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_done.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_fail.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_fail.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_failed.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_failed.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_idle.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_idle.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_init.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_init.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_ack.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_ack.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_req.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_req.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminate.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminate.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminated.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminated.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_ack.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_ack.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_req.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_req.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_chan_man.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_chan_man.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_chan_wrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_chan_wrapper.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_command.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_command.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_command_reader.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_command_reader.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_command_writer.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_command_writer.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_man.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_man_master.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_man_master.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_slave_wrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_cont_slave_wrapper.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_exception.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_exception.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_in_connector.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_in_connector.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_init_listener.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_init_listener.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_logging.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_logging.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_out_connector.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_out_connector.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_rem_chan_if.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_in.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_in.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_out.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_out.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_simulator.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_simulator.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_sock_poller.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_sock_poller.h [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_socket.cpp [new file with mode: 0644]
dol/src/dol/visitor/hdsd/scd/scd_socket.h [new file with mode: 0644]
dol/src/dol/visitor/package.html [new file with mode: 0644]
dol/src/dol/visitor/protothread/ProtothreadMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/protothread/ProtothreadModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/protothread/ProtothreadProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/protothread/ProtothreadVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/Fifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/Fifo.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/ProcessWrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/ProcessWrapper.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/WindowedFifo.cpp [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/WindowedFifo.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/dolSupport.cpp [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/dolSupport.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/lc-addrlabels.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/lc-switch.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/lc.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/pt-sem.h [new file with mode: 0644]
dol/src/dol/visitor/protothread/lib/pt.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/RtemsMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/rtems/RtemsModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/rtems/RtemsProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/rtems/RtemsPropertiesVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/rtems/RtemsShaperVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/rtems/RtemsVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/README [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/appsupport.c [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/appsupport.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/buffer_test_io.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/process_wrapper_template.c [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/rtems_process_wrapper.c [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/rtems_process_wrapper.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/system.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/tmacros.h [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/traffic_shaping.c [new file with mode: 0644]
dol/src/dol/visitor/rtems/lib/traffic_shaping.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/MakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/systemC/PNSystemCVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/systemC/ProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/systemC/SCModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/dol.c [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/dol_fifo.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/dol_fifo_if.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/dol_rp_ids.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/dol_sched_if.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/lib/simple_fifo.h [new file with mode: 0644]
dol/src/dol/visitor/systemC/package.html [new file with mode: 0644]
dol/src/dol/visitor/xml/MapXmlVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/xml/PNXmlVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/xml/package.html [new file with mode: 0644]
dol/src/dol/visitor/yapi/YapiMakefileVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/yapi/YapiModuleVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/yapi/YapiProcessVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/yapi/YapiVisitor.java [new file with mode: 0644]
dol/src/dol/visitor/yapi/lib/ProcessWrapper.cpp [new file with mode: 0644]
dol/src/dol/visitor/yapi/lib/ProcessWrapper.h [new file with mode: 0644]
dol/src/dol/visitor/yapi/lib/dol.h [new file with mode: 0644]
dol/src/dol/visitor/yapi/lib/dolSupport.cpp [new file with mode: 0644]
dol/src/dol/visitor/yapi/lib/dolSupport.h [new file with mode: 0644]
dol/src/dol/visitor/yapi/lib/main.cpp [new file with mode: 0644]
dol/src/dol/visitor/yapi/package.html [new file with mode: 0644]
dol/src/dol_template.properties [new file with mode: 0644]
dol/test/dolziptest.xml [new file with mode: 0644]
dol/test/reference/example1_Linux.txt [new file with mode: 0644]
dol/test/reference/example1_Windows XP.txt [new file with mode: 0644]
dol/test/reference/example2_Linux.txt [new file with mode: 0644]
dol/test/reference/example2_Windows XP.txt [new file with mode: 0644]
dol/test/reference/example3_Linux.txt [new file with mode: 0644]
dol/test/reference/example3_Windows XP.txt [new file with mode: 0644]
dol/test/reference/example4_Linux.txt [new file with mode: 0644]
dol/test/reference/example4_Windows XP.txt [new file with mode: 0644]
dol/test/reference/example5_Linux.txt [new file with mode: 0644]
dol/test/reference/example5_Windows XP.txt [new file with mode: 0644]
dol/test/reference/example6_Linux.txt [new file with mode: 0644]
dol/test/reference/example6_Windows XP.txt [new file with mode: 0644]
dol/test/reference/example7_Linux.txt [new file with mode: 0644]
dol/test/reference/example7_Windows XP.txt [new file with mode: 0644]
dol/test/reference/examplesingleprocess_Linux.txt [new file with mode: 0644]
dol/test/reference/examplesingleprocess_Windows XP.txt [new file with mode: 0644]
dol/test/runtests.xml [new file with mode: 0644]
dol/test/src/test/test/TreeValidator.java [new file with mode: 0644]
dol/test/src/test/util/Diff.java [new file with mode: 0644]
dol/test/src/test/util/XMLValidator.java [new file with mode: 0644]
dol/test/test.properties [new file with mode: 0644]

diff --git a/dol/.classpath b/dol/.classpath
new file mode 100644 (file)
index 0000000..b331c6d
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="test/src"/>\r
+       <classpathentry kind="lib" path="jars/jdom.jar"/>\r
+       <classpathentry kind="lib" path="jars/xercesImpl.jar"/>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/dol/.project b/dol/.project
new file mode 100644 (file)
index 0000000..cb7f5e5
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>DOL_tecmp</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/dol/build.xml b/dol/build.xml
new file mode 100644 (file)
index 0000000..a47b050
--- /dev/null
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="dol" default="compile" basedir=".">
+
+  <description>
+    Ant build file for DOL and its documentation.
+  </description>
+
+  <!-- ************************************************************** -->
+  <!-- properties                                                     -->
+  <!-- ************************************************************** -->
+  <!-- source directories -->
+  <property name="dol.path"      value="${basedir}"/>
+  <property name="systemc.inc"   value="/home/shapes/base/resources/lib/systemC/include"/>
+  <property name="systemc.lib"   value="/home/shapes/base/resources/lib/systemC/lib-linux/libsystemc.a"/>
+
+  <property name="src.dir"       location="src"/>
+  <property name="doc.dir"       location="docs"/>
+  <property name="jars.dir"      location="jars"/>
+  <property name="example.dir"   location="examples"/>
+
+  <!-- build directories -->
+  <property name="build.dir"     location="build"/>
+  <property name="bin.dir"       location="${build.dir}/bin"/>
+  <property name="bin.main.dir"  location="${bin.dir}/main"/>
+  <property name="doc.api.dir"   location="${doc.dir}/api"/>
+  <property name="doc.build.dir" location="${build.dir}/docs"/>
+  <property name="expo.dir"      location="../expo"/>
+
+  <!-- distribution directories -->
+  <property name="bin-dist.name" value="dol.jar"/>
+  <property name="api.name"      value="SHAPES Distributed Operation Layer (DOL)"/>
+
+  <!-- jar files -->
+  <property name="jars"          value=".:${jars.dir}/jdom.jar:${jars.dir}/xercesImpl.jar"/>
+
+
+  <!-- *************************************************************** -->
+  <!-- tasks                                                           -->
+  <!-- *************************************************************** -->
+  <!-- build all -->
+  <target name="all" depends="config, compile"/>
+
+  <!-- compile DOL java classes -->
+  <target name="compile">
+    <mkdir dir="${build.dir}"/>
+    <mkdir dir="${bin.dir}"/>
+    <mkdir dir="${bin.main.dir}"/>
+
+    <!-- compile dol sources -->
+    <javac destdir="${bin.main.dir}" debug="true" classpath="${jars}">
+      <src path="${src.dir}"/>
+      <compilerarg value="-Xlint:unchecked"/>
+    </javac>
+    <javac destdir="${bin.main.dir}"
+      debug="true"
+      classpath="jars/jdom.jar:jars/xercesImpl.jar">
+      <src path="test/src"/>
+    </javac>
+    <copy todir="${bin.main.dir}" file="${src.dir}/dol.properties"/>
+    <copy todir="${bin.main.dir}">
+      <fileset dir="${src.dir}"
+        includes="dol/visitor/systemC/lib/**
+                  dol/visitor/hds/lib/**
+                  dol/visitor/PipeAndFilter/lib/**
+                  dol/visitor/hdsd/lib/**
+                  dol/visitor/hdsd/scd/**
+                  dol/visitor/hdsd/scd/fsm/**
+                  dol/visitor/rtems/lib/**
+                  dol/visitor/protothread/lib/**
+                  dol/visitor/cbe/lib/**
+                  dol/visitor/cbe/template/**
+                  dol/visitor/cell/lib/**
+                  dol/visitor/cell/template/**"/>
+    </copy>
+
+    <!-- copy example run scripts -->
+    <copy todir="${bin.main.dir}" file="examples/runexample.xml"/>
+    <copy todir="${bin.main.dir}" file="examples/runprofiler.xml"/>
+    <copy todir="${bin.main.dir}">
+      <fileset dir="examples"
+               includes="schema/**"
+               excludes="schema/createschemastex"/>
+    </copy>
+    
+    <!-- compile test sources -->
+    <javac destdir="${bin.main.dir}"
+      debug="true"
+      classpath="jars/jdom.jar:jars/xercesImpl.jar">
+      <src path="test/src"/>
+    </javac>
+    <copy todir="${bin.main.dir}" file="test/runtests.xml"/>
+    <copy tofile="${bin.main.dir}/test.properties" file="test/test.properties">
+      <filterchain>
+         <replacetokens>
+            <token key="schema_path" value="${example.dir}/schema"/>
+         </replacetokens>
+      </filterchain>
+      <filterchain>
+        <tokenfilter>
+          <replaceregex pattern="(.)\\([^ ])"
+                        replace="\1/\2"
+                        flags="g"/>
+        </tokenfilter>
+      </filterchain>
+    </copy>
+
+    <antcall target="createjar"/>
+    <!-- <antcall target="javadoc"/> -->
+  </target>
+
+  <target name="config">
+    <echo message="Create new dol.properties file."/>
+    <delete file="${src.dir}/dol.properties" quiet="true"/>
+    <copy file="${src.dir}/dol_template.properties"
+      tofile="${src.dir}/dol.properties">
+      <filterchain>
+         <replacetokens>
+            <token key="dol_path"                value="${dol.path}"/>
+            <token key="systemc_inc"             value="${systemc.inc}"/>
+            <token key="systemc_lib"             value="${systemc.lib}"/>
+         </replacetokens>
+      </filterchain>
+    </copy>
+  </target>
+
+  <!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
+  <target name="test" depends="compile">
+    <javac destdir="${bin.main.dir}" debug="true" classpath="jars/jdom.jar:jar/xercesImpl.jar">
+      <src path="test/src"/>
+    </javac>
+    <copy todir="${bin.main.dir}" file="test/runtests.xml"/>
+    <copy todir="${bin.main.dir}" file="examples/runexample.xml"/>
+    <copy tofile="${bin.main.dir}/test.properties" file="test/test.properties">
+      <filterchain>
+         <replacetokens>
+            <token key="schema_path" value="${example.dir}/schema"/>
+         </replacetokens>
+      </filterchain>
+      <filterchain>
+        <tokenfilter>
+          <replaceregex pattern="(.)\\([^ ])"
+                        replace="\1/\2"
+                        flags="g"/>
+        </tokenfilter>
+      </filterchain>
+    </copy>
+  </target>
+  -->
+
+  <target name="javadoc">
+    <mkdir dir="${doc.build.dir}"/>
+    <javadoc packagenames="dol.*"
+             classpath="${jars}"
+             sourcepath="${src.dir}"
+             destdir="${doc.build.dir}"
+             access="public"
+             author="true"
+             version="true"
+             use="true"
+             windowtitle="${api.name}">
+      <doctitle><![CDATA[<h1>${api.name}</h1>]]></doctitle>
+      <bottom><![CDATA[<i>Copyright &#169; 2005-2007 Computer Engineering and Networks Laboratory (TIK), ETH Z&uuml;rich. All Rights Reserved.</i>]]></bottom>
+    </javadoc>
+  </target>
+
+  <target name="createjar">
+    <jar destfile="${bin-dist.name}" manifest="${src.dir}/MANIFEST.MF">
+      <fileset dir="${bin.main.dir}"
+               includes="dol/** dol.properties"/>
+      <fileset dir="examples"
+               includes="schema/**"
+               excludes="schema/createschemastex"/>
+    </jar>
+    <copy file="${bin-dist.name}" todir="${expo.dir}/jars"/>
+  </target>
+
+  <!-- clean up everything -->
+  <target name="clean">
+    <delete dir="${build.dir}"/>
+    <delete file="${bin-dist.name}"/>
+  </target>
+</project>
diff --git a/dol/examples/arch/cell.xml b/dol/examples/arch/cell.xml
new file mode 100644 (file)
index 0000000..c1397f3
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<architecture xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE
+                      http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd"
+  name="Sony/Toshiba/IBM Cell Broadband Engine architecture">
+
+  <processor name="ppu" type="RISC">
+  </processor>
+  
+  <processor name="spu_0" type="DSP">
+  </processor>
+
+  <processor name="spu_1" type="DSP">
+  </processor>
+  
+  <processor name="spu_2" type="DSP">
+  </processor>
+  
+  <processor name="spu_3" type="DSP">
+  </processor>
+  
+  <processor name="spu_4" type="DSP">
+  </processor>
+  
+  <processor name="spu_5" type="DSP">
+  </processor>
+  
+</architecture>
diff --git a/dol/examples/arch/mparm.xml b/dol/examples/arch/mparm.xml
new file mode 100644 (file)
index 0000000..af637da
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<architecture xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE
+                      http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd"
+  name="MPARM architecture">
+
+  <processor name="processor_0" basename="processor" range="8" type="RISC">
+  </processor>
+  
+  <processor name="processor_1" basename="processor" range="8" type="RISC">
+  </processor>
+
+  <processor name="processor_2" basename="processor" range="8" type="RISC">
+  </processor>
+
+  <processor name="processor_3" basename="processor" range="8" type="RISC">
+  </processor>
+
+  <processor name="processor_4" basename="processor" range="8" type="RISC">
+  </processor>
+
+  <processor name="processor_5" basename="processor" range="8" type="RISC">
+  </processor>
+
+  <processor name="processor_6" basename="processor" range="8" type="RISC">
+  </processor>
+
+  <processor name="processor_7" basename="processor" range="8" type="RISC">
+  </processor>
+</architecture>
diff --git a/dol/examples/arch/rdt1.xml b/dol/examples/arch/rdt1.xml
new file mode 100644 (file)
index 0000000..aa385c7
--- /dev/null
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<architecture xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE"\r
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE\r
+                      http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd"\r
+  name="RDT1">\r
+\r
+  <!-- rdt(tile_0) arm subsystem -->\r
+  <processor name="tile_0.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_0.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_0.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!-- rdt(tile_0) magic subsystem -->\r
+  <processor name="tile_0.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_0.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_0.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_0.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!-- rdt(tile_0) distributed external memory -->\r
+  <memory name="tile_0.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <!-- rdt(tile_0) ahb multi-layer bus -->\r
+  <hw_channel name="tile_0.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_0.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!-- rdt(tile_0) dnp -->\r
+  <hw_channel name="tile_0.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!-- rdt(tile_0) on-tile communication paths -->\r
+  <!-- rdt(tile_0) arm paths via dxm-->\r
+  <writepath name="tile_0.rdmtodxm">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.rdmfromdxm">\r
+    <processor name="tile_0.arm"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <rxbuf name="tile_0.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- rdt(tile_0) arm paths via rdm-->\r
+  <writepath name="tile_0.rdmtordm">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <chbuf name="tile_0.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.rdmfromrdm">\r
+    <processor name="tile_0.arm"/>\r
+    <chbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <rxbuf name="tile_0.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- rdt(tile_0) magic paths via ddm-->\r
+  <writepath name="tile_0.ddmtoddm">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.magicbus"/>\r
+    <chbuf name="tile_0.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.ddmfromddm">\r
+    <processor name="tile_0.magic"/>\r
+    <chbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.magicbus"/>\r
+    <rxbuf name="tile_0.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- rdt(tile_0) magic paths via dxm-->\r
+  <writepath name="tile_0.ddmtodxm">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.dma"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.ddmfromdxm">\r
+    <processor name="tile_0.magic"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <hw_channel name="tile_0.dma"/>\r
+    <rxbuf name="tile_0.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+</architecture>\r
diff --git a/dol/examples/arch/rdt8.xml b/dol/examples/arch/rdt8.xml
new file mode 100644 (file)
index 0000000..5f7189b
--- /dev/null
@@ -0,0 +1,2059 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<architecture xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE"\r
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE\r
+                      http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd"\r
+  name="RDT8">\r
+  <!-- 8 Tiles communicating via a mesh of DNPs -->\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_0 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_0.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_0.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_0.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_0.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_0.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_0.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_0.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_0.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_0.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_0.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_0.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_1 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_1.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_1.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_1.armbus" type="BUS">\r
+   <configuration name="frequency" value="100000000"/>\r
+   <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_1.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_1.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_1.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_1.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_1.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_1.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_1.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_1.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_2 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_2.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_2.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_2.armbus" type="BUS">\r
+   <configuration name="frequency" value="100000000"/>\r
+   <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_2.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_2.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_2.magicbus" type="BUS">\r
+   <configuration name="frequency" value="100000000"/>\r
+   <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_2.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_2.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_2.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_2.ahb1" type="BUS">\r
+   <configuration name="frequency" value="100000000"/>\r
+   <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_2.dnp" type="SPI">\r
+   <configuration name="frequency" value="100000000"/>\r
+   <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_3 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_3.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_3.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_3.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_3.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_3.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_3.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_3.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_3.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_3.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_3.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_3.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_4 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_4.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_4.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_4.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_4.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_4.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_4.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_4.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_4.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_4.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_4.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_4.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_5 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_5.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_5.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_5.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_5.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_5.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_5.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_5.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_5.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_5.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_5.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_5.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_6 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_6.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_6.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_6.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_6.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_6.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_6.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_6.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_6.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_6.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_6.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_6.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_7 -->\r
+  <!--*****************************************************************-->\r
+  <processor name="tile_7.arm" type="RISC">\r
+  </processor>\r
+\r
+  <memory name="tile_7.rdm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_7.armbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <processor name="tile_7.magic" type="DSP">\r
+  </processor>\r
+\r
+  <memory name="tile_7.ddm" type="RAM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_7.magicbus" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_7.dma" type="DMA">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <memory name="tile_7.dxm" type="DXM">\r
+  </memory>\r
+\r
+  <hw_channel name="tile_7.ahb0" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_7.ahb1" type="BUS">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+  <hw_channel name="tile_7.dnp" type="SPI">\r
+    <configuration name="frequency" value="100000000"/>\r
+    <configuration name="bytespercycle" value="1"/>\r
+  </hw_channel>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_0 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_0.rdmtodxm">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.rdmfromdxm">\r
+    <processor name="tile_0.arm"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <rxbuf name="tile_0.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_0.rdmtordm">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <chbuf name="tile_0.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.rdmfromrdm">\r
+    <processor name="tile_0.arm"/>\r
+    <chbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.armbus"/>\r
+    <rxbuf name="tile_0.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_0.ddmtoddm">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.magicbus"/>\r
+    <chbuf name="tile_0.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.ddmfromddm">\r
+    <processor name="tile_0.magic"/>\r
+    <chbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.magicbus"/>\r
+    <rxbuf name="tile_0.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_0.ddmtodxm">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.dma"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_0.ddmfromdxm">\r
+    <processor name="tile_0.magic"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+    <hw_channel name="tile_0.ahb1"/>\r
+    <hw_channel name="tile_0.dma"/>\r
+    <rxbuf name="tile_0.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_0 ARM inter-tile communication paths -->\r
+  <writepath name="tile_0.rdmtodnp_1">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.rdmtodnp_2">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.rdmtodnp_3">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.rdmtodnp_4">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.rdmtodnp_5">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.rdmtodnp_6">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.rdmtodnp_7">\r
+    <processor name="tile_0.arm"/>\r
+    <txbuf name="tile_0.rdm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_0 DSP inter-tile communication paths -->\r
+  <writepath name="tile_0.ddmtodnp_1">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.ddmtodnp_2">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.ddmtodnp_3">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.ddmtodnp_4">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.ddmtodnp_5">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.ddmtodnp_6">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_0.ddmtodnp_7">\r
+    <processor name="tile_0.magic"/>\r
+    <txbuf name="tile_0.ddm"/>\r
+    <hw_channel name="tile_0.ahb0"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_1 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_1.rdmtodxm">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.armbus"/>\r
+    <hw_channel name="tile_1.ahb1"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_1.rdmfromdxm">\r
+    <processor name="tile_1.arm"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+    <hw_channel name="tile_1.ahb1"/>\r
+    <hw_channel name="tile_1.armbus"/>\r
+    <rxbuf name="tile_1.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_1.rdmtordm">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.armbus"/>\r
+    <chbuf name="tile_1.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_1.rdmfromrdm">\r
+    <processor name="tile_1.arm"/>\r
+    <chbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.armbus"/>\r
+    <rxbuf name="tile_1.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_1.ddmtoddm">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.magicbus"/>\r
+    <chbuf name="tile_1.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_1.ddmfromddm">\r
+    <processor name="tile_1.magic"/>\r
+    <chbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.magicbus"/>\r
+    <rxbuf name="tile_1.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_1.ddmtodxm">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.dma"/>\r
+    <hw_channel name="tile_1.ahb1"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_1.ddmfromdxm">\r
+    <processor name="tile_1.magic"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+    <hw_channel name="tile_1.ahb1"/>\r
+    <hw_channel name="tile_1.dma"/>\r
+    <rxbuf name="tile_1.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_1 ARM inter-tile communication paths -->\r
+  <writepath name="tile_1.rdmtodnp_0">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.rdmtodnp_2">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.rdmtodnp_3">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.rdmtodnp_4">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.rdmtodnp_5">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.rdmtodnp_6">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.rdmtodnp_7">\r
+    <processor name="tile_1.arm"/>\r
+    <txbuf name="tile_1.rdm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_1 DSP inter-tile communication paths -->\r
+  <writepath name="tile_1.ddmtodnp_0">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.ddmtodnp_2">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.ddmtodnp_3">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.ddmtodnp_4">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.ddmtodnp_5">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.ddmtodnp_6">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_1.ddmtodnp_7">\r
+    <processor name="tile_1.magic"/>\r
+    <txbuf name="tile_1.ddm"/>\r
+    <hw_channel name="tile_1.ahb0"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_2 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_2.rdmtodxm">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.armbus"/>\r
+    <hw_channel name="tile_2.ahb1"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_2.rdmfromdxm">\r
+    <processor name="tile_2.arm"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+    <hw_channel name="tile_2.ahb1"/>\r
+    <hw_channel name="tile_2.armbus"/>\r
+    <rxbuf name="tile_2.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_2.rdmtordm">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.armbus"/>\r
+    <chbuf name="tile_2.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_2.rdmfromrdm">\r
+    <processor name="tile_2.arm"/>\r
+    <chbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.armbus"/>\r
+    <rxbuf name="tile_2.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_2.ddmtoddm">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.magicbus"/>\r
+    <chbuf name="tile_2.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_2.ddmfromddm">\r
+    <processor name="tile_2.magic"/>\r
+    <chbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.magicbus"/>\r
+    <rxbuf name="tile_2.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_2.ddmtodxm">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.dma"/>\r
+    <hw_channel name="tile_2.ahb1"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_2.ddmfromdxm">\r
+    <processor name="tile_2.magic"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+    <hw_channel name="tile_2.ahb1"/>\r
+    <hw_channel name="tile_2.dma"/>\r
+    <rxbuf name="tile_2.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_2 ARM inter-tile communication paths -->\r
+  <writepath name="tile_2.rdmtodnp_0">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.rdmtodnp_1">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.rdmtodnp_3">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.rdmtodnp_4">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.rdmtodnp_5">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.rdmtodnp_6">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.rdmtodnp_7">\r
+    <processor name="tile_2.arm"/>\r
+    <txbuf name="tile_2.rdm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_2 DSP inter-tile communication paths -->\r
+  <writepath name="tile_2.ddmtodnp_0">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.ddmtodnp_1">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.ddmtodnp_3">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.ddmtodnp_4">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.ddmtodnp_5">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.ddmtodnp_6">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_2.ddmtodnp_7">\r
+    <processor name="tile_2.magic"/>\r
+    <txbuf name="tile_2.ddm"/>\r
+    <hw_channel name="tile_2.ahb0"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_3 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_3.rdmtodxm">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.armbus"/>\r
+    <hw_channel name="tile_3.ahb1"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_3.rdmfromdxm">\r
+    <processor name="tile_3.arm"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+    <hw_channel name="tile_3.ahb1"/>\r
+    <hw_channel name="tile_3.armbus"/>\r
+    <rxbuf name="tile_3.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_3.rdmtordm">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.armbus"/>\r
+    <chbuf name="tile_3.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_3.rdmfromrdm">\r
+    <processor name="tile_3.arm"/>\r
+    <chbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.armbus"/>\r
+    <rxbuf name="tile_3.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_3.ddmtoddm">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.magicbus"/>\r
+    <chbuf name="tile_3.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_3.ddmfromddm">\r
+    <processor name="tile_3.magic"/>\r
+    <chbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.magicbus"/>\r
+    <rxbuf name="tile_3.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_3.ddmtodxm">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.dma"/>\r
+    <hw_channel name="tile_3.ahb1"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_3.ddmfromdxm">\r
+    <processor name="tile_3.magic"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+    <hw_channel name="tile_3.ahb1"/>\r
+    <hw_channel name="tile_3.dma"/>\r
+    <rxbuf name="tile_3.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_3 ARM inter-tile communication paths -->\r
+  <writepath name="tile_3.rdmtodnp_0">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.rdmtodnp_1">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.rdmtodnp_2">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.rdmtodnp_4">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.rdmtodnp_5">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.rdmtodnp_6">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.rdmtodnp_7">\r
+    <processor name="tile_3.arm"/>\r
+    <txbuf name="tile_3.rdm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_3 DSP inter-tile communication paths -->\r
+  <writepath name="tile_3.ddmtodnp_0">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.ddmtodnp_1">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.ddmtodnp_2">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.ddmtodnp_4">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.ddmtodnp_5">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.ddmtodnp_6">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_3.ddmtodnp_7">\r
+    <processor name="tile_3.magic"/>\r
+    <txbuf name="tile_3.ddm"/>\r
+    <hw_channel name="tile_3.ahb0"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_4 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_4.rdmtodxm">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.armbus"/>\r
+    <hw_channel name="tile_4.ahb1"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_4.rdmfromdxm">\r
+    <processor name="tile_4.arm"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+    <hw_channel name="tile_4.ahb1"/>\r
+    <hw_channel name="tile_4.armbus"/>\r
+    <rxbuf name="tile_4.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_4.rdmtordm">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.armbus"/>\r
+    <chbuf name="tile_4.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_4.rdmfromrdm">\r
+    <processor name="tile_4.arm"/>\r
+    <chbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.armbus"/>\r
+    <rxbuf name="tile_4.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_4.ddmtoddm">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.magicbus"/>\r
+    <chbuf name="tile_4.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_4.ddmfromddm">\r
+    <processor name="tile_4.magic"/>\r
+    <chbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.magicbus"/>\r
+    <rxbuf name="tile_4.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_4.ddmtodxm">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.dma"/>\r
+    <hw_channel name="tile_4.ahb1"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_4.ddmfromdxm">\r
+    <processor name="tile_4.magic"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+    <hw_channel name="tile_4.ahb1"/>\r
+    <hw_channel name="tile_4.dma"/>\r
+    <rxbuf name="tile_4.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_4 ARM inter-tile communication paths -->\r
+  <writepath name="tile_4.rdmtodnp_0">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.rdmtodnp_1">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.rdmtodnp_2">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.rdmtodnp_3">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.rdmtodnp_5">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.rdmtodnp_6">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.rdmtodnp_7">\r
+    <processor name="tile_4.arm"/>\r
+    <txbuf name="tile_4.rdm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_4 DSP inter-tile communication paths -->\r
+  <writepath name="tile_4.ddmtodnp_0">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.ddmtodnp_1">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.ddmtodnp_2">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.ddmtodnp_3">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.ddmtodnp_5">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.ddmtodnp_6">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_4.ddmtodnp_7">\r
+    <processor name="tile_4.magic"/>\r
+    <txbuf name="tile_4.ddm"/>\r
+    <hw_channel name="tile_4.ahb0"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_5 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_5.rdmtodxm">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.armbus"/>\r
+    <hw_channel name="tile_5.ahb1"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_5.rdmfromdxm">\r
+    <processor name="tile_5.arm"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+    <hw_channel name="tile_5.ahb1"/>\r
+    <hw_channel name="tile_5.armbus"/>\r
+    <rxbuf name="tile_5.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_5.rdmtordm">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.armbus"/>\r
+    <chbuf name="tile_5.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_5.rdmfromrdm">\r
+    <processor name="tile_5.arm"/>\r
+    <chbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.armbus"/>\r
+    <rxbuf name="tile_5.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_5.ddmtoddm">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.magicbus"/>\r
+    <chbuf name="tile_5.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_5.ddmfromddm">\r
+    <processor name="tile_5.magic"/>\r
+    <chbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.magicbus"/>\r
+    <rxbuf name="tile_5.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_5.ddmtodxm">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.dma"/>\r
+    <hw_channel name="tile_5.ahb1"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_5.ddmfromdxm">\r
+    <processor name="tile_5.magic"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+    <hw_channel name="tile_5.ahb1"/>\r
+    <hw_channel name="tile_5.dma"/>\r
+    <rxbuf name="tile_5.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_5 ARM inter-tile communication paths -->\r
+  <writepath name="tile_5.rdmtodnp_0">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.rdmtodnp_1">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.rdmtodnp_2">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.rdmtodnp_3">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.rdmtodnp_4">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.rdmtodnp_6">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.rdmtodnp_7">\r
+    <processor name="tile_5.arm"/>\r
+    <txbuf name="tile_5.rdm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_5 DSP inter-tile communication paths -->\r
+  <writepath name="tile_5.ddmtodnp_0">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.ddmtodnp_1">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.ddmtodnp_2">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.ddmtodnp_3">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.ddmtodnp_4">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.ddmtodnp_6">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_5.ddmtodnp_7">\r
+    <processor name="tile_5.magic"/>\r
+    <txbuf name="tile_5.ddm"/>\r
+    <hw_channel name="tile_5.ahb0"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_6 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_6.rdmtodxm">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.armbus"/>\r
+    <hw_channel name="tile_6.ahb1"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_6.rdmfromdxm">\r
+    <processor name="tile_6.arm"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+    <hw_channel name="tile_6.ahb1"/>\r
+    <hw_channel name="tile_6.armbus"/>\r
+    <rxbuf name="tile_6.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_6.rdmtordm">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.armbus"/>\r
+    <chbuf name="tile_6.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_6.rdmfromrdm">\r
+    <processor name="tile_6.arm"/>\r
+    <chbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.armbus"/>\r
+    <rxbuf name="tile_6.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_6.ddmtoddm">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.magicbus"/>\r
+    <chbuf name="tile_6.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_6.ddmfromddm">\r
+    <processor name="tile_6.magic"/>\r
+    <chbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.magicbus"/>\r
+    <rxbuf name="tile_6.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_6.ddmtodxm">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.dma"/>\r
+    <hw_channel name="tile_6.ahb1"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_6.ddmfromdxm">\r
+    <processor name="tile_6.magic"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+    <hw_channel name="tile_6.ahb1"/>\r
+    <hw_channel name="tile_6.dma"/>\r
+    <rxbuf name="tile_6.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_6 ARM inter-tile communication paths -->\r
+  <writepath name="tile_6.rdmtodnp_0">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.rdmtodnp_1">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.rdmtodnp_2">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.rdmtodnp_3">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.rdmtodnp_4">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.rdmtodnp_5">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.rdmtodnp_7">\r
+    <processor name="tile_6.arm"/>\r
+    <txbuf name="tile_6.rdm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_6 DSP inter-tile communication paths -->\r
+  <writepath name="tile_6.ddmtodnp_0">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.ddmtodnp_1">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.ddmtodnp_2">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.ddmtodnp_3">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.ddmtodnp_4">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.ddmtodnp_5">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_6.ddmtodnp_7">\r
+    <processor name="tile_6.magic"/>\r
+    <txbuf name="tile_6.ddm"/>\r
+    <hw_channel name="tile_6.ahb0"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+  </writepath>\r
+\r
+\r
+  <!--*****************************************************************-->\r
+  <!-- tile_7 communication paths -->\r
+  <!--*****************************************************************-->\r
+  <writepath name="tile_7.rdmtodxm">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.armbus"/>\r
+    <hw_channel name="tile_7.ahb1"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_7.rdmfromdxm">\r
+    <processor name="tile_7.arm"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+    <hw_channel name="tile_7.ahb1"/>\r
+    <hw_channel name="tile_7.armbus"/>\r
+    <rxbuf name="tile_7.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_7.rdmtordm">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.armbus"/>\r
+    <chbuf name="tile_7.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_7.rdmfromrdm">\r
+    <processor name="tile_7.arm"/>\r
+    <chbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.armbus"/>\r
+    <rxbuf name="tile_7.rdm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_7.ddmtoddm">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.magicbus"/>\r
+    <chbuf name="tile_7.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_7.ddmfromddm">\r
+    <processor name="tile_7.magic"/>\r
+    <chbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.magicbus"/>\r
+    <rxbuf name="tile_7.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <writepath name="tile_7.ddmtodxm">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.dma"/>\r
+    <hw_channel name="tile_7.ahb1"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </writepath>\r
+\r
+  <readpath name="tile_7.ddmfromdxm">\r
+    <processor name="tile_7.magic"/>\r
+    <chbuf name="tile_7.dxm"/>\r
+    <hw_channel name="tile_7.ahb1"/>\r
+    <hw_channel name="tile_7.dma"/>\r
+    <rxbuf name="tile_7.ddm"/>\r
+    <configuration name="delay" value="0"/>\r
+    <configuration name="cycles" value="8"/>\r
+  </readpath>\r
+\r
+  <!-- tile_7 ARM inter-tile communication paths -->\r
+  <writepath name="tile_7.rdmtodnp_0">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.rdmtodnp_1">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.rdmtodnp_2">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.rdmtodnp_3">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.rdmtodnp_4">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.rdmtodnp_5">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.rdmtodnp_6">\r
+    <processor name="tile_7.arm"/>\r
+    <txbuf name="tile_7.rdm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+  <!-- tile_7 DSP inter-tile communication paths -->\r
+  <writepath name="tile_7.ddmtodnp_0">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_0.dnp"/>\r
+    <chbuf name="tile_0.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.ddmtodnp_1">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_1.dnp"/>\r
+    <chbuf name="tile_1.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.ddmtodnp_2">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_2.dnp"/>\r
+    <chbuf name="tile_2.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.ddmtodnp_3">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_3.dnp"/>\r
+    <chbuf name="tile_3.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.ddmtodnp_4">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_4.dnp"/>\r
+    <chbuf name="tile_4.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.ddmtodnp_5">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_5.dnp"/>\r
+    <chbuf name="tile_5.dxm"/>\r
+  </writepath>\r
+\r
+  <writepath name="tile_7.ddmtodnp_6">\r
+    <processor name="tile_7.magic"/>\r
+    <txbuf name="tile_7.ddm"/>\r
+    <hw_channel name="tile_7.ahb0"/>\r
+    <hw_channel name="tile_7.dnp"/>\r
+    <hw_channel name="tile_6.dnp"/>\r
+    <chbuf name="tile_6.dxm"/>\r
+  </writepath>\r
+\r
+</architecture>
\ No newline at end of file
diff --git a/dol/examples/example1/example1.xml b/dol/examples/example1/example1.xml
new file mode 100644 (file)
index 0000000..654aaad
--- /dev/null
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork 
+xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" 
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+    http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="example1"> 
+
+  <!-- processes -->
+  <process name="generator"> 
+    <port type="output" name="1"/>
+    <source type="c" location="generator.c"/>
+  </process>
+
+  <process name="consumer"> 
+    <port type="input" name="1"/> 
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <process name="square"> 
+    <port type="input" name="1"/>
+    <port type="output" name="2"/>
+    <source type="c" location="square.c"/>
+  </process>
+
+  <!-- sw_channels -->
+  <sw_channel type="fifo" size="10" name="C1">
+    <port type="input" name="0"/>
+    <port type="output" name="1"/>
+  </sw_channel>
+
+  <sw_channel type="fifo" size="10" name="C2">
+    <port type="input" name="0"/>
+    <port type="output" name="1"/>
+  </sw_channel>
+
+  <!-- connections -->
+  <connection name="g-c">
+    <origin name="generator">
+      <port name="1"/>
+    </origin>
+    <target name="C1">
+      <port name="0"/>
+    </target>
+  </connection>
+
+  <connection name="c-c">
+    <origin name="C2">
+      <port name="1"/>
+    </origin>
+    <target name="consumer">
+      <port name="1"/>
+    </target>
+  </connection>
+
+  <connection name="s-c">
+    <origin name="square">
+      <port name="2"/>
+    </origin>
+    <target name="C2">
+      <port name="0"/>
+    </target>
+  </connection>
+
+  <connection name="c-s">
+    <origin name="C1">
+      <port name="1"/>
+    </origin>
+    <target name="square">
+      <port name="1"/>
+    </target>
+  </connection>
+
+</processnetwork>
diff --git a/dol/examples/example1/map_1.xml b/dol/examples/example1/map_1.xml
new file mode 100644 (file)
index 0000000..46820c3
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mapping xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING     http://www.tik.ee.ethz.ch/~shapes/schema/mapping.xsd" name="example1_map_1">
+<binding name="generator" xsi:type="computation">
+       <process name="generator" />
+       <processor name="sim1" />
+</binding>
+<binding name="consumer" xsi:type="computation">
+       <process name="consumer" />
+       <processor name="sim1" />
+</binding>
+<binding name="square" xsi:type="computation">
+       <process name="square" />
+       <processor name="sim1" />
+</binding>
+</mapping>
diff --git a/dol/examples/example1/map_3.xml b/dol/examples/example1/map_3.xml
new file mode 100644 (file)
index 0000000..976172a
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mapping xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING     http://www.tik.ee.ethz.ch/~shapes/schema/mapping.xsd" name="example1_map_3">
+<binding name="generator" xsi:type="computation">
+       <process name="generator" />
+       <processor name="sim1" />
+</binding>
+<binding name="consumer" xsi:type="computation">
+       <process name="consumer" />
+       <processor name="sim2" />
+</binding>
+<binding name="square" xsi:type="computation">
+       <process name="square" />
+       <processor name="sim3" />
+</binding>
+</mapping>
diff --git a/dol/examples/example1/map_mparm.xml b/dol/examples/example1/map_mparm.xml
new file mode 100644 (file)
index 0000000..a68d309
--- /dev/null
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mapping xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING
+                      http://www.tik.ee.ethz.ch/~shapes/schema/mapping.xsd"
+  name="Example1 on MPARM">
+
+  <binding name="binding_generator" xsi:type="computation">
+    <process name="generator"/>
+    <processor name="processor_1"/>
+  </binding>
+
+  <binding name="binding_square" xsi:type="computation">
+    <process name="square"/>
+    <processor name="processor_0"/>
+  </binding>
+
+  <binding name="binding_consumer" xsi:type="computation">
+    <process name="consumer"/>
+    <processor name="processor_1"/>
+  </binding>
+
+ <schedule name="schedule_0" type="fixedpriority">
+    <resource name="processor_0"/>
+    <origin name="square">
+      <configuration name="priority" value="1"/>
+    </origin>
+  </schedule>
+
+  <schedule name="schedule_1" type="fixedpriority">
+    <resource name="processor_1"/>
+    <origin name="consumer">
+      <configuration name="priority" value="1"/>
+    </origin>
+    <origin name="generator">
+      <configuration name="priority" value="2"/>
+    </origin>
+  </schedule>
+
+</mapping>
diff --git a/dol/examples/example1/src/arraygen.c b/dol/examples/example1/src/arraygen.c
new file mode 100644 (file)
index 0000000..14b3fed
--- /dev/null
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "arragygen.h"
+
+// initialization function
+void arraygen_init(DOLProcess *p) {
+    p->local->index = 0;
+    srand((unsigned) time(NULL));
+    //p->local->len = LENGTH;
+}
+
+int arraygen_fire(DOLProcess *p) {
+
+    
+  /* generate a random integer array of length L */
+  //int num = rand() % 1000;
+
+  int i;
+  int len = LENGTH;
+  int * array;
+  array = (int *) malloc(sizeof(int)*len);
+
+  for(i=0;i<len;i++)
+    array[i] = rand() % (len*2);
+#if DEBUG 
+  for(i=0;i<LENGTH;i++)
+    printf("%d ", array[i]);
+  printf("\n");
+  printf("generated\n");
+#endif
+
+  DOL_write((void*)PORT_OUT1, &(len), sizeof(int), p);
+  DOL_write((void*)PORT_OUT2, array, sizeof(int)*length, p);
+
+  free(array);
+  DOL_detach(p);
+  return -1;
+    
+}
diff --git a/dol/examples/example1/src/arraygen.h b/dol/examples/example1/src/arraygen.h
new file mode 100644 (file)
index 0000000..12a285f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef ARRAYGEN_H
+#define ARRAYGEN_H
+
+#include <dol.h>
+#include "global.h"
+
+#define  PORT_OUT1 1
+#define  PORT_OUT2 2
+
+
+typedef struct _local_states {
+    int index;
+} Arraygen_State;
+
+void arraygen_init(DOLProcess *);
+int arraygen_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example1/src/consumer.c b/dol/examples/example1/src/consumer.c
new file mode 100644 (file)
index 0000000..711614b
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "consumer");
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int consumer_fire(DOLProcess *p) {
+    float c;
+    if (p->local->index < p->local->len) {
+        DOL_read((void*)PORT_IN, &c, sizeof(float), p);
+        printf("%s: %f\n", p->local->name, c);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/example1/src/consumer.h b/dol/examples/example1/src/consumer.h
new file mode 100644 (file)
index 0000000..677609a
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN 1
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example1/src/generator.c b/dol/examples/example1/src/generator.c
new file mode 100644 (file)
index 0000000..88c801f
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "generator.h"
+
+// initialization function
+void generator_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int generator_fire(DOLProcess *p) {
+
+    if (p->local->index < p->local->len) {
+        float x = (float)p->local->index;
+        DOL_write((void*)PORT_OUT, &(x), sizeof(float), p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/example1/src/generator.h b/dol/examples/example1/src/generator.h
new file mode 100644 (file)
index 0000000..b938a38
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <dol.h>
+#include "global.h"
+
+#define  PORT_OUT 1
+
+typedef struct _local_states {
+    int index;
+    int len;
+} Generator_State;
+
+void generator_init(DOLProcess *);
+int generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example1/src/global.h b/dol/examples/example1/src/global.h
new file mode 100644 (file)
index 0000000..78aaffd
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include <stdio.h>
+
+#define ARRAY_LEN 10
+#define DEBUG 1
+
+#endif
diff --git a/dol/examples/example1/src/printarray.c b/dol/examples/example1/src/printarray.c
new file mode 100644 (file)
index 0000000..b140b96
--- /dev/null
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+#include "printarray.h"
+
+void printarray_init(DOLProcess *p) {
+    p->local->index = 0;
+}
+
+int printarray_fire(DOLProcess *p) {
+
+  int len;
+  int * array;
+  DOL_read((void*)PORT_IN1, &len, sizeof(int), p); 
+  DOL_read((void*)PORT_IN2, array, sizeof(int)*len, p); 
+
+  printf("sorted output\n");
+  for(i=0;i<LENGTH;i++)
+    printf("%d ", array[i]);
+  printf("\n");
+
+  free(array);
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example1/src/printarray.h b/dol/examples/example1/src/printarray.h
new file mode 100644 (file)
index 0000000..59e818c
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef PRINTARRAY_H
+#define PRINTARRAY_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN1 1
+#define PORT_IN2 2
+
+typedef struct _local_states {
+    int index;
+} Printarray_State;
+
+void printarray_init(DOLProcess *);
+int printarray_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example1/src/quicksort.c b/dol/examples/example1/src/quicksort.c
new file mode 100644 (file)
index 0000000..5512fda
--- /dev/null
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <math.h>
+
+#include "quicksort.h"
+
+int smaller_arr(int *dst, int *src, int pivot,int len)
+{
+  int i;
+  int num=0;
+  for(i=0;i<len;i++)
+  {
+    if(src[i]<=pivot)
+    {
+      dst[num++]=src[i];
+    }
+  }
+  return num;
+}
+
+int bigger_arr(int *dst, int *src, int pivot,int len)
+{
+  int i;
+  int num=0;
+  for(i=0;i<len;i++)
+  {
+    if(src[i]>pivot)
+    {
+      dst[num++]=src[i];
+    }
+  }
+  return num;
+}
+
+int median_const(int len, int * array)
+{
+  int i,j;
+  int desired_rank = ceil(len/2);
+
+  for(i=0;i<len;i++)
+  {
+    int rank = 1;
+    for(j=0;j<len;j++)
+    {
+      /* FIXME: exception handling */
+      if(i!=j && array[j]>array[i])
+        rank++;
+    }
+
+    if(rank==desired_rank)
+      return array[i];
+  }
+  return array[0];
+}
+
+int select_med(int size, int * array)
+{
+  int ret;
+  int * array_of_median;
+  int len = ceil(size/5);
+  int i,j;
+
+  /* divide array into groups of five elements */
+  array_of_median = malloc(sizeof(int)*len);
+
+  for(i=0;i<len;i++)
+  {
+    if(i!=len-1)
+      array_of_median[i] = median_const(5,array+5*i);
+    else
+      array_of_median[i] = median_const(len%5,array+5*i);
+  }
+
+  /* call itself recursively */
+  ret = select_med(len, array_of_median);
+
+  /* release */
+  free(array_of_median);
+
+  return ret;
+}
+
+
+
+void quicksort_init(DOLProcess *p) {
+    p->local->index = 0;
+}
+
+int quicksort_fire(DOLProcess *p) {
+
+  int len=LENGTH;
+  int * array;
+  int median;
+  int down,up;
+
+  /* receive the 'size' / 'array' */
+  DOL_read((void*)PORT_IN1, &len, sizeof(int), p); 
+  DOL_read((void*)PORT_IN2, array, sizeof(int)*len, p); 
+
+  /* selection */
+  median = select_med(len, array);
+
+  /* divide */
+  down = 0; up =0;
+  down=smaller_arr(arr1,array,median,len);
+  up=bigger_arr(arr2,array,median,len);
+
+  // down + up == len
+
+  /* sort */
+  quick
+  
+  /* merge */
+
+  /* send the 'size' / 'sorted array' */
+  DOL_write((void*)PORT_OUT1, &len, sizeof(int), p); 
+
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example1/src/quicksort.h b/dol/examples/example1/src/quicksort.h
new file mode 100644 (file)
index 0000000..09227ed
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef QUICKSORT_H
+#define QUICKSORT_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN1 1
+#define PORT_IN2 2
+#define PORT_OUT1 3
+#define PORT_OUT2 4
+
+typedef struct _local_states {
+    int index;
+    int * arr1;
+    int * arr2;
+} Quicksort_State;
+
+void quicksort_init(DOLProcess *);
+int quicksort_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example1/src/square.c b/dol/examples/example1/src/square.c
new file mode 100644 (file)
index 0000000..126378b
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+#include "square.h"
+
+void square_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int square_fire(DOLProcess *p) {
+    float i;
+
+    if (p->local->index < p->local->len) {
+        DOL_read((void*)PORT_IN, &i, sizeof(float), p);
+        i = i*i;
+        DOL_write((void*)PORT_OUT, &i, sizeof(float), p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/example1/src/square.h b/dol/examples/example1/src/square.h
new file mode 100644 (file)
index 0000000..2db7edc
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SQUARE_H
+#define SQUARE_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN  1
+#define PORT_OUT 2
+
+typedef struct _local_states {
+    int index;
+    int len;
+} Square_State;
+
+void square_init(DOLProcess *);
+int square_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example2/example2.xml b/dol/examples/example2/example2.xml
new file mode 100644 (file)
index 0000000..9a915a4
--- /dev/null
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="example2"> 
+
+  <variable value="3" name="N"/>
+
+  <!-- instantiate resources -->
+  <process name="generator">
+    <port type="output" name="10"/>
+    <source type="c" location="generator.c"/>
+  </process>
+
+  <iterator variable="i" range="N">
+    <process name="square">
+      <append function="i"/>
+      <port type="input" name="0"/>
+      <port type="output" name="1"/>
+      <source type="c" location="square.c"/>
+    </process>
+  </iterator>
+
+  <process name="consumer">
+    <port type="input" name="100"/>
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <iterator variable="i" range="N + 1">
+    <sw_channel type="fifo" size="10" name="C2">
+      <append function="i"/>
+      <port type="input" name="0"/>
+      <port type="output" name="1"/>
+    </sw_channel>
+  </iterator>
+
+  <!-- instantiate connection -->
+  <iterator variable="i" range="N">
+    <connection name="to_square">
+      <append function="i"/>
+      <origin name="C2">
+        <append function="i"/>
+        <port name="1"/>
+      </origin>
+      <target name="square">
+        <append function="i"/>
+        <port name="0"/>
+      </target>
+    </connection>
+
+    <connection name="from_square">
+        <append function="i"/>
+        <origin name="square">
+          <append function="i"/>
+          <port name="1"/>
+        </origin>
+        <target name="C2">
+          <append function="i + 1"/>
+          <port name="0"/>
+        </target>
+    </connection>
+  </iterator>
+
+  <connection name="g_">
+    <origin name="generator">
+     <port name="10"/>
+    </origin>
+    <target name="C2"> 
+      <append function="0"/>
+      <port name="0"/>
+    </target>
+  </connection>
+
+  <connection name="_c">
+    <origin name="C2">
+      <append function="N"/>
+      <port name="1"/>
+    </origin>
+    <target name="consumer">
+      <port name="100"/>
+    </target>
+  </connection>
+
+</processnetwork>
diff --git a/dol/examples/example2/src/consumer.c b/dol/examples/example2/src/consumer.c
new file mode 100644 (file)
index 0000000..711614b
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "consumer");
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int consumer_fire(DOLProcess *p) {
+    float c;
+    if (p->local->index < p->local->len) {
+        DOL_read((void*)PORT_IN, &c, sizeof(float), p);
+        printf("%s: %f\n", p->local->name, c);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/example2/src/consumer.h b/dol/examples/example2/src/consumer.h
new file mode 100644 (file)
index 0000000..2a4a545
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN 100
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example2/src/generator.c b/dol/examples/example2/src/generator.c
new file mode 100644 (file)
index 0000000..88c801f
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "generator.h"
+
+// initialization function
+void generator_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int generator_fire(DOLProcess *p) {
+
+    if (p->local->index < p->local->len) {
+        float x = (float)p->local->index;
+        DOL_write((void*)PORT_OUT, &(x), sizeof(float), p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/example2/src/generator.h b/dol/examples/example2/src/generator.h
new file mode 100644 (file)
index 0000000..4f05280
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <dol.h>
+#include "global.h"
+
+#define  PORT_OUT 10
+
+typedef struct _local_states {
+    int index;
+    int len;
+} Generator_State;
+
+void generator_init(DOLProcess *);
+int generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example2/src/global.h b/dol/examples/example2/src/global.h
new file mode 100644 (file)
index 0000000..dfcbb84
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#define LENGTH 20
+
+#endif
diff --git a/dol/examples/example2/src/square.c b/dol/examples/example2/src/square.c
new file mode 100644 (file)
index 0000000..126378b
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+#include "square.h"
+
+void square_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int square_fire(DOLProcess *p) {
+    float i;
+
+    if (p->local->index < p->local->len) {
+        DOL_read((void*)PORT_IN, &i, sizeof(float), p);
+        i = i*i;
+        DOL_write((void*)PORT_OUT, &i, sizeof(float), p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/example2/src/square.h b/dol/examples/example2/src/square.h
new file mode 100644 (file)
index 0000000..27b2bcc
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SQUARE_H
+#define SQUARE_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN  0
+#define PORT_OUT 1
+
+typedef struct _local_states {
+    int index;
+    int len;
+} Square_State;
+
+void square_init(DOLProcess *);
+int square_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example3/example3.xml b/dol/examples/example3/example3.xml
new file mode 100644 (file)
index 0000000..68859ae
--- /dev/null
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="example3">
+
+  <variable value="3" name="N"/>
+  <variable value="10" name="FIFO_SIZE"/>
+
+  <!-- instantiate resources -->
+  <iterator variable="i" range="N">
+    <process name="horizontal_generator">
+      <append function="i"/> 
+      <port type="output" name="h_out"/>
+      <source type="c" location="horizontal_generator.c"/>
+    </process>
+     <process name="horizontal_consumer">
+      <append function="i"/> 
+      <port type="input" name="h_in"/>
+      <source type="c" location="horizontal_consumer.c"/>
+    </process>
+  </iterator>
+
+  <iterator variable="i" range="N">
+    <process name="vertical_generator">
+      <append function="i"/>
+      <port type="output" name="v_out"/>
+      <source type="c" location="vertical_generator.c"/>
+    </process>
+     <process name="vertical_consumer">
+      <append function="i"/>
+      <port type="input" name="v_in"/>
+      <source type="c" location="vertical_consumer.c"/>
+    </process>
+  </iterator>
+  
+  <iterator variable="i" range="N">
+    <iterator variable="j" range="N">
+      <process name="forward">
+        <append function="i"/>
+        <append function="j"/>
+        <port type="input" name="west"/>
+        <port type="input" name="north"/>
+        <port type="output" name="east"/>
+        <port type="output" name="south"/>
+        <source type="c" location="forward.c"/>
+      </process>
+    </iterator>
+  </iterator>
+  
+  <iterator variable="i" range="N + 1">
+    <iterator variable="j" range="N">
+      <sw_channel type="fifo" size="FIFO_SIZE" name="C_h">
+        <append function="i"/>
+        <append function="j"/>
+        <port type="input" name="in"/>
+        <port type="output" name="out"/>
+      </sw_channel>
+      <sw_channel type="fifo" size="FIFO_SIZE" name="C_v">
+        <append function="j"/>
+        <append function="i"/>
+        <port type="input" name="in"/>
+        <port type="output" name="out"/>
+      </sw_channel>
+    </iterator>
+  </iterator>
+
+  <!-- instantiate connections -->
+  <iterator variable="i" range="N">
+    <iterator variable="j" range="N">
+      <connection name="west">
+        <append function="i"/>
+        <append function="j"/>
+        <origin name="C_h">
+          <append function="i"/>
+          <append function="j"/>
+          <port name="out"/>
+        </origin>
+        <target name="forward">
+           <append function="i"/>
+           <append function="j"/>
+           <port name="west"/>
+         </target>
+      </connection>
+      
+      <connection name="east">
+        <append function="i"/>
+        <append function="j"/>
+        <origin name="forward">
+          <append function="i"/>
+          <append function="j"/>
+          <port name="east"/>
+        </origin>
+        <target name="C_h">
+           <append function="i + 1"/>
+           <append function="j"/>
+           <port name="in"/>
+         </target>
+      </connection>
+            
+      <connection name="north">
+        <append function="i"/>
+        <append function="j"/>
+        <origin name="C_v">
+          <append function="i"/>
+          <append function="j"/>
+          <port name="out"/>
+        </origin>
+        <target name="forward">
+           <append function="i"/>
+           <append function="j"/>
+           <port name="north"/>
+         </target>
+      </connection>
+      
+      <connection name="south">
+        <append function="i"/>
+        <append function="j"/>
+        <origin name="forward">
+          <append function="i"/>
+          <append function="j"/>
+          <port name="south"/>
+        </origin>
+        <target name="C_v">
+           <append function="i"/>
+           <append function="j + 1"/>
+           <port name="in"/>
+         </target>
+      </connection>
+    </iterator>
+  </iterator>
+  
+  <!-- boundary connections -->
+  <iterator variable="i" range="N">
+    <connection name="west">
+      <append function="i + 1"/>
+      <origin name="horizontal_generator">
+        <append function="i"/>
+        <port name="h_out"/>
+      </origin>
+      <target name="C_h">
+         <append function="0"/>
+         <append function="i"/>
+         <port name="in"/>
+       </target>
+    </connection>
+
+    <connection name="east">
+      <append function="i + 1"/>
+      <origin name="C_h">
+         <append function="N"/>
+         <append function="i"/>
+         <port name="out"/>
+      </origin>
+      <target name="horizontal_consumer">
+         <append function="i"/>
+         <port name="h_in"/>
+       </target>
+    </connection>
+
+    <connection name="north">
+      <append function="i + 1"/>
+      <origin name="vertical_generator">
+        <append function="i"/>
+        <port name="v_out"/>
+      </origin>
+      <target name="C_v">
+         <append function="i"/>
+         <append function="0"/>
+         <port name="in"/>
+       </target>
+    </connection>
+
+    <connection name="south">
+      <append function="i + 1"/>
+      <origin name="C_v">
+         <append function="i"/>
+         <append function="N"/>
+         <port name="out"/>
+      </origin>
+      <target name="vertical_consumer">
+         <append function="i"/>
+         <port name="v_in"/>
+       </target>
+    </connection>
+  </iterator>
+
+</processnetwork>
diff --git a/dol/examples/example3/src/forward.c b/dol/examples/example3/src/forward.c
new file mode 100644 (file)
index 0000000..a3b7e81
--- /dev/null
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+#include "forward.h"
+
+void forward_init(DOLProcess *p) {
+    sprintf(p->local->name,"Forward");
+}
+
+int forward_fire(DOLProcess *p) {
+    char c;
+    char c2;
+
+    DOL_read((void*)PORT_IN1, &c, 1, p);
+    DOL_read((void*)PORT_IN2, &c2, 1, p);
+    DOL_write((void*)PORT_OUT1, &c, 1, p);
+    DOL_write((void*)PORT_OUT2, &c2, 1, p);
+
+    return 0;
+}
diff --git a/dol/examples/example3/src/forward.h b/dol/examples/example3/src/forward.h
new file mode 100644 (file)
index 0000000..62d4309
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef FORWARD_H
+#define FORWARD_H
+
+#include <dol.h>
+
+#define PORT_IN1  "west"
+#define PORT_IN2  "north"
+#define PORT_OUT1 "east"
+#define PORT_OUT2 "south"
+
+typedef struct _local_states {
+    char name[20];
+} Forward_State;
+
+void forward_init(DOLProcess *);
+int forward_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example3/src/horizontal_consumer.c b/dol/examples/example3/src/horizontal_consumer.c
new file mode 100644 (file)
index 0000000..3849aed
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+#include "horizontal_consumer.h"
+
+void horizontal_consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "h_consumer");
+}
+
+int horizontal_consumer_fire(DOLProcess *p) {
+    char c;
+    DOL_read((void*)PORT_IN, &c, 1, p);
+    printf("%s: %c\n", p->local->name, c);
+
+    return 0;
+}
+
diff --git a/dol/examples/example3/src/horizontal_consumer.h b/dol/examples/example3/src/horizontal_consumer.h
new file mode 100644 (file)
index 0000000..f09bffb
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+
+#define PORT_IN "h_in"
+
+typedef struct _local_states {
+    char name[20];
+} Horizontal_consumer_State;
+
+void horizontal_consumer_init(DOLProcess *);
+int horizontal_consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example3/src/horizontal_generator.c b/dol/examples/example3/src/horizontal_generator.c
new file mode 100644 (file)
index 0000000..501ff1b
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "horizontal_generator.h"
+
+// initialization function
+void horizontal_generator_init(DOLProcess *p) {
+    sprintf(p->local->str, "nopqrstuvwxyz");
+    p->local->index = 0;
+    p->local->len = strlen(p->local->str);
+}
+
+int horizontal_generator_fire(DOLProcess *p) {
+
+    if (p->local->index < p->local->len) {
+        DOL_write((void*)PORT_OUT, (p->local->str + p->local->index), 1, p);
+        p->local->index++;
+    }
+    else {
+        DOL_detach(p);
+    }
+    return 0;
+}
+
diff --git a/dol/examples/example3/src/horizontal_generator.h b/dol/examples/example3/src/horizontal_generator.h
new file mode 100644 (file)
index 0000000..fdc8a3c
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include <dol.h>
+
+#define PORT_OUT "h_out"
+
+typedef struct _local_states {
+    int index;
+    char str[25];
+    int len;
+} Horizontal_generator_State;
+
+void horizontal_generator_init(DOLProcess *);
+int horizontal_generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example3/src/vertical_consumer.c b/dol/examples/example3/src/vertical_consumer.c
new file mode 100644 (file)
index 0000000..a4f166b
--- /dev/null
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+#include "vertical_consumer.h"
+
+void vertical_consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "v_consumer");
+}
+
+int vertical_consumer_fire(DOLProcess *p) {
+    char c;
+    DOL_read((void*)PORT_IN, &c, 1, p);
+    printf("%s: %c\n", p->local->name, c);
+
+    return 0;
+}
diff --git a/dol/examples/example3/src/vertical_consumer.h b/dol/examples/example3/src/vertical_consumer.h
new file mode 100644 (file)
index 0000000..8dd538b
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+
+#define PORT_IN "v_in"
+
+typedef struct _local_states {
+    char name[20];
+} Vertical_consumer_State;
+
+void vertical_consumer_init(DOLProcess *);
+int vertical_consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example3/src/vertical_generator.c b/dol/examples/example3/src/vertical_generator.c
new file mode 100644 (file)
index 0000000..5dfa100
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "vertical_generator.h"
+
+// initialization function
+void vertical_generator_init(DOLProcess *p) {
+    sprintf(p->local->str,"abcdefghijklm");
+    p->local->index = 0;
+    p->local->len = strlen(p->local->str);
+}
+
+int vertical_generator_fire(DOLProcess *p) {
+
+    if (p->local->index < p->local->len) {
+        DOL_write((void*)PORT_OUT, (p->local->str + p->local->index), 1, p);
+        p->local->index++;
+    } else {
+        DOL_detach(p);
+    }
+
+    return 0;
+}
diff --git a/dol/examples/example3/src/vertical_generator.h b/dol/examples/example3/src/vertical_generator.h
new file mode 100644 (file)
index 0000000..f6dec58
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include <dol.h>
+
+#define PORT_OUT "v_out"
+
+typedef struct _local_states {
+    int index;
+    char str[20];
+    int len;
+} Vertical_generator_State;
+
+void vertical_generator_init(DOLProcess *);
+int vertical_generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example4/example4.xml b/dol/examples/example4/example4.xml
new file mode 100644 (file)
index 0000000..f9db3d6
--- /dev/null
@@ -0,0 +1,344 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="MatrixMult"> 
+
+  <variable value="2" name="N"/> <!-- number of rows/columns of square matrix -->
+
+  <!-- instantiate processes -->
+  <!-- process for generating matrices -->
+  <process name="input_generator">
+    <iterator variable="i" range="N">
+      <iterator  variable="row" range="N">
+        <iterator variable="col" range="N">
+          <port type="output" name="matrixA">
+            <append function="row"/>
+            <append function="col"/>
+            <append function="i"/>
+          </port>
+          <port type="output" name="matrixB">
+            <append function="row"/>
+            <append function="col"/>
+            <append function="i"/>
+          </port>
+        </iterator>
+      </iterator>
+    </iterator>
+    <iterator variable="i" range="N * N">
+      <port type="output" name="zeroinput">
+        <append function="i"/>
+      </port>
+    </iterator>
+    <source type="c" location="generator.c"/>
+  </process>
+
+  <!-- process to collect result -->
+  <process name="output_consumer">
+    <iterator  variable="row" range="N">
+      <iterator variable="col" range="N">
+        <port type="input" name="matrixC">
+          <append function="row"/>
+          <append function="col"/>
+        </port>
+      </iterator>
+    </iterator>
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <!-- processes to compute result -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N">
+        <process name="addmult">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <port type="input" name="factor1"/>
+          <port type="input" name="factor2"/>
+          <port type="input" name="summand"/>
+          <port type="output" name="sum"/>
+          <source type="c" location="addmult.c"/>
+        </process>
+      </iterator>
+    </iterator>
+  </iterator>
+
+
+  <!-- instantiate channels -->
+  <!-- channels for matrices -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N">
+        <sw_channel type="fifo" size="8" name="matrixAchannel">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <port type="input" name="in"/>
+          <port type="output" name="out"/>
+        </sw_channel>
+        <sw_channel type="fifo" size="8" name="matrixBchannel">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <port type="input" name="in"/>
+          <port type="output" name="out"/>
+        </sw_channel>
+      </iterator>
+    </iterator>
+  </iterator>
+
+  <!-- channels for zeros -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <sw_channel type="fifo" size="8" name="zerochannel">
+        <append function="i"/>
+        <append function="row"/>
+        <port type="input" name="in"/>
+        <port type="output" name="out"/>
+      </sw_channel>
+    </iterator>
+  </iterator>
+
+  <!-- channels for result -->
+  <iterator variable="row" range="N">
+    <iterator variable="col" range="N">
+      <sw_channel type="fifo" size="8" name="resultchannel">
+        <append function="row"/>
+        <append function="col"/>
+        <port type="input" name="in"/>
+        <port type="output" name="out"/>
+      </sw_channel>
+    </iterator>
+  </iterator>
+  
+  <!-- channels between processes -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N - 1">
+        <sw_channel type="fifo" size="8" name="addmultchannel">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <port type="input" name="in"/>
+          <port type="output" name="out"/>
+        </sw_channel>
+      </iterator>
+    </iterator>
+  </iterator>
+
+
+  <!-- instantiate connections -->
+  <!-- connect the input_generator to the "matrix" and zero channels -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N">
+        <connection name="tomatrixAchannel">
+          <append function="row"/>
+          <append function="col"/>
+          <append function="i"/>
+          <origin name="input_generator">
+            <port name="matrixA">
+              <append function="row"/>
+              <append function="col"/>
+              <append function="i"/>
+            </port>
+          </origin>
+          <target name="matrixAchannel">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="in"/>
+          </target>
+        </connection>
+
+        <connection name="tomatrixBchannel">
+          <append function="row"/>
+          <append function="col"/>
+          <append function="i"/>
+          <origin name="input_generator">
+            <port name="matrixB">
+              <append function="row"/>
+              <append function="col"/>
+              <append function="i"/>
+            </port>
+          </origin>
+          <target name="matrixBchannel">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="in"/>
+          </target>
+        </connection>
+      </iterator>
+
+      <connection name="tozerochannel">
+        <append function="i * N + row"/>
+        <origin name="input_generator">
+          <port name="zeroinput">
+            <append function="i * N + row"/>
+          </port>
+        </origin>
+        <target name="zerochannel">
+          <append function="i"/>
+          <append function="row"/>
+          <port name="in"/>
+        </target>
+      </connection>
+    </iterator>
+  </iterator>
+  
+  <!-- connect the "matrix" and "zero" channels to the addmults -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N">
+        <!-- connection for matrix A -->
+        <connection name="matrixA_connection">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <origin name="matrixAchannel">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="out"/>
+          </origin>
+          <target name="addmult">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="factor1"/>
+          </target>
+        </connection>
+
+        <!-- connection for matrix B -->
+        <!-- note the order of appends for matrixBchannel -->
+        <connection name="matrixB_connection">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <origin name="matrixBchannel">
+            <append function="row"/>
+            <append function="col"/>
+            <append function="i"/>
+            <port name="out"/>
+          </origin>
+          <target name="addmult">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="factor2"/>
+          </target>
+        </connection>
+      </iterator>
+
+      <!-- zero input connections to addmults -->
+      <connection name="zero_connection">
+        <append function="i"/>
+        <append function="row"/>
+        <origin name="zerochannel">
+          <append function="i"/>
+          <append function="row"/>
+          <port name="out"/>
+        </origin>
+        <target name="addmult">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="0"/>
+          <port name="summand"/>
+        </target>
+      </connection>
+    </iterator>
+  </iterator>
+
+  <!-- connections from output of addmults to "addmult" channels -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N - 1">
+        <connection name="fromaddmult">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col"/>
+          <origin name="addmult">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="sum"/>
+          </origin>
+          <target name="addmultchannel">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="in"/>
+          </target>
+        </connection>
+      </iterator>
+    </iterator>
+  </iterator>
+
+  <!-- connections from "addmult" channels to input of addmults -->
+  <iterator variable="i" range="N">
+    <iterator variable="row" range="N">
+      <iterator variable="col" range="N - 1">
+        <connection name="toaddmult">
+          <append function="i"/>
+          <append function="row"/>
+          <append function="col + 1"/>
+          <origin name="addmultchannel">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col"/>
+            <port name="out"/>
+          </origin>
+          <target name="addmult">
+            <append function="i"/>
+            <append function="row"/>
+            <append function="col + 1"/>
+            <port name="summand"/>
+          </target>
+        </connection>
+      </iterator>
+    </iterator>
+  </iterator>
+  
+  <!-- connections from addmults to "result" channels -->
+  <iterator variable="row" range="N">
+    <iterator variable="col" range="N">
+      <connection name="tomatrixCchannel">
+        <append function="row"/>
+        <append function="col"/>
+        <origin name="addmult">
+          <append function="col"/>
+          <append function="row"/>
+          <append function="N-1"/>
+          <port name="sum"/>
+        </origin>
+        <target name="resultchannel">
+          <append function="row"/>
+          <append function="col"/>
+          <port name="in"/>
+        </target>
+      </connection>
+    </iterator>
+  </iterator>
+
+  <!-- connections from "result" channels to output_consumer -->
+  <iterator variable="row" range="N">
+    <iterator variable="col" range="N">
+      <connection name="frommatrixCchannel">
+        <append function="row"/>
+        <append function="col"/>
+        <origin name="resultchannel">
+          <append function="row"/>
+          <append function="col"/>
+          <port name="out"/>
+        </origin>
+        <target name="output_consumer">
+          <port name="matrixC">
+            <append function="row"/>
+            <append function="col"/>
+          </port>
+        </target>
+      </connection>
+    </iterator>
+  </iterator>
+    
+</processnetwork>
diff --git a/dol/examples/example4/src/addmult.c b/dol/examples/example4/src/addmult.c
new file mode 100644 (file)
index 0000000..00ef15e
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include "addmult.h"
+
+void addmult_init(DOLProcess *p)
+{
+  sprintf(p->local->id, "addmult_%d_%d_%d",
+          GETINDEX(0),
+          GETINDEX(1),
+          GETINDEX(2));
+}
+
+
+int addmult_fire(DOLProcess *p)
+{
+  float factor1, factor2, summand;
+
+  DOL_read((void*)PORT_FACTOR1, &factor1, sizeof(float), p);
+  DOL_read((void*)PORT_FACTOR2, &factor2, sizeof(float), p);
+  DOL_read((void*)PORT_SUMMAND, &summand, sizeof(float), p);
+  p->local->sum = factor1 * factor2 + summand;
+  DOL_write((void*)PORT_SUM, &(p->local->sum), sizeof(float), p);
+
+  printf("%15s: %f * %f + %f = %f\n",
+         p->local->id, factor1, factor2, summand, p->local->sum);
+
+  return 0;
+}
+
diff --git a/dol/examples/example4/src/addmult.h b/dol/examples/example4/src/addmult.h
new file mode 100644 (file)
index 0000000..7eb7c3a
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef ADDMULT_H
+#define ADDMULT_H
+
+#include <dol.h>
+
+#define PORT_FACTOR1 "factor1"
+#define PORT_FACTOR2 "factor2"
+#define PORT_SUMMAND "summand"
+#define PORT_SUM     "sum"
+
+typedef struct _local_states
+{
+  char id[14];
+  float sum;
+} Addmult_State;
+
+void addmult_init(DOLProcess *);
+int addmult_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example4/src/constants.h b/dol/examples/example4/src/constants.h
new file mode 100644 (file)
index 0000000..36d73b2
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+/*
+#define NUMBER_OF_ROWS_COLS     1
+#define MATRIX_A_INITIAL_VALUE  { 1.0 }
+#define MATRIX_B_INITIAL_VALUE  { 2.5 }
+*/
+
+#define NUMBER_OF_ROWS_COLS     2
+#define MATRIX_A_INITIAL_VALUE  { {1.0,  2.0 }, {  3.0,  4.0 } }
+#define MATRIX_B_INITIAL_VALUE  { {0.0, -1.0 }, { -2.0, -3.0 } }
+
+/*
+#define NUMBER_OF_ROWS_COLS     3
+#define MATRIX_A_INITIAL_VALUE  { {1.0, 2.0, 3.0 }, {4.0, 5.0, -4.0 }, {-3.0, -2.0, -1.0} }
+#define MATRIX_B_INITIAL_VALUE  { {1.0, 0.0, 0.0 }, {0.0, 1.0,  0.0 }, { 0.0,  0.0,  1.0} }
+*/
+
+#endif
diff --git a/dol/examples/example4/src/consumer.c b/dol/examples/example4/src/consumer.c
new file mode 100644 (file)
index 0000000..ebd4e98
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void output_consumer_init(DOLProcess *p)
+{
+  ; //nothing to be done here
+}
+
+int output_consumer_fire(DOLProcess *p)
+{
+  CREATEPORTVAR(port);
+
+  for (p->local->row = 0; p->local->row < NUMBER_OF_ROWS_COLS; p->local->row++)
+  {
+    for (p->local->col = 0; p->local->col < NUMBER_OF_ROWS_COLS; p->local->col++)
+    {
+      CREATEPORT(port, PORT_MATRIXC, 2,
+              p->local->row, NUMBER_OF_ROWS_COLS,
+              p->local->col, NUMBER_OF_ROWS_COLS);
+
+      DOL_read((void*)port, &p->local->matrixC_value, sizeof(float), p);
+      printf("%15s: matrixC[%d][%d]: %f\n",
+             "output_consumer", p->local->row, p->local->col, p->local->matrixC_value);
+    }
+  }
+  return 0;
+}
+
diff --git a/dol/examples/example4/src/consumer.h b/dol/examples/example4/src/consumer.h
new file mode 100644 (file)
index 0000000..7406a75
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include "constants.h"
+#include <dol.h>
+
+#define PORT_MATRIXC "matrixC"
+
+typedef struct _local_states
+{
+  unsigned row, col;
+  float matrixC_value;
+} Output_consumer_State;
+
+void output_consumer_init(DOLProcess *);
+int output_consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example4/src/generator.c b/dol/examples/example4/src/generator.c
new file mode 100644 (file)
index 0000000..60f3962
--- /dev/null
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "generator.h"
+
+
+Input_generator_State input_generator_state =
+  { matrixA: MATRIX_A_INITIAL_VALUE, matrixB: MATRIX_B_INITIAL_VALUE };
+
+void input_generator_init(DOLProcess *p)
+{
+  for (p->local->row = 0; p->local->row < NUMBER_OF_ROWS_COLS; p->local->row++)
+  {
+    for (p->local->col = 0; p->local->col < NUMBER_OF_ROWS_COLS; p->local->col++)
+    {
+      p->local->matrixA[p->local->row][p->local->col] = (NUMBER_OF_ROWS_COLS * p->local->row) + p->local->col + 1;
+      p->local->matrixB[p->local->row][p->local->col] = -((NUMBER_OF_ROWS_COLS * p->local->row) + p->local->col);
+    }
+  }
+}
+
+
+int input_generator_fire(DOLProcess *p)
+{
+  CREATEPORTVAR(port);
+
+  for (p->local->row = 0; p->local->row < NUMBER_OF_ROWS_COLS; p->local->row++)
+  {
+    for (p->local->col = 0; p->local->col < NUMBER_OF_ROWS_COLS; p->local->col++)
+    {
+      CREATEPORT(port, PORT_ZEROINPUT, 1,
+              p->local->row * NUMBER_OF_ROWS_COLS + p->local->col, NUMBER_OF_ROWS_COLS
+              * NUMBER_OF_ROWS_COLS);
+      printf("%15s: Write to zeroinput_%d: %f\n", "input_generator",
+             p->local->row * NUMBER_OF_ROWS_COLS + p->local->col, 0.0);
+      DOL_write((void*)port, &(p->local->zero), sizeof(float), p);
+
+      for (p->local->i = 0; p->local->i < NUMBER_OF_ROWS_COLS; p->local->i++)
+      {
+        CREATEPORT(port, PORT_MATRIXA, 3,
+                p->local->row, NUMBER_OF_ROWS_COLS,
+                p->local->col, NUMBER_OF_ROWS_COLS,
+                p->local->i, NUMBER_OF_ROWS_COLS);
+        printf("%15s: Write to matrixA_%d_%d_%d: %f\n",
+               "input_generator", p->local->i, p->local->row, p->local->col,
+               p->local->matrixA[p->local->row][p->local->col]);
+        DOL_write((void*)port, &(p->local->matrixA[p->local->row][p->local->col]),
+                  sizeof(float), p);
+        CREATEPORT(port, PORT_MATRIXB, 3,
+                p->local->row, NUMBER_OF_ROWS_COLS,
+                p->local->col, NUMBER_OF_ROWS_COLS,
+                p->local->i, NUMBER_OF_ROWS_COLS);
+        printf("%15s: Write to matrixB_%d_%d_%d: %f\n",
+               "input_generator", p->local->i, p->local->row, p->local->col,
+               p->local->matrixB[p->local->row][p->local->col]);
+        DOL_write((void*)port, &(p->local->matrixB[p->local->row][p->local->col]),
+                  sizeof(float), p);
+      }
+    }
+  }
+
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example4/src/generator.h b/dol/examples/example4/src/generator.h
new file mode 100644 (file)
index 0000000..c4ad94e
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include "constants.h"
+#include <dol.h>
+
+#define PORT_MATRIXA   "matrixA"
+#define PORT_MATRIXB   "matrixB"
+#define PORT_ZEROINPUT "zeroinput"
+
+typedef struct _local_states
+{
+  float matrixA[NUMBER_OF_ROWS_COLS][NUMBER_OF_ROWS_COLS];
+  float matrixB[NUMBER_OF_ROWS_COLS][NUMBER_OF_ROWS_COLS];
+  int row, col, i;
+  float zero;
+} Input_generator_State;
+
+void input_generator_init(DOLProcess *);
+int input_generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example5/example5.xml b/dol/examples/example5/example5.xml
new file mode 100644 (file)
index 0000000..659342f
--- /dev/null
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="FFT">
+
+  <!--
+  N is the number of FFT points
+  number_of_layers = ld(N)
+  processes_per_layer = N/2
+  -->
+  
+  <!--
+  <variable value="4" name="N"/> 
+  <variable value="2" name="NUMBER_OF_LAYERS"/>
+  <variable value="2" name="PROCESSES_PER_LAYER"/>
+  -->
+
+  <!--
+  <variable value="8" name="N"/>
+  <variable value="3" name="NUMBER_OF_LAYERS"/>
+  <variable value="4" name="PROCESSES_PER_LAYER"/>
+  -->
+
+  <variable value="16" name="N"/>
+  <variable value="4" name="NUMBER_OF_LAYERS"/>
+  <variable value="8" name="PROCESSES_PER_LAYER"/>
+  
+  <!--
+  <variable value="32" name="N"/>
+  <variable value="5" name="NUMBER_OF_LAYERS"/>
+  <variable value="16" name="PROCESSES_PER_LAYER"/>
+  -->
+  
+  <!--
+  <variable value="64" name="N"/>
+  <variable value="6" name="NUMBER_OF_LAYERS"/>
+  <variable value="32" name="PROCESSES_PER_LAYER"/>
+  -->
+
+  <!--  
+  <variable value="128" name="N"/>
+  <variable value="7" name="NUMBER_OF_LAYERS"/>
+  <variable value="64" name="PROCESSES_PER_LAYER"/>
+  -->
+
+  <!--
+  <variable value="256" name="N"/>
+  <variable value="8" name="NUMBER_OF_LAYERS"/>
+  <variable value="128" name="PROCESSES_PER_LAYER"/>
+  -->  
+
+  <function>
+    <![CDATA[
+    public static int bitreverse(int n, int N)
+    {
+      String numberString = Integer.toString(n, 2); //binary representation of n
+  
+      //prepend zeros until string is N characters long
+      while (numberString.length() < N)
+      {
+        numberString = "0" + numberString;
+      }
+  
+      //reverse the string
+      char[] numberCharArray = numberString.toCharArray();
+      for (int count = 0; count < numberCharArray.length / 2; count++)
+      {
+        char help = numberCharArray[count];
+        numberCharArray[count] = numberCharArray[N - 1 - count];
+        numberCharArray[N - 1 - count] = help;
+      }
+  
+      //convert back to integer
+      return Integer.valueOf(String.valueOf(numberCharArray), 2);
+    }
+    ]]>
+  </function>
+  
+  <function>
+    <![CDATA[
+    public static int butterfly(int layer, int p, int addOffset)
+    {
+      int index = 2 * (p % (1 << (layer - 1))) +
+                  p / (1 << (layer - 1)) +
+                  (p / (1 << layer)) * ((1 << (layer + 1)) - 2);
+
+      if (addOffset == 1)
+        return index + (1 << layer);
+
+      return index;
+    }
+    ]]>
+  </function>
+  
+  <!-- instantiate processes -->
+  <process name="generator">
+    <iterator  variable="i" range="N">
+      <port type="output" name="input_coefficients">
+        <append function="i"/>
+      </port>
+    </iterator>
+    <source type="c" location="generator.c"/>
+  </process>
+
+  <process name="consumer">
+    <iterator  variable="i" range="N">
+      <port type="input" name="output_coefficients">
+        <append function="i"/>
+      </port>
+    </iterator>
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <iterator variable="i" range="NUMBER_OF_LAYERS">
+    <iterator variable="j" range="PROCESSES_PER_LAYER">
+      <process name="fft2">
+        <append function="i"/>
+        <append function="j"/>
+        <port type="input" name="inA"/>
+        <port type="input" name="inB"/>
+        <port type="output" name="outA"/>
+        <port type="output" name="outB"/>
+        <source type="c" location="fft2.c"/>
+      </process>
+    </iterator>
+  </iterator>
+
+  <!-- instantiate channels -->
+  <!-- channels for input and output coefficients -->
+  <iterator variable="i" range="N">
+    <sw_channel type="fifo" size="16" name="inputchannel">
+      <append function="i"/>
+      <port type="input" name="in"/>
+      <port type="output" name="out"/>
+    </sw_channel>
+    <sw_channel type="fifo" size="16" name="outputchannel">
+      <append function="i"/>
+      <port type="input" name="in"/>
+      <port type="output" name="out"/>
+    </sw_channel>
+  </iterator>
+  
+  <!-- channels for butterfly network -->
+  <iterator variable="layer" range="NUMBER_OF_LAYERS - 1">
+    <iterator variable="i" range="N">
+      <sw_channel type="fifo" size="16" name="butterflychannel">
+        <append function="layer"/>
+        <append function="i"/>
+        <port type="input" name="in"/>
+        <port type="output" name="out"/>
+      </sw_channel>
+    </iterator>
+  </iterator>
+
+  <!-- instantiate connections -->
+  <!-- connections from input generator to input channel and from output channel to output consumer -->
+  <iterator variable="i" range="N">
+    <connection name="input_connection">
+      <append function="i"/>
+      <origin name="generator">
+        <port name="input_coefficients">
+          <append function="i"/>
+        </port>
+      </origin>
+      <target name="inputchannel">
+        <append function="i"/>
+        <port name="in"/>
+      </target>
+    </connection>
+    <connection name="output_connection">
+      <append function="i"/>
+      <origin name="outputchannel">
+        <append function="i"/>
+        <port name="out"/>
+      </origin>
+      <target name="consumer">
+        <port name="output_coefficients">
+          <append function="i"/>
+        </port>
+      </target>
+    </connection>
+  </iterator>
+  
+  <!-- connections from FFT2 to channels -->
+  <iterator variable="layer" range="NUMBER_OF_LAYERS - 1">
+    <iterator variable="i" range="PROCESSES_PER_LAYER">
+      <connection name="layerkconnection_A">
+        <append function="layer + 1"/>
+        <append function="i"/>
+        <origin name="fft2">
+          <append function="layer"/>
+          <append function="i"/>
+          <port name="outA"/>
+        </origin>
+        <target name="butterflychannel">
+          <append function="layer"/>
+          <append function="2 * i"/>
+          <port name="in"/>
+        </target>
+      </connection>
+      <connection name="layerkconnection_B">
+        <append function="layer + 1"/>
+        <append function="i"/>
+        <origin name="fft2">
+          <append function="layer"/>
+          <append function="i"/>
+          <port name="outB"/>
+        </origin>
+        <target name="butterflychannel">
+          <append function="layer"/>
+          <append function="2 * i + 1"/>
+          <port name="in"/>
+        </target>
+      </connection>
+    </iterator>
+  </iterator>
+  
+  <!-- connections from channels to FFT2 -->
+  <!-- connections from input channels to first FFT layer -->
+  <iterator variable="i" range="PROCESSES_PER_LAYER">
+    <connection name="layer1connection_A">
+      <append function="i"/>
+      <origin name="inputchannel">
+        <append function="bitreverse(2 * i, NUMBER_OF_LAYERS)"/>
+        <port name="out"/>
+      </origin>
+      <target name="fft2_0">
+        <append function="i"/>
+        <port name="inA"/>
+      </target>
+    </connection>
+    <connection name="layer1connection_B">
+      <append function="i"/>
+      <origin name="inputchannel">
+        <append function="bitreverse(2 * i + 1, NUMBER_OF_LAYERS)"/>
+        <port name="out"/>
+      </origin>
+      <target name="fft2_0">
+        <append function="i"/>
+        <port name="inB"/>
+      </target>
+    </connection>
+  </iterator>
+
+  <!-- connections from last FFT layer to output channels -->
+  <iterator variable="i" range="PROCESSES_PER_LAYER">
+    <connection name="lastlayerconnection_A">
+      <append function="i"/>
+      <origin name="fft2">
+        <append function="NUMBER_OF_LAYERS - 1"/>
+        <append function="i"/>
+        <port name="outA"/>
+      </origin>
+      <target name="outputchannel">
+        <append function="i"/>
+        <port name="in"/>
+      </target>
+    </connection>
+    <connection name="lastlayerconnection_B">
+      <append function="i"/>
+      <origin name="fft2">
+        <append function="NUMBER_OF_LAYERS - 1"/>
+        <append function="i"/>
+        <port name="outB"/>
+      </origin>
+      <target name="outputchannel">
+        <append function="i + PROCESSES_PER_LAYER"/>
+        <port name="in"/>
+      </target>
+    </connection>
+  </iterator>
+
+  <!-- other connections -->
+  <iterator variable="layer" range="NUMBER_OF_LAYERS - 1">
+    <iterator variable="i" range="PROCESSES_PER_LAYER">
+      <connection name="FFTconnection_A">
+        <append function="layer"/>
+        <append function="i"/>
+        <origin name="butterflychannel">
+          <append function="layer"/>
+          <append function="butterfly(layer + 1, i, 0)"/>
+          <port name="out"/>
+        </origin>
+        <target name="fft2">
+          <append function="layer + 1"/>
+          <append function="i"/>
+          <port name="inA"/>
+        </target>
+      </connection>
+      <connection name="FFTconnection_B">
+        <append function="layer"/>
+        <append function="i"/>
+        <origin name="butterflychannel">
+          <append function="layer"/>
+          <append function="butterfly(layer + 1, i, 1)"/>
+          <port name="out"/>
+        </origin>
+        <target name="fft2">
+          <append function="layer + 1"/>
+          <append function="i"/>
+          <port name="inB"/>
+        </target>
+      </connection>
+    </iterator>
+  </iterator>
+</processnetwork>
diff --git a/dol/examples/example5/fft_script.m b/dol/examples/example5/fft_script.m
new file mode 100644 (file)
index 0000000..4a418ea
--- /dev/null
@@ -0,0 +1,146 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Matlab script to compute the reference result for the FFT example.
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+close all;
+clear all;
+clc;
+
+wNk = inline('exp(-j * 2 * pi * k / N)', 'N', 'k');
+
+%coefficients produced by c's random number generator in producer_fire()
+x = [ -9 + j *  4
+      -2 + j *  0
+      -3 + j *  0
+       8 + j *  3
+       6 + j *  0
+      -7 + j * -9
+      -5 + j *  2
+       1 + j *  2
+       8 + j * -4
+      -6 + j * -4
+       9 + j * -2
+      -8 + j * -4
+      -3 + j *  1
+      -9 + j *  7
+      -9 + j * -9
+      -7 + j *  7
+       4 + j * -6
+       5 + j * -5
+       4 + j *  8
+       7 + j * -6
+      -3 + j *  9
+      -6 + j * -2
+      -8 + j * -9
+       2 + j *  7
+      -5 + j * -7
+       7 + j * -9
+       0 + j *  9
+       5 + j *  1
+      -8 + j *  1
+       5 + j *  6
+      -2 + j * -8
+       6 + j * -8
+      -5 + j *  7
+       5 + j * -9
+       8 + j * -5
+      -6 + j *  9
+       2 + j * -3
+       3 + j * -6
+       5 + j *  0
+      -7 + j *  6
+       3 + j * -4
+      -2 + j *  4
+      -4 + j * -2
+       9 + j * -8
+      -3 + j *  3
+       0 + j * -6
+       6 + j *  4
+      -2 + j * -4
+       9 + j *  0
+      -8 + j * -9
+       0 + j * -4
+       7 + j * -4
+       8 + j *  6
+      -2 + j * -1
+      -8 + j *  6
+       9 + j * -3
+       1 + j *  4
+       3 + j * -3
+       2 + j * -2
+       9 + j *  6
+      -8 + j * -7
+      -7 + j *  2
+       8 + j * -1
+       1 + j *  0
+      -1 + j * -3
+       3 + j * -9
+       1 + j *  9
+      -2 + j *  8
+       8 + j * -5
+       6 + j *  4
+       8 + j *  3
+       9 + j *  9
+       3 + j * -9
+       4 + j * -5
+       4 + j * -2
+       8 + j *  2
+      -3 + j *  1
+      -8 + j * -9
+       4 + j *  6
+       4 + j *  7
+       2 + j *  7
+      -4 + j * -6
+       6 + j *  9
+       3 + j * -5
+       6 + j * -7
+      -4 + j * -6
+       3 + j * -1
+       5 + j *  8
+       6 + j * -6
+      -5 + j *  0
+       2 + j * -2
+      -2 + j * -5
+      -4 + j * -8
+       9 + j * -5
+       3 + j *  3
+      -3 + j * -9
+      -5 + j * -7
+       6 + j * -6
+      -9 + j * -3
+       1 + j * -9
+       3 + j * -5
+       3 + j *  9
+       8 + j * -9
+      -8 + j *  3
+       1 + j * -5
+       9 + j *  4
+      -6 + j *  7
+       3 + j *  5
+       9 + j *  9
+      -4 + j * -6
+      -1 + j * -8
+      -6 + j *  3
+       4 + j * -3
+      -6 + j * -7
+       2 + j * -3
+      -8 + j *  0
+       1 + j *  9
+       9 + j *  0
+      -3 + j *  2
+      -2 + j *  7
+       8 + j * -9
+       1 + j *  6
+      -4 + j * -1
+       5 + j * -1
+       8 + j *  9
+       3 + j * -9
+       8 + j *  3
+      -3 + j * -2 ];
+
+fft(x(1:8))
+fft(x(1:16))
+fft(x(1:64))
+fft(x)
diff --git a/dol/examples/example5/src/consumer.c b/dol/examples/example5/src/consumer.c
new file mode 100644 (file)
index 0000000..376ecee
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p)
+{
+  ; //nothing to be done here
+}
+
+int consumer_fire(DOLProcess *p)
+{
+  CREATEPORTVAR(input_port);
+
+  for (p->local->index = 0; p->local->index < NUMBER_OF_FFT_POINTS;
+       p->local->index++) {
+    CREATEPORT(input_port, PORT_OUTPUT_COEFFICIENTS, 1,
+            p->local->index, NUMBER_OF_FFT_POINTS);
+    DOL_read((void*)input_port, &(p->local->coeffs[p->local->index]),
+        sizeof(ComplexNumber), p);
+    printf("%15s: coeff[%d]: %9f + j * %9f\n",
+           "output_consumer", p->local->index,
+           p->local->coeffs[p->local->index].real,
+           p->local->coeffs[p->local->index].imag);
+  }
+
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example5/src/consumer.h b/dol/examples/example5/src/consumer.h
new file mode 100644 (file)
index 0000000..0daf317
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_OUTPUT_COEFFICIENTS "output_coefficients"
+
+typedef struct _local_states
+{
+  int index;
+  ComplexNumber coeffs[NUMBER_OF_FFT_POINTS];
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example5/src/fft2.c b/dol/examples/example5/src/fft2.c
new file mode 100644 (file)
index 0000000..ec56b82
--- /dev/null
@@ -0,0 +1,75 @@
+#include <stdio.h>
+#include <math.h>
+#include "fft2.h"
+
+/**
+ * Determines the twiddle factor of this 2-point FFT based on the
+ * indices of the process.
+ */
+void fft2_init(DOLProcess *p)
+{
+  const float PI = 2.0 * asin(1.0);
+  int layer_index = GETINDEX(0);
+  int process_index = GETINDEX(1);
+  float exponent = 2.0 * PI *
+          (float)(process_index % (1 << layer_index)) /
+          (float)(1 << (layer_index + 1));
+
+  sprintf(p->local->id, "FFT2_%d_%d",
+          GETINDEX(0),
+          GETINDEX(1));
+  p->local->twiddle_factor.real = cos(exponent);
+  p->local->twiddle_factor.imag = -sin(exponent);
+
+  printf("%15s: twiddle_factor %9f + j * %9f\n",
+          p->local->id,
+          p->local->twiddle_factor.real,
+          p->local->twiddle_factor.imag);
+}
+
+/**
+ * Computes 2-point FFT.
+ */
+int fft2_fire(DOLProcess *p)
+{
+  DOL_read((void*)PORT_INA, &(p->local->inA), sizeof(ComplexNumber), p);
+  DOL_read((void*)PORT_INB, &(p->local->inB), sizeof(ComplexNumber), p);
+
+  p->local->rotated_inB.real = p->local->inB.real
+           * p->local->twiddle_factor.real
+           - p->local->inB.imag
+           * p->local->twiddle_factor.imag ;
+  p->local->rotated_inB.imag = p->local->inB.real
+           * p->local->twiddle_factor.imag
+           + p->local->inB.imag
+           * p->local->twiddle_factor.real;
+
+  p->local->outA.real = p->local->inA.real
+           + p->local->rotated_inB.real;
+  p->local->outA.imag = p->local->inA.imag
+           + p->local->rotated_inB.imag;
+
+  p->local->outB.real = p->local->inA.real
+           - p->local->rotated_inB.real;
+  p->local->outB.imag = p->local->inA.imag
+           - p->local->rotated_inB.imag;
+
+  DOL_write((void*)PORT_OUTA, &(p->local->outA), sizeof(ComplexNumber), p);
+  DOL_write((void*)PORT_OUTB, &(p->local->outB), sizeof(ComplexNumber), p);
+
+  /*
+  printf("%15s: ", p->local->id);
+  printf("%9f + j * %9f, %9f + j * %9f => %9f + j * %9f, %9f + j * %9f\n",
+          p->local->inA.real,
+          p->local->inA.imag,
+          p->local->inB.real,
+          p->local->inB.imag,
+          p->local->outA.real,
+          p->local->outA.imag,
+          p->local->outB.real,
+          p->local->outB.imag);
+  */
+
+  DOL_detach(p);
+  return -1;
+}
diff --git a/dol/examples/example5/src/fft2.h b/dol/examples/example5/src/fft2.h
new file mode 100644 (file)
index 0000000..79e567e
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef FFT2_H
+#define FFT2_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_INA  "inA"
+#define PORT_INB  "inB"
+#define PORT_OUTA "outA"
+#define PORT_OUTB "outB"
+
+typedef struct _local_states
+{
+  char id[14];
+  ComplexNumber inA, inB, outA, outB, rotated_inB, twiddle_factor;
+} Fft2_State;
+
+void fft2_init(DOLProcess *);
+int fft2_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example5/src/generator.c b/dol/examples/example5/src/generator.c
new file mode 100644 (file)
index 0000000..9d160cf
--- /dev/null
@@ -0,0 +1,47 @@
+#include <stdio.h>
+
+#include "generator.h"
+
+/**
+ * Returns a random integer in the range between lower_bound and
+ * upper_bound, where the bounding values are included in the interval.
+ */
+int getRandomNumber(int lower_bound, int upper_bound)
+{
+  return (rand() % (upper_bound - lower_bound + 1)) + lower_bound;
+}
+
+
+void generator_init(DOLProcess *p)
+{
+  ; //nothing to be done here
+}
+
+
+int generator_fire(DOLProcess *p)
+{
+  CREATEPORTVAR(output_port);
+
+  srand(0); //initialize random number generator
+
+  //generate input coefficients and write them to output ports
+  for (p->local->index = 0;
+       p->local->index < NUMBER_OF_FFT_POINTS;
+       p->local->index++) {
+    p->local->coeffs[p->local->index].real = (float)getRandomNumber(-9, 9);
+    p->local->coeffs[p->local->index].imag = (float)getRandomNumber(-9, 9);
+
+    CREATEPORT(output_port, PORT_INPUT_COEFFICIENTS, 1,
+            p->local->index, NUMBER_OF_FFT_POINTS);
+    printf("%15s: Write to input_coefficients_%d: %9f + j * %9f\n",
+           "input_generator", p->local->index,
+           p->local->coeffs[p->local->index].real,
+           p->local->coeffs[p->local->index].imag);
+    DOL_write((void*)output_port, &(p->local->coeffs[p->local->index]),
+              sizeof(ComplexNumber), p);
+  }
+
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example5/src/generator.h b/dol/examples/example5/src/generator.h
new file mode 100644 (file)
index 0000000..511ec04
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include <dol.h>
+#include "global.h"
+#include "stdlib.h"
+
+#define PORT_INPUT_COEFFICIENTS "input_coefficients"
+
+typedef struct _local_states
+{
+  int index;
+  ComplexNumber coeffs[NUMBER_OF_FFT_POINTS];
+} Generator_State;
+
+void generator_init(DOLProcess *);
+int generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example5/src/global.h b/dol/examples/example5/src/global.h
new file mode 100644 (file)
index 0000000..b1373b2
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#define NUMBER_OF_FFT_POINTS 16
+
+//structure for holding complex numbers
+typedef struct complex_number
+{
+  float real;
+  float imag;
+} ComplexNumber;
+
+#endif
diff --git a/dol/examples/example6/example6.xml b/dol/examples/example6/example6.xml
new file mode 100644 (file)
index 0000000..f8a0d19
--- /dev/null
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="filter">
+
+  <!-- instantiate processes -->
+  <process name="producer">
+    <port type="output" name="out"/>
+    <source type="c" location="producer.c"/>
+  </process>
+
+  <process name="consumer">
+    <port type="input" name="in"/>
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <process name="filter">
+    <port type="input" name="inA"/>
+    <port type="input" name="inB"/>
+    <port type="output" name="outA"/>
+    <port type="output" name="outB"/>
+    <source type="c" location="filter.c"/>
+  </process>
+  
+  <sw_channel type="fifo" size="4" name="inputchannel">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <sw_channel type="fifo" size="4" name="outputchannel">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <sw_channel type="fifo" size="4" name="filterchannel">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <connection name="inputconnection">
+    <origin name="producer">
+      <port name="out"/>
+    </origin>
+    <target name="inputchannel">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <connection name="outputconnection">
+    <origin name="outputchannel">
+      <port name="out"/>
+    </origin>
+    <target name="consumer">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <connection name="filterconnectionin">
+    <origin name="inputchannel">
+      <port name="out"/>
+    </origin>
+    <target name="filter">
+      <port name="inA"/>
+    </target>
+  </connection>
+
+  <connection name="filterconnectionout">
+    <origin name="filter">
+      <port name="outA"/>
+    </origin>
+    <target name="outputchannel">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <!-- feedback connection -->
+  <connection name="filterconnectionfeedbackA">
+    <origin name="filter">
+      <port name="outB"/>
+    </origin>
+    <target name="filterchannel">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <connection name="filterconnectionfeedbackB">
+    <origin name="filterchannel">
+      <port name="out"/>
+    </origin>
+    <target name="filter">
+      <port name="inB"/>
+    </target>
+  </connection>
+
+</processnetwork>
diff --git a/dol/examples/example6/src/consumer.c b/dol/examples/example6/src/consumer.c
new file mode 100644 (file)
index 0000000..f79ccf9
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p)
+{
+  ; //nothing to be done here
+}
+
+int consumer_fire(DOLProcess *p)
+{
+  static int index;
+  static float sample;
+
+  for (index = 0; index < 10; index++)
+  {
+    DOL_read((void*)PORT_IN, &sample, sizeof(float), p);
+    printf("%8s:                             Read sample[%02d]: %+6.4f\n",
+           "consumer", index, sample);
+  }
+  return 0;
+}
+
diff --git a/dol/examples/example6/src/consumer.h b/dol/examples/example6/src/consumer.h
new file mode 100644 (file)
index 0000000..09d158b
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+
+#define PORT_IN "in"
+
+typedef struct _local_states
+{
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example6/src/filter.c b/dol/examples/example6/src/filter.c
new file mode 100644 (file)
index 0000000..2715647
--- /dev/null
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <math.h>
+#include "filter.h"
+
+/**
+ * Write zero to feedback output.
+ */
+void filter_init(DOLProcess *p)
+{
+  p->local->zero = 0.0;
+  p->local->factor = 0.5;
+  p->local->firstiteration = 1;
+}
+
+/**
+ * Filter.
+ */
+int filter_fire(DOLProcess *p)
+{
+  if (p->local->firstiteration) {
+      DOL_write((void*)PORT_OUTB, &(p->local->zero), sizeof(float), p);
+      p->local->firstiteration = 0;
+  }
+
+  DOL_read((void*)PORT_INA, &(p->local->inA), sizeof(float), p);
+  DOL_read((void*)PORT_INB, &(p->local->inB), sizeof(float), p);
+  p->local->out = p->local->inA + p->local->factor * p->local->inB;
+  DOL_write((void*)PORT_OUTA, &(p->local->out), sizeof(float), p);
+  DOL_write((void*)PORT_OUTB, &(p->local->out), sizeof(float), p);
+
+  return 0;
+}
diff --git a/dol/examples/example6/src/filter.h b/dol/examples/example6/src/filter.h
new file mode 100644 (file)
index 0000000..a068113
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef FILTER_H
+#define FILTER_H
+
+#include <dol.h>
+
+#define PORT_INA  "inA"
+#define PORT_INB  "inB"
+#define PORT_OUTA "outA"
+#define PORT_OUTB "outB"
+
+typedef struct _local_states
+{
+  int firstiteration;
+  float inA, inB, out, zero, factor;
+} Filter_State;
+
+void filter_init(DOLProcess *);
+int filter_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example6/src/producer.c b/dol/examples/example6/src/producer.c
new file mode 100644 (file)
index 0000000..58e161a
--- /dev/null
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "producer.h"
+
+/**
+ * Returns a random integer in the range between lower_bound and
+ * upper_bound, where the bounding values are included in the interval.
+ */
+int getRandomNumber(int lower_bound, int upper_bound)
+{
+  return (rand() % (upper_bound - lower_bound + 1)) + lower_bound;
+}
+
+
+void producer_init(DOLProcess *p)
+{
+  ; //nothing to be done here
+}
+
+
+int producer_fire(DOLProcess *p)
+{
+  static int index;
+
+  srand(0); //initialize random number generator
+
+  //generate input samples and display them
+  printf("producer: samples = { ");
+
+  for (index = 0; index < 10; index++) {
+    p->local->sample[index] = (float) getRandomNumber(-9, 9);
+    if (index < 9) {
+      printf("%+3.1f, ", p->local->sample[index]);
+    }
+    else {
+      printf("%+3.1f }\n", p->local->sample[index]);
+    }
+  }
+
+  //write samples to output port
+  for (index = 0; index < 10; index++) {
+    printf("%8s: Write sample[%02d]: %+6.4f\n",
+           "producer", index, p->local->sample[index]);
+    DOL_write((void*)PORT_OUT, &(p->local->sample[index]),
+            sizeof(float), p);
+  }
+
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example6/src/producer.h b/dol/examples/example6/src/producer.h
new file mode 100644 (file)
index 0000000..9aacfe7
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include <dol.h>
+#include "stdlib.h"
+
+#define PORT_OUT "out"
+
+typedef struct _local_states
+{
+  float sample[10];
+} Producer_State;
+
+void producer_init(DOLProcess *);
+int producer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example7/example7.xml b/dol/examples/example7/example7.xml
new file mode 100644 (file)
index 0000000..271c3b9
--- /dev/null
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="filter">
+
+  <!-- N - 1 is the filter order -->
+  <variable name="N" value="3"/>
+
+  <!-- instantiate processes -->
+  <process name="producer">
+    <port type="output" name="out"/>
+    <source type="c" location="producer.c"/>
+  </process>
+
+  <process name="consumer">
+    <port type="input" name="in"/>
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <iterator  variable="i" range="N">
+    <process name="filter">
+      <append function="i"/>
+      <port type="input" name="inA"/>
+      <port type="input" name="inB"/>
+      <port type="output" name="outA"/>
+      <port type="output" name="outB"/>
+      <source type="c" location="filter.c"/>
+    </process>
+  </iterator>
+  
+  <!-- instantiate sw_channels -->
+  <sw_channel type="fifo" size="4" name="inputchannel">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <sw_channel type="fifo" size="4" name="outputchannel">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+  
+  <iterator  variable="i" range="N - 1">  
+    <sw_channel type="fifo" size="4" name="filterchannelA">
+      <append function="i"/>
+      <port type="input" name="in"/>
+      <port type="output" name="out"/>
+    </sw_channel>
+
+    <sw_channel type="fifo" size="4" name="filterchannelB">
+      <append function="i"/>
+      <port type="input" name="in"/>
+      <port type="output" name="out"/>
+    </sw_channel>
+  </iterator>
+  
+  <sw_channel type="fifo" size="4" name="feedbackchannel">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <!-- connections of top filter stage -->
+  <connection name="inputconnection">
+    <origin name="producer">
+      <port name="out"/>
+    </origin>
+    <target name="inputchannel">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <connection name="outputconnection">
+    <origin name="outputchannel">
+      <port name="out"/>
+    </origin>
+    <target name="consumer">
+      <port name="in"/>
+    </target>
+  </connection>
+  
+  <connection name="filterconnectionin">
+    <origin name="inputchannel">
+      <port name="out"/>
+    </origin>
+    <target name="filter">
+      <append function="0"/>
+      <port name="inA"/>
+    </target>
+  </connection>
+
+  <connection name="filterconnectionout">
+    <origin name="filter">
+      <append function="0"/>
+      <port name="outB"/>
+    </origin>
+    <target name="outputchannel">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <!-- connections of intermediate filter stage(s) -->  
+  <iterator  variable="i" range="N - 1">  
+    <connection name="filterconnectionoutAinA1">
+      <append function="i"/>
+      <origin name="filter">
+        <append function="i"/>
+        <port name="outA"/>
+      </origin>
+      <target name="filterchannelA">
+        <append function="i"/>
+        <port name="in"/>
+      </target>
+    </connection>
+    <connection name="filterconnectionoutAinA2">
+      <append function="i"/>
+      <origin name="filterchannelA">
+        <append function="i"/>
+        <port name="out"/>
+      </origin>
+      <target name="filter">
+        <append function="i + 1"/>
+        <port name="inA"/>
+      </target>
+    </connection>
+
+    <connection name="filterconnectionoutBinB1">
+      <append function="i"/>
+      <origin name="filter">
+        <append function="i + 1"/>
+        <port name="outB"/>
+      </origin>
+      <target name="filterchannelB">
+        <append function="i"/>
+        <port name="in"/>
+      </target>
+    </connection>
+    <connection name="filterconnectionoutBinB2">
+      <append function="i"/>
+      <origin name="filterchannelB">
+        <append function="i"/>
+        <port name="out"/>
+      </origin>
+      <target name="filter">
+        <append function="i"/>
+        <port name="inB"/>
+      </target>
+    </connection>
+  </iterator>
+  
+  <!-- connection of bottom filter stage -->
+  <connection name="sinkconnectionA1">
+    <origin name="filter">
+      <append function="N - 1"/>
+      <port name="outA"/>
+    </origin>
+    <target name="feedbackchannel">
+      <port name="in"/>
+    </target>
+  </connection>
+  
+  <connection name="sinkconnectionA2">
+    <origin name="feedbackchannel">
+      <port name="out"/>
+    </origin>
+    <target name="filter">
+      <append function="N - 1"/>
+      <port name="inB"/>
+    </target>
+  </connection>
+</processnetwork>
diff --git a/dol/examples/example7/filter_script.m b/dol/examples/example7/filter_script.m
new file mode 100644 (file)
index 0000000..dab0c8a
--- /dev/null
@@ -0,0 +1,15 @@
+clear all;
+close all;
+clc;
+
+N = 3;
+NUMBER_OF_SAMPLES = 5;
+FILTER_COEFFICIENTS = [0.1 -0.1 0.4 1.0 -0.7 0.2 -0.9 -0.4 -0.8];
+x = [-9  4 -2  0 -3  0  8  3  6  0, ...
+     -7 -9 -5  2  1  2  8 -4 -6 -4];
+%example 6
+y = filter(1, [1 -0.5], x(1:10))
+
+%example 7
+y = filter(1, [1 -FILTER_COEFFICIENTS(1:N-1)], x (1:NUMBER_OF_SAMPLES))
diff --git a/dol/examples/example7/src/consumer.c b/dol/examples/example7/src/consumer.c
new file mode 100644 (file)
index 0000000..ace9ccc
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p)
+{
+  printf("init consumer.\n");
+}
+
+int consumer_fire(DOLProcess *p)
+{
+  static int index;
+  static float sample;
+
+  for (index = 0; index < NUMBER_OF_SAMPLES; index++)
+  {
+    DOL_read((void*)PORT_IN, &sample, sizeof(float), p);
+    printf("%8s:                             Read sample[%02d]: %+6.4f\n",
+           "consumer", index, sample);
+  }
+  return 0;
+}
+
diff --git a/dol/examples/example7/src/consumer.h b/dol/examples/example7/src/consumer.h
new file mode 100644 (file)
index 0000000..8908e5d
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN "in"
+
+typedef struct _local_states
+{
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example7/src/filter.c b/dol/examples/example7/src/filter.c
new file mode 100644 (file)
index 0000000..fd8c3ab
--- /dev/null
@@ -0,0 +1,83 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "filter.h"
+
+/**
+ * Init.
+ */
+void filter_init(DOLProcess *p)
+{
+  int k;
+  p->local->process_index = GETINDEX(0);
+
+  srand(0); //initialize random number generator
+  for (k = 0; k < p->local->process_index; k++)
+    rand();
+
+  sprintf(p->local->id, "filter_%d",
+          GETINDEX(0));
+  p->local->first_invocation = 1;
+  //generate a random filter coefficient between -1 and 1
+  p->local->filter_coefficient = ((float) (rand() % 21) - 10)/10.0;
+  p->local->zero = 0.0;
+  printf("init %s: filter coefficient = %+2.1f\n",
+         p->local->id, p->local->filter_coefficient);
+}
+
+/**
+ * Filter.
+ */
+int filter_fire(DOLProcess *p)
+{
+  //behaviour of the top filter stage
+  if (p->local->process_index == 0) {
+    if (p->local->first_invocation) {
+      DOL_read((void*)PORT_INA, &(p->local->inA), sizeof(float), p);
+      p->local->out = p->local->inA;
+      p->local->inB = 0.0;
+      p->local->first_invocation = 0;
+    }
+    else {
+      DOL_read((void*)PORT_INA, &(p->local->inA), sizeof(float), p);
+      DOL_read((void*)PORT_INB, &(p->local->inB), sizeof(float), p);
+      p->local->out = p->local->inB + p->local->inA;
+    }
+
+    DOL_write((void*)PORT_OUTA, &(p->local->out), sizeof(float), p);
+    DOL_write((void*)PORT_OUTB, &(p->local->out), sizeof(float), p);
+
+    printf("%8s: inA: %6.4f, inB: %6.4f, outA = outB: %6.4f\n",
+           p->local->id, p->local->inA, p->local->inB, p->local->out);
+  }
+  //behaviour of the intermediate filter stages
+  else {
+    if (p->local->first_invocation) {
+      DOL_read((void*)PORT_INA, &(p->local->inA), sizeof(float), p);
+      p->local->out = p->local->filter_coefficient * p->local->inA;
+      p->local->inB = 0.0;
+      p->local->first_invocation = 0;
+    }
+    else {
+      DOL_read((void*)PORT_INA, &(p->local->inA), sizeof(float), p);
+      DOL_read((void*)PORT_INB, &(p->local->inB), sizeof(float), p);
+      p->local->out = p->local->inB + p->local->filter_coefficient
+              * p->local->inA;
+    }
+
+    if (p->local->process_index < N - 1) {
+      DOL_write((void*)PORT_OUTA, &(p->local->inA), sizeof(float), p);
+      DOL_write((void*)PORT_OUTB, &(p->local->out), sizeof(float), p);
+    }
+    //behaviour of the bottom filter stage
+    else {
+      DOL_write((void*)PORT_OUTA, &(p->local->zero), sizeof(float), p);
+      DOL_write((void*)PORT_OUTB, &(p->local->out), sizeof(float), p);
+    }
+
+    printf("%8s: inA: %6.4f, inB: %6.4f, outA: %6.4f, outB: %6.4f\n",
+           p->local->id, p->local->inA, p->local->inB, p->local->inA,
+           p->local->out);
+  }
+
+  return 0;
+}
diff --git a/dol/examples/example7/src/filter.h b/dol/examples/example7/src/filter.h
new file mode 100644 (file)
index 0000000..8d6b07b
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef FILTER_H
+#define FILTER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_INA  "inA"
+#define PORT_INB  "inB"
+#define PORT_OUTA "outA"
+#define PORT_OUTB "outB"
+
+typedef struct _local_states
+{
+  char id[10]; //will contain "filter_xx"
+  int first_invocation;
+  int process_index;
+  float inA, inB, out, filter_coefficient, zero;
+} Filter_State;
+
+void filter_init(DOLProcess *);
+int filter_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/example7/src/global.h b/dol/examples/example7/src/global.h
new file mode 100644 (file)
index 0000000..b2931f2
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#define N                 3
+#define NUMBER_OF_SAMPLES 5
+
+#endif
diff --git a/dol/examples/example7/src/producer.c b/dol/examples/example7/src/producer.c
new file mode 100644 (file)
index 0000000..89f2aaa
--- /dev/null
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "producer.h"
+
+/**
+ * Returns a random integer in the range between lower_bound and
+ * upper_bound, where the bounding values are included in the interval.
+ */
+int getRandomNumber(int lower_bound, int upper_bound)
+{
+  return (rand() % (upper_bound - lower_bound + 1)) + lower_bound;
+}
+
+
+void producer_init(DOLProcess *p)
+{
+  printf("init producer.\n");
+}
+
+
+int producer_fire(DOLProcess *p)
+{
+  srand(0); //initialize random number generator
+
+  //generate input samples and display them
+  printf("producer: samples = { ");
+
+  for (p->local->index = 0; p->local->index < NUMBER_OF_SAMPLES; p->local->index++) {
+    p->local->sample[p->local->index] = (float) getRandomNumber(-9, 9);
+    if (p->local->index < NUMBER_OF_SAMPLES - 1) {
+      printf("%+3.1f, ", p->local->sample[p->local->index]);
+    }
+    else {
+      printf("%+3.1f }\n", p->local->sample[p->local->index]);
+    }
+  }
+
+  //write samples to output port
+  for (p->local->index = 0; p->local->index < NUMBER_OF_SAMPLES; p->local->index++) {
+    printf("%8s: Write sample[%02d]: %+6.4f\n",
+           "producer", p->local->index, p->local->sample[p->local->index]);
+    DOL_write((void*)PORT_OUT, &(p->local->sample[p->local->index]),
+            sizeof(float), p);
+  }
+
+  DOL_detach(p);
+  return -1;
+}
+
diff --git a/dol/examples/example7/src/producer.h b/dol/examples/example7/src/producer.h
new file mode 100644 (file)
index 0000000..2cffa95
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include <dol.h>
+#include "global.h"
+#include "stdlib.h"
+
+#define PORT_OUT "out"
+
+typedef struct _local_states
+{
+  int index;
+  float sample[NUMBER_OF_SAMPLES];
+} Producer_State;
+
+void producer_init(DOLProcess *);
+int producer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/examplecell/cell.xml b/dol/examples/examplecell/cell.xml
new file mode 100644 (file)
index 0000000..c1397f3
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<architecture xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE
+                      http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd"
+  name="Sony/Toshiba/IBM Cell Broadband Engine architecture">
+
+  <processor name="ppu" type="RISC">
+  </processor>
+  
+  <processor name="spu_0" type="DSP">
+  </processor>
+
+  <processor name="spu_1" type="DSP">
+  </processor>
+  
+  <processor name="spu_2" type="DSP">
+  </processor>
+  
+  <processor name="spu_3" type="DSP">
+  </processor>
+  
+  <processor name="spu_4" type="DSP">
+  </processor>
+  
+  <processor name="spu_5" type="DSP">
+  </processor>
+  
+</architecture>
diff --git a/dol/examples/examplecell/examplecell.xml b/dol/examples/examplecell/examplecell.xml
new file mode 100644 (file)
index 0000000..5e63359
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK\r
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="example2"> \r
+\r
+  <variable value="9" name="N"/>\r
+
+\r
+  <!-- instantiate resources -->\r
+  <process name="generator">\r
+    <port type="output" name="10"/>\r
+    <source type="c" location="generator.c"/>\r
+  </process>\r
+\r
+  <iterator variable="i" range="N">\r
+    <process name="square">\r
+      <append function="i"/>\r
+      <port type="input" name="0"/>\r
+      <port type="output" name="1"/>\r
+      <source type="c" location="square.c"/>\r
+    </process>\r
+  </iterator>\r
+\r
+  <process name="consumer">\r
+    <port type="input" name="100"/>\r
+    <source type="c" location="consumer.c"/>\r
+  </process>\r
+\r
+  <iterator variable="i" range="N + 1">\r
+    <sw_channel type="fifo" size="10" name="C2">\r
+      <append function="i"/>\r
+      <port type="input" name="0"/>\r
+      <port type="output" name="1"/>\r
+    </sw_channel>\r
+  </iterator>\r
+\r
+  <!-- instantiate connection -->\r
+  <iterator variable="i" range="N">\r
+    <connection name="to_square">\r
+      <append function="i"/>\r
+      <origin name="C2">\r
+        <append function="i"/>\r
+        <port name="1"/>\r
+      </origin>\r
+      <target name="square">\r
+        <append function="i"/>\r
+        <port name="0"/>\r
+      </target>\r
+    </connection>\r
+\r
+    <connection name="from_square">\r
+        <append function="i"/>\r
+        <origin name="square">\r
+          <append function="i"/>\r
+          <port name="1"/>\r
+        </origin>\r
+        <target name="C2">\r
+          <append function="i + 1"/>\r
+          <port name="0"/>\r
+        </target>\r
+    </connection>\r
+  </iterator>\r
+\r
+  <connection name="g_">\r
+    <origin name="generator">\r
+     <port name="10"/>\r
+    </origin>\r
+    <target name="C2"> \r
+      <append function="0"/>\r
+      <port name="0"/>\r
+    </target>\r
+  </connection>\r
+\r
+  <connection name="_c">\r
+    <origin name="C2">\r
+      <append function="N"/>\r
+      <port name="1"/>\r
+    </origin>\r
+    <target name="consumer">\r
+      <port name="100"/>\r
+    </target>\r
+  </connection>\r
+\r
+</processnetwork>\r
diff --git a/dol/examples/examplecell/mapping.xml b/dol/examples/examplecell/mapping.xml
new file mode 100644 (file)
index 0000000..aafe1d8
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mapping xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING
+                      http://www.tik.ee.ethz.ch/~shapes/schema/mapping.xsd"
+  name="examplecell on Cell">
+
+  <binding name="binding_generator" xsi:type="computation">
+    <process name="generator"/>
+    <processor name="ppu"/>
+  </binding>
+  
+  <binding name="binding_square_0" xsi:type="computation">
+    <process name="square_0">
+    </process>
+    <processor name="spu_4"/>
+  </binding>
+
+  <binding name="binding_square_1" xsi:type="computation">
+    <process name="square_1">
+    </process>
+    <processor name="spu_1"/>
+  </binding>
+  
+  <binding name="binding_square_2" xsi:type="computation">
+    <process name="square_2">
+    </process>
+    <processor name="spu_2"/>
+  </binding>
+  
+  <binding name="binding_square_3" xsi:type="computation">
+    <process name="square_3">
+    </process>
+    <processor name="spu_3"/>
+  </binding>
+  
+  <binding name="binding_square_4" xsi:type="computation">
+    <process name="square_4">
+    </process>
+    <processor name="spu_4"/>
+  </binding>
+
+  <binding name="binding_square_5" xsi:type="computation">
+    <process name="square_5">
+    </process>
+    <processor name="spu_5"/>
+  </binding>
+  
+  <binding name="binding_square_6" xsi:type="computation">
+    <process name="square_6">
+    </process>
+    <processor name="spu_1"/>
+  </binding>
+  
+  <binding name="binding_square_7" xsi:type="computation">
+    <process name="square_7">
+    </process>
+    <processor name="spu_2"/>
+  </binding>
+  
+  <binding name="binding_square_8" xsi:type="computation">
+    <process name="square_8">
+    </process>
+    <processor name="spu_3"/>
+  </binding>
+  
+  <binding name="binding_consumer" xsi:type="computation">
+    <process name="consumer"/>
+    <processor name="spu_0"/>
+  </binding>
+</mapping>
diff --git a/dol/examples/examplecell/src/consumer.c b/dol/examples/examplecell/src/consumer.c
new file mode 100644 (file)
index 0000000..cb89dd0
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "consumer");
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int consumer_fire(DOLProcess *p) {
+    if (p->local->index < p->local->len) {
+        DOL_read((void*)PORT_IN, &p->local->c, sizeof(float), p);
+        printf("%s: %f\n", p->local->name, p->local->c);
+        p->local->index++;
+    } else {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplecell/src/consumer.h b/dol/examples/examplecell/src/consumer.h
new file mode 100644 (file)
index 0000000..ca0fbba
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN 100
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+    float c;
+} Consumer_State;
+
+#endif
diff --git a/dol/examples/examplecell/src/generator.c b/dol/examples/examplecell/src/generator.c
new file mode 100644 (file)
index 0000000..237f54e
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#include "generator.h"
+
+void generator_init(DOLProcess *p) {
+    sprintf(p->local->name, "generator");
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int generator_fire(DOLProcess *p) {
+    if (p->local->index < p->local->len) {
+        p->local->x = (float)p->local->index;
+        DOL_write((void*)PORT_OUT, &p->local->x, sizeof(float), p);
+        p->local->index++;
+    } else {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplecell/src/generator.h b/dol/examples/examplecell/src/generator.h
new file mode 100644 (file)
index 0000000..dbc225f
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <dol.h>
+#include "global.h"
+
+#define  PORT_OUT 10
+
+void generator_init(DOLProcess *);
+int generator_fire(DOLProcess *);
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+    float x;
+} Generator_State;
+
+#endif
diff --git a/dol/examples/examplecell/src/global.h b/dol/examples/examplecell/src/global.h
new file mode 100644 (file)
index 0000000..92dc11c
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#define LENGTH 6
+
+#endif
diff --git a/dol/examples/examplecell/src/square.c b/dol/examples/examplecell/src/square.c
new file mode 100644 (file)
index 0000000..c1c6caa
--- /dev/null
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+#include "square.h"
+
+void square_init(DOLProcess *p) {
+    sprintf(p->local->name, "square");
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int square_fire(DOLProcess *p) {
+    if (p->local->index < p->local->len) {
+        DOL_read((void*)PORT_IN, &p->local->i, sizeof(float), p);
+        p->local->i = p->local->i + p->local->i;
+        DOL_write((void*)PORT_OUT, &p->local->i, sizeof(float), p);
+        p->local->index++;
+    } else {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplecell/src/square.h b/dol/examples/examplecell/src/square.h
new file mode 100644 (file)
index 0000000..5b947a8
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef SQUARE_H
+#define SQUARE_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN  0
+#define PORT_OUT 1
+
+void square_init(DOLProcess *);
+int square_fire(DOLProcess *);
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+    float i;
+} Square_State;
+
+#endif
diff --git a/dol/examples/exampleproducerconsumer/exampleproducerconsumer.xml b/dol/examples/exampleproducerconsumer/exampleproducerconsumer.xml
new file mode 100644 (file)
index 0000000..5ccb2f3
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="example8"> 
+
+  <!-- processes -->
+  <process name="producer"> 
+    <port type="output" name="A"/>
+    <port type="output" name="B"/>
+     <source type="c" location="producer.c"/>
+  </process>
+
+  <process name="consumer"> 
+    <port type="input" name="A"/> 
+       <port type="input" name="B"/>
+    <source type="c" location="consumer.c"/>
+  </process>
+
+
+  <!-- sw_channels -->
+  <sw_channel type="fifo" size="10" name="C1">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <sw_channel type="fifo" size="10" name="C2">
+    <port type="input" name="in"/>
+    <port type="output" name="out"/>
+  </sw_channel>
+
+  <!-- connections -->
+  <connection name="p-c1-a">
+    <origin name="producer">
+      <port name="A"/>
+    </origin>
+    <target name="C1">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <connection name="p-c1-b">
+    <origin name="producer">
+      <port name="B"/>
+    </origin>
+    <target name="C2">
+      <port name="in"/>
+    </target>
+  </connection>
+
+  <connection name="c-c1-a">
+    <origin name="C1">
+      <port name="out"/>
+    </origin>
+    <target name="consumer">
+      <port name="A"/>
+    </target>
+  </connection>
+
+  <connection name="c-c2-b">
+    <origin name="C2">
+     <port name="out"/>
+    </origin>
+    <target name="consumer">
+      <port name="B"/>
+    </target>
+  </connection>
+
+</processnetwork>
diff --git a/dol/examples/exampleproducerconsumer/src/consumer.c b/dol/examples/exampleproducerconsumer/src/consumer.c
new file mode 100644 (file)
index 0000000..c39157b
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "consumer");
+}
+
+int consumer_fire(DOLProcess *p) {
+    char c;
+
+    if (DOL_rtest((void*)PORT_INB, 1, p)) {
+        DOL_read((void*)PORT_INA, &c, sizeof(char), p);
+        printf("from port B: %c\n", c);
+        DOL_read((void*)PORT_INA, &c, sizeof(char), p);
+        printf("from port A: %c\n", c);
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/exampleproducerconsumer/src/consumer.h b/dol/examples/exampleproducerconsumer/src/consumer.h
new file mode 100644 (file)
index 0000000..47d5ebf
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+
+#define PORT_INA "A"
+#define PORT_INB "B"
+
+typedef struct _local_states {
+    char name[10];
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/exampleproducerconsumer/src/producer.c b/dol/examples/exampleproducerconsumer/src/producer.c
new file mode 100644 (file)
index 0000000..2e0130b
--- /dev/null
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "producer.h"
+
+// initialization function
+void producer_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = 20;
+    sprintf(p->local->str, "abcdefghijklmnopqrstuvwxyz");
+
+}
+
+int producer_fire(DOLProcess *p) {
+
+    if (p->local->index < p->local->len) {
+        if (DOL_wtest((void*)PORT_OUTA, 1, p)) {
+            DOL_write((void*)PORT_OUTA, &(p->local->str[p->local->index]),
+                    1, p);
+            printf("p write to port A %c\n",
+                    p->local->str[p->local->index]);
+        }
+        else {
+            DOL_write((void*)PORT_OUTB, &(p->local->str[p->local->index]),
+                    1, p);
+            printf("p write to port B %c\n",
+                    p->local->str[p->local->index]);
+        }
+        p->local->index++;
+        return 0;
+    }
+    else {
+        DOL_detach(p);
+        return -1;
+    }
+}
+
diff --git a/dol/examples/exampleproducerconsumer/src/producer.h b/dol/examples/exampleproducerconsumer/src/producer.h
new file mode 100644 (file)
index 0000000..6668050
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef PRODUCER_H
+#define PRODUCER_H
+
+#include <dol.h>
+
+#define  PORT_OUTA "A"
+#define  PORT_OUTB "B"
+
+typedef struct _local_states {
+    int index;
+    int len;
+    char str[26];
+} Producer_State;
+
+void producer_init(DOLProcess *);
+int producer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/examplesingleprocess/examplesingleprocess.xml b/dol/examples/examplesingleprocess/examplesingleprocess.xml
new file mode 100644 (file)
index 0000000..07937ae
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork 
+xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" 
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+    http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="independent processes"> 
+
+  <!-- processes -->
+  <iterator variable="i" range="3">
+    <process name="task"> 
+      <append function="i"/>
+      <source type="c" location="task.c"/>
+    </process>
+  </iterator>
+
+</processnetwork>
diff --git a/dol/examples/examplesingleprocess/src/task.c b/dol/examples/examplesingleprocess/src/task.c
new file mode 100644 (file)
index 0000000..9544c0b
--- /dev/null
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+#include "task.h"
+
+void task_init(DOLProcess *p) {
+    sprintf(p->local->name, "task_%d", GETINDEX(0));
+    p->local->index = 0;
+}
+
+int task_fire(DOLProcess *p) {
+    if (p->local->index < 10) {
+        printf("%s: %d\n", p->local->name, p->local->index++);
+    }
+
+    if (p->local->index >= 10) {
+        DOL_detach(p);
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplesingleprocess/src/task.h b/dol/examples/examplesingleprocess/src/task.h
new file mode 100644 (file)
index 0000000..c68d499
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef TASK_H
+#define TASK_H
+
+#include <dol.h>
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+} Task_State;
+
+void task_init(DOLProcess *);
+int task_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/examplewindowedfifo/examplewindowedfifo.xml b/dol/examples/examplewindowedfifo/examplewindowedfifo.xml
new file mode 100644 (file)
index 0000000..a09d69b
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<processnetwork 
+xmlns="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" 
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+xsi:schemaLocation="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK
+    http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd" name="examplewindowedfifo"> 
+
+  <!-- processes -->
+  <process name="generator"> 
+    <port type="output" name="1"/>
+    <source type="c" location="generator.c"/>
+    <configuration name="triggerPeriod" value="100000"/>
+  </process>
+
+  <process name="consumer"> 
+    <port type="input" name="1"/> 
+    <source type="c" location="consumer.c"/>
+  </process>
+
+  <process name="square"> 
+    <port type="input" name="100"/>
+    <port type="output" name="200"/>
+    <source type="c" location="square.c"/>
+  </process>
+
+  <!-- sw_channels -->
+  <sw_channel type="wfifo" size="12" name="C1">
+    <port type="input" name="0"/>
+    <port type="output" name="1"/>
+  </sw_channel>
+
+  <sw_channel type="wfifo" size="12" name="C2">
+    <port type="input" name="0"/>
+    <port type="output" name="1"/>
+  </sw_channel>
+
+  <!-- connections -->
+  <connection name="g-c">
+    <origin name="generator">
+      <port name="1"/>
+    </origin>
+    <target name="C1">
+      <port name="0"/>
+    </target>
+  </connection>
+
+  <connection name="c-c">
+    <origin name="C2">
+      <port name="1"/>
+    </origin>
+    <target name="consumer">
+      <port name="1"/>
+    </target>
+  </connection>
+
+  <connection name="s-c">
+    <origin name="square">
+      <port name="200"/>
+    </origin>
+    <target name="C2">
+      <port name="0"/>
+    </target>
+  </connection>
+
+  <connection name="c-s">
+    <origin name="C1">
+      <port name="1"/>
+    </origin>
+    <target name="square">
+      <port name="100"/>
+    </target>
+  </connection>
+
+</processnetwork>
diff --git a/dol/examples/examplewindowedfifo/src/consumer.c b/dol/examples/examplewindowedfifo/src/consumer.c
new file mode 100644 (file)
index 0000000..cf6902a
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+#include "consumer.h"
+
+void consumer_init(DOLProcess *p) {
+    sprintf(p->local->name, "consumer");
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int consumer_fire(DOLProcess *p) {
+    float *c;
+    if (p->local->index < p->local->len) {
+        DOL_capture((void*)PORT_IN, &c, sizeof(float), p);
+        printf("%s: %f\n", p->local->name, *c);
+        DOL_consume((void*)PORT_IN, p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplewindowedfifo/src/consumer.h b/dol/examples/examplewindowedfifo/src/consumer.h
new file mode 100644 (file)
index 0000000..677609a
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef CONSUMER_H
+#define CONSUMER_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN 1
+
+typedef struct _local_states {
+    char name[10];
+    int index;
+    int len;
+} Consumer_State;
+
+void consumer_init(DOLProcess *);
+int consumer_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/examplewindowedfifo/src/generator.c b/dol/examples/examplewindowedfifo/src/generator.c
new file mode 100644 (file)
index 0000000..943294d
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "generator.h"
+
+// initialization function
+void generator_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int generator_fire(DOLProcess *p) {
+
+    if (p->local->index < p->local->len) {
+        float *x;
+        DOL_reserve((void*)PORT_OUT, &x, sizeof(float), p);
+        *x = (float)p->local->index;
+        DOL_release((void*)PORT_OUT, p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplewindowedfifo/src/generator.h b/dol/examples/examplewindowedfifo/src/generator.h
new file mode 100644 (file)
index 0000000..b938a38
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <dol.h>
+#include "global.h"
+
+#define  PORT_OUT 1
+
+typedef struct _local_states {
+    int index;
+    int len;
+} Generator_State;
+
+void generator_init(DOLProcess *);
+int generator_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/examplewindowedfifo/src/global.h b/dol/examples/examplewindowedfifo/src/global.h
new file mode 100644 (file)
index 0000000..dfcbb84
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#define LENGTH 20
+
+#endif
diff --git a/dol/examples/examplewindowedfifo/src/square.c b/dol/examples/examplewindowedfifo/src/square.c
new file mode 100644 (file)
index 0000000..7e0b5d2
--- /dev/null
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+#include "square.h"
+
+void square_init(DOLProcess *p) {
+    p->local->index = 0;
+    p->local->len = LENGTH;
+}
+
+int square_fire(DOLProcess *p) {
+    float *i, *j;
+
+    if (p->local->index < p->local->len) {
+        DOL_capture((void*)PORT_IN, &i, sizeof(float), p);
+        DOL_reserve((void*)PORT_OUT, &j, sizeof(float), p);
+        *j = *i * *i;
+        DOL_consume((void*)PORT_IN, p);
+        DOL_release((void*)PORT_OUT, p);
+        p->local->index++;
+    }
+
+    if (p->local->index >= p->local->len) {
+        DOL_detach(p);
+        return -1;
+    }
+
+    return 0;
+}
+
diff --git a/dol/examples/examplewindowedfifo/src/square.h b/dol/examples/examplewindowedfifo/src/square.h
new file mode 100644 (file)
index 0000000..e2eebd0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SQUARE_H
+#define SQUARE_H
+
+#include <dol.h>
+#include "global.h"
+
+#define PORT_IN  100
+#define PORT_OUT 200
+
+typedef struct _local_states {
+    int index;
+    int len;
+} Square_State;
+
+void square_init(DOLProcess *);
+int square_fire(DOLProcess *);
+
+#endif
diff --git a/dol/examples/runexample.xml b/dol/examples/runexample.xml
new file mode 100644 (file)
index 0000000..fa03bfe
--- /dev/null
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="dol" default="runexample" basedir=".">
+
+  <description>
+    Ant build file to build and run examples.
+  </description>
+
+  <!-- java compiler properties: a java compiler for Java Platform 5.0 is required -->
+  <!-- do _not_ comment out the following line to use the specified external java compiler and virtual machine -->
+  <!-- <property name="use.external.java" value="yes"/> -->
+  <!-- <property name="use.external.javac" value="yes"/> -->
+
+  <!-- external java binaries -->
+  <property name="java.executable" value="/usr/sepp/bin/java"/>
+  <property name="javac.executable" value="/usr/sepp/bin/javac"/>
+
+  <!-- directory paths -->
+  <property name="lib.dir"     location="./../../../jars"/>
+  <property name="bin.dir"     location="./../../../bin"/>
+  <property name="jars"        value=".:./..:${lib.dir}/dol.jar:${lib.dir}/xercesImpl.jar:${lib.dir}/jdom.jar:${bin.dir}/dol.jar:${bin.dir}/xercesImpl.jar:${bin.dir}/jdom.jar"/>
+  <property name="example.dir" location="./../../../examples"/>
+
+  <!-- these properties can be overwritten using the -D option when calling ant, e.g.: -Dnumber=2 -Dgenerator=protothread -->
+  <property name="number" value="1"/>
+  <property name="generator" value="HdS"/> <!-- HdS, protothread, systemC, PaF, rtems, yapi -->
+
+
+  <!-- main target: calls all the targets required to run an example -->
+  <target name="runexample" depends="showversion">
+    <antcall target="prepare"/>
+    <antcall target="validate"/>
+    <antcall target="flatten1"/>
+    <antcall target="flatten2"/>
+    <antcall target="dol1"/>
+    <antcall target="dol2"/>
+    <antcall target="execute"/>
+  </target>
+
+  <target name="mparm" depends="showversion">
+    <antcall target="prepare"/>
+    <antcall target="validate"/>
+    <antcall target="flatten1"/>
+    <antcall target="flatten2"/>
+    <antcall target="dol_mparm1"/>
+    <antcall target="dol_mparm2"/>
+  </target>
+
+  <target name="cell" depends="showversion">
+    <antcall target="prepare"/>
+    <antcall target="validate"/>
+    <antcall target="flatten1"/>
+    <antcall target="flatten2"/>
+    <antcall target="dol_cell1"/>
+    <antcall target="dol_cell2"/>
+  </target>
+
+  <!-- prepare directory structure and copy sources -->
+  <target name="prepare">
+    <echo message="Create directory example${number}."/>
+    <deletedirectory dir="example${number}"/>
+    <mkdir dir="example${number}"/>
+
+    <echo message="Copy C source files."/>
+    <deletedirectory dir="example${number}/src"/>
+    <mkdir dir="example${number}/src"/>
+    <copy todir="example${number}/src">
+      <fileset dir="${example.dir}/example${number}/src" includes="*.h *.c"/>
+    </copy>
+  </target>
+
+  <!-- validateXML by means of external schema -->
+  <target name="validate" unless="use.external.java">
+    <echo message="check XML compliance of example${number}_flattened.xml."/>
+    <java classname="dol.helper.validator.XMLValidator"
+          dir="example${number}"
+          fork="true"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="${example.dir}/example${number}/example${number}.xml"/>
+    </java>
+  </target>
+
+  <!-- create flattened XML (non-external java version) -->
+  <target name="flatten1" unless="use.external.java">
+    <echo message="Create flattened XML example${number}_flattened.xml."/>
+    <java classname="dol.helper.flattener.XMLFlattener"
+          dir="example${number}"
+          fork="true"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="${example.dir}/example${number}/example${number}.xml Example${number}Generator"/>
+    </java>
+
+    <javac srcdir="example${number}"
+           destdir="example${number}"
+           includes="Example${number}Generator.java"
+           fork="${use.external.javac}"
+           executable="${javac.executable}"/>
+
+    <java classname="Example${number}Generator"
+          output="example${number}/example${number}_flattened.xml"
+          fork="true"
+          failonerror="true">
+      <classpath path="example${number}"/>
+    </java>
+  </target>
+
+  <!-- create flattened XML (external java version) -->
+  <target name="flatten2" if="use.external.java">
+    <echo message="Create flattened XML example${number}_flattened.xml."/>
+    <java classname="dol.helper.flattener.XMLFlattener"
+          dir="example${number}"
+          fork="true"
+          jvm="${java.executable}"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="${example.dir}/example${number}/example${number}.xml Example${number}Generator"/>
+    </java>
+
+    <javac srcdir="example${number}"
+           destdir="example${number}"
+           includes="Example${number}Generator.java"
+           fork="${use.external.javac}"
+           executable="${javac.executable}"/>
+
+    <java classname="Example${number}Generator"
+          output="example${number}/example${number}_flattened.xml"
+          fork="true"
+          jvm="${java.executable}"
+          failonerror="true">
+      <classpath path="example${number}"/>
+    </java>
+  </target>
+
+  <!-- run DOL (non-external java version) -->
+  <target name="dol1" unless="use.external.java">
+    <echo message="Run DOL."/>
+    <java classname="dol.main.Main"
+          dir="example${number}"
+          fork="true"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="-P example${number}_flattened.xml -D example${number}.dot --${generator} ${generator} -c"/> 
+    </java>
+  </target>
+
+  <target name="dol_mparm1" unless="use.external.java">
+    <echo message="Run mparm generation."/>
+    <java classname="dol.main.Main"
+          dir="example${number}"
+          fork="true"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="-P example${number}_flattened.xml -D example${number}.dot -Rmparm mparm -c"/>
+    </java>
+  </target>
+
+  <target name="dol_cell1" unless="use.external.java">
+    <echo message="Run cell generation."/>
+    <java classname="dol.main.Main"
+          dir="example${number}"
+          fork="true"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="-P example${number}_flattened.xml -D example${number}.dot --cbe cell --platform ./../../../../examples/example${number}/cell.xml --mapping ./../../../../examples/example${number}/mapping.xml -c"/>
+    </java>
+  </target>
+
+  <!-- run DOL (external java version) -->
+  <target name="dol2" if="use.external.java">
+    <echo message="Run DOL."/>
+    <java classname="dol.main.Main"
+          dir="example${number}"
+          fork="true"
+          jvm="${java.executable}"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="-P example${number}_flattened.xml -D example${number}.dot --${generator} ${generator} -c"/> 
+    </java>
+  </target>
+
+  <target name="dol_mparm2" if="use.external.java">
+    <echo message="Run mparm generation."/>
+    <java classname="dol.main.Main"
+          dir="example${number}"
+          fork="true"
+          jvm="${java.executable}"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="-P example${number}_flattened.xml -D example${number}.dot -Rmparm mparm -c"/>
+    </java>
+  </target>
+
+  <target name="dol_cell2" if="use.external.java">
+    <echo message="Run cell generation."/>
+    <java classname="dol.main.Main"
+          dir="example${number}"
+          fork="true"
+          jvm="${java.executable}"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="-P example${number}_flattened.xml -D example${number}.dot --cbe cell --platform cell.xml --mapping mapping.xml -c"/>
+    </java>
+  </target>
+
+
+  <!-- create and run SystemC application -->
+  <target name="execute">
+    <!-- the first two tasks are needed to avoid make's clock skew warning -->
+    <tstamp>
+      <format property="touch.time"
+              pattern="MM/dd/yyyy hh:mm aa"
+              offset="-5" unit="second"/>
+    </tstamp>
+    <touch datetime="${touch.time}">
+      <fileset dir="example${number}"/>
+    </touch>
+
+    <echo message="Make ${generator} application."/>
+    <exec executable="make" dir="example${number}/${generator}/src"/>
+
+    <echo message="Run ${generator} application."/>
+    <exec executable="${basedir}/example${number}/${generator}/src/sc_application"
+          output="example${number}/${generator}/src/log.txt"
+          error="example${number}/${generator}/src/errorlog.txt"/>
+    <concat>
+      <fileset dir="example${number}/${generator}/src" includes="log.txt"/>
+    </concat>
+  </target>
+
+  <!-- run the XML checker -->
+  <target name="checkxmls">
+    <java classname="dol.util.CheckXMLs" failonerror="true" fork="true">
+       <classpath path="${jars}"/>
+       <arg line="${example.dir}/examplecell/examplecell.xml ${example.dir}/examplecell/cell.xml ${example.dir}/examplecell/mapping.xml"/>
+    </java>
+  </target>
+
+  <!-- run the application generator -->
+  <target name="applicationgenerator">
+    <java classname="dol.util.ApplicationGenerator" failonerror="true" fork="true">
+       <classpath path="${jars}"/>
+    </java>
+  </target>
+
+  <!-- recursively delete a directory -->
+  <macrodef name="deletedirectory">
+    <attribute name="dir"/>
+    <sequential>
+      <delete includeemptydirs="true" quiet="true">
+        <fileset dir="${dir}" includes="**/*"/>
+      </delete>
+    </sequential>
+  </macrodef>
+
+  <target name="showversion">
+    <antcall target="showantversion"/>
+    <antcall target="showjavaversion1"/>
+    <antcall target="showjavaversion2"/>
+    <antcall target="showjavacversion1"/>
+    <antcall target="showjavacversion2"/>
+  </target>
+
+  <target name="showantversion">
+    <echo message="Use ${ant.version}."/>
+  </target>
+
+  <target name="showjavacversion1" unless="use.external.javac">
+    <echo message="Use Java version ${java.version} (required version: 1.5.0 or higher)."/>
+  </target>
+
+  <target name="showjavacversion2" if="use.external.javac">
+    <echo message="Use the following javac: ${javac.executable}."/>
+  </target>
+
+  <target name="showjavaversion1" unless="use.external.java">
+    <echo message="Use Java version ${java.version} (required version: 1.5.0 or higher)."/>
+  </target>
+
+  <target name="showjavaversion2" if="use.external.java">
+    <echo message="Use the following java: ${java.executable}."/>
+  </target>
+
+</project>
diff --git a/dol/examples/runprofiler.xml b/dol/examples/runprofiler.xml
new file mode 100644 (file)
index 0000000..a3e4ade
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="runprofiler" default="run" basedir=".">
+
+  <!-- *************************************************************** -->
+  <!-- * properties                                                  * -->
+  <!-- *************************************************************** -->
+  
+  <!-- modify the following properties as required -->
+
+  <!-- directory where DOL is located (needed for reading processnetwork from XML file-->
+  <property name="lib.dir"     location="./../../../jars"/>
+  <property name="bin.dir"     location="./../../../bin"/>
+  <property name="jars"        value=".:./..:${lib.dir}/dol.jar:${lib.dir}/xercesImpl.jar:${lib.dir}/jdom.jar:${bin.dir}/dol.jar:${bin.dir}/xercesImpl.jar:${bin.dir}/jdom.jar"/>
+
+  <!-- classpath delimiter ":" for UNIX, ";" for Windows -->
+  <property name="classpathdelimiter" value=":"/>
+  
+  <!-- this can be overwritten using the -D option to ant, e.g.: -Dnumber=2 -->
+  <property name="number"           value="1"/>
+  
+  <!-- *************************************************************** -->
+  <!-- * targets                                                     * -->
+  <!-- *************************************************************** -->
+  <target name="arch">
+    <java classname="dol.main.Main"
+          classpath="${jars}">
+      <arg line=" -p ../../../examples/arch/vsp.xml"/>
+    </java>
+  </target>
+  
+  <target name="run">
+    <java classname="dol.main.Main"
+          classpath="${jars}">
+      <arg line=" -T profile.txt -P example${number}/example${number}_flattened.xml -G example${number}/example${number}_flattened_annotated.xml"/>
+    </java>
+  </target>
+
+  <target name="standalone">
+    <java classname="dol.helper.profiler.Profiler"
+          classpath="${jars}">
+      <arg line=" profile.txt example${number}/example${number}_flattened.xml"/>
+    </java>
+  </target>
+</project>
diff --git a/dol/examples/schema/architecture.xsd b/dol/examples/schema/architecture.xsd
new file mode 100644 (file)
index 0000000..ddb3871
--- /dev/null
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:arch="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE" targetNamespace="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE" elementFormDefault="qualified">
+  <xsd:include schemaLocation="generics.xsd"/>
+
+  <xsd:element name="architecture">
+    <xsd:complexType>
+      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="variable" type="arch:variable" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="function" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="processor" type="arch:processor" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="memory" type="arch:memory" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="hw_channel" type="arch:hw_channel" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="iterator" type="arch:generaliterator" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="readpath" type="arch:readpath" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="writepath" type="arch:writepath" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:complexType name="processor">
+    <xsd:complexContent>
+      <xsd:extension base="arch:resource">
+        <xsd:attribute name="type" use="required">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="RISC"/>
+              <xsd:enumeration value="DSP"/>
+              <xsd:enumeration value="POT"/>
+              <xsd:enumeration value="NETSIM"/>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:attribute>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="memory">
+    <xsd:complexContent>
+      <xsd:extension base="arch:resource">
+        <xsd:attribute name="type" use="required">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="ROM"/>
+              <xsd:enumeration value="RAM"/>
+              <xsd:enumeration value="REG"/>
+              <xsd:enumeration value="DXM"/>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:attribute>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="hw_channel">
+    <xsd:complexContent>
+      <xsd:extension base="arch:resource">
+        <xsd:attribute name="type" use="required">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="FIFO"/>
+              <xsd:enumeration value="BUS"/>
+              <xsd:enumeration value="DMA"/>
+              <xsd:enumeration value="SPI"/>
+              <xsd:enumeration value="BRIDGE"/>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:attribute>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="resource">
+    <xsd:complexContent>
+      <xsd:extension base="arch:element">
+        <xsd:sequence>
+          <xsd:element name="append" type="arch:append" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="configuration" type="arch:configuration" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="writepath">
+    <xsd:sequence minOccurs="1" maxOccurs="1">
+      <xsd:element name="append" type="arch:append" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="processor" type="arch:resourcereference" minOccurs="1" maxOccurs="1"/>
+      <xsd:element name="txbuf" type="arch:resourcereference" minOccurs="1" maxOccurs="1"/>
+      <xsd:element name="hw_channel" type="arch:resourcereference" minOccurs="1" maxOccurs="unbounded"/>
+      <xsd:element name="chbuf" type="arch:resourcereference" minOccurs="1" maxOccurs="1"/>
+      <xsd:element name="configuration" type="arch:configuration" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="readpath">
+    <xsd:sequence minOccurs="1" maxOccurs="1">
+      <xsd:element name="append" type="arch:append" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="processor" type="arch:resourcereference" minOccurs="1" maxOccurs="1"/>
+      <xsd:element name="chbuf" type="arch:resourcereference" minOccurs="1" maxOccurs="1"/>
+      <xsd:element name="hw_channel" type="arch:resourcereference" minOccurs="1" maxOccurs="unbounded"/>
+      <xsd:element name="rxbuf" type="arch:resourcereference" minOccurs="1" maxOccurs="1"/>
+      <xsd:element name="configuration" type="arch:configuration" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="resourcereference">
+    <xsd:sequence>
+      <xsd:element name="append" type="arch:append" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="generaliterator">
+    <xsd:complexContent>
+      <xsd:extension base="arch:iterator">
+        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+          <xsd:element name="readpath" type="arch:readpath" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="writepath" type="arch:writepath" minOccurs="0" maxOccurs="unbounded"/>    
+          <xsd:element name="processor" type="arch:processor" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="memory" type="arch:memory" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="hw_channel" type="arch:hw_channel" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="iterator" type="arch:generaliterator" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+</xsd:schema>
diff --git a/dol/examples/schema/createschemastex b/dol/examples/schema/createschemastex
new file mode 100644 (file)
index 0000000..9b7fe4a
--- /dev/null
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+##########################################################################
+# Script to collect together processnetwork.xsd, architecture.xsd, and
+# mapping.xsd into a single LaTeX document.
+#
+# Lines longer than 80 characters in the source files are truncated.
+# 
+# modification history:
+# 2006-08-22: created
+#
+##########################################################################
+
+##########################################################################
+# create LaTeX header
+##########################################################################
+
+echo -e %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'\n'\
+% XML Schema Definitions.'\n'\
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'\n'\
+'\n'\
+'\\'documentclass[11pt,oneside]{book}'\n'\
+'\\'usepackage{fancyhdr,ifthen,a4wide,textcomp,version,amsmath,bbm,url}'\n'\
+'\\'usepackage[latin1]{inputenc}'\n'\
+'\n'\
+%package for including listings'\n'\
+'\\'usepackage{listings}'\n'\
+'\\'lstset{basicstyle='\\'small, xleftmargin=12pt, numbersep=12pt, numbers=left,'\n'\
+         numberstyle='\\'tiny, numbersep=5pt}'\n'\
+%print two-digit line numbers'\n'\
+'\\'newcommand{'\\'twodig}[1]'\n'\
+   {'\\'ifcase#1 00'\\'or01'\\'or02'\\'or03'\\'or04'\\'or05'\\'or06'\\'or07'\\'or08'\\'or09'\\'else#1'\\'fi}'\n'\
+'\\'renewcommand{'\\'thelstnumber}{'\\'twodig{'\\'arabic{lstnumber}}}'\n'\
+'\n'\
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'\n'\
+%page layout and graphics path'\n'\
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'\n'\
+'\\'setlength{'\\'textwidth}{18 true cm}'\n'\
+'\\'setlength{'\\'textheight}{27.4 true cm}'\n'\
+'\\'oddsidemargin  -1.0 cm'\n'\
+'\\'evensidemargin -1.0 cm'\n'\
+'\\'topmargin      -2.4 cm'\n'\
+'\\'setlength{'\\'parindent}{0pt}'\n'\
+'\\'sloppy'\n'\
+'\\'flushbottom'\n'\
+'\\'pagestyle{empty}'\n'\
+'\n'\
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'\n'\
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'\n'\
+'\n'\
+'\\'begin{document} > latex_header.tex
+
+
+##########################################################################
+# create LaTeX footer
+##########################################################################
+
+echo -e '\\'end{document} > latex_footer.tex
+
+
+##########################################################################
+# create listings header and footer
+##########################################################################
+
+echo -e '\\'newpage'\n'\
+'\\'begin{lstlisting} > listing_header.tex
+
+echo -e '\\'end{lstlisting} > listing_footer.tex
+
+
+##########################################################################
+# create document
+##########################################################################
+
+cat latex_header.tex listing_header.tex processnetwork.xsd listing_footer.tex \
+                     listing_header.tex architecture.xsd   listing_footer.tex \
+                     listing_header.tex mapping.xsd listing_footer.tex latex_footer.tex > schemas.tex
+
+
+##########################################################################
+# truncate lines longer than 80 characters
+##########################################################################
+
+sed -i 's/\(^.\{80\}\).*/\1.../g' schemas.tex
+
+
+##########################################################################
+# remove help files
+##########################################################################
+
+rm -f latex_header.tex latex_footer.tex listing_header.tex listing_footer.tex
\ No newline at end of file
diff --git a/dol/examples/schema/generics.xsd b/dol/examples/schema/generics.xsd
new file mode 100644 (file)
index 0000000..28b9108
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+  <xsd:complexType name="variable">
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+    <xsd:attribute name="value" type="xsd:integer" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="function">
+    <xsd:simpleContent>
+      <xsd:extension base="xsd:string">
+        <xsd:attribute name="name" type="xsd:string" use="optional"/>
+      </xsd:extension>
+    </xsd:simpleContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="append">
+    <xsd:attribute name="function" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="iterator">
+    <xsd:attribute name="variable" type="xsd:string" use="required"/>
+    <xsd:attribute name="range" type="xsd:string" use="required"/>
+    <!-- 
+    <xsd:attribute name="range" use="required">
+      <xsd:simpleType>
+        <xsd:restriction base="xsd:string">
+          <xsd:pattern value="for.*"/>
+        </xsd:restriction>
+      </xsd:simpleType>
+    </xsd:attribute>
+    -->
+  </xsd:complexType>
+
+  <xsd:complexType name="configuration">
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+    <xsd:attribute name="value" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="profiling">
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+    <xsd:attribute name="value" type="xsd:string" use="required"/>
+  </xsd:complexType>
+  
+  <xsd:complexType name="element">
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+    <xsd:attribute name="basename" type="xsd:string" use="optional"/>
+    <xsd:attribute name="range" type="xsd:string" use="optional"/>
+  </xsd:complexType>
+  
+</xsd:schema>
diff --git a/dol/examples/schema/internal/architecture_internal.xsd b/dol/examples/schema/internal/architecture_internal.xsd
new file mode 100644 (file)
index 0000000..e76fe32
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:arch="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE" targetNamespace="http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE" elementFormDefault="qualified">
+  <xsd:include schemaLocation="../architecture.xsd"/>
+</xsd:schema>
diff --git a/dol/examples/schema/internal/mapping_internal.xsd b/dol/examples/schema/internal/mapping_internal.xsd
new file mode 100644 (file)
index 0000000..d0cad50
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:arch="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING" targetNamespace="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING" elementFormDefault="qualified">
+  <xsd:include schemaLocation="../mapping.xsd"/>
+</xsd:schema>
diff --git a/dol/examples/schema/internal/processnetwork_internal.xsd b/dol/examples/schema/internal/processnetwork_internal.xsd
new file mode 100644 (file)
index 0000000..0e2d87c
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pn="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" targetNamespace="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" elementFormDefault="qualified">
+
+<xsd:redefine schemaLocation="../processnetwork.xsd">
+  <xsd:complexType name="process">
+    <xsd:complexContent>
+      <xsd:extension base="pn:process">
+        <xsd:sequence>
+          <xsd:element name="profiling" type="pn:profiling" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="sw_channel">
+    <xsd:complexContent>
+      <xsd:extension base="pn:sw_channel">
+        <xsd:sequence>
+          <xsd:element name="profiling" type="pn:profiling" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+</xsd:redefine>
+
+</xsd:schema>
diff --git a/dol/examples/schema/mapping.xsd b/dol/examples/schema/mapping.xsd
new file mode 100644 (file)
index 0000000..dbaef38
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:map="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING" targetNamespace="http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING" elementFormDefault="qualified">
+  <xsd:include schemaLocation="generics.xsd"/>
+
+  <xsd:element name="mapping">
+    <xsd:complexType>
+      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="variable" type="map:variable" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="function" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="iterator" type="map:generaliterator" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="binding" type="map:binding" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="schedule" type="map:schedule" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:complexType name="binding">
+    <xsd:sequence>
+      <xsd:element name="append" type="map:append" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+  
+  <xsd:complexType name="computation">
+    <xsd:complexContent>
+      <xsd:extension base="map:binding">
+        <xsd:sequence>
+          <xsd:element name="process" type="map:resource" minOccurs="1" maxOccurs="1"/>
+          <xsd:element name="processor" type="map:resource" minOccurs="1" maxOccurs="1"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="communication">
+    <xsd:complexContent>
+      <xsd:extension base="map:binding">
+        <xsd:sequence>
+          <xsd:element name="sw_channel" type="map:resource" minOccurs="1" maxOccurs="1"/>
+          <xsd:element name="writepath" type="map:resource" minOccurs="1" maxOccurs="1"/>
+          <xsd:element name="readpath" type="map:resource" minOccurs="1" maxOccurs="1"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="schedule">
+    <xsd:sequence>
+      <xsd:element name="append" type="map:append" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="resource" type="map:resource"/>
+      <xsd:element name="origin" type="map:configuredresource" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="configuration" type="map:configuration" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+    <xsd:attribute name="type" use="required">
+      <xsd:simpleType>
+        <xsd:restriction base="xsd:string">
+          <xsd:enumeration value="static"/>
+          <xsd:enumeration value="fixedpriority"/>
+          <xsd:enumeration value="fifo"/>
+          <xsd:enumeration value="tdma"/>
+          <xsd:enumeration value="roundrobin"/>
+        </xsd:restriction>
+      </xsd:simpleType>
+    </xsd:attribute>
+  </xsd:complexType>
+
+  <xsd:complexType name="resource">
+    <xsd:sequence>
+      <xsd:element name="append" type="map:append" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="configuredresource">
+    <xsd:sequence>
+      <xsd:element name="append" type="map:append" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="configuration" type="map:configuration" minOccurs="0" maxOccurs="unbounded"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="generaliterator">
+    <xsd:complexContent>
+      <xsd:extension base="map:iterator">
+        <xsd:sequence>
+          <xsd:element name="iterator" type="map:generaliterator" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="binding" type="map:binding" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="schedule" type="map:schedule" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+</xsd:schema>
diff --git a/dol/examples/schema/processnetwork.xsd b/dol/examples/schema/processnetwork.xsd
new file mode 100644 (file)
index 0000000..d3c2d93
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pn="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK" targetNamespace="http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK"  elementFormDefault="qualified" >
+  <xsd:include schemaLocation="generics.xsd"/>
+
+  <xsd:element name="processnetwork">
+    <xsd:complexType>
+      <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="variable" type="pn:variable" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="function" type="pn:function" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="process" type="pn:process" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="sw_channel" type="pn:sw_channel" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="iterator" type="pn:generaliterator" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="connection" type="pn:connection" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="configuration" type="pn:configuration" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:complexType name="process">
+    <xsd:complexContent>
+      <xsd:extension base="pn:element">
+        <xsd:sequence>
+          <xsd:element name="append" type="pn:append" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:choice minOccurs="0">
+            <xsd:sequence>
+              <xsd:element name="iterator" type="pn:qualifiedportiterator" maxOccurs="unbounded"/>
+              <xsd:element name="port" type="pn:qualifiedport" minOccurs="0" maxOccurs="unbounded"/>
+            </xsd:sequence>
+            <xsd:element name="port" type="pn:qualifiedport" maxOccurs="unbounded"/>
+          </xsd:choice>
+          <xsd:element name="source" type="pn:source"/>
+          <xsd:element name="configuration" type="pn:configuration" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="source">
+    <xsd:attribute name="type" use="required">
+      <xsd:simpleType>
+        <xsd:restriction base="xsd:string">
+          <xsd:enumeration value="c"/>
+          <xsd:enumeration value="c++"/>
+        </xsd:restriction>
+      </xsd:simpleType>
+    </xsd:attribute>
+    <xsd:attribute name="location" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="sw_channel">
+    <xsd:complexContent>
+      <xsd:extension base="pn:element">
+        <xsd:sequence>
+          <xsd:element name="append" type="pn:append" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="port" type="pn:qualifiedport" minOccurs="2" maxOccurs="2"/>
+          <xsd:element name="configuration" type="pn:configuration" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+        <xsd:attribute name="size" type="xsd:string" use="required"/>
+        <xsd:attribute name="tokensize" type="xsd:string" default="1" use="optional"/>
+        <xsd:attribute name="type" use="required">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="fifo"/>
+              <xsd:enumeration value="wfifo"/>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:attribute>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="port">
+    <xsd:complexContent>
+      <xsd:extension base="pn:element">
+        <xsd:sequence>
+          <xsd:element name="append" type="pn:append" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="qualifiedport">
+    <xsd:complexContent>
+      <xsd:extension base="pn:port">
+        <xsd:attribute name="type" use="required">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="input"/>
+              <xsd:enumeration value="output"/>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:attribute>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="connection">
+    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+      <xsd:element name="append" type="pn:append" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="origin" type="pn:connector"/>
+      <xsd:element name="target" type="pn:connector"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+
+  <xsd:complexType name="connector">
+    <xsd:sequence>
+      <xsd:element name="append" type="pn:append" minOccurs="0" maxOccurs="unbounded"/>
+      <xsd:element name="port" type="pn:port"/>
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required"/>
+  </xsd:complexType>
+  
+  <xsd:complexType name="generaliterator">
+    <xsd:complexContent>
+      <xsd:extension base="pn:iterator">
+        <xsd:sequence>
+          <xsd:element name="iterator" type="pn:generaliterator" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="process" type="pn:process" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="sw_channel" type="pn:sw_channel" minOccurs="0" maxOccurs="unbounded"/>
+          <xsd:element name="connection" type="pn:connection" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+  <xsd:complexType name="qualifiedportiterator">
+    <xsd:complexContent>
+      <xsd:extension base="pn:iterator">
+        <xsd:choice>
+          <xsd:sequence>
+            <xsd:element name="iterator" type="pn:qualifiedportiterator" maxOccurs="unbounded"/>
+            <xsd:element name="port" type="pn:qualifiedport" minOccurs="0" maxOccurs="unbounded"/>
+          </xsd:sequence>
+          <xsd:element name="port" type="pn:qualifiedport" maxOccurs="unbounded"/>
+        </xsd:choice>
+      </xsd:extension>
+    </xsd:complexContent>
+  </xsd:complexType>
+
+</xsd:schema>
diff --git a/dol/jars/jdom.jar b/dol/jars/jdom.jar
new file mode 100644 (file)
index 0000000..288e64c
Binary files /dev/null and b/dol/jars/jdom.jar differ
diff --git a/dol/jars/xercesImpl.jar b/dol/jars/xercesImpl.jar
new file mode 100644 (file)
index 0000000..33990e8
Binary files /dev/null and b/dol/jars/xercesImpl.jar differ
diff --git a/dol/src/MANIFEST.MF b/dol/src/MANIFEST.MF
new file mode 100644 (file)
index 0000000..19165c3
--- /dev/null
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0\r
+Main-Class: dol.main.Main\r
+Created-By: Computer Engineering Group, Computer Engineering and Networks Laboratory, ETH Zurich\r
+Class-Path: jars/xercesImpl.jar jars/jdom.jar
\ No newline at end of file
diff --git a/dol/src/docs/doxygen/doxygen.cfg b/dol/src/docs/doxygen/doxygen.cfg
new file mode 100644 (file)
index 0000000..7e541a1
--- /dev/null
@@ -0,0 +1,1078 @@
+# Doxyfile 1.3.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = DOL
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 1.0
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../../../build/doxygen/
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese, 
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = ../../src
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = YES
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = ../../dol
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS          = *.java
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 1
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+#HTML_HEADER            = header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+#HTML_FOOTER            = footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output dir.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similiar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = /usr/local/bin/dot
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 600
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 600
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = YES
diff --git a/dol/src/docs/doxygen/footer.html b/dol/src/docs/doxygen/footer.html
new file mode 100644 (file)
index 0000000..20d26b2
--- /dev/null
@@ -0,0 +1,3 @@
+<hr/>
+<p class="small">Generated on $datetime for $projectname by <a href="http://www.doxygen.org/index.html">doxygen</a> $doxygenversion</p>
+<!-- <?php include("/home/khuang/footer.php"); ?> -->
diff --git a/dol/src/docs/doxygen/header.html b/dol/src/docs/doxygen/header.html
new file mode 100644 (file)
index 0000000..6efcc86
--- /dev/null
@@ -0,0 +1 @@
+<?php $nonvalidhtml=true; $mytitle="developer reference"; ?>
diff --git a/dol/src/dol.properties b/dol/src/dol.properties
new file mode 100644 (file)
index 0000000..56d50ac
--- /dev/null
@@ -0,0 +1,15 @@
+# template for dol.properties file
+# use ant config to fill in the values
+
+# SystemC library path:
+# SYSTEMC_INC and SYSTEMC_LIB are the paths to SystemC header and library,
+# respectively. These two path will be used in the generated Makefile to
+# build the SystemC executable binary file. They have to point to local
+# SystemC directory.
+#
+# example:
+# SYSTEMC_INC = /home/shapes/base/resources/lib/systemC/systemc-2.1.v1/include
+# SYSTEMC_LIB = /home/shapes/base/resources/lib/systemC/systemc-2.1.v1/lib-linux/libsystemc.a
+
+SYSTEMC_INC = /home/shapes/base/resources/lib/systemC/include
+SYSTEMC_LIB = /home/shapes/base/resources/lib/systemC/lib-linux/libsystemc.a
diff --git a/dol/src/dol/check/SanityCheck.java b/dol/src/dol/check/SanityCheck.java
new file mode 100644 (file)
index 0000000..88f82db
--- /dev/null
@@ -0,0 +1,419 @@
+/* $Id: SanityCheck.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.check;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Vector;
+
+import dol.datamodel.architecture.ArchiResource;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.Configuration;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Connection;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Resource;
+
+/**
+ * Check semantic correctness of process network.
+ *
+ * This class checks
+ * <ul><li>whether it is a processnetwork</li>
+ * <li>a channel only has two ports</li>
+ * <li>each channel port has only one peer port of process</li>
+ * </ul>
+ */
+public class SanityCheck {
+    /**
+     * Return the singleton instance of this class;
+     *
+     * @return  the instance.
+     */
+    public final static SanityCheck getInstance() {
+        return _instance;
+    }
+
+    /**
+     * Check if the process network spec is correct
+     *
+     * @param pn processnetwork to check
+     */
+    public void checkPN(ProcessNetwork pn) {
+        try {
+            _checkNameConflict(pn);
+            _checkChannelPorts(pn);
+            _checkChannelConnection(pn);
+        }
+        catch (Exception e) {
+            System.out.println("err: " + e.getMessage());
+            //e.printStackTrace();
+            System.exit(-1);
+        }
+
+        try {
+            _checkProcessConnection(pn);
+        }
+        catch (Exception e) {
+            System.out.println("warning: " + e.getMessage());
+        }
+    }
+   
+    /**
+     * Check if the architecture spec is correct
+     *
+     * @param arch architecture to check
+     */
+    public void checkArch(Architecture arch)
+    {
+       try
+       {
+               _checkNameConflict(arch);
+               _checkNETSIM(arch);
+            _checkMaster(arch);
+       }
+       catch (Exception e)
+       {
+               System.out.println("err: " + e.getMessage());
+               System.exit(-1);
+       }
+    }
+
+    /**
+     * Check if the mapping spec is correct
+     *
+     * @param map mapping to check
+     */
+    public void checkMap(Mapping map)
+    {
+       try
+       {
+            _checkMultibind(map);
+            _checkProcessesBound(map);
+       }
+       catch (Exception e)
+       {
+               System.out.println("err: " + e.getMessage());
+               System.exit(-1);
+       }
+    }
+
+
+    /**
+     * Check name exclusiveness, including processes, channels, and
+     * connections.
+     *
+     * @param pn processnetwork to check
+     */
+    private void _checkNameConflict(ProcessNetwork pn) throws Exception {
+        System.out.println("APPL: Checking resource name ...");
+
+        Vector<Resource> n = new Vector<Resource>(pn.getChannelList());
+        n.addAll(pn.getProcessList());
+        n.addAll(pn.getConnectionList());
+
+        //sort resources in n by name
+        Collections.sort(n,
+          new Comparator<Resource>()
+          {
+            public int compare(Resource resource1, Resource resource2) {
+              return resource1.getName().compareTo(resource2.getName());
+            }
+          } );
+
+        //test adjacent resources in n for equal name
+        for (int k = 0; k < n.size() - 1; k++)
+        {
+          if (((Resource) n.elementAt(k)).getName().equals(
+              ((Resource) n.elementAt(k + 1)).getName())) {
+            throw new Exception("Name conflict: " +
+                                ((Resource)n.elementAt(k + 1)).getName() +
+                                " appears (at least) twice.");
+          }
+        }
+    }
+
+    /**
+     * Check number of ports for every channel.
+     *
+     * @param pn processnetwork to check
+     */
+    private void _checkChannelPorts(ProcessNetwork pn) throws Exception {
+        System.out.println("APPL: Checking channel ports ...");
+
+        for (Channel c : pn.getChannelList()) {
+            if (c.getPortList().size() < 2) {
+                throw new Exception("channel ports less than 2: " +
+                                    c.getName());
+            }
+        }
+    }
+
+    /**
+     * Check whether all processes are connected.
+     *
+     * @param pn processnetwork to check
+     */
+    private void _checkProcessConnection(ProcessNetwork pn)
+        throws Exception {
+        System.out.println("APPL: Checking Process connection ...");
+
+        String result = "";
+        boolean hasUnused = false;
+        for (Process r : pn.getProcessList()) {
+            boolean flag = false;
+            for (Connection c : pn.getConnectionList()) {
+                Resource origin = c.getOrigin();
+                Resource target = c.getTarget();
+                if (r.getName().equals(origin.getName())) {
+                    flag = true; break;
+                } else if (r.getName().equals(target.getName())) {
+                    flag = true; break;
+                }
+            }
+            if (flag == false) {
+                hasUnused = true;
+                result += " " + r.getName();
+            }
+        }
+
+        if (hasUnused == true)
+            throw new Exception("process(es) without connection to channels:" + result);
+    }
+
+    /**
+     * Check whether there are unused channels in the processnetwork.
+     *
+     * @param pn processnetwork to check
+     */
+    private void _checkChannelConnection(ProcessNetwork pn)
+        throws Exception {
+        System.out.println("APPL: Checking channel connection ...");
+
+        String result = "";
+        boolean hasUnused = false;
+        for (Channel r : pn.getChannelList()) {
+            boolean flag = false;
+            for (Connection c: pn.getConnectionList()) {
+                Resource origin = c.getOrigin();
+                Resource target = c.getTarget();
+                if (r.getName().equals(origin.getName())) {
+                    flag = true; break;
+                } else if (r.getName().equals(target.getName())) {
+                    flag = true; break;
+                }
+            }
+            if (flag == false) {
+                hasUnused = true;
+                result += " " + r.getName();
+            }
+        }
+
+        if (hasUnused == true)
+            throw new Exception("unused channel: " + result);
+    }
+
+    
+    /**
+     * Check name exclusiveness, including both processors and memories.
+     *
+     * @param arch architecture to check
+     */
+    private void _checkNameConflict(Architecture arch) throws Exception {
+        System.out.println("ARCH: Checking resource name ...");
+        Vector<ArchiResource> n = new Vector<ArchiResource>(arch.getProcessorList());
+        n.addAll(arch.getMemoryList());
+
+        //sort resources in n by name
+        Collections.sort(n,
+          new Comparator<ArchiResource>()
+          {
+            public int compare(ArchiResource resource1, ArchiResource resource2) {
+              return resource1.getName().compareTo(resource2.getName());
+            }
+          } );
+
+        //test adjacent resources in n for equal name
+        for (int k = 0; k < n.size() - 1; k++)
+        {
+          if (((ArchiResource) n.elementAt(k)).getName().equals(
+              ((ArchiResource) n.elementAt(k + 1)).getName())) {
+            throw new Exception("Name conflict: " +
+                                ((ArchiResource)n.elementAt(k + 1)).getName() +
+                                " appears (at least) twice.");
+          }
+        }
+    }
+    
+    /**
+     * every processor of type NETSIM must have a configuration tag with
+     * name "address" and one with name "port". these address-port pairs
+     * have to be unique
+     * @param arch
+     * @throws Exception
+     */
+    private void _checkNETSIM(Architecture arch) throws Exception
+    {
+        System.out.println("ARCH: Checking network simulators ...");
+        
+        Vector<Processor> sockets = new Vector<Processor>();
+        
+        for (Processor proc : arch.getProcessorList()) {
+               if ( proc.getType().equals("NETSIM") )
+               {
+                       if ( proc.getCfg("address") == null 
+                        || proc.getCfg("port") == null )
+                {
+                               throw new Exception("Processor " + proc.getName() + 
+                            " is of type NETSIM but address or port is missing");
+                }
+                if ( proc.getCfg("address").equals("") 
+                        || proc.getCfg("port").equals("") )
+                {
+                    throw new Exception("Processor " + proc.getName() + 
+                            " has empty address or port");
+                }
+                sockets.add(proc);  // add processor to socket list
+               }
+       }
+        
+        /* socket comperator */
+        Comparator<Processor> sockComp = new Comparator<Processor>()
+        {
+            public int compare(Processor proc1, Processor proc2)
+            {
+                String ad1, ad2;
+                ad1 = proc1.getCfg("address").getValue();
+                ad2 = proc2.getCfg("address").getValue();
+                
+                int comp = ad1.compareToIgnoreCase(ad2);
+                
+                if (comp != 0)
+                {
+                    return comp;
+                }
+                else
+                {
+                    String p1, p2;
+                    p1 = proc1.getCfg("port").getValue();
+                    p2 = proc2.getCfg("port").getValue();
+                    
+                    return p1.compareToIgnoreCase(p2);
+                }
+            }
+        };
+        
+        
+       /* sort sockets */
+        Collections.sort(sockets, sockComp);
+        
+        /* check for uniqueness */
+        Processor proc1 = null;
+        Processor proc2 = null;
+        if (!sockets.isEmpty())
+            proc1 = sockets.get(0);
+        for (int i=1; i<sockets.size(); i++)
+        {
+            proc2 = sockets.get(i);
+            if (sockComp.compare(proc1, proc2) == 0)
+            {
+                throw new Exception("multiple processors with hostname \"" +
+                        proc1.getCfg("address").getValue() +
+                        "\" and port " + proc1.getCfg("port").getValue() +
+                        " exist");
+            }
+            proc1 = proc2;
+        }
+    } // _checkNETSIM()
+    
+    
+    /**
+     * Checks that exactly one master simulator is defined if
+     * processors of type "NETSIM" exist.
+     * @param arch the architecture to check 
+     * @throws Exception
+     */
+    private void _checkMaster(Architecture arch) throws Exception
+    {
+        boolean hasMaster = false;
+        boolean hasHosts = false;
+        
+        for (Processor p : arch.getProcessorList()) {
+            if (p.getType().equals("NETSIM"))
+            {
+                hasHosts = true;
+                Configuration opt = p.getCfg("master");
+                if (opt != null && opt.getValue().equals("true"))
+                {
+                    if (hasMaster)
+                        throw new Exception("multiple master simulators"
+                                + "defined");
+                    else
+                        hasMaster = true;
+                
+                }
+            }
+        }
+        
+        if (hasHosts && !hasMaster)
+            throw new Exception("no master simulator defined");
+        
+    } // _checkMaster()
+    
+    /**
+     * Check that software resources bind only to one hardware resource. 
+     *
+     * @param map mapping to check
+     */
+    private void _checkMultibind(Mapping map) throws Exception {
+        System.out.println("MAP: Checking multiple bindings ...");
+        Vector<Process> processes = map.getProcessList();
+        
+        //sort processes in n by name
+        Collections.sort(processes,
+                new Comparator<Process>()
+                {
+                  public int compare(Process p1, Process p2) {
+                    return p1.getName().compareTo(p2.getName());
+                  }
+                } );
+
+        //test adjacent origins for equal name
+        String o1 = null;
+        String o2 = null;
+        if (!processes.isEmpty())
+            o1 = processes.get(0).getName();
+        for (int k = 1; k < processes.size(); k++)
+        {
+            o2 = processes.get(k).getName();
+            if (o1.equals(o2))
+            {
+                throw new Exception("sw resource \"" + o1 +
+                        "\" has multiple bindings");
+            }
+        }
+    }
+    
+    /**
+     * Checks that every process is bound to a processor.
+     * @param map the map to check
+     * @throws Exception if not all processes are bound to a processor
+     */
+    private void _checkProcessesBound(Mapping map) throws Exception
+    {
+        System.out.println("MAP: Checking that all processes have a binding ...");
+        Vector<Process> boundList = map.getProcessList();
+        Vector<Process> totalList = map.getPN().getProcessList();
+        
+        if (boundList.size() != totalList.size())
+        {
+            throw new Exception("some processes are not bound to a processor");
+        }
+    }
+    
+    /**
+     * singleton instance
+     */
+    private final static SanityCheck _instance = new SanityCheck();
+}
diff --git a/dol/src/dol/check/package.html b/dol/src/dol/check/package.html
new file mode 100644 (file)
index 0000000..685bef4
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Consistency checker for DOL spcific XML files.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/datamodel/XmlTag.java b/dol/src/dol/datamodel/XmlTag.java
new file mode 100644 (file)
index 0000000..bb87156
--- /dev/null
@@ -0,0 +1,76 @@
+/* $Id: XmlTag.java 203 2010-10-11 08:59:47Z dchokshi $ */
+package dol.datamodel;
+
+
+/**
+ * Class to store XML tag for xml element
+ */
+public class XmlTag {
+
+    /**
+     * Get a single instance of the XmlTag object.
+     */
+    private final static XmlTag _instance = new XmlTag();
+
+    /**
+     * Constructor. Private since only a single version may exist.
+     */
+    private XmlTag() {}
+    
+    /**
+     * returns the singleton instance of this class.
+     *
+     * @return The instance value
+     */
+    public final static XmlTag getInstance() { return _instance; }
+
+    // processnetwork XML tag
+    public final String getPNTag() { return "processnetwork";}
+    public final String getVariableTag() { return "variable";}
+    public final String getProcessTag() { return "process";}
+    public final String getSWChannelTag() { return "sw_channel";}
+    public final String getPortTag() { return "port";}        
+    public final String getSourceTag() { return "source";}
+    public final String getProfilingTag() { return "profiling";}
+
+    // architecture XML tag
+    public final String getArchiTag() { return "architecture";}
+    public final String getProcessorTag() { return "processor";}
+    public final String getMemoryTag() { return "memory";}
+    public final String getNodeTag() { return "node";}
+    public final String getInPortTag() { return "inputport";}
+    public final String getOutPortTag() { return "outputport";}
+    public final String getDuplexPortTag() { return "duplexport";}
+    public final String getHWChannelTag() { return "hw_channel";}
+    public final String getReadPathTag() { return "readpath";}
+    public final String getWritePathTag() { return "writepath";}
+    public final String getTXBufTag() { return "txbuf";}
+    public final String getRXBufTag() { return "rxbuf";}
+    public final String getCHBufTag() { return "chbuf";}
+    
+    // mapping XML tag
+    public final String getMappingTag() { return "mapping";}
+    public final String getBindingTag() { return "binding";}
+    public final String getScheduleTag() { return "schedule";}
+    public final String getResourceTag() { return "resource";}
+
+    // common tag
+    public final String getConfigurationTag() { return "configuration";}
+    
+    //iterator related XML tag
+    public final String getIteratorTag() { return "iterator";}
+    public final String getFunctionTag() { return "function";}
+    public final String getAppendTag() { return "append";}
+    
+    // connection tag
+    public final String getConnectionTag() { return "connection";}
+    public final String getOriginTag() { return "origin";}
+    public final String getTargetTag() { return "target";}
+
+    // processnetwork profiling value
+    public final String getProfilingTotalReadData() { return "TotalReadData";}
+    public final String getProfilingNumOfReads() { return "NumOfReads";}
+    public final String getProfilingNumOfWrites() { return "NumOfWrites";}
+    public final String getProfilingNumOfFires() { return "NumOfFires";}
+}
+
diff --git a/dol/src/dol/datamodel/architecture/ArchiConnection.java b/dol/src/dol/datamodel/architecture/ArchiConnection.java
new file mode 100644 (file)
index 0000000..9e2d713
--- /dev/null
@@ -0,0 +1,80 @@
+/* $Id: ArchiConnection.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class defines an architecture connection. Used in the simplified
+ * architecture specification. An architecture connection contains one
+ * origin and one target resource.
+ */
+public class ArchiConnection extends ArchiResource {
+    /**
+     * Constructor to create an architecture connection with a name.
+     *
+     */
+    public ArchiConnection(String name) {
+      super(name);
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this architectural connection.
+     *
+     * @return  a new instance of the architectural connection.
+     */
+    public Object clone() {
+        ArchiConnection newObj = (ArchiConnection) super.clone();
+        newObj.setOrigin(_origin);
+        newObj.setTarget(_target);
+        return (newObj);
+    }
+
+    /**
+     * Return a string representation of the architectural connection.
+     *
+     * @return string representation of the architectural connection
+     */
+    public String toString() {
+        return "ArchiConnection: " + getName();
+    }
+
+    /**
+     * Return the origin of the architectural connection.
+     *
+     * @return origin architectural resource of the architectural connection
+     */
+    public ArchiResource getOrigin() { return _origin; }
+
+    /**
+     * Set the origin of the architectural connection.
+     *
+     * @param origin architectural resource.
+     */
+    public void setOrigin(ArchiResource origin) { _origin = origin; }
+
+    /**
+     * Return the target of the architectural connection.
+     *
+     * @return target architectural resource of the architectural connection
+     */
+    public ArchiResource getTarget() { return _target; }
+
+    /**
+     * Set the target of the architectural connection.
+     *
+     * @param target architectural resource.
+     */
+    public void setTarget(ArchiResource target) { _target = target; }
+
+    protected ArchiResource _origin;
+    protected ArchiResource _target;
+}
diff --git a/dol/src/dol/datamodel/architecture/ArchiResource.java b/dol/src/dol/datamodel/architecture/ArchiResource.java
new file mode 100644 (file)
index 0000000..04de406
--- /dev/null
@@ -0,0 +1,254 @@
+/* $Id: ArchiResource.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class is the basic class which abstracts an architectural resource
+ * of a generic architecture. The architectural resource has a name and a
+ * list of included nodes.
+ */
+public class ArchiResource implements Cloneable {
+    /**
+     *  Constructor to create an architectural resource with a name and
+     *  an empty node list.
+     */
+    public ArchiResource(String name) {
+        _name = name;
+        _basename = name;
+        _nodeList = new Vector<Node>();
+        _cfgList = new Vector<Configuration>();
+    }
+
+    /**
+     * Accept a Visitor
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this architectural resource.
+     *
+     * @return new instance of the architectural resource.
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        try {
+            ArchiResource newObj = (ArchiResource) super.clone();
+            newObj.setName(_name);
+            newObj.setBasename(_basename);
+            newObj.setNodeList((Vector)_nodeList.clone() );
+            newObj.setCfgList((Vector)_cfgList.clone() );
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the name of this architectural resource.
+     *
+     * @return name of the architectural resource
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this architectural resource.
+     *
+     * @param name name of the architectural resource
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the basename of this architectural resource.
+     *
+     * @return basename of the architectural resource
+     */
+    public String getBasename() {
+        return _basename;
+    }
+
+    /**
+     * Set the basename of this architectural resource.
+     *
+     * @param basename name of the architectural resource
+     */
+    public void setBasename(String basename) {
+        _basename = basename;
+    }
+
+    /**
+     * Get the iterator indices of this process.
+     *
+     * @return range
+     */
+    public Vector<Integer> getIteratorIndices() {
+        Vector<Integer> indices = new Vector<Integer>();
+        StringTokenizer tokenizer =
+            new StringTokenizer(_name.replaceAll(_basename, ""), "_");
+        while (tokenizer.hasMoreTokens()) {
+            indices.add(Integer.valueOf(tokenizer.nextToken()));
+        }
+        return indices;
+    }
+    
+    /**
+     * Get the list of nodes of this architectural resource.
+     *
+     * @return list of nodes
+     */
+    public Vector<Node> getNodeList() {
+        return _nodeList;
+    }
+
+    /**
+     * Set the list of nodes of this architectural resource.
+     *
+     * @param nodeList nodes list
+     */
+    public void setNodeList(Vector<Node> nodeList) {
+        _nodeList = nodeList;
+    }
+
+    /**
+     * Get the hierarchical parent of this architectural resource.
+     *
+     * @return parent of this architectural resource
+     */
+    public ArchiResource getParentResource() {
+        return _parentResource;
+    }
+
+    /**
+     * Set the hierarchical parent of this architectural resource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(ArchiResource parentResource) {
+        _parentResource = parentResource;
+    }
+
+    /**
+     * Return a string representation of the architectural resource.
+     *
+     * @return string representation of the architectural resource
+     */
+    public String toString() {
+        return "ArchiResource: " + _name;
+    }
+
+    /**
+     * Return a node (which has a specific name). Return null when node
+     * cannot be found.
+     *
+     * @param name of the node to search for
+     * @return node with the specified name
+     */
+    public Node getNode(String name) {
+        Iterator<Node> i;
+        i = _nodeList.iterator();
+        while (i.hasNext()) {
+            Node node = i.next();
+            if (node.getName().equals(name)) {
+                return node;
+            }
+         }
+         return null;
+     }
+
+    /**
+     * Return a node. Return null when node cannot be found.
+     *
+     * @return node
+     */
+    public Node getNode() {
+        Iterator<Node> i;
+        i = _nodeList.iterator();
+        while (i.hasNext()) {
+            Node node = i.next();
+            return node;
+         }
+         return null;
+     }
+
+    /**
+     * Has this resource nodes?
+     *
+     * @return boolean value
+     */
+    public boolean hasNodes() {
+        return !_nodeList.isEmpty();
+    }
+
+
+    /**
+     * Return the first node of the nodelist.
+     *
+     * @return the first node of the nodelist.
+     */
+    public Node getFirstNode() {
+        return (Node) _nodeList.firstElement();
+    }
+
+    /**
+     * Get the list of configurations of this resource.
+     *
+     * @return list of configurations
+     */
+    public Vector<Configuration> getCfgList() {
+        return _cfgList;
+    }
+
+    /**
+     * Set the list of configurations of this resource.
+     *
+     * @param cfgList configuration list
+     */
+    public void setCfgList(Vector<Configuration> cfgList) {
+        _cfgList = cfgList;
+    }
+
+    /**
+     * Return a configuration which has a specific name. Return
+     * null when configuration cannot be found.
+     *
+     * @param name name of the configuration to search for
+     * @return configuration with the specified name
+     */
+     public Configuration getCfg(String name) {
+          for (Configuration config : _cfgList) {
+              if (config.getName().equals(name)) {
+                 return config;
+              }
+          }
+          return null;
+     }
+
+
+    /** list of the configurations of the ArchiResource */
+    protected Vector<Configuration> _cfgList = null;
+
+    /** name of the architectural resource */
+    protected String _name = null;
+
+    /** basename of the architectural resource, if no basename, store the name */
+    protected String _basename = null;
+
+    /** list of the nodes, paths of the architectural resource */
+    protected Vector<Node> _nodeList = null;
+
+    /** parent resource of this architectural resource */
+    protected ArchiResource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/architecture/Architecture.java b/dol/src/dol/datamodel/architecture/Architecture.java
new file mode 100644 (file)
index 0000000..06d510d
--- /dev/null
@@ -0,0 +1,400 @@
+/* $Id: Architecture.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Hashtable;
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+
+/**
+ * This class defines an architecture.
+ */
+public class Architecture extends ArchiResource {
+    /**
+     *  Constructor to create an architecture with a name,
+     *  empty processor list, empty memory list, empty hwChannel list and empty connection list.
+     */
+    public Architecture(String name) {
+        super(name);
+        _processorList = new Vector<Processor>();
+        _memoryList = new Vector<Memory>();
+        _hwChannelList = new Vector<HWChannel>();
+        _varList = new Vector<Variable>();
+        _connectionList = new Vector<ArchiConnection>();
+        _readPathList = new Vector<ReadPath>();
+        _writePathList = new Vector<WritePath>();
+        _pathList = new Vector<Path>();
+        _processorPathList = new Hashtable<Processor,
+                Hashtable<Processor, Vector<Path>>>();
+
+    }
+
+    /**
+     * Accept a visitor
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Architecture.
+     *
+     * @return new instance of the Architecure
+     */
+    /*
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        Architecture newObj = (Architecture) super.clone();
+        newObj.setProcessorList((Vector<Processor>)_processorList.clone());
+        newObj.setMemoryList((Vector<Memory>)_memoryList.clone());
+        newObj.setHWChannelList((Vector<HWChannel>)_hwChannelList.clone());
+        newObj.setVarList((Vector<Variable>)_varList.clone());
+        newObj.setConnectionList((Vector<ArchiConnection>)_connectionList.clone());
+        newObj.setReadPathList((Vector<ReadPath>)_readPathList.clone());
+        newObj.setWritePathList((Vector<WritePath>)_writePathList.clone());
+        newObj.setPathList((Vector<Vector<Node>>)_pathList.clone());
+        return newObj;
+    }
+    */
+
+
+    /**
+     * Get the processor list of a Architecture.
+     *
+     * @return the processor list
+     */
+    public Vector<Processor> getProcessorList() {
+        return _processorList;
+    }
+
+    /**
+     * Get the memory list of a Architecture.
+     *
+     * @return the memory list
+     */
+    public Vector<Memory> getMemoryList() {
+        return _memoryList;
+    }
+
+    /**
+     * Get the hwChannel list of a Architecture.
+     *
+     * @return the hwChannel list
+     */
+    public Vector<HWChannel> getHWChannelList() {
+        return _hwChannelList;
+    }
+
+    /**
+     * Get the  paths list of a Architecture.
+     *
+     * @return the paths list
+     */
+    public Vector<ReadPath> getReadPathList() {
+        return _readPathList;
+    }
+
+    /**
+     * Get the write paths list of a Architecture.
+     *
+     * @return the paths list
+     */
+    public Vector<WritePath> getWritePathList( ) {
+        return _writePathList;
+    }
+
+    /**
+     * Set the processor paths list of a Architecture.
+     *
+     * @param pathList The new list
+     */
+    public void setPathList(Vector<Path> pathList) {
+        _pathList = pathList;
+    }
+
+    /**
+     * Get the processor paths list of a Architecture.
+     *
+     * @return the processor paths list
+     */
+    public Vector<Path> getPathList() {
+        return _pathList;
+    }
+
+    /**
+     * Return a processor/memory/hwChannel which has a specific name. Return null if
+     * processor cannot be found.
+     *
+     * @param name the name of the processor/memory/hwChannel to search for.
+     * @return the processor/memory/hwChannel with the specific name.
+     */
+    public Processor getProcessor(String name) {
+        for (Processor processor : _processorList) {
+            if (processor.getName().equals(name)) {
+                return processor;
+            }
+        }
+        return null;
+    }
+
+    /**
+     *
+     */
+    public Memory getMemory(String name) {
+        for (Memory memory : _memoryList) {
+            if (memory.getName().equals(name)) {
+                return memory;
+            }
+        }
+        return null;
+    }
+
+    /**
+     *
+     */
+    public HWChannel getHWChannel(String name) {
+        for (HWChannel hwChannel : _hwChannelList) {
+            if (hwChannel.getName().equals(name)) {
+                return hwChannel;
+            }
+        }
+        return null;
+    }
+
+    
+    /**
+     * Return a read path which has a specific name. Return null if
+     * not found.
+     *
+     * @param  name the name of the read path to search for.
+     * @return the read path with the specific name.
+     */
+    public ReadPath getReadPath(String name) {
+        for (ReadPath p : _readPathList) {
+            if (p.getName().equals(name)) {
+                return p;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Return a write path which has a specific name. Return null if
+     * not found.
+     *
+     * @param  name the name of the write path to search for.
+     * @return the write path with the specific name.
+     */
+    public WritePath getWritePath(String name) {
+        for (WritePath p : _writePathList) {
+            if (p.getName().equals(name)) {
+                return p;
+            }
+        }
+        return null;
+    }
+    
+    public Vector<Variable> getVarList() { return _varList; }
+
+    public Vector<ArchiConnection> getConnectionList() {
+        return _connectionList;
+    }
+
+    /**
+     * Compute all paths between processors.
+     */
+    public void computePaths() {
+        for (WritePath w : _writePathList) {
+            String channelBuffer = w.getCHBuf().getName();
+            for (ReadPath r : _readPathList) {
+                if (r.getCHBuf().getName().equals(channelBuffer)) {
+                    Path path = new Path();
+                    path.setWritePath(w);
+                    path.setReadPath(r);
+                    _pathList.add(path);
+                }
+            }
+        }
+
+        /*
+        //print all paths in this architecture
+        for (int j = 0; j < _pathList.size(); j++) {
+            Vector<ArchiResource> path = _pathList.elementAt(j).getPath();
+            for (int k = 0; k < path.size(); k++) {
+                System.out.print(path.elementAt(k).
+                        getName() + (k < path.size() - 1 ? " -> " : ""));
+            }
+            System.out.println();
+        }
+        System.out.println("Found " + _pathList.size() + " paths.");
+        */
+
+        computeProcessorPath();
+    }
+
+    /**
+     * Compute all write path from one processor to another processor
+     * in this architecture.
+     */
+    protected void computeProcessorPath() {
+        //iterate over all path in this architecture
+        for (int j = 0; j < _pathList.size(); j++) {
+            Processor startProcessor = _pathList.elementAt(j).getStartProcessor();
+            Processor targetProcessor = _pathList.elementAt(j).getTargetProcessor();
+
+            //create new hashtable entry for this start processor
+            if (!_processorPathList.containsKey(startProcessor)) {
+                Hashtable<Processor, Vector<Path>>
+                        processorPathList = new Hashtable<Processor,
+                        Vector<Path>>();
+                _processorPathList.put(startProcessor, processorPathList);
+            }
+
+            Hashtable<Processor, Vector<Path>>
+                    processorPathList = _processorPathList.
+                    get(startProcessor);
+
+            //create new path list for this target processor
+            if(!processorPathList.containsKey(targetProcessor)) {
+                Vector<Path> processorPath = new Vector<Path>();
+                processorPathList.put(targetProcessor, processorPath);
+            }
+
+            Vector<Path> processorPath =
+                    processorPathList.get(targetProcessor);
+
+            //add this path to the list of paths
+            processorPath.add(_pathList.elementAt(j));
+        }
+
+        /*
+        //print all processor to processor path
+        int pathCounter = 0;
+        for (int j = 0; j < _processorList.size(); j++) {
+            for (int k = 0; k < _processorList.size(); k++) {
+                Vector<Path> processorPathList =
+                        getPaths(_processorList.elementAt(j),
+                        _processorList.elementAt(k));
+                for (int l = 0; l < processorPathList.size(); l++) {
+                    pathCounter++;
+                    Vector<ArchiResource> path = processorPathList.
+                            elementAt(l).getPath();
+                    for (int m = 0; m < path.size(); m++) {
+                        System.out.print(path.elementAt(m).getName()
+                        + (m < path.size() - 1 ? " -> " : ""));
+                    }
+                    System.out.println();
+                }
+            }
+        }
+        System.out.println("Found " + pathCounter + " paths.");
+        */
+    }
+
+    /**
+     * Get all write paths from the given start processor to the given
+     * target processor.
+     *
+     * @param startProcessor processor where write path begins
+     * @param targetProcessor processor where write path ends
+     * @return vector of all write paths between startProcessor and
+     *         targetProcessor
+     */
+    public Vector<Path> getPaths(
+            Processor startProcessor, Processor targetProcessor) {
+        if (_processorPathList.get(startProcessor) == null) {
+            return null;
+        }
+        return _processorPathList.get(startProcessor).get(targetProcessor);
+    }
+
+    /**
+     * Register the RX/TX/CH buffer to each resource.
+     * Can be used for dotty generation.
+     */
+    public void registerRWPath2Resource()
+    {
+        for (ReadPath r : _readPathList) {
+            // register rxbuf
+            String memName = r.getRXBuf().getName();
+            for (Memory m : _memoryList) {
+                if (m.getName().equals(memName)) {
+                    m.getRXBufList().add(r.getName());
+                }
+            }
+
+            // register chbuf
+            memName = r.getCHBuf().getName();
+            for (Memory m : _memoryList) {
+                if (m.getName().equals(memName)) {
+                    m.getCHBufList().add(r.getName() + "_RPath");
+                }
+            }
+
+            // register pathes via a communication resource
+            for (HWChannel c : r.getHWChannelList()) {
+                if (c.getName().equals(r.getName())) {
+                    // premise: a path cannot go via a bus twice.
+                    c.getPathList().add(r.getName() + "_RPath");
+                }
+            }
+        }
+
+        for (WritePath w : _writePathList) {
+            // register txbuf
+            String memName = w.getTXBuf().getName();
+            for (Memory m : _memoryList) {
+                if (m.getName().equals(memName)) {
+                    m.getTXBufList().add(w.getName());
+                }
+            }
+
+            // register chbuf
+            memName = w.getCHBuf().getName();
+            for (Memory m : _memoryList) {
+                if (m.getName().equals(memName)) {
+                    m.getCHBufList().add(w.getName() + "_WPath");
+                }
+            }
+
+            // register pathes via a communication resource
+            for (HWChannel c : w.getHWChannelList()) {
+                if (c.getName().equals(w.getName())) {
+                    // premise: a path cannot go via a bus twice.
+                    c.getPathList().add(w.getName() + "_WPath");
+                }
+            }
+        }
+    }
+
+    /** List of the processors in the Architecture */
+    protected Vector<Processor> _processorList = null;
+
+    /** List of the memories in the Architecture */
+    protected Vector<Memory> _memoryList = null;
+
+    /** List of hwChannels in the Architecture */
+    protected Vector<HWChannel> _hwChannelList = null;
+
+    /** List of variables in the Architecture */
+    protected Vector<Variable> _varList = null;
+
+    /** List of connections in the Architecture: for simplified arch*/
+    protected Vector<ArchiConnection> _connectionList = null;
+
+    /** List of read paths in the Architecture: for detail arch */
+    protected Vector<ReadPath> _readPathList = null;
+
+    /** List of write paths in the Architecture: for detail arch */
+    protected Vector<WritePath> _writePathList = null;
+
+    /** List of paths in the Architecture */
+    protected Vector<Path> _pathList = null;
+
+    /** hashtable to access all processor to processor path */
+    protected Hashtable<Processor, Hashtable<Processor,
+            Vector<Path>>> _processorPathList = null;
+}
diff --git a/dol/src/dol/datamodel/architecture/Configuration.java b/dol/src/dol/datamodel/architecture/Configuration.java
new file mode 100644 (file)
index 0000000..b370b95
--- /dev/null
@@ -0,0 +1,113 @@
+/* $Id: Configuration.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+
+/**
+ * This class represents a name-value pair of a configuration tag in XML.
+ */
+public class Configuration {
+
+    /**
+     * Constructor to create a Configuration.
+     */
+    public Configuration(String name) {
+        _name = name;
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+     */
+
+    
+    /**
+     * Clone this Configuration.
+     *
+     * @return new instance of the Configuration.
+     */
+    public Object clone() {
+        try {
+            Configuration newObj = (Configuration) super.clone();
+            newObj.setName(_name);
+            newObj.setValue(_value);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the Configuration.
+     *
+     * @return the value of the configuration.
+     */
+    public String getValue() {
+        return _value;
+    }
+
+    /**
+     * Set the value of the Configuration.
+     *
+     * @param value the value of the configuration.
+     */
+    public void setValue(String value) {
+        _value = value;
+    }
+
+    /**
+     * Get the name of this configuration.
+     *
+     * @return  the name
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this configuration.
+     *
+     * @param name name of the configuration
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the hierarchical parent of this resource.
+     *
+     * @return parent of this resource
+
+     public Resource getParentResource() {
+        return _parentResource;
+    }
+     */
+    
+    /**
+     * Set the hierarchical parent of this resource.
+     *
+     * @param parentResource new parent
+
+    public void setParentResource(Resource parentResource) {
+        _parentResource = parentResource;
+    }
+     */
+    
+    /**
+     * Return a string representation of the Configuration.
+     *
+     * @return string representation of the Configuration
+     */
+    public String toString() {
+        return "Configuration: " + getName();
+    }
+
+    protected String _value = null;
+    protected String _name = null;
+    protected ArchiResource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/architecture/HWChannel.java b/dol/src/dol/datamodel/architecture/HWChannel.java
new file mode 100644 (file)
index 0000000..f4ed94e
--- /dev/null
@@ -0,0 +1,128 @@
+/* $Id: HWChannel.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class represents an interconnect element in the architecture.
+ */
+public class HWChannel extends ArchiResource {
+    /**
+     * Constructor to create a HWChannel with a name and an empty
+     * nodeList.
+     */
+    public HWChannel(String name) {
+        super(name);
+        _pathList = new Vector<String>();
+    }
+
+    /**
+     * Accept a Visitor
+     * @param x A Visitor Object.
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this HWChannel
+     *
+     * @return a new instance of the HWChannel.
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        HWChannel newObj = (HWChannel) super.clone();
+        newObj.setPathList((Vector<String>)_pathList.clone());
+        return (newObj);
+    }
+
+    /**
+     * Get the range of this processor.
+     *
+     * @return range
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this process.
+     *
+     * @param range new range value
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    /**
+     * Get the type of this hw_channel.
+     *
+     * @return type
+     */
+    public String getType() {
+        return _type;
+    }
+
+    /**
+     * Set the type of this hw_channel.
+     *
+     * @param type new range value
+     */
+    public void setType(String type) {
+        _type= type;
+    }
+
+    /**
+     * Has this processor nodes?
+     *
+     * @return boolean value
+     */
+    public boolean hasNodes() {
+        Iterator<Node> i = getNodeList().iterator();
+        while (i.hasNext()) {
+            i.next();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get the list of pathes via this resource.
+     *
+     * @return list of path.
+     */
+    public Vector<String> getPathList() {
+        return _pathList;
+    }
+
+    /**
+     * Set the list of pathes via this resource.
+     *
+     * @param list path list
+     */
+    public void setPathList(Vector<String> list) {
+        _pathList = list;
+    }
+
+    /**
+     * Return a description of the processor.
+     *
+     * @return a description of the processor.
+     */
+    public String toString() {
+        return "HWChannel: " + getName() ;
+    }
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of processors.
+     */
+    protected String _range;
+    protected String _type;
+
+    // Store the name of pathes which go via this communication resource.
+    protected Vector<String> _pathList;
+}
diff --git a/dol/src/dol/datamodel/architecture/Memory.java b/dol/src/dol/datamodel/architecture/Memory.java
new file mode 100644 (file)
index 0000000..f7efe33
--- /dev/null
@@ -0,0 +1,170 @@
+/* $Id: Memory.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class represents a memory element in the archietcture.
+ */
+public class Memory extends ArchiResource {
+    /**
+     * Constructor to create a Memory with a name and an empty
+     * nodeList.
+     */
+    public Memory(String name) {
+        super(name);
+        _rxBufList = new Vector<String>();
+        _txBufList = new Vector<String>();
+        _chBufList = new Vector<String>();
+    }
+
+    /**
+     * Accept a Visitor
+     * @param x A Visitor Object.
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Memory
+     *
+     * @return a new instance of the Memory.
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        Memory newObj = (Memory) super.clone();
+        newObj.setRXBufList((Vector<String>)_rxBufList.clone());
+        newObj.setTXBufList((Vector<String>)_txBufList.clone());
+        newObj.setCHBufList((Vector<String>)_chBufList.clone());
+        return (newObj);
+    }
+
+    /**
+     * Get the range of this Memory.
+     *
+     * @return range
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this Memory.
+     *
+     * @param range new range value
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    /**
+     * Get the type of this Memory.
+     *
+     * @return type
+     */
+    public String getType() {
+        return _type;
+    }
+
+    /**
+     * Set the type of this Memory.
+     *
+     * @param type new range value
+     */
+    public void setType(String type) {
+        _type= type;
+    }
+
+    /**
+     * Get the list of RXBuf of this memory
+     *
+     * @return list of RX buffer.
+     */
+    public Vector<String> getRXBufList() {
+        return _rxBufList;
+    }
+
+    /**
+     * Set the list of RXBuf of this memory.
+     *
+     * @param list RX buffer list
+     */
+    public void setRXBufList(Vector<String> list) {
+        _rxBufList = list;
+    }
+
+    /**
+     * Get the list of TXBuf of this memory.
+     *
+     * @return list of TX buffers.
+     */
+    public Vector<String> getTXBufList() {
+        return _txBufList;
+    }
+
+    /**
+     * Set the list of TXBuf of this memory.
+     *
+     * @param list TX buffer list
+     */
+    public void setTXBufList(Vector<String> list) {
+        _txBufList = list;
+    }
+
+    /**
+     * Get the list of channel buffers of this memory.
+     *
+     * @return list of channel buffers.
+     */
+    public Vector<String> getCHBufList() {
+        return _chBufList;
+    }
+
+    /**
+     * Set the list of channel Buf of this memory.
+     *
+     * @param list channel buffer list
+     */
+    public void setCHBufList(Vector<String> list) {
+        _chBufList = list;
+    }
+
+    /**
+     * Has this memory nodes?
+     *
+     * @return boolean value
+     */
+    public boolean hasNodes() {
+        Iterator<Node> i = getNodeList().iterator();
+        while (i.hasNext()) {
+            i.next();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Return a description of the Memory.
+     *
+     * @return a description of the Memory.
+     */
+    public String toString() {
+        return "Memory: " + getName() ;
+    }
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of Memories.
+     */
+    protected String _range;
+    protected String _type;
+
+    // store the name of rx, tx channel buffer, can be used for dotty gen.
+    protected Vector<String> _rxBufList;
+    protected Vector<String> _txBufList;
+    protected Vector<String> _chBufList;
+}
diff --git a/dol/src/dol/datamodel/architecture/Node.java b/dol/src/dol/datamodel/architecture/Node.java
new file mode 100644 (file)
index 0000000..89d51b8
--- /dev/null
@@ -0,0 +1,211 @@
+/* $Id: Node.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class represents a node in the archietcture.
+ */
+public class Node implements Cloneable {
+
+    /**
+     * Constructor to create a Node with a name and an empty
+     * portList.
+     */
+    public Node(String name) {
+        _name = name;
+        _basename = name;
+        _portList = new Vector<PortNode>();
+    }
+
+    /**
+     * Accept a Visitor
+     * @param x A Visitor Object.
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Node
+     *
+     * @return a new instance of the Node.
+     */
+    public Object clone() {
+        try {
+            Node newObj = (Node) super.clone();
+            newObj.setName(_name);
+            newObj.setBasename(_basename);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the range of this node.
+     *
+     * @return range
+     */
+   public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this node.
+     *
+     * @param range new range value
+     */
+     public void setRange(String range) {
+        _range= range;
+    }
+
+
+    /**
+     * Get the name of this node.
+     *
+     * @return name of the node
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this node.
+     *
+     * @param name name of the node
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the basename of this node.
+     *
+     * @return basename of the node
+     */
+    public String getBasename() {
+        return _basename;
+    }
+
+    /**
+     * Set the basename of this node.
+     *
+     * @param basename name of the node
+     */
+    public void setBasename(String basename) {
+        _basename = basename;
+    }
+
+    /**
+     * Has this node IN/OUT/INOUT ports?
+     *
+     * @return boolean value
+     */
+    public boolean hasInPorts() {
+        for (PortNode port : getPortList()) {
+            if (port.isInPort())
+                return true;
+        }
+        return false;
+    }
+
+    public boolean hasOutPorts() {
+        for (PortNode port : getPortList()) {
+            if (port.isOutPort())
+                return true;
+        }
+        return false;
+    }
+
+    public boolean hasInOutPorts() {
+        for (PortNode port : getPortList()) {
+            if (port.isInOutPort())
+                return true;
+        }
+        return false;
+   }
+
+    /**
+     * Return a port which has a specific name. Return null when port
+     * cannot be found.
+     *
+     * @param name name of the port to search for
+     * @return port with the specified name
+     */
+    public PortNode getPort(String name) {
+        for (PortNode port : getPortList()) {
+            if (port.getName().equals(name)) {
+                return port;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return the first port on the List.
+     *
+     * @return first port element
+     */
+    public PortNode getFirstPort() {
+        return (PortNode) _portList.firstElement();
+    }
+
+   /**
+    * Get the corresponding ArchiResource.
+    *
+    * @return the corresponding ArchiResource
+    */
+    public ArchiResource getCorrespResource() {
+        return _correspResource;
+    }
+
+   /**
+    * Set the corresponding ArchiResource.
+    *
+    * @param correspResource new ArchiResource
+    */
+    public void setCorrespResource(ArchiResource correspResource) {
+        _correspResource = correspResource;
+    }
+
+    /**
+     * Get the port list of a Node.
+     *
+     * @return the port list
+     */
+    public Vector<PortNode> getPortList() {
+        return _portList;
+    }
+
+    /**
+     * Set the port list of a Node.
+     *
+     * @param portList The new list
+     */
+    public void setPortList( Vector<PortNode> portList ) {
+        _portList = portList;
+    }
+
+    /**
+     * Return a description of the node.
+     *
+     * @return a description of the node.
+     */
+    public String toString() {
+        return "Node: " + getName();
+    }
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of nodes.
+     */
+    protected String _range;
+    protected String _name = null;
+    protected String _basename = null;
+    protected ArchiResource _correspResource = null;
+    protected Vector<PortNode> _portList = null;
+}
diff --git a/dol/src/dol/datamodel/architecture/Path.java b/dol/src/dol/datamodel/architecture/Path.java
new file mode 100644 (file)
index 0000000..c18084a
--- /dev/null
@@ -0,0 +1,118 @@
+/* $Id: Path.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * Path consisting of write path and read path.
+ */
+public class Path {
+    /**
+     * Default constructor.
+     */
+    public Path() {
+        _path = new Vector<ArchiResource>();
+    }
+
+    /**
+     * Set the read path of this path.
+     */
+    public void setReadPath(ReadPath readPath) {
+        _readPath = readPath;
+        computeArchitectureResources();
+    }
+
+    /**
+     * Return the read path of this path.
+     *
+     * @return read path
+     */
+    public ReadPath getReadPath() {
+        return _readPath;
+    }
+
+    /**
+     * Set the write path of this path.
+     */
+    public void setWritePath(WritePath writePath) {
+        _writePath = writePath;
+        computeArchitectureResources();
+    }
+
+    /**
+     * Return the write path of this path.
+     *
+     * @return write path
+     */
+    public WritePath getWritePath() {
+        return _writePath;
+    }
+
+    /**
+     * Return all resources contained in this path.
+     *
+     * @return all resources contained in this path
+     */
+    public Vector<ArchiResource> getPath() {
+        return _path;
+    }
+
+    /**
+     * Return the processor where this path starts.
+     *
+     * @return processor where this path starts
+     */
+    public Processor getStartProcessor() {
+        if (_path.size() == 0)
+            return null;
+
+        return (Processor)_path.elementAt(0);
+    }
+
+    /**
+     * Return the processor where this path ends.
+     *
+     * @return processor where this path ends
+     */
+    public Processor getTargetProcessor() {
+        if (_path.size() == 0)
+            return null;
+
+        return (Processor)_path.elementAt(_path.size() - 1);
+    }
+
+    /**
+     * Compute the vector of all resources contained in this path.
+     */
+    protected void computeArchitectureResources() {
+        _path.clear();
+
+        if (_readPath == null || _writePath == null)
+            return;
+
+        _path.add(_writePath.getProcessor());
+        _path.add(_writePath.getTXBuf());
+        Iterator<HWChannel> channelIterator =
+                _writePath.getHWChannelList().iterator();
+        while (channelIterator.hasNext()) {
+            _path.add(channelIterator.next());
+        }
+        _path.add(_readPath.getCHBuf());
+        channelIterator = _readPath.getHWChannelList().iterator();
+        while (channelIterator.hasNext()) {
+            _path.add(channelIterator.next());
+        }
+        _path.add(_readPath.getRXBuf());
+        _path.add(_readPath.getProcessor());
+    }
+
+    /** read path of this path*/
+    protected ReadPath _readPath = null;
+
+    /** write path of this path */
+    protected WritePath _writePath = null;
+
+    /** resources contained in this path */
+    Vector<ArchiResource> _path;
+}
diff --git a/dol/src/dol/datamodel/architecture/PortNode.java b/dol/src/dol/datamodel/architecture/PortNode.java
new file mode 100644 (file)
index 0000000..2db5cd1
--- /dev/null
@@ -0,0 +1,253 @@
+/* $Id: PortNode.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class represents a port of an architectural node.
+ */
+public class PortNode implements Cloneable {
+    /**
+     *  Constructor to create a PortNode with a name.
+     */
+    public PortNode(String name) {
+        _name = name;
+        _isInPort = false;
+        _isOutPort = false;
+        _isInOutPort = false;
+    }
+
+    /**
+     *  Constructor to create a PortNode with a name and a type.
+     */
+    public PortNode(String name, boolean type) {
+        _name = name;
+        _isInPort = (type == INPORT);
+        _isOutPort = (type == OUTPORT);
+        _isInOutPort = (type == INOUTPORT);
+    }
+
+    /**
+     * Accept a visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this PortNode
+     *
+     * @return new instance of the PortNode
+     */
+    public Object clone() {
+        try {
+            PortNode newObj = (PortNode) super.clone();
+            newObj.setName(_name);
+            newObj.setBasename(_basename);
+            newObj.setPeerPort(_peerPort);
+            newObj.setPeerResource(_peerResource);
+            newObj.setPeerNode(_peerNode);
+            newObj.setResource(_resource );
+            newObj.setNode(_node);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Check whether this port is an inport.
+     *
+     * @return true if this port is an inport, otherwise false
+     */
+    public boolean isInPort() {
+        return _isInPort;
+    }
+
+    /**
+     * Check whether this port is an outport.
+     *
+     * @return true if this port is an outport, otherwise false
+     */
+    public boolean isOutPort() {
+        return _isOutPort;
+    }
+
+    /**
+     * Check whether this port is an inoutport.
+     *
+     * @return true if this port is an inoutport, otherwise false
+     */
+    public boolean isInOutPort() {
+        return _isInOutPort;
+    }
+
+    /**
+     * Get the name of this port.
+     *
+     * @return name of the port
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this port.
+     *
+     * @param name name of the port
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    public void setBasename(String basename) { _basename = basename; }
+    public String getBasename() { return _basename; }
+
+    /**
+     * Get the range of this port.
+     *
+     * @return range of the port
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this port.
+     *
+     * @param range range of the port
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    /**
+     * Get the resource/node of this port.
+     *
+     * @return the resource/node
+     */
+    public ArchiResource getResource() {
+        return _resource;
+    }
+    public Node getNode() {
+        return _node;
+    }
+
+    /**
+     * Set the resource/node of this port.
+     *
+     * @param resource
+     */
+    public void setResource(ArchiResource resource) {
+        _resource = resource;
+    }
+    public void setNode(Node node) {
+        _node = node;
+    }
+
+    /**
+     * Set the peer resource/node/port of this port.
+     *
+     * @param peer The new node
+     */
+    public void setPeerPort(PortNode peer) { _peerPort = peer; }
+
+    /**
+     *
+     */
+    public void setPeerResource(ArchiResource n) { _peerResource = n; }
+
+    /**
+     *
+     */
+    public void setPeerNode(Node n) { _peerNode = n; }
+
+    /**
+     * Get the peer resource/node/port of this port.
+     *
+     * @return the peer resource/node/port
+     */
+    public PortNode getPeerPort(){ return _peerPort; }
+
+    /**
+     *
+     */
+    public ArchiResource getPeerResource() { return _peerResource; }
+
+    /**
+     *
+     */
+    public Node getPeerNode() { return _peerNode; }
+
+    /**
+     * Get the type of this port.
+     *
+     * @return type of this port
+     */
+    public String getType() {
+        if (_isInPort) return  "input";
+        if (_isOutPort) return "output";
+        if (_isInOutPort) return "duplex";
+        return "type not set.";
+    }
+
+    /**
+     * Return a string representation of the port.
+     *
+     * @return string representation of the port
+     */
+    public String toString() {
+        return "PortNode: " + _name;
+    }
+
+    /** constant for inport for usage in the constructor **/
+    public static final boolean INPORT = true;
+
+    /** constant for outport for usage in the constructor **/
+    public static final boolean OUTPORT = false;
+
+    /** constant for inoutport for usage in the constructor **/
+    public static final boolean INOUTPORT = false;
+
+    /** defines whether this port is an inport **/
+    protected boolean _isInPort = false;
+
+    /** defines whether this port is an outport **/
+    protected boolean _isOutPort = false;
+
+    /** defines whether this port is an inout **/
+    protected boolean _isInOutPort = false;
+
+    /** name of the port */
+    protected String _name = null;
+
+    /** basename of the resource, if no basename, store the name */
+    protected String _basename = null;
+
+    /** resource (process or channel) this port belongs to */
+    protected ArchiResource _resource = null;
+
+    /** node this port belongs to */
+    protected Node _node = null;
+
+    /** resource which peerPort belongs to */
+    protected ArchiResource _peerResource = null;
+
+    /** node which peerPort belongs to */
+    protected Node _peerNode = null;
+
+    /** connected peer port name */
+    protected PortNode _peerPort = null;
+
+    /** peer channel name */
+    protected String _channelName = null;
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of ports.
+     */
+    protected String _range = null;
+}
diff --git a/dol/src/dol/datamodel/architecture/Processor.java b/dol/src/dol/datamodel/architecture/Processor.java
new file mode 100644 (file)
index 0000000..cffc781
--- /dev/null
@@ -0,0 +1,135 @@
+/* $Id: Processor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Vector;
+
+import dol.datamodel.pn.Process;
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class represents a processor element in the architecture.
+ */
+public class Processor extends ArchiResource {
+
+    /**
+     * Constructor to create a Processor with a name and an empty
+     * nodeList.
+     */
+    public Processor(String name) {
+        super(name);
+        _processList = new Vector<Process>();
+    }
+
+    /**
+     * Accept a Visitor
+     * @param x A Visitor Object.
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Processor
+     *
+     * @return a new instance of the Processor.
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        Processor newObj = (Processor) super.clone();
+        newObj.setProcessList((Vector<Process>)_processList.clone());
+        return (newObj);
+    }
+
+    /**
+     * Get the range of this processor.
+     *
+     * @return range
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this process.
+     *
+     * @param range new range value
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    /**
+     * Get the type of this processor.
+     *
+     * @return type
+     */
+    public String getType() {
+        return _type;
+    }
+
+    /**
+     * Set the type of this processor.
+     *
+     * @param type new range value
+     */
+    public void setType(String type) {
+        _type= type;
+    }
+
+
+
+    /**
+     * Set the list of processes bound to this processor.
+     * @param processList the new process list
+     */
+    public void setProcessList(Vector<Process> processList)
+    {
+        _processList = processList;
+    }
+
+    /**
+     * Get the list of processes bound to this processor.
+     */
+    public Vector<Process> getProcessList()
+    {
+        return _processList;
+    }
+
+    /**
+     * Indicates if a process with a specific name is bound
+     * to this processor.
+     * @param name the name of the process to search for
+     * @return true if a process with the specifed name is bound to this
+     * processor
+     */
+    public boolean hasProcess(String name)
+    {
+        for (Process iter : _processList) {
+            if (iter.getName().equals(name))
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Return a description of the processor.
+     *
+     * @return a description of the processor.
+     */
+    public String toString() {
+        return "Processor: " + getName() ;
+    }
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of processors.
+     */
+    protected String _range;
+    protected String _type;
+
+    /**
+     * List of processes bound to this processor.
+     */
+    protected Vector<Process> _processList;
+}
diff --git a/dol/src/dol/datamodel/architecture/ReadPath.java b/dol/src/dol/datamodel/architecture/ReadPath.java
new file mode 100644 (file)
index 0000000..ce380c1
--- /dev/null
@@ -0,0 +1,115 @@
+/* $Id: ReadPath.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class defines a read path. A read path contains one processor,
+ * one rxbuf, one channel buf, and one or more hw channels.
+ */
+public class ReadPath extends ArchiResource {
+    /**
+     * Constructor to create an architecture connection with a name.
+     *
+     */
+    public ReadPath(String name) {
+        super(name);
+        _hwChannelList = new Vector<HWChannel>();
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this architectural connection.
+     *
+     * @return  a new instance of the architectural connection.
+     */
+    /*
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        ReadPath newObj = (ReadPath) super.clone();
+        newObj.setProcessor(_processor);
+        newObj.setRXBuf(_rxBuf);
+        newObj.setCHBuf(_chBuf);
+        newObj.setHWChannelNameList((Vector)_hwChannelNameList.clone());
+        return (newObj);
+    }
+    */
+
+    /**
+     * Return a string representation of the architectural connection.
+     *
+     * @return string representation of the architectural connection
+     */
+    public String toString() {
+        return "ReadPath: " + getName();
+    }
+
+    /**
+     * Return the memory where the receive buffer is located.
+     *
+     * @return name of memory
+     */
+    public Memory getRXBuf() { return _rxBuf; }
+
+    /**
+     * Set the receive buffer location.
+     *
+     * @param rxbuf rxbuf location
+     */
+    public void setRXBuf(Memory rxbuf) { _rxBuf = rxbuf; }
+
+    /**
+     * Return the memory where the channel buffer is located.
+     *
+     * @return channel buffer location
+     */
+    public Memory getCHBuf() { return _chBuf; }
+
+    /**
+     * Set the channel buffer location
+     *
+     * @param chbuf memory where channel buffer is located.
+     */
+    public void setCHBuf(Memory chbuf) { _chBuf = chbuf; }
+
+    /**
+     * Return the list of the HW channels.
+     *
+     * @return list of HW channels
+     */
+    public Vector<HWChannel> getHWChannelList() { return _hwChannelList; }
+
+    /**
+     * Return the processor to which this path is associated.
+     *
+     * @return processor
+     */
+    public Processor getProcessor() {
+        return _processor;
+    }
+
+    /**
+     * Set the processor to which this path is associated
+     *
+     * @param processor processor
+     */
+    public void setProcessor(Processor processor) {
+        _processor = processor;
+    }
+
+
+    protected Processor _processor;
+    protected Memory _rxBuf;
+    protected Memory _chBuf;
+    protected Vector<HWChannel> _hwChannelList;
+}
diff --git a/dol/src/dol/datamodel/architecture/Variable.java b/dol/src/dol/datamodel/architecture/Variable.java
new file mode 100644 (file)
index 0000000..2c91a2d
--- /dev/null
@@ -0,0 +1,109 @@
+/* $Id: Variable.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class represents a global variable in the architecture XML.
+ */
+public class Variable implements Cloneable {
+
+    /**
+     * Constructor to create a Variable.
+     */
+    public Variable(String name) {
+        _name = name;
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Variable.
+     *
+     * @return new instance of the Variable.
+     */
+    public Object clone() {
+        try {
+            Variable newObj = (Variable) super.clone();
+            newObj.setName(_name);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the Variable.
+     *
+     * @return the value of the variable
+     */
+    public int getValue() {
+        return _value;
+    }
+
+    /**
+     * Set the value of the Variable.
+     *
+     * @param value the value of the variable
+     */
+    public void setValue(int value) {
+        _value = value;
+    }
+
+    /**
+     * Get the name of this SourceCode.
+     *
+     * @return  the name
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this SourceCode.
+     *
+     * @param name name of the SourceCode
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the parent ArchiResource.
+     *
+     * @return parent ArchiResource
+     */
+     public ArchiResource getParentResource() {
+        return _parentResource;
+    }
+
+    /**
+     * Set the parent ArchiResource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(ArchiResource parentResource) {
+        _parentResource = parentResource;
+    }
+
+    /**
+     * Return a string representation of the Variable.
+     *
+     * @return string representation of the Variable
+     */
+    public String toString() {
+        return "Variable: " + getName();
+    }
+
+    protected int _value;
+    protected String _name = null;
+    protected ArchiResource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/architecture/WritePath.java b/dol/src/dol/datamodel/architecture/WritePath.java
new file mode 100644 (file)
index 0000000..80244a7
--- /dev/null
@@ -0,0 +1,113 @@
+/* $Id: WritePath.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.architecture;
+
+import java.util.Vector;
+
+import dol.visitor.ArchiVisitor;
+
+/**
+ * This class defines a write path. A write path contains one processor,
+ * one txbuf, one channel buf, and one or more hw channels.
+ */
+public class WritePath extends ArchiResource {
+    /**
+     * Constructor to create an architecture connection with a name.
+     */
+    public WritePath(String name) {
+        super(name);
+        _hwChannelList = new Vector<HWChannel>();
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(ArchiVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this architectural connection.
+     *
+     * @return  a new instance of the architectural connection.
+     */
+    /*
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        WritePath newObj = (WritePath) super.clone();
+        newObj.setProcessor(_processor);
+        newObj.setTXBuf(_txBuf);
+        newObj.setCHBuf(_chBuf);
+        newObj.setHWChannelNameList((Vector)_hwChannelNameList.clone());
+        return (newObj);
+    }
+    */
+
+    /**
+     * Return a string representation of the architectural connection.
+     *
+     * @return string representation of the architectural connection
+     */
+    public String toString() {
+        return "WritePath: " + getName();
+    }
+
+    /**
+     * Return the memory where the transmit buffer is located.
+     *
+     * @return name of memory
+     */
+    public Memory getTXBuf() { return _txBuf; }
+
+    /**
+     * Set the transmit buffer location.
+     *
+     * @param txbuf txbuf location
+     */
+    public void setTXBuf(Memory txbuf) { _txBuf = txbuf; }
+
+    /**
+     * Return the memory where the channel buffer is located.
+     *
+     * @return channel buffer location
+     */
+    public Memory getCHBuf() { return _chBuf; }
+
+    /**
+     * Set the channel buffer location
+     *
+     * @param chbuf memory where channel buffer is located.
+     */
+    public void setCHBuf(Memory chbuf) { _chBuf = chbuf; }
+
+    /**
+     * Return the list of the HW channels.
+     *
+     * @return list of HW channels
+     */
+    public Vector<HWChannel> getHWChannelList() { return _hwChannelList; }
+
+    /**
+     * Return the processor to which this path is associated.
+     *
+     * @return processor
+     */
+    public Processor getProcessor() {
+        return _processor;
+    }
+
+    /**
+     * Set the processor to which this path is associated.
+     *
+     * @param processor processor
+     */
+    public void setProcessor(Processor processor) {
+        _processor = processor;
+    }
+
+    protected Processor _processor;
+    protected Memory _txBuf;
+    protected Memory _chBuf;
+    protected Vector<HWChannel> _hwChannelList;
+}
diff --git a/dol/src/dol/datamodel/architecture/package.html b/dol/src/dol/datamodel/architecture/package.html
new file mode 100644 (file)
index 0000000..a6f1658
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Internal data model for the architecture representation.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/datamodel/mapping/Binding.java b/dol/src/dol/datamodel/mapping/Binding.java
new file mode 100644 (file)
index 0000000..ac39c52
--- /dev/null
@@ -0,0 +1,87 @@
+package dol.datamodel.mapping;
+
+import dol.visitor.MapVisitor;
+
+/**
+ * This class represents a binding element in the mapping.
+ */
+abstract public class Binding extends MapResource {
+
+    /**
+     * Constructor to create a Binding with a name.
+     */
+    public Binding(String name) {
+        super(name);
+    }
+
+    /**
+     * Accept a Visitor
+     * @param x A Visitor Object.
+     */
+    public void accept(MapVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Binding
+     *
+     * @return a new instance of the Binding.
+     */
+    public Object clone() {
+        Binding newObj = (Binding) super.clone();
+        return (newObj);
+    }
+
+    /**
+     * Get the range of this binding.
+     *
+     * @return range
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this binding.
+     *
+     * @param range new range value
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    /**
+     * Get the type of this binding.
+     *
+     * @return type
+     */
+    public String getType() {
+        return _type;
+    }
+
+    /**
+     * Return a description of the binding.
+     *
+     * @return a description of the binding.
+     */
+    public String toString() {
+        return "Binding: " + getName() ;
+    }
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of bindings.
+     */
+    protected String _range;
+    protected String _type;
+
+    /**
+     * Type specifier for communication bindings.
+     */
+    public static final String COMMUNICATION = "communication";
+    
+    /**
+     * Type specifier for computation bindings.
+     */
+    public static final String COMPUTATION = "computation";
+}
diff --git a/dol/src/dol/datamodel/mapping/CommunicationBinding.java b/dol/src/dol/datamodel/mapping/CommunicationBinding.java
new file mode 100644 (file)
index 0000000..568c326
--- /dev/null
@@ -0,0 +1,89 @@
+/* $Id: CommunicationBinding.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.mapping;\r
+\r
+import dol.datamodel.architecture.ReadPath;\r
+import dol.datamodel.architecture.WritePath;\r
+import dol.datamodel.pn.Channel;\r
+import dol.visitor.MapVisitor;\r
+\r
+/**\r
+ * This class represents a communication binding element in the mapping.\r
+ */\r
+public class CommunicationBinding extends Binding {\r
+\r
+    /**\r
+     * Constructor to create a CommunicationBinding with a name.\r
+     */\r
+    public CommunicationBinding(String name) {\r
+        super(name);\r
+        _type = COMMUNICATION;\r
+    }\r
+\r
+    /**\r
+     * Clone this Binding\r
+     *\r
+     * @return a new instance of the Binding.\r
+     */\r
+    public Object clone() {\r
+        CommunicationBinding newObj = (CommunicationBinding) super.clone();\r
+        newObj.setChannel(_channel);\r
+        newObj.setReadPath(_readPath);\r
+        newObj.setWritePath(_writePath);\r
+        return (newObj);\r
+    }\r
+\r
+    /**\r
+     * Accept a Visitor\r
+     *\r
+     * @param x visitor object\r
+     */\r
+    public void accept(MapVisitor x) {\r
+        x.visitComponent(this);\r
+    }\r
+\r
+    /** Set the SW channel */\r
+    public void setChannel(Channel c) {\r
+        _channel = c;\r
+    }\r
+\r
+    /** Get the SW channel */\r
+    public Channel getChannel() {\r
+        return _channel;\r
+    }\r
+\r
+    /** Set the read path */\r
+    public void setReadPath(ReadPath p) {\r
+        _readPath = p;\r
+    }\r
+\r
+    /** Get the read path */\r
+    public ReadPath getReadPath() {\r
+        return _readPath;\r
+    }\r
+\r
+    /** Set the write path */\r
+    public void setWritePath(WritePath p) {\r
+        _writePath = p;\r
+    }\r
+\r
+    /** Get the write path */\r
+    public WritePath getWritePath() {\r
+        return _writePath;\r
+    }\r
+\r
+    /**\r
+     * Return a description of the binding.\r
+     *\r
+     * @return a description of the binding.\r
+     */\r
+    public String toString() {\r
+        return "CommunicationBinding: " + getName() ;\r
+    }\r
+\r
+    private Channel _channel = null;\r
+\r
+    private ReadPath _readPath = null;\r
+\r
+    private WritePath _writePath = null;\r
+\r
+}\r
diff --git a/dol/src/dol/datamodel/mapping/ComputationBinding.java b/dol/src/dol/datamodel/mapping/ComputationBinding.java
new file mode 100644 (file)
index 0000000..c117265
--- /dev/null
@@ -0,0 +1,75 @@
+/* $Id: ComputationBinding.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.mapping;\r
+\r
+import dol.datamodel.architecture.Processor;\r
+import dol.datamodel.pn.Process;\r
+import dol.visitor.MapVisitor;\r
+\r
+/**\r
+ * This class represents a computation binding element in the mapping.\r
+ */\r
+public class ComputationBinding extends Binding {\r
+\r
+    /**\r
+     * Constructor to create a ComputationBinding with a name.\r
+     */\r
+    public ComputationBinding(String name) {\r
+        super(name);\r
+        _type = COMPUTATION;\r
+    }\r
+\r
+    /**\r
+     * Clone this Binding\r
+     *\r
+     * @return a new instance of the Binding.\r
+     */\r
+    public Object clone() {\r
+        ComputationBinding newObj = (ComputationBinding) super.clone();\r
+        newObj.setProcessor(_processor);\r
+        newObj.setProcess(_process);\r
+        return (newObj);\r
+    }\r
+\r
+    /**\r
+     * Accept a Visitor\r
+     *\r
+     * @param x visitor object\r
+     */\r
+    public void accept(MapVisitor x) {\r
+        x.visitComponent(this);\r
+    }\r
+\r
+    /** Set the PN process */\r
+    public void setProcess(Process p) {\r
+        _process = p;\r
+    }\r
+\r
+    /** Get the PN process */\r
+    public Process getProcess() {\r
+        return _process;\r
+    }\r
+\r
+    /** Set the processor from the architecture */\r
+    public void setProcessor(Processor p) {\r
+        _processor = p;\r
+    }\r
+\r
+    /** Get the processor */\r
+    public Processor getProcessor() {\r
+        return _processor;\r
+    }\r
+\r
+    /**\r
+     * Return a description of the binding.\r
+     *\r
+     * @return a description of the binding.\r
+     */\r
+    public String toString() {\r
+        return "ComputationBinding: " + getName() ;\r
+    }\r
+\r
+    private Process _process = null;\r
+\r
+    private Processor _processor = null;\r
+\r
+}\r
diff --git a/dol/src/dol/datamodel/mapping/Configuration.java b/dol/src/dol/datamodel/mapping/Configuration.java
new file mode 100644 (file)
index 0000000..fe3a3a4
--- /dev/null
@@ -0,0 +1,75 @@
+/* $Id: Configuration.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.mapping;\r
+\r
+import dol.visitor.MapVisitor;\r
+\r
+/**\r
+ * This class represents a name-value pair of a configuration tag in XML.\r
+ */\r
+public class Configuration {\r
+\r
+    /**\r
+     * Constructor to create a Configuration.\r
+     */\r
+    public Configuration(String name, String value) {\r
+        _name = name;\r
+        _value = value;\r
+    }\r
+\r
+    /**\r
+     * Accept a Visitor.\r
+     *\r
+     * @param x visitor object\r
+     */\r
+    public void accept(MapVisitor x) {\r
+        x.visitComponent(this);\r
+    }\r
+\r
+    /**\r
+     * Clone this Configuration.\r
+     *\r
+     * @return new instance of the Configuration.\r
+     */\r
+    public Object clone() {\r
+        try {\r
+            Configuration newObj = (Configuration) super.clone();\r
+            newObj._name = _name;\r
+            newObj._value = _value;\r
+            return (newObj);\r
+        } catch (CloneNotSupportedException e) {\r
+            System.out.println("Error Clone not Supported");\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Get the value of the Configuration.\r
+     *\r
+     * @return the value of the configuration.\r
+     */\r
+    public String getValue() {\r
+        return _value;\r
+    }\r
+\r
+    /**\r
+     * Get the name of this configuration.\r
+     *\r
+     * @return  the name\r
+     */\r
+    public String getName() {\r
+        return _name;\r
+    }\r
+\r
+    /**\r
+     * Return a string representation of the Configuration.\r
+     *\r
+     * @return string representation of the Configuration\r
+     */\r
+    public String toString() {\r
+        return "Configuration: " + _name + "/" + _value;\r
+    }\r
+\r
+    protected String _value = null;\r
+    protected String _name = null;\r
+\r
+}
\ No newline at end of file
diff --git a/dol/src/dol/datamodel/mapping/MapResource.java b/dol/src/dol/datamodel/mapping/MapResource.java
new file mode 100644 (file)
index 0000000..2aa9cf8
--- /dev/null
@@ -0,0 +1,116 @@
+package dol.datamodel.mapping;
+
+import dol.visitor.MapVisitor;
+
+/**
+ * This class is the basic class which abstracts a mapping resource.
+ */
+public class MapResource implements Cloneable {
+    /**
+     *  Constructor to create a mapping resource with a name.
+     */
+    public MapResource(String name) {
+        _name = name;
+        _basename = name;
+    }
+
+    /**
+     * Accept a Visitor
+     *
+     * @param x visitor object
+     */
+    public void accept(MapVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this mapping resource.
+     *
+     * @return new instance of the mapping resource.
+     */
+    public Object clone() {
+        try {
+            MapResource newObj = (MapResource) super.clone();
+            newObj.setName(_name);
+            newObj.setBasename(_basename);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the name of this mapping resource.
+     *
+     * @return name of the mapping resource
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this mapping resource.
+     *
+     * @param name name of the mapping resource
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the basename of this mapping resource.
+     *
+     * @return basename of the mapping resource
+     */
+    public String getBasename() {
+        return _basename;
+    }
+
+    /**
+     * Set the basename of this mapping resource.
+     *
+     * @param basename name of the mapping resource
+     */
+    public void setBasename(String basename) {
+        _basename = basename;
+    }
+
+    /**
+     * Get the hierarchical parent of this mapping resource.
+     *
+     * @return parent of this mapping resource
+     */
+     public MapResource getParentResource() {
+        return _parentResource;
+    }
+
+    /**
+     * Set the hierarchical parent of this mapping resource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(MapResource parentResource) {
+        _parentResource = parentResource;
+    }
+    
+    /**
+     * Return a string representation of the architectural resource.
+     *
+     * @return string representation of the architectural resource
+     */
+    public String toString() {
+        return "MapResource: " + _name;
+    }
+
+    /** name of the architectural resource */
+    protected String _name = null;
+
+    /** basename of the architectural resource, if no basename, store the name */
+    protected String _basename = null;
+
+    /**
+     * parent resource of this architectural resource in a hierarchical architecture network
+     */
+    protected MapResource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/mapping/Mapping.java b/dol/src/dol/datamodel/mapping/Mapping.java
new file mode 100644 (file)
index 0000000..c0123a5
--- /dev/null
@@ -0,0 +1,274 @@
+package dol.datamodel.mapping;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.MapVisitor;
+
+    
+/**
+ * This class defines a mapping.
+ */    
+public class Mapping extends MapResource
+{
+    public Mapping(String name)
+    {
+        super(name);
+        _compBindList = new Vector<ComputationBinding>();
+        _commBindList = new Vector<CommunicationBinding>();
+        _scheduleList = new Vector<Schedule>();
+        _variableList = new Vector<Variable>();
+        /**
+         * For some code generation back end, traversing via architecture
+         * model rather than mapping model is more convenient, since the 
+         * mapping model is a flattened view of the binding where one can
+         * not access all the binded processes from a processor. Therefore
+         * we annotate the binding information back to processor.
+         */
+        _processList = new Vector<Process>();
+        _processorList = new Vector<Processor>();
+    }
+
+    /**
+     * Accept a visitor
+     *
+     * @param x visitor object
+     */
+    public void accept(MapVisitor x) {
+        x.visitComponent(this);
+    }
+    
+    
+    /**
+     * Clone this Mapping.
+     *
+     * @return new instance of the Mapping
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        Mapping newObj = (Mapping) super.clone();
+        newObj.setCompBindList((Vector<ComputationBinding>)_compBindList.clone());
+        newObj.setCommBindList((Vector<CommunicationBinding>)_commBindList.clone());
+        newObj.setScheduleList((Vector<Schedule>)_scheduleList.clone());
+        newObj.setVarList((Vector<Variable>)_variableList.clone());
+        newObj.setProcessorList((Vector<Processor>)_processorList.clone());
+        newObj.setProcessList((Vector<Process>)_processList.clone());
+        return (newObj);
+    }
+    
+    /** Get the process network. */
+    public ProcessNetwork getPN() { return _pn; }
+    
+    /** Store a reference to the process network. */
+    public void setPN(ProcessNetwork pn) { _pn = pn; }
+    
+    /** Get the architecture */
+    public Architecture getArch() { return _arch; }
+    
+    /** Store a reference to the architecture. */
+    public void setArch(Architecture arch) { _arch = arch; }
+    
+    /**
+     * Get a list of computation bindings in this Mapping.
+     *
+     * @return the binding list
+     */
+    public Vector<ComputationBinding> getCompBindList() {
+        return _compBindList;
+    }
+
+    /**
+     * Get a list of processes in this Mapping.
+     *
+     * @return the process list
+     */
+    public Vector<Process> getProcessList() {
+        return _processList;
+    }
+
+    /**
+     * Return a process which has a specific name. Return null if
+     * process cannot be found.
+     *
+     * @param name the name of the process to search for.
+     * @return the process with the specific name or null if not found.
+     */    
+    public Process getProcess(String name)
+    {
+        for (Process process : _processList) {
+            if (process.getName().equals(name)) {
+                return process;
+            }
+        }
+        return null;
+    }
+    /**
+     * Set the computation binding list of this mapping.
+     *
+     * @param compBindList The new list
+     */
+    public void setCompBindList( Vector<ComputationBinding> compBindList ) {
+        _compBindList = compBindList;
+    }
+    
+    /**
+     * Get a list of communication bindings in this Mapping.
+     *
+     * @return the binding list
+     */
+    public Vector<CommunicationBinding> getCommBindList() {
+        return _commBindList;
+    }
+
+    /**
+     * Set the communication binding list of this mapping.
+     *
+     * @param commBindList The new list
+     */
+    public void setCommBindList( Vector<CommunicationBinding> commBindList ) {
+        _commBindList = commBindList;
+    }
+
+    /**
+     * Set the process list of this mapping.
+     *
+     * @param processList The new list
+     */
+    public void setProcessList( Vector<Process> processList ) {
+        _processList = processList;
+    }
+
+    /**
+     * Get the a list of processors in this Mapping.
+     *
+     * @return the processor list
+     */
+    public Vector<Processor> getProcessorList() {
+        return _processorList;
+    }
+
+    /**
+     * Set the processor list of this mapping.
+     *
+     * @param processorList The new list
+     */
+    public void setProcessorList( Vector<Processor> processorList ) {
+        _processorList = processorList;
+    }
+    
+    /**
+     * Return a processor which has a specific name. Return null if
+     * processor cannot be found.
+     *
+     * @param name the name of the processor to search for.
+     * @return the processor with the specific name or null if not found.
+     */    
+    public Processor getProcessor(String name)
+    {
+        Iterator<Processor> i;
+        i = _processorList.iterator();
+        while (i.hasNext()) {
+            Processor processor = i.next();
+            if (processor.getName().equals(name)) {
+                return processor;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the a list of schedules in this Mapping.
+     *
+     * @return the schedule list
+     */
+    public Vector<Schedule> getScheduleList() {
+        return _scheduleList;
+    }
+
+    /**
+     * Set the schedule list of this mapping.
+     *
+     * @param scheduleList The new list
+     */
+    public void setScheduleList( Vector<Schedule> scheduleList ) {
+        _scheduleList = scheduleList;
+    }
+    
+    /**
+     * Return the schedule for a resource that has a specific name. 
+     * Return null if schedule cannot be found.
+     *
+     * @param  name the name of the resource for which we are looking for the schedule.
+     * @return the schedule for the resource with the specified name.
+     */
+    public Schedule getScheduleByResource(String name) {
+        for(Schedule schedule : _scheduleList) {
+            if (schedule.getResource().getName().equals(name)) {
+                return schedule;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Return the communication binding for a channel that has a specific name. 
+     * Return null if binding cannot be found.
+     *
+     * @param  name the name of the channel for which we are looking for the binding.
+     * @return the binding for the channel with the specified name.
+     */
+    public CommunicationBinding getCommBindingByChannel(String name) {
+        for(CommunicationBinding b : _commBindList) {
+            if (b.getChannel().getName().equals(name)) {
+                return b;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Get the variable list of a Mapping.
+     *
+     * @return the variable list
+     */
+    public Vector<Variable> getVarList() {
+        return _variableList;
+    }
+
+    /**
+     * Set the variable list of a mapping.
+     *
+     * @param variableList The new list
+     */
+    public void setVarList( Vector<Variable> variableList ) {
+        _variableList = variableList;
+    }
+  
+    /** ProcessNetwork Reference **/
+    protected ProcessNetwork _pn = null;
+    
+    /** Architecture Reference **/
+    protected Architecture _arch = null;
+
+    /** List of processes in the mapping **/
+    protected Vector<Process> _processList = null;
+    
+    /** List of processors actually used in the mapping **/
+    protected Vector<Processor> _processorList = null;
+    
+    /** List of computations bindings in the mapping **/
+    protected Vector<ComputationBinding> _compBindList = null;
+    
+    /** List of communication bindings in the mapping **/
+    protected Vector<CommunicationBinding> _commBindList = null;
+    
+    /** List of schedules in the mapping **/
+    protected Vector<Schedule> _scheduleList = null;
+    
+    /** List of variables in the mapping **/
+    protected Vector<Variable> _variableList = null;
+}
diff --git a/dol/src/dol/datamodel/mapping/Schedule.java b/dol/src/dol/datamodel/mapping/Schedule.java
new file mode 100644 (file)
index 0000000..688afca
--- /dev/null
@@ -0,0 +1,160 @@
+/* $Id: Schedule.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.mapping;\r
+\r
+import java.util.Vector;\r
+\r
+import dol.datamodel.architecture.ArchiResource;\r
+import dol.visitor.MapVisitor;\r
+\r
+/**\r
+ * This class represents a schedule element in the mapping.\r
+ */\r
+public class Schedule extends MapResource {\r
+\r
+    /**\r
+     * Constructor to create a Schedule with a name.\r
+     */\r
+    public Schedule(String name) {\r
+        super(name);\r
+        _entryList = new Vector<ScheduleEntry>();\r
+        _cfgList = new Vector<Configuration>();\r
+    }\r
+\r
+    /**\r
+     * Accept a Visitor\r
+     *\r
+     * @param x visitor object\r
+     */\r
+    public void accept(MapVisitor x) {\r
+        x.visitComponent(this);\r
+    }\r
+\r
+    /**\r
+     * Clone this Schedule resource.\r
+     *\r
+     * @return new instance of the Schedule resource.\r
+     */\r
+    @SuppressWarnings("unchecked")\r
+    public Object clone() {\r
+        Schedule newObj = (Schedule) super.clone();\r
+        newObj.setResource(_resource);\r
+        newObj.setSchedPolicy(_policy);\r
+        newObj.setCfgList((Vector<Configuration>)_cfgList.clone() );\r
+        newObj.setEntryList((Vector<ScheduleEntry>)_entryList.clone());\r
+        return (newObj);\r
+    }\r
+\r
+    /** Set the resource, a HW channel or a processor from the architecture */\r
+    public void setResource(ArchiResource r) {\r
+        _resource = r;\r
+    }\r
+\r
+    /** Get the resource */\r
+    public ArchiResource getResource() {\r
+        return _resource;\r
+    }\r
+\r
+    /** Set the scheduling policy */\r
+    public void setSchedPolicy(SchedulingPolicy p) {\r
+        _policy = p;\r
+    }\r
+\r
+    /** Get the scheduling policy */\r
+    public SchedulingPolicy getSchedPolicy() {\r
+        return _policy;\r
+    }\r
+\r
+    /**\r
+     * Get the list of configurations of this schedule.\r
+     *\r
+     * @return list of configurations\r
+     */\r
+    public Vector<Configuration> getCfgList() {\r
+        return _cfgList;\r
+    }\r
+\r
+    /**\r
+     * Set the list of configurations of this schedule.\r
+     *\r
+     * @param cfgList configuration list\r
+     */\r
+    public void setCfgList(Vector<Configuration> cfgList) {\r
+        _cfgList = cfgList;\r
+    }\r
+\r
+    /**\r
+     * Set the list of scheduler table entries.\r
+     *\r
+     * @param entryList The new list\r
+     */\r
+    public void setEntryList(Vector<ScheduleEntry> entryList) {\r
+        _entryList = entryList;\r
+    }\r
+\r
+    /** Get the list of scheduler table entries */\r
+    public Vector<ScheduleEntry> getEntryList() {\r
+        return _entryList;\r
+    }\r
+\r
+    /**\r
+     * Return the scheduler table entry with its schedule configuration \r
+     * that has a specific name.\r
+     * Return null if the entry cannot be found.\r
+     *\r
+     * @param  name the name of the entry for which we are looking for.\r
+     * @return the entry with its schedule configuration with the specified name.\r
+     */\r
+    public ScheduleEntry getScheduleEntry(String name) {\r
+        for(ScheduleEntry entry : _entryList) {\r
+            if (entry.getName().equals(name)) {\r
+                return entry;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Return the value for the given configuration key. Return null\r
+     * when the key cannot be found.\r
+     *\r
+     * @param name name of the configuration key to search for\r
+     * @return value of the specified configuration key\r
+     */\r
+     public String getCfgValue(String name) {\r
+         for(Configuration c : _cfgList) {\r
+             if(c.getName().equals(name)) {\r
+                 return c.getValue();\r
+             }\r
+         }\r
+         return null;\r
+     }\r
+\r
+    /**\r
+     * Return a string representation of the Schedule.\r
+     *\r
+     * @return string representation of the Schedule\r
+     */\r
+    public String toString() {\r
+        return "Schedule: " + getName();\r
+    }\r
+\r
+    /** Resource that is scheduled */\r
+    ArchiResource _resource = null;\r
+\r
+    /** Scheduling policy */\r
+    SchedulingPolicy _policy = null;\r
+\r
+    /** List of the configurations of the Schedule */\r
+    protected Vector<Configuration> _cfgList = null;\r
+\r
+    /** List of scheduler table entries */\r
+    Vector<ScheduleEntry> _entryList = null;\r
+\r
+    /** Configuration key for the slots per cycle of a TDMA scheduler */\r
+    final public static String cfdTdmaSlotsPerCycle = "slotsonecycle";\r
+\r
+    /** Configuration key for the general slot length\r
+     * in nanoseconds of a TDMA scheduler */\r
+    final public static String cfgTdmaSlotLength = "slotlength";\r
+\r
+}\r
diff --git a/dol/src/dol/datamodel/mapping/ScheduleEntry.java b/dol/src/dol/datamodel/mapping/ScheduleEntry.java
new file mode 100644 (file)
index 0000000..2ee5331
--- /dev/null
@@ -0,0 +1,113 @@
+/* $Id: ScheduleEntry.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.mapping;\r
+\r
+import java.util.Vector;\r
+\r
+import dol.datamodel.pn.Schedulable;\r
+import dol.visitor.MapVisitor;\r
+\r
+/**\r
+ * This class represents an origin element in the mapping which refers\r
+ * to a PN process or a SW channel with a configuration element.\r
+ */\r
+public class ScheduleEntry extends MapResource {\r
+\r
+    /**\r
+     * Constructor to create a ScheduleProcess with a name.\r
+     */\r
+    public ScheduleEntry(String name) {\r
+        super(name);\r
+        _cfgList = new Vector<Configuration>();\r
+    }\r
+\r
+    /**\r
+     * Accept a Visitor\r
+     *\r
+     * @param x visitor object\r
+     */\r
+    public void accept(MapVisitor x) {\r
+        x.visitComponent(this);\r
+    }\r
+\r
+    /**\r
+     * Clone this ScheduleProcess resource.\r
+     *\r
+     * @return new instance of the ScheduleProcess resource.\r
+     */\r
+    @SuppressWarnings("unchecked")\r
+    public Object clone() {\r
+        ScheduleEntry newObj = (ScheduleEntry) super.clone();\r
+        newObj.setConsumer(_consumer);\r
+        newObj.setCfgList((Vector<Configuration>)_cfgList.clone());\r
+        return (newObj);\r
+    }\r
+\r
+    /**\r
+     * Get the list of configurations of this scheduled process.\r
+     *\r
+     * @return list of configurations\r
+     */\r
+    public Vector<Configuration> getCfgList() {\r
+        return _cfgList;\r
+    }\r
+\r
+    /**\r
+     * Set the list of configurations of this scheduled process.\r
+     *\r
+     * @param cfgList configuration list\r
+     */\r
+    public void setCfgList(Vector<Configuration> cfgList) {\r
+        _cfgList = cfgList;\r
+    }\r
+\r
+    /** Set the consumer */\r
+    public void setConsumer(Schedulable c) {\r
+        _consumer = c;\r
+    }\r
+\r
+    /** Get the consumer */\r
+    public Schedulable getConsumer() {\r
+        return _consumer;\r
+    }\r
+\r
+    /**\r
+     * Return the value for the given configuration key. Return null\r
+     * when the key cannot be found.\r
+     *\r
+     * @param name name of the configuration key to search for\r
+     * @return value of the specified configuration key\r
+     */\r
+     public String getCfgValue(String name) {\r
+         for(Configuration c : _cfgList) {\r
+             if(c.getName().equals(name)) {\r
+                 return c.getValue();\r
+             }\r
+         }\r
+         return null;\r
+     }\r
+\r
+    /**\r
+     * Return a string representation of the ScheduleProcess.\r
+     *\r
+     * @return string representation of the ScheduleProcess\r
+     */\r
+    public String toString() {\r
+        return "ScheduleProcess: " + getName();\r
+    }\r
+\r
+    /** Consumer: PN process or SW channel */\r
+    private Schedulable _consumer = null;\r
+\r
+    /** list of the configurations of the ScheduleProcess */\r
+    protected Vector<Configuration> _cfgList = null;\r
+\r
+    /** Configuration key for the priority of a task in a fixed priority scheduler */\r
+    final public static String cfgFpPriority = "priority";\r
+\r
+    /** Configuration key for the index of the TDMA slot of a process */\r
+    final public static String cfgTdmaStartSlot = "startslot";\r
+\r
+    /** Configuration key for the number of TDMA slots for a process */\r
+    final public static String cfgTdmaNumberOfSlots = "numberofslots";\r
+\r
+}\r
diff --git a/dol/src/dol/datamodel/mapping/SchedulingPolicy.java b/dol/src/dol/datamodel/mapping/SchedulingPolicy.java
new file mode 100644 (file)
index 0000000..6589174
--- /dev/null
@@ -0,0 +1,43 @@
+/* $Id: SchedulingPolicy.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.mapping;\r
+\r
+/**\r
+ * This class defines the supported scheduling policies.\r
+ */\r
+public enum SchedulingPolicy {\r
+\r
+    STATIC, FIXEDPRIORITY, FIFO, TDMA, ROUNDROBIN;\r
+\r
+    private static final String staticVal = "static";\r
+    private static final String fixedPriorityVal = "fixedpriority";\r
+    private static final String fifoVal = "fifo";\r
+    private static final String tdmaVal = "tdma";\r
+    private static final String roundRobinVal = "roundrobin";\r
+\r
+    static public SchedulingPolicy fromString(String s) {\r
+        if(s.equals(staticVal)) {\r
+            return SchedulingPolicy.STATIC;\r
+        } else if(s.equals(fixedPriorityVal)) {\r
+            return SchedulingPolicy.FIXEDPRIORITY;\r
+        } else if(s.equals(fifoVal)) {\r
+            return SchedulingPolicy.FIFO;\r
+        } else if(s.equals(tdmaVal)) {\r
+            return SchedulingPolicy.TDMA;\r
+        }\r
+        return SchedulingPolicy.ROUNDROBIN;\r
+    }\r
+\r
+    static public String toString(SchedulingPolicy t) {\r
+        if(t == SchedulingPolicy.STATIC) {\r
+            return staticVal;\r
+        } else if(t == SchedulingPolicy.FIXEDPRIORITY) {\r
+            return fixedPriorityVal;\r
+        } else if(t == SchedulingPolicy.FIFO) {\r
+            return fifoVal;\r
+        } else if(t == SchedulingPolicy.TDMA) {\r
+            return tdmaVal;\r
+        }\r
+        return roundRobinVal;\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/dol/src/dol/datamodel/mapping/Variable.java b/dol/src/dol/datamodel/mapping/Variable.java
new file mode 100644 (file)
index 0000000..a097b87
--- /dev/null
@@ -0,0 +1,108 @@
+package dol.datamodel.mapping;
+
+import dol.visitor.MapVisitor;
+
+/**
+ * This class represents a global variable in the mapping XML.
+ */
+public class Variable implements Cloneable {
+
+    /**
+     * Constructor to create a Variable.
+     */
+    public Variable(String name) {
+        _name = name;
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(MapVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Variable.
+     *
+     * @return new instance of the Variable.
+     */
+    public Object clone() {
+        try {
+            Variable newObj = (Variable) super.clone();
+            newObj.setName(_name);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the Variable.
+     *
+     * @return the value of the variable
+     */
+    public int getValue() {
+        return _value;
+    }
+
+    /**
+     * Set the value of the Variable.
+     *
+     * @param value the value of the variable
+     */
+    public void setValue(int value) {
+        _value = value;
+    }
+
+    /**
+     * Get the name of this SourceCode.
+     *
+     * @return  the name
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this SourceCode.
+     *
+     * @param name name of the SourceCode
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the parent ArchiResource.
+     *
+     * @return parent ArchiResource
+     */
+     public MapResource getParentResource() {
+        return _parentResource;
+    }
+
+    /**
+     * Set the parent ArchiResource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(MapResource parentResource) {
+        _parentResource = parentResource;
+    }
+
+    /**
+     * Return a string representation of the Variable.
+     *
+     * @return string representation of the Variable
+     */
+    public String toString() {
+        return "Variable: " + getName();
+    }
+
+    protected int _value;
+    protected String _name = null;
+    protected MapResource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/mapping/package.html b/dol/src/dol/datamodel/mapping/package.html
new file mode 100644 (file)
index 0000000..38cfb44
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Internal data model for the mapping representation.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/datamodel/package.html b/dol/src/dol/datamodel/package.html
new file mode 100644 (file)
index 0000000..398bc27
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Internal data model.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/datamodel/pn/Channel.java b/dol/src/dol/datamodel/pn/Channel.java
new file mode 100644 (file)
index 0000000..2aa0706
--- /dev/null
@@ -0,0 +1,129 @@
+/* $Id: Channel.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is the basic channel in a process network.
+ * The channel has a name and a list of ports connected by this channel.
+ * In this model, a channel has only two ports: one input port and one
+ * output port.
+ */
+public class Channel extends Resource implements Schedulable {
+
+    /**
+     *  Constructor to create a channel with a name and an empty
+     *  portList.
+     */
+    public Channel(String name) {
+        super(name);
+    }
+
+    /**
+     * Accept a visitor.
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this channel.
+     *
+     * @return new instance of the channel
+     */
+    public Object clone() {
+        Channel newObj = (Channel) super.clone();
+        return (newObj);
+    }
+
+    /**
+     * Get the size of this channel.
+     *
+     * @return size of the channel
+     */
+    public int getSize() {
+        return _size;
+    }
+
+    /**
+     * Set the size of this channel.
+     *
+     * @param size new size value
+     */
+    public void setSize(int size) {
+        _size = size;
+    }
+
+    /**
+     * Get the token  size of this channel.
+     *
+     * @return token size of the channel
+     */
+    public int getTokenSize() {
+        return _tokenSize;
+    }
+
+    /**
+     * Set the token size of this channel.
+     *
+     * @param size new token size
+     */
+    public void setTokenSize(int size) {
+        _tokenSize = size;
+    }
+
+    /**
+     * Return a string representation of the channel.
+     *
+     * @return string representation of the channel
+     */
+    public String toString() {
+        return "Channel: " + getName();
+    }
+
+    /**
+     * Get the process where this channel starts from.
+     *
+     * @return origin process
+     */
+    public Process getOrigin() {
+        return _origin;
+    }
+
+    /**
+     * Set the process where this channel starts from.
+     *
+     * @param origin origin process
+     */
+    public void setOrigin(Process origin) {
+        _origin = origin;
+    }
+
+    /**
+     * Get the process where this channel ends.
+     *
+     * @return target process
+     */
+    public Process getTarget() {
+        return _target;
+    }
+
+    /**
+     * Set the process where this channel ends.
+     *
+     * @param target target process
+     */
+    public void setTarget(Process target) {
+        _target = target;
+    }
+
+    protected Process _origin;
+    protected Process _target;
+
+    /** size of the channel */
+    protected int _size;
+
+    /** token size fo the channel */
+    protected int _tokenSize;
+}
diff --git a/dol/src/dol/datamodel/pn/Configuration.java b/dol/src/dol/datamodel/pn/Configuration.java
new file mode 100644 (file)
index 0000000..153173d
--- /dev/null
@@ -0,0 +1,112 @@
+/* $Id: Configuration.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class represents a name-value pair of a configuration tag in XML.
+ */
+public class Configuration {
+
+    /**
+     * Constructor to create a Configuration.
+     */
+    public Configuration(String name) {
+        _name = name;
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Configuration.
+     *
+     * @return new instance of the Configuration.
+     */
+    public Object clone() {
+        try {
+            Configuration newObj = (Configuration) super.clone();
+            newObj.setName(_name);
+            newObj.setValue(_value);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the Configuration.
+     *
+     * @return the value of the configuration.
+     */
+    public String getValue() {
+        return _value;
+    }
+
+    /**
+     * Set the value of the Configuration.
+     *
+     * @param value the value of the configuration.
+     */
+    public void setValue(String value) {
+        _value = value;
+    }
+
+    /**
+     * Get the name of this configuration.
+     *
+     * @return  the name
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this configuration.
+     *
+     * @param name name of the configuration
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the hierarchical parent of this resource.
+     *
+     * @return parent of this resource
+     */
+     public Resource getParentResource() {
+        return _parentResource;
+    }
+
+    
+    /**
+     * Set the hierarchical parent of this resource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(Resource parentResource) {
+        _parentResource = parentResource;
+    }
+
+    
+    /**
+     * Return a string representation of the Configuration.
+     *
+     * @return string representation of the Configuration
+     */
+    public String toString() {
+        return "Configuration: " + getName();
+    }
+
+    protected String _value = null;
+    protected String _name = null;
+    protected Resource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/pn/Connection.java b/dol/src/dol/datamodel/pn/Connection.java
new file mode 100644 (file)
index 0000000..3830f96
--- /dev/null
@@ -0,0 +1,130 @@
+/* $Id: Connection.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class defines a connection.
+ * A connection contains one origin and one target resource and the
+ * according ports.
+ */
+public class Connection extends Resource {
+
+    /**
+     * Constructor to create a Connection with a name,
+     * empty process list and empty channel list.
+     */
+    public Connection(String name) {
+      super(name);
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Connection.
+     *
+     * @return  a new instance of the Connection.
+     */
+    public Object clone() {
+        Connection newObj = (Connection) super.clone();
+        newObj.setOrigin(_origin);
+        newObj.setOriginPort(_originPort);
+        newObj.setTarget(_target);
+        newObj.setTargetPort(_targetPort);
+        return (newObj);
+    }
+
+    /**
+     * Return a string representation of the connection.
+     *
+     * @return string representation of the connection
+     */
+    public String toString() {
+        return "Connection: " + getName();
+    }
+
+
+    /**
+     * Get the origin resource of his connection.
+     *
+     * @return origin resource
+     */
+    public Resource getOrigin() {
+        return _origin;
+    }
+
+    /**
+     * Set the origin resource of this connection.
+     *
+     * @param origin origin resource
+     */
+    public void setOrigin(Resource origin) {
+        _origin = origin;
+    }
+
+    /**
+     * Get the origin port of this connection.
+     *
+     * @return origin port
+     */
+    public Port getOriginPort() {
+        return _originPort;
+    }
+
+    /**
+     * Set the origin port of this connection.
+     *
+     * @param port origin port
+     */
+    public void setOriginPort(Port port) {
+        _originPort = port;
+    }
+
+    /**
+     * Get the target resource of his connection.
+     *
+     * @return target resource
+     */
+    public Resource getTarget() {
+        return _target;
+    }
+
+    /**
+     * Set the target resource of this connection.
+     *
+     * @param target target resource
+     */
+    public void setTarget(Resource target) {
+        _target = target;
+    }
+
+    /**
+     * Get the target port of this connection.
+     *
+     * @return target port
+     */
+    public Port getTargetPort() {
+        return _targetPort;
+    }
+
+    /**
+     * Set the target port of this connection.
+     *
+     * @param port target port
+     */
+    public void setTargetPort(Port port) {
+        _targetPort = port;
+    }
+
+    protected Resource _origin;
+    protected Port _originPort;
+    protected Resource _target;
+    protected Port _targetPort;
+}
diff --git a/dol/src/dol/datamodel/pn/Port.java b/dol/src/dol/datamodel/pn/Port.java
new file mode 100644 (file)
index 0000000..e82e46e
--- /dev/null
@@ -0,0 +1,189 @@
+/* $Id: Port.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class represents a port of a process or channel.
+ */
+public class Port {
+
+    /**
+     *  Constructor to create a Port with a name.
+     */
+    public Port(String name) {
+        _name = name;
+        _isInPort = false;
+        _isOutPort = false;
+    }
+
+    public Port(String name, boolean type) {
+        _name = name;
+        _isInPort = (type == INPORT);
+        _isOutPort = (type == OUTPORT);
+    }
+
+
+    /**
+     * Accept a visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Port
+     *
+     * @return new instance of the Port
+     */
+    public Object clone() {
+        try {
+            Port newObj = (Port) super.clone();
+            newObj.setName(_name);
+            newObj.setBasename(_basename);
+            newObj.setPeerPort(_peerPort);
+            newObj.setPeerResource(_peerResource);
+            newObj.setResource(_resource );
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Check whether this port is an inport.
+     *
+     * @return true if this port is an inport, otherwise false
+     */
+    public boolean isInPort() {
+        return _isInPort;
+    }
+
+    /**
+     * Check whether this port is an outport.
+     *
+     * @return true if this port is an outport, otherwise false
+     */
+    public boolean isOutPort() {
+        return _isOutPort;
+    }
+
+    /**
+     * Get the name of this port.
+     *
+     * @return name of the port
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this port.
+     *
+     * @param name name of the port
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the range of this port.
+     *
+     * @return range of the port
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Set the range of this port.
+     *
+     * @param range range of the port
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    /**
+     * Get the resource of this port.
+     *
+     * @return the resource
+     */
+    public Resource getResource() {
+        return _resource;
+    }
+
+    /**
+     * Set the process of this port.
+     *
+     * @param  resource The new resource
+     */
+    public void setResource(Resource resource) {
+        _resource = resource;
+    }
+
+    public void setBasename(String basename) { _basename = basename; }
+    public String getBasename() { return _basename; }
+
+    // for channel port
+    public void setPeerPort(Port peer) { _peerPort = peer; }
+    public Port getPeerPort() { return _peerPort; }
+
+    // for process port: peer channel name
+    public void setPeerResource(Resource n) { _peerResource = n; }
+    public Resource getPeerResource() { return _peerResource; }
+
+    public String getType() {
+        if (_isInPort) return  "input";
+        else if (_isOutPort) return "output";
+        else return "";
+    }
+
+    /**
+     * Return a string representation of the port.
+     *
+     * @return string representation of the port
+     */
+    public String toString() {
+        return "Port: " + _name;
+    }
+
+    /** constant for inport for usage in the constructor **/
+    public static final boolean INPORT = true;
+
+    /** constant for outport for usage in the constructor **/
+    public static final boolean OUTPORT = false;
+
+    /** defines whether this port is an inport **/
+    protected boolean _isInPort = false;
+
+    /** defines whether this port is an outport **/
+    protected boolean _isOutPort = false;
+
+    /** name of the port */
+    protected String _name = null;
+
+    /** basename of the resource, if no basename, store the name */
+    protected String _basename = null;
+
+    /** resource (process or channel) this port belongs to */
+    protected Resource _resource = null;
+
+    /** resource which peerPort belongs to */
+    protected Resource _peerResource = null;
+
+    /** connected peer port name */
+    protected Port _peerPort = null;
+
+    /** peer channel name */
+    protected String _channelName = null;
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of ports.
+     */
+    protected String _range = "";
+}
diff --git a/dol/src/dol/datamodel/pn/Process.java b/dol/src/dol/datamodel/pn/Process.java
new file mode 100644 (file)
index 0000000..1b825b4
--- /dev/null
@@ -0,0 +1,150 @@
+/* $Id: Process.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Processor;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class represents a process.
+ */
+public class Process extends Resource implements Schedulable {
+
+    /**
+     * Constructor to create a Process with a name and an empty
+     * portList.
+     */
+    public Process(String name) {
+        super(name);
+    }
+
+    /**
+     * Accept a Visitor
+     * @param x A Visitor Object.
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Process
+     *
+     * @return  a new instance of the Process.
+     */
+    public Object clone() {
+        Process newObj = (Process) super.clone();
+        newObj.setRange(_range);
+        newObj.setProcessor(_processor);
+        return (newObj);
+    }
+
+    /**
+     * Get the range of this process.
+     *
+     * @return range
+     */
+    public String getRange() {
+        return _range;
+    }
+
+    /**
+     * Get the iterator indices of this process.
+     *
+     * @return range
+     */
+    public Vector<Integer> getIteratorIndices() {
+        Vector<Integer> indices = new Vector<Integer>();
+        StringTokenizer tokenizer =
+            new StringTokenizer(_name.replaceAll(_basename, ""), "_");
+        while (tokenizer.hasMoreTokens()) {
+            indices.add(Integer.valueOf(tokenizer.nextToken()));
+        }
+        return indices;
+    }
+
+    /**
+     * Set the range of this process.
+     *
+     * @param range new range value
+     */
+    public void setRange(String range) {
+        _range= range;
+    }
+
+    public boolean hasInPorts() {
+        for (Port port : getPortList()) {
+            if (port.isInPort())
+                return true;
+        }
+        return false;
+    }
+
+    public boolean hasOutPorts() {
+        for (Port port : getPortList()) {
+            if (port.isOutPort())
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get number of inport
+     */
+    public int getNumOfInports() {
+        int i = 0;
+        for (Port port : getPortList())
+            if (port.isInPort())
+                i++;
+        return i;
+    }
+
+    /**
+     * Get number of outport
+     */
+    public int getNumOfOutports() {
+        int i = 0;
+        for (Port port : getPortList())
+            if (port.isOutPort())
+                i++;
+        return i;
+    }
+
+    /**
+     * Set the processor this process runs on.
+     * @param processor
+     */
+    public void setProcessor(Processor processor)
+    {
+        _processor = processor;
+    }
+    
+    /**
+     * Get the processor this process runs on.
+     */
+    public Processor getProcessor()
+    {
+        return _processor;
+    }
+    
+    /**
+     * Return a description of the process.
+     *
+     * @return a description of the process.
+     */
+    public String toString() {
+        return "Process: " + getName();
+    }
+
+    /**
+     * Range of the iterator when the instance belongs to an iterated
+     * series of processes.
+     */
+    protected String _range = "";
+    
+    /**
+     * Processor that executes this process.
+     */
+    protected Processor _processor = null;
+}
diff --git a/dol/src/dol/datamodel/pn/ProcessNetwork.java b/dol/src/dol/datamodel/pn/ProcessNetwork.java
new file mode 100644 (file)
index 0000000..b41facc
--- /dev/null
@@ -0,0 +1,189 @@
+/* $Id: ProcessNetwork.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import java.util.Vector;
+
+import dol.visitor.PNVisitor;
+
+
+/**
+ * This class defines a process network.
+ */
+public class ProcessNetwork extends Resource {
+
+    /**
+     *  Constructor to create a process network with a name,
+     *  empty process list and empty channel list.
+     */
+    public ProcessNetwork(String name) {
+        super(name);
+        _processList = new Vector<Process>();
+        _channelList = new Vector<Channel>();
+        _varList = new Vector<Variable>();
+        _connectionList = new Vector<Connection>();
+    }
+
+    /**
+     * Accept a visitor
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this ProcessNetwork.
+     *
+     * @return new instance of the ProcessNetwork
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        ProcessNetwork newObj = (ProcessNetwork) super.clone();
+        newObj.setProcessList((Vector<Process>)_processList.clone());
+        newObj.setChannelList((Vector<Channel>)_channelList.clone());
+        newObj.setVarList((Vector<Variable>)_varList.clone());
+        newObj.setConnectionList((Vector<Connection>)_connectionList.clone());
+        return (newObj);
+    }
+
+    /**
+     * Get the process list of a ProcessNetwork.
+     *
+     * @return  the process list
+     */
+    public Vector<Process> getProcessList() {
+        return _processList;
+    }
+
+    /**
+     * Get the process basenames.
+     * 
+     * @return process basenames
+     */
+    public Vector<String> getProcessBasenames() {
+        Vector<String> basenames = new Vector<String>();
+        for (Process p : _processList) {
+            String basename = p.getBasename();
+            if (!basenames.contains(basename)) {
+                basenames.add(basename);
+            }
+        }
+        return basenames;
+    }
+    
+    /**
+     * Set the process list of a ProcessNetwork.
+     *
+     * @param  processList The new list
+     */
+    public void setProcessList(Vector<Process> processList) {
+        _processList = processList;
+    }
+
+    /**
+     * Get the channel list of a ProcessNetwork
+     *
+     * @return  the channel list
+     */
+    public Vector<Channel> getChannelList() {
+        return _channelList;
+    }
+
+    /**
+     * Set the channel list of a ProcessNetwork
+     *
+     * @param  channelList The new list
+     */
+    public void setChannelList(Vector<Channel> channelList) {
+        _channelList = channelList;
+    }
+
+    public Vector<Variable> getVarList() { return _varList; }
+    public void setVarList(Vector<Variable> list) { _varList = list; }
+
+    public void setConnectionList(Vector<Connection> list) { _connectionList = list; }
+    public Vector<Connection> getConnectionList() { return _connectionList; }
+
+
+    /**
+     * Return a description of the ProcessNetwork.
+     *
+     * @return  a description of the ProcessNetwork.
+     */
+    public String toString() {
+        return "ProcessNetwork: " + getName();
+    }
+
+    /**
+     * Return a process which has a specific name. Return null if
+     * process cannot be found.
+     *
+     * @param  name the name of the process to search for.
+     * @return  the process with the specific name.
+     */
+    public Process getProcess(String name) {
+        for (Process process : _processList) {
+            if (process.getName().equals(name)) {
+                return process;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return a channel which has a specific name. Return null if
+     * not found.
+     *
+     * @param  name the name of the channel to search for.
+     * @return  the channel with the specific name.
+     */
+    public Channel getChannel(String name) {
+        for (Channel c : _channelList) {
+            if (c.getName().equals(name)) {
+                return c;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * In this version, we only deal with the flattened process network.
+     * Connection infomation is filled to each process and channel for fast
+     * iteration.
+     */
+    public void fillPortPeerInfo() throws Exception {
+        for (Connection c : getConnectionList()) {
+            Port originPort = c.getOriginPort();
+            Port targetPort = c.getTargetPort();
+            originPort.setPeerResource(c.getTarget());
+            originPort.setPeerPort(targetPort);
+            targetPort.setPeerResource(c.getOrigin());
+            targetPort.setPeerPort(originPort);
+        }
+
+        //for each sw channel, determine which processes it connects
+        for (Connection c : getConnectionList()) {
+            if (c.getOrigin() instanceof Process) {
+                Channel channel = (Channel)c.getTarget();
+                channel.setOrigin((Process)c.getOrigin());
+            }
+            else if (c.getOrigin() instanceof Channel) {
+                Channel channel = (Channel)c.getOrigin();
+                channel.setTarget((Process)c.getTarget());
+            }
+        }
+    }
+
+    /** list of the processes in the ProcessNetwork. */
+    protected Vector<Process> _processList = null;
+
+    /** list of the channels in the ProcessNetwork. */
+    protected Vector<Channel> _channelList = null;
+
+    /** list of variables in the ProcessNetwork */
+    protected Vector<Variable> _varList = null;
+
+    /** list of connections in the ProcessNetwork */
+    protected Vector<Connection> _connectionList = null;
+}
diff --git a/dol/src/dol/datamodel/pn/ProfilingConfiguration.java b/dol/src/dol/datamodel/pn/ProfilingConfiguration.java
new file mode 100644 (file)
index 0000000..a7c4c73
--- /dev/null
@@ -0,0 +1,34 @@
+/* $Id: ProfilingConfiguration.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.pn;\r
+\r
+import dol.visitor.PNVisitor;\r
+\r
+public class ProfilingConfiguration extends Configuration {\r
+\r
+    /**\r
+     * Constructor to create a ProfilerConfiguration.\r
+     */\r
+    public ProfilingConfiguration(String name) {\r
+        super(name);\r
+    }\r
+\r
+    /**\r
+     * Accept a Visitor.\r
+     *\r
+     * @param x visitor object\r
+     */\r
+    public void accept(PNVisitor x) {\r
+        x.visitComponent(this);\r
+    }\r
+\r
+    /**\r
+     * Clone this Configuration.\r
+     *\r
+     * @return new instance of the Configuration.\r
+     */\r
+    public Object clone() {\r
+        ProfilingConfiguration newObj = (ProfilingConfiguration) super.clone();\r
+        return newObj;\r
+    }\r
+\r
+}\r
diff --git a/dol/src/dol/datamodel/pn/Resource.java b/dol/src/dol/datamodel/pn/Resource.java
new file mode 100644 (file)
index 0000000..d212bbe
--- /dev/null
@@ -0,0 +1,269 @@
+/* $Id: Resource.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import java.util.Vector;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is the basic class which abstracts a resource of a generic
+ * process network. The resource has a name and a list of ports.
+ */
+public class Resource {
+
+    /**
+     *  Constructor to create a resource with a name and an empty
+     *  portList.
+     */
+    public Resource(String name) {
+        _name = name;
+        _basename = name;
+        _portList = new Vector<Port>();
+        _srcList = new Vector<SourceCode>();
+        _cfgList = new Vector<Configuration>();
+        _profilingList = new Vector<ProfilingConfiguration>();
+    }
+
+    /**
+     * Accept a Visitor
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this resource.
+     *
+     * @return new instance of the resource.
+     */
+    @SuppressWarnings("unchecked")
+    public Object clone() {
+        try {
+            Resource newObj = (Resource) super.clone();
+            newObj.setName(_name);
+            newObj.setType(_type);
+            newObj.setBasename(_basename);
+            newObj.setPortList((Vector)_portList.clone() );
+            newObj.setSrcList((Vector)_srcList.clone() );
+            newObj.setCfgList((Vector)_cfgList.clone() );
+            newObj.setProfilingList((Vector)_profilingList.clone() );
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    public String getBasename() {
+        return _basename;
+    }
+
+    public void setBasename(String basename) {
+        _basename = basename;
+    }
+
+    /**
+     * Get the name of this resource.
+     *
+     * @return name of the resource
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this resource.
+     *
+     * @param name name of the resource
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the type of this resource.
+     *
+     * @return type of the resource
+     */
+    public String getType() {
+        return _type;
+    }
+
+    /**
+     * Set the type of this resource.
+     *
+     * @param type type of the resource
+     */
+    public void setType(String type) {
+        _type = type;
+    }
+
+    /**
+     * Get the list of source codes of this resource.
+     *
+     * @return list of source codes
+     */
+    public Vector<SourceCode> getSrcList() {
+        return _srcList;
+    }
+
+    /**
+     * Get the list of ports of this resource.
+     *
+     * @return list of ports
+     */
+    public Vector<Port> getPortList() {
+        return _portList;
+    }
+
+    /**
+     * Set the list of ports of this resource.
+     *
+     * @param portList port list
+     */
+    public void setPortList(Vector<Port> portList) {
+        _portList = portList;
+    }
+    
+    /**
+     * Get the list of configurations of this resource.
+     *
+     * @return list of configurations
+     */
+    public Vector<Configuration> getCfgList() {
+        return _cfgList;
+    }
+
+    /**
+     * Set the list of configurations of this resource.
+     *
+     * @param cfgList configuration list
+     */
+    public void setCfgList(Vector<Configuration> cfgList) {
+        _cfgList = cfgList;
+    }
+
+    /**
+     * Get the list of profiling info of this resource.
+     *
+     * @return list of profiling info
+     */
+    public Vector<ProfilingConfiguration> getProfilingList() {
+        return _profilingList;
+    }
+
+    /**
+     * Set the list of profiling info of this resource.
+     *
+     * @param cfgList profiling info list
+     */
+    public void setProfilingList(Vector<ProfilingConfiguration> cfgList) {
+        _profilingList = cfgList;
+    }
+
+    /**
+     * Return a profiling which has a specific name. Return null when it
+     * cannot be found.
+     *
+     * @param name name of the profiling to search for
+     * @return profiling with the specified name
+     */
+    public ProfilingConfiguration getProfilingCfg(String name) {
+        for (ProfilingConfiguration cfg : _profilingList) {
+            if (cfg.getName().equals(name)) {
+                return cfg;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set the list of source code of this resource.
+     *
+     * @param srcList port list
+     */
+    public void setSrcList(Vector<SourceCode> srcList) {
+        _srcList = srcList;
+    }
+
+    /**
+     * Get the hierarchical parent of this resource.
+     *
+     * @return parent of this resource
+     */
+     public Resource getParentResource() {
+        return _parentResource;
+    }
+
+    /**
+     * Set the hierarchical parent of this resource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(Resource parentResource) {
+        _parentResource = parentResource;
+    }
+
+    /**
+     * Return a string representation of the resource.
+     *
+     * @return string representation of the resource
+     */
+    public String toString() {
+        return "Resource: " + _name;
+    }
+
+    /**
+     * Return a port which has a specific name. Return null when port
+     * cannot be found.
+     *
+     * @param name name of the port to search for
+     * @return port with the specified name
+     */
+    public Port getPort(String name) {
+        for (Port port : _portList) {
+            if (port.getName().equals(name)) {
+                return port;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return a port which has a specific name. Return null when port
+     * cannot be found.
+     *
+     * @return port with the specified name
+     */
+    public Port getFirstPort() {
+        return (Port) _portList.firstElement();
+    }
+
+    /** name of the resource */
+    protected String _name = null;
+
+    /** type of the resource */
+    protected String _type = null;
+
+    /** basename of the resource, if no basename, store the name */
+    protected String _basename = null;
+
+    /** list of the ports of the Resource */
+    protected Vector<Port> _portList = null;
+
+    /** list of the source codes of the Resource */
+    protected Vector<SourceCode> _srcList = null;
+
+    /** list of the configurations of the Resource */
+    protected Vector<Configuration> _cfgList = null;
+
+    /** list of the profiling info of the Resource */
+    protected Vector<ProfilingConfiguration> _profilingList = null;
+
+    /**
+     * parent resource of this resource in a hierarchical process network
+     */
+    protected Resource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/pn/Schedulable.java b/dol/src/dol/datamodel/pn/Schedulable.java
new file mode 100644 (file)
index 0000000..4e5336c
--- /dev/null
@@ -0,0 +1,10 @@
+/* $Id: Schedulable.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.datamodel.pn;\r
+\r
+/**\r
+ * Marker interface for all entities that can be added\r
+ * to a scheduler table.\r
+ */\r
+public interface Schedulable {\r
+\r
+}\r
diff --git a/dol/src/dol/datamodel/pn/SourceCode.java b/dol/src/dol/datamodel/pn/SourceCode.java
new file mode 100644 (file)
index 0000000..26f09e1
--- /dev/null
@@ -0,0 +1,131 @@
+/* $Id: SourceCode.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is the basic source code of a process.
+ */
+public class SourceCode {
+
+    /**
+     *  Constructor to create a SourceCode with a name.
+     */
+    public SourceCode(String name) {
+        _name = name;
+    }
+
+    /**
+     * Accept a visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this SourceCode.
+     *
+     * @return new instance of the SourceCode.
+     */
+    public Object clone() {
+        try {
+            SourceCode newObj = (SourceCode) super.clone();
+            newObj.setName(_name);
+            newObj.setType(_type);
+            newObj.setLocality(_locality);
+            newObj.setProcess( (Process) _process.clone() );
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the name of this SourceCode.
+     *
+     * @return  the name
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this SourceCode.
+     *
+     * @param name name of the SourceCode
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the process of this SourceCode.
+     *
+     * @return process to which this SourceCode belongs
+     */
+    public Process getProcess() {
+        return _process;
+    }
+
+    /**
+     * Set the proces of this SourceCode.
+     *
+     * @param process process to which this SourceCode belongs
+     */
+    public void setProcess(Process process) {
+        _process = process;
+    }
+
+    /**
+     * Get the locality of this SourceCode.
+     *
+     * @return locality of the SourceCode
+     */
+    public String getLocality() {
+        return _locality;
+    }
+
+    /**
+     * Set the locality of this SourceCode.
+     *
+     * @param locality locality of the SourceCode
+     */
+    public void setLocality(String locality) {
+        _locality = locality;
+    }
+
+    /**
+     * Get the type of this SourceCode.
+     *
+     * @return type of the SourceCode
+     */
+    public String getType() {
+        return _type;
+    }
+
+    /**
+     * Set the type of this SourceCode.
+     *
+     * @param  type The new type
+     */
+    public void setType(String type) {
+        _type = type;
+    }
+
+    /**
+     * Return a string representation of the SourceCode.
+     *
+     * @return string representation of the SourceCode
+     */
+    public String toString() {
+        return "SourceCode: " + _name;
+    }
+
+    protected String _name = null;
+    protected Process _process = null;
+    protected String _type = null;
+    protected String _locality = null;
+}
diff --git a/dol/src/dol/datamodel/pn/Variable.java b/dol/src/dol/datamodel/pn/Variable.java
new file mode 100644 (file)
index 0000000..623a25c
--- /dev/null
@@ -0,0 +1,109 @@
+/* $Id: Variable.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.datamodel.pn;
+
+import dol.visitor.PNVisitor;
+
+/**
+ * This class represents a global variable in XML.
+ */
+public class Variable {
+
+    /**
+     * Constructor to create a Variable.
+     */
+    public Variable(String name) {
+        _name = name;
+    }
+
+    /**
+     * Accept a Visitor.
+     *
+     * @param x visitor object
+     */
+    public void accept(PNVisitor x) {
+        x.visitComponent(this);
+    }
+
+    /**
+     * Clone this Variable.
+     *
+     * @return new instance of the Variable.
+     */
+    public Object clone() {
+        try {
+            Variable newObj = (Variable) super.clone();
+            newObj.setName(_name);
+            return (newObj);
+        } catch (CloneNotSupportedException e) {
+            System.out.println("Error Clone not Supported");
+        }
+        return null;
+    }
+
+    /**
+     * Get the value of the Variable.
+     *
+     * @return the value of the variable
+     */
+    public int getValue() {
+        return _value;
+    }
+
+    /**
+     * Set the value of the Variable.
+     *
+     * @param value the value of the variable
+     */
+    public void setValue(int value) {
+        _value = value;
+    }
+
+    /**
+     * Get the name of this SourceCode.
+     *
+     * @return  the name
+     */
+    public String getName() {
+        return _name;
+    }
+
+    /**
+     * Set the name of this SourceCode.
+     *
+     * @param name name of the SourceCode
+     */
+    public void setName(String name) {
+        _name = name;
+    }
+
+    /**
+     * Get the hierarchical parent of this resource.
+     *
+     * @return parent of this resource
+     */
+     public Resource getParentResource() {
+        return _parentResource;
+    }
+
+    /**
+     * Set the hierarchical parent of this resource.
+     *
+     * @param parentResource new parent
+     */
+    public void setParentResource(Resource parentResource) {
+        _parentResource = parentResource;
+    }
+
+    /**
+     * Return a string representation of the Variable.
+     *
+     * @return string representation of the Variable
+     */
+    public String toString() {
+        return "Variable: " + getName();
+    }
+
+    protected int _value;
+    protected String _name = null;
+    protected Resource _parentResource = null;
+}
diff --git a/dol/src/dol/datamodel/pn/package.html b/dol/src/dol/datamodel/pn/package.html
new file mode 100644 (file)
index 0000000..1151360
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Internal data model for the process network representation.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/helper/flattener/ArchFlattener.java b/dol/src/dol/helper/flattener/ArchFlattener.java
new file mode 100644 (file)
index 0000000..c011d43
--- /dev/null
@@ -0,0 +1,281 @@
+/* $Id: ArchFlattener.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;
+
+import java.util.List;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ *
+ */
+public class ArchFlattener extends FlattenerHelper {
+
+    /**
+     * Constructor.
+     *
+     * @param classname class name of the generated class
+     */
+    public ArchFlattener(String classname) {
+        super(classname);
+    }
+
+    public String processElement(Element element)
+        throws RuntimeException {
+
+        String string = "";
+
+        if (element.getName().equalsIgnoreCase("processor")) {
+            _generateElement = true;
+            string = generateProcessor(element);
+        }
+        else if (element.getName().equalsIgnoreCase("hw_channel")) {
+            _generateElement = true;
+            string = generateLink(element);
+        }
+        else if (element.getName().equalsIgnoreCase("memory")) {
+            _generateElement = true;
+            string = generateMemory(element);
+        }
+        else if (element.getName().equalsIgnoreCase("node")) {
+            _generateElement = true;
+            string = generateNode(element);
+        }
+
+        if (element.getName().equalsIgnoreCase("connection")) {
+            _generateElement = false;
+            string = generateConnection(element);
+        }
+
+        //belongs to mapping!
+        if (element.getName().equalsIgnoreCase("binding")) {
+            string = generateBinding(element);
+        }
+        return string;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateProcessor(Element element) {
+        String attributes[] = {"name", "type", "basename"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("iterator")) {
+                sourceCode += generateIterator(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("node")) {
+                sourceCode += generateNode(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("configuration")) {
+                sourceCode += generateConfiguration(childElement);
+            }
+
+        }
+        sourceCode += _indent + "System.out.println(\"</processor>\");\n";
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateMemory(Element element) {
+        String attributes[] = {"name", "type", "basename"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("iterator")) {
+                sourceCode += generateIterator(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("node")) {
+                sourceCode += generateNode(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("configuration")) {
+                sourceCode += generateConfiguration(childElement);
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</memory>\");\n";
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateLink(Element element) {
+        String attributes[] = {"name", "type", "basename"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("iterator")) {
+                sourceCode += generateIterator(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("node")) {
+                sourceCode += generateNode(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("configuration")) {
+                sourceCode += generateConfiguration(childElement);
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</hw_channel>\");\n";
+        return sourceCode;
+    }
+
+    protected String generateConfiguration(Element element) {
+        String attributes[] = {"name", "value"};
+        increaseXmlIndent();
+        String sourceCode = generateElement(element, attributes, true);
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateNode(Element element) {
+        increaseXmlIndent();
+
+        String sourceCode = "";
+        if (_generateElement) {
+          String attributes[] = {"name", "basename"};
+          sourceCode = generateElement(element, attributes, false);
+        }
+        else {
+          String attributes[] = {"name"};
+          sourceCode = generateElement(element, attributes, false);
+        }
+
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("duplexport")) {
+                sourceCode += generatePort(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("inputport")) {
+                sourceCode += generatePort(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("outputport")) {
+                sourceCode += generatePort(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("port")) {
+                sourceCode += generatePort(childElement);
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"" + _xmlIndent
+                   + "</node>\");\n";
+
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+
+    protected String generatePort(Element element) {
+        increaseXmlIndent();
+        String sourceCode = "";
+        if (_generateElement) {
+          String attributes[] = {"name", "basename"};
+          sourceCode = generateElement(element, attributes, true);
+        }
+        else {
+          String attributes[] = {"name"};
+          sourceCode = generateElement(element, attributes, true);
+        }
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateConnection(Element element) {
+        String attributes[] = {"name"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add origin and target elements
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("origin")) {
+                //origin found
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement, attributes, false);
+
+                Namespace ns= childElement.getNamespace();
+                Element nodeElement = childElement.getChild("node", ns);
+                if (nodeElement != null) {
+                    sourceCode += generateNode(nodeElement);
+                }
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</origin>\");\n";
+                decreaseXmlIndent();
+            }
+            else if (childElement.getName().equalsIgnoreCase("target")) {
+                //target found
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement, attributes, false);
+
+                Namespace ns= childElement.getNamespace();
+                Element nodeElement = childElement.getChild("node", ns);
+                if (nodeElement != null) {
+                    sourceCode += generateNode(nodeElement);
+                }
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</target>\");\n";
+                decreaseXmlIndent();
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</connection>\");\n";
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateBinding(Element element) {
+        String attributes[] = {"name", "parameter", "type"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add origin and target elements
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("origin")) {
+                //origin found
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement, attributes, false);
+
+                Namespace ns = childElement.getNamespace();
+                Element portElement = childElement.getChild("port", ns);
+                if (portElement != null) {
+                    increaseXmlIndent();
+                    String[] portAttributes = {"name", "basename"};
+                    sourceCode += generateElement(portElement,
+                                                  portAttributes, true);
+                    decreaseXmlIndent();
+                }
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</origin>\");\n";
+                decreaseXmlIndent();
+            }
+            else if (childElement.getName().equalsIgnoreCase("target")) {
+                //target found
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement, attributes, false);
+
+                Namespace ns = childElement.getNamespace();
+                Element portElement = childElement.getChild("port", ns);
+                if (portElement != null) {
+                    increaseXmlIndent();
+                    String[] portAttributes = {"name", "basename"};
+                    sourceCode += generateElement(portElement,
+                                                  portAttributes, true);
+                    decreaseXmlIndent();
+                }
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</target>\");\n";
+                decreaseXmlIndent();
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</binding>\");\n";
+        return sourceCode;
+    }
+}
diff --git a/dol/src/dol/helper/flattener/BugCatcher.java b/dol/src/dol/helper/flattener/BugCatcher.java
new file mode 100644 (file)
index 0000000..30fa28f
--- /dev/null
@@ -0,0 +1,26 @@
+/* $Id: BugCatcher.java 1 2010-02-24 13:03:05Z haidw $ */
+
+package dol.helper.flattener;
+
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXParseException;
+
+/**
+ *
+ */
+class BugCatcher implements ErrorHandler {
+   public void error(SAXParseException ex) {
+      System.out.println("[ERROR  ]: "+ex.getMessage());
+
+   }
+
+   public void fatalError(SAXParseException ex)  {
+      System.out.println("[PIZDEC ]: "+ex.getMessage());
+
+   }
+
+   public void warning(SAXParseException ex)  {
+      System.out.println("[WARNING]: "+ex.getMessage());
+
+   }
+}
diff --git a/dol/src/dol/helper/flattener/DomDocumentParser.java b/dol/src/dol/helper/flattener/DomDocumentParser.java
new file mode 100644 (file)
index 0000000..e67a896
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id: DomDocumentParser.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;\r
+\r
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import org.apache.xerces.parsers.DOMParser;
+import org.w3c.dom.Document;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+\r
+/**\r
+ *\r
+ */\r
+public class DomDocumentParser {\r
+\r
+    DOMParser dp = null;\r
+    public ErrorHandler bc = new BugCatcher();\r
+\r
+    public DomDocumentParser() {\r
+        dp = new DOMParser();\r
+        dp.setErrorHandler(bc);\r
+    }\r
+\r
+    public Document parseDocument(File file){\r
+       try {\r
+           InputStream is = new FileInputStream(file);\r
+           InputSource iss = new InputSource(is);\r
+           dp.parse(iss);\r
+           return dp.getDocument();\r
+       } catch (Exception ex) {\r
+         ex.printStackTrace();\r
+       }\r
+       return null;\r
+    }\r
+\r
+    public Document parseDocument(String pathToFile){\r
+        return parseDocument(new File(pathToFile));\r
+    }\r
+}\r
diff --git a/dol/src/dol/helper/flattener/FlattenerHelper.java b/dol/src/dol/helper/flattener/FlattenerHelper.java
new file mode 100644 (file)
index 0000000..b11d977
--- /dev/null
@@ -0,0 +1,314 @@
+/* $Id: FlattenerHelper.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;
+
+import java.util.List;
+
+import org.jdom.Document;
+import org.jdom.Element;
+
+import dol.datamodel.XmlTag;
+
+/**
+ * Helper class to generate the source code of a class for writing
+ * an XML file based on an XML file with iterators. For details, refer
+ * to removeIterators().
+ *
+ * @see #removeIterators(org.jdom.Document doc)
+ */
+public class FlattenerHelper {
+
+    protected String _preamble = "public class Generator {\n\n  public "
+        + "Generator() {\n    //nothing to be done here\n  }\n"
+        + "\n  public static void main(String[] args) {\n";
+
+
+    //true, when an element is generated. places a restriction on the append
+    //element, namely that it must be a single variable, no function of a
+    //variable
+    protected boolean _generateElement = false;
+
+    protected String _indent = ""; //indentation of lines in Generator class
+
+    //code for obtaining range of iterator variables. is updated in each
+    //call of generateAppend
+    protected String _iteratorRangeCode = "";
+
+    //indentation of XML elements (use increaseXmlIndent() and
+    //decreaseXmlIndent() to change the indentation)
+    protected String _xmlIndent = "";
+
+    /**
+     * Default constructor. The generated class will have the name
+     * "Generator".
+     */
+    public FlattenerHelper() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param classname class name of the generated class
+     */
+    public FlattenerHelper(String classname) {
+        _preamble = _preamble.replace("Generator", classname);
+    }
+
+    public String processElement(Element element) {
+        return "";
+    }
+
+    /**
+     * Generate source code for println statement that prints out an XML
+     * element.
+     * @param element    the XML element itself
+     * @param attributes attributes to include in the XML element
+     * @param standalone true, when element shall be closed. false, otherwise
+     * @return println statement which prints out the XML element
+     */
+    protected String generateElement(Element element,
+                                     String[] attributes, boolean standalone)
+    {
+        String sourceCode = _indent + "System.out.println(\"";
+        sourceCode += _xmlIndent + "<" + element.getName();
+        for (int i = 0; i < attributes.length; i++) {
+
+            if (attributes[i].equals("basename")) {
+                sourceCode += " " + attributes[i] + "=\\\"";
+                sourceCode += element.getAttributeValue("name");
+                
+                if (!generateAppend(element).equals("")) {
+                    sourceCode += "\\\"";
+                    sourceCode += " range=\\\"" + _iteratorRangeCode;
+                }
+                sourceCode += "\\\"";
+            } else if (attributes[i].equals("name")) {
+                sourceCode += " " + attributes[i] + "=\\\"";
+                sourceCode += element.getAttributeValue("name");
+                sourceCode += generateAppend(element);
+                sourceCode += "\\\"";
+            } else if (attributes[i].equals("size")
+                       && element.getName().equals(_xt.getSWChannelTag())) {
+                sourceCode += " " + attributes[i] + "=\\\"";
+                sourceCode += "\" + ";
+                sourceCode += element.getAttributeValue("size");
+                sourceCode += "+ \"";
+                sourceCode += "\\\"";
+            } else if (attributes[i].equals("tokensize")
+                       && element.getName().equals(_xt.getSWChannelTag())) {
+                if (element.getAttributeValue("tokensize") != null) {
+                    sourceCode += " " + attributes[i] + "=\\\"";
+                    sourceCode += "\"";
+                    sourceCode += " + ";
+                    sourceCode += element.getAttributeValue("tokensize");
+                    sourceCode += "+ \"";
+                    sourceCode += "\\\"";
+                }
+            } else {
+                sourceCode += " " + attributes[i] + "=\\\"";
+                sourceCode += element.getAttributeValue(attributes[i]);
+                sourceCode += "\\\"";
+            }
+
+        }
+
+        if (standalone)
+            sourceCode += "/";
+        sourceCode +=">\");\n";
+
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    public String removeIterators(Document doc)
+        throws RuntimeException {
+        String sourceCode = _preamble;
+        String functionString = "";
+        String rootName = "";
+        _indent = "    ";
+
+        Element root = doc.getRootElement();
+        String xmlns = root.getNamespaceURI();
+        String xsiLocation = "";
+        for (org.jdom.Attribute attr :
+                 (List<org.jdom.Attribute>)root.getAttributes()) { 
+            //System.out.println(attr.getName() + ": ");
+            //System.out.println(attr.getValue());
+            if (attr.getName().equals("schemaLocation"))
+                xsiLocation = attr.getValue();
+        }
+
+        if (!root.getChildren().isEmpty()) {
+            //if there are any elements in the document, create a new header
+            //for the xml document
+            rootName = root.getName();
+
+            sourceCode += _indent
+                + "java.util.Hashtable<String, Integer> table = "
+                + "new java.util.Hashtable<String, Integer>();\n";
+
+            sourceCode += _indent + "System.out.println(\""
+                + "<?xml version=\\\"1.0\\\" "
+                + "encoding=\\\"UTF-8\\\"?>\");\n";
+            sourceCode += _indent + "System.out.println(\"<"
+                + rootName + " xmlns=\\\"" + xmlns
+                + "\\\" xmlns:xsi=\\\"http://www.w3.org/2001/"
+                + "XMLSchema-instance\\\" \\n  xsi:schemaLocation=\\\""
+                + xsiLocation + "\\\" name=\\\""
+                + root.getAttributeValue("name") + "_flattened"
+                + "\\\">\\n \");\n";
+        }
+
+
+        for (Element elmt : (List<Element>)root.getChildren()) {
+            try {
+                if (elmt.getName().equalsIgnoreCase(_xt.getIteratorTag())) {
+                    sourceCode += generateIterator(elmt);
+                }
+                else if (elmt.getName().equalsIgnoreCase(_xt.getVariableTag())) {
+                    sourceCode += generateVariable(elmt);
+                }
+                else if (elmt.getName().equalsIgnoreCase(_xt.getFunctionTag())) {
+                    functionString += generateFunction(elmt);
+                }
+                else {
+                    sourceCode += processElement(elmt);
+                }
+            }
+            catch (RuntimeException e) {
+                String elementName = "";
+                System.out.println(e.getMessage());
+                if (!elmt.getName().equalsIgnoreCase(_xt.getIteratorTag()) &&
+                    !elmt.getName().equalsIgnoreCase(_xt.getVariableTag())) {
+                    elementName = elmt.getAttributeValue("name");
+                }
+                throw new RuntimeException(
+                    "Error: An error occurred while parsing the <"
+                    + elmt.getName() + "> element \""
+                    + elementName + "\".");
+            }
+        }
+
+        sourceCode += _indent + "System.out.println(\"</"
+            + rootName +">\");\n  }\n";
+        _indent = "  ";
+        sourceCode += functionString;
+        sourceCode += "\n}";
+
+        return sourceCode;
+    }
+
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateIterator(Element element) {
+        String variableName = element.getAttributeValue("variable");
+        /*
+        //extract the upper iteration boundary and construct the for loop
+        String forLoop = element.getAttributeValue("range");
+        String boundary = forLoop.replaceAll(
+        "for.*;[ ]*\\w*[ ]*[<>=]* *(.*);.*", "$1");
+        */
+        String forLoop = "for (int " + variableName + " = 0; " + variableName
+            + " < " + element.getAttributeValue("range") + "; "
+            + variableName + "++)";
+
+        String sourceCode = _indent + "table.put(\"" + variableName
+            + "\", " + element.getAttributeValue("range") + ");\n";
+
+        sourceCode += _indent + forLoop + " {\n";
+        _indent += "  ";
+
+        for (Element el : (List<Element>)element.getChildren()) {
+            try {
+                if (el.getName().equalsIgnoreCase(_xt.getIteratorTag())) {
+                    sourceCode += generateIterator(el);
+                }
+                else {
+                    sourceCode += processElement(el);
+                }
+            }
+            catch (RuntimeException e) {
+                System.out.println(e.getMessage());
+                throw new RuntimeException(
+                    "Error: An error occurred while parsing the <"
+                    + el.getName() + "> element \""
+                    + el.getAttributeValue("name") + "\".");
+            }
+        }
+        _indent = _indent.substring(0, _indent.length() - 2);
+        sourceCode += _indent + "}\n";
+        sourceCode += _indent + "table.remove(\"" + variableName + "\");\n";
+
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateAppend(Element element)
+        throws RuntimeException {
+        String sourceCode = "";
+        
+        _iteratorRangeCode = "";
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("append")) {
+                if (_generateElement &&
+                    !childElement.getAttributeValue(_xt.getFunctionTag()).replaceAll(
+                        "\\w", "").equals("")) {
+                    throw new RuntimeException("Error: Found \""
+                                               + childElement.getAttributeValue("function")
+                                               + "\" in <append>. When constructing elements with an "
+                                               + "iterator using <append function=\"xxx\">, xxx must "
+                                               + "be a single variable. No mathematical operations "
+                                               + "are permitted.");
+                }
+                sourceCode += "\" + \"_\" + ("
+                    + childElement.getAttributeValue(_xt.getFunctionTag())
+                    + ") + \"";
+
+                if (!_iteratorRangeCode.equals(""))
+                    _iteratorRangeCode += ";";
+
+                _iteratorRangeCode += "\" + table.get(\""
+                    + childElement.getAttributeValue(_xt.getFunctionTag())
+                    + "\") + \"";
+            }
+        }
+        return sourceCode;
+    }
+
+    protected String generateVariable(Element element) {
+        String sourceCode = _indent + "int ";
+        sourceCode += element.getAttributeValue("name");
+        sourceCode += " = ";
+        sourceCode += element.getAttributeValue("value");
+        sourceCode += ";\n";
+        return sourceCode;
+    }
+
+    protected String generateFunction(Element element) {
+        return element.getText();
+    }
+
+    /**
+     * Increase the XML indentation.
+     **/
+    protected void increaseXmlIndent() {
+        _xmlIndent += "  ";
+    }
+
+    /**
+     * Decrease the XML indentation.
+     */
+    protected void decreaseXmlIndent() {
+        _xmlIndent = _xmlIndent.substring(0, _xmlIndent.length() - 2);
+    }
+
+    protected XmlTag _xt = XmlTag.getInstance();
+}
diff --git a/dol/src/dol/helper/flattener/MappingFlattener.java b/dol/src/dol/helper/flattener/MappingFlattener.java
new file mode 100644 (file)
index 0000000..19ae0e7
--- /dev/null
@@ -0,0 +1,156 @@
+/* $Id: MappingFlattener.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;
+
+import java.util.List;
+
+import org.jdom.Element;
+
+/**
+ *
+ */
+public class MappingFlattener extends FlattenerHelper {
+
+    /**
+     * Constructor.
+     *
+     * @param classname class name of the generated class
+     */
+    public MappingFlattener(String classname) {
+        super(classname);
+    }
+
+    public String processElement(Element element)
+        throws RuntimeException {
+
+        String string = "";
+
+        if (element.getName().equalsIgnoreCase("binding")) {
+            _generateElement = false;
+            string = generateBinding(element);
+        }
+        else if (element.getName().equalsIgnoreCase("path")) {
+            _generateElement = false;
+            string = generatePath(element);
+        }
+        else if (element.getName().equalsIgnoreCase("schedule")) {
+            _generateElement = false;
+            string = generateSchedule(element);
+        }
+
+        return string;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generatePath(Element element) {
+        String attributes[] = {"name"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add origin and target elements
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("origin")
+                || childElement.getName().equalsIgnoreCase("target")) {
+                sourceCode += generateOriginOrTarget(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("resource")) {
+                String rAttributes[] = {"name"};
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement,rAttributes, false);
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</resource>\");\n";
+                decreaseXmlIndent();
+            }
+            else if (childElement.getName().equalsIgnoreCase("buffer")) {
+                String bAttributes[] = {"name"};
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement,bAttributes, false);
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</buffer>\");\n";
+                decreaseXmlIndent();
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</path>\");\n";
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateSchedule(Element element) {
+        String attributes[] = {"name", "type"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add origin and target elements
+        
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("origin")) {
+                sourceCode += generateOriginOrTarget(childElement);
+            }
+            else if (childElement.getName().equalsIgnoreCase("resource")) {
+                String rAttributes[] = {"name"};
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement,rAttributes, false);
+                sourceCode += _indent +
+                    "System.out.println(\"" + _xmlIndent + "</resource>\");\n";
+                decreaseXmlIndent();
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</schedule>\");\n";
+        return sourceCode;
+    }
+    
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateBinding(Element element) {
+        String attributes[] = {"name", "type"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add origin and target elements
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("origin")
+                || childElement.getName().equalsIgnoreCase("target")) {
+                sourceCode += generateOriginOrTarget(childElement);
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</binding>\");\n";
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateOriginOrTarget(Element element) {
+        String attributes[] = {"name"};
+        increaseXmlIndent();
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add configuration elements
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase(_xt.getConfigurationTag())) {
+                sourceCode += generateConfiguration(childElement);
+            }
+        }
+
+        sourceCode += _indent + "System.out.println(\"" + _xmlIndent + "</"
+            + element.getName() + ">\");\n";
+        decreaseXmlIndent();
+        
+        return sourceCode;
+    }
+
+    protected String generateConfiguration(Element element) {
+        String attributes[] = {"name", "value"};
+        increaseXmlIndent();
+        String sourceCode = generateElement(element, attributes, true);
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+
+
+}
diff --git a/dol/src/dol/helper/flattener/PNFlattener.java b/dol/src/dol/helper/flattener/PNFlattener.java
new file mode 100644 (file)
index 0000000..fc6af53
--- /dev/null
@@ -0,0 +1,184 @@
+/* $Id: PNFlattener.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;
+
+import java.util.List;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ *
+ */
+public class PNFlattener extends FlattenerHelper {
+
+    /**
+     * Constructor.
+     *
+     * @param classname class name of the generated class
+     */
+    public PNFlattener(String classname) {
+        super(classname);
+    }
+
+    public String processElement(Element element)
+        throws RuntimeException {
+
+        String string = "";
+
+        _generateElement = true;
+        if (element.getName().equalsIgnoreCase(_xt.getProcessTag())) {
+            string = generateProcess(element);
+        } else if (element.getName().equalsIgnoreCase(_xt.getSWChannelTag())) {
+            string = generateChannel(element);
+        } else if (element.getName().equalsIgnoreCase(_xt.getPortTag())) {
+            string = generatePort(element);
+        } else if (element.getName().equalsIgnoreCase(_xt.getConfigurationTag())) {
+            string = generateConfiguration(element);
+        } else if (element.getName().equalsIgnoreCase(_xt.getProfilingTag())) {
+            string = generateProfiling(element);
+        }
+
+        _generateElement = false;
+
+        if (element.getName().equalsIgnoreCase(_xt.getConnectionTag())) {
+            string = generateConnection(element);
+        }
+        return string;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateProcess(Element element) {
+        String attributes[] = {"name", "basename"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (!(childElement.getName().equalsIgnoreCase(_xt.getPortTag()) ||
+                  childElement.getName().equalsIgnoreCase(_xt.getSourceTag()) ||
+                  childElement.getName().equalsIgnoreCase(_xt.getConfigurationTag()) ||
+                  childElement.getName().equalsIgnoreCase(_xt.getProfilingTag()))) {
+                if (childElement.getName().equalsIgnoreCase(_xt.getIteratorTag())) {
+                    sourceCode += generateIterator(childElement);
+                }
+            } else {
+                if (childElement.getName().equalsIgnoreCase(_xt.getPortTag())) {
+                    sourceCode += generatePort(childElement);
+                } else if (childElement.getName().equalsIgnoreCase(_xt.getConfigurationTag())) {
+                    sourceCode += generateConfiguration(childElement);
+                } else if (childElement.getName().equalsIgnoreCase(_xt.getProfilingTag())) {
+                    sourceCode += generateProfiling(childElement);
+                }
+                else {
+                    //source found
+                    increaseXmlIndent();
+                    String[] sourceAttributes = {"location", "type"};
+                    sourceCode += generateElement(childElement,
+                                                  sourceAttributes, true);
+                    decreaseXmlIndent();
+                }
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</process>\");\n";
+        return sourceCode;
+    }
+
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateChannel(Element element) {
+        String attributes[] = {"name", "type", "size",
+                               "basename", "tokensize"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase(_xt.getPortTag())) {
+                sourceCode += generatePort(childElement);
+            } else if (childElement.getName().equalsIgnoreCase(_xt.getConfigurationTag())) {
+                sourceCode += generateConfiguration(childElement);
+            } else if (childElement.getName().equalsIgnoreCase(_xt.getProfilingTag())) {
+                sourceCode += generateProfiling(childElement);
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</sw_channel>\");\n";
+        return sourceCode;
+    }
+
+    protected String generatePort(Element element) {
+        String attributes[] = {"name", "type", "basename"};
+        increaseXmlIndent();
+        String sourceCode = generateElement(element, attributes, true);
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+
+    protected String generateConfiguration(Element element) {
+        String attributes[] = {"name", "value"};
+        increaseXmlIndent();
+        String sourceCode = generateElement(element, attributes, true);
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+
+    protected String generateProfiling(Element element) {
+        String attributes[] = {"name", "value"};
+        increaseXmlIndent();
+        String sourceCode = generateElement(element, attributes, true);
+        decreaseXmlIndent();
+        return sourceCode;
+    }
+    
+    /**
+     * 
+     */
+    @SuppressWarnings("unchecked")
+    protected String generateConnection(Element element) {
+        String attributes[] = {"name"};
+        String sourceCode = generateElement(element, attributes, false);
+
+        //add origin and target elements
+        for (Element childElement : (List<Element>)element.getChildren()) {
+            if (childElement.getName().equalsIgnoreCase("origin")) {
+                //origin found
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement, attributes, false);
+
+                Namespace ns = childElement.getNamespace();
+                Element portElement = childElement.getChild("port", ns);
+                if (portElement != null) {
+                    increaseXmlIndent();
+                    String[] portAttributes = {"name"};
+                    sourceCode += generateElement(portElement,
+                                                  portAttributes, true);
+                    decreaseXmlIndent();
+                }
+                decreaseXmlIndent();
+                sourceCode += _indent +
+                    "System.out.println(\"  </" + _xt.getOriginTag()+">\");\n";
+            }
+            else if (childElement.getName().equalsIgnoreCase(_xt.getTargetTag())) {
+                //target found
+                increaseXmlIndent();
+                sourceCode += generateElement(childElement, attributes, false);
+
+                Namespace ns = childElement.getNamespace();
+                Element portElement = childElement.getChild(_xt.getPortTag(), ns);
+                if (portElement != null) {
+                    increaseXmlIndent();
+                    String[] portAttributes = {"name"};
+                    sourceCode += generateElement(portElement,
+                                                  portAttributes, true);
+                    decreaseXmlIndent();
+                }
+                decreaseXmlIndent();
+                sourceCode += _indent +
+                    "System.out.println(\"  </"+_xt.getTargetTag()+">\");\n";
+            }
+        }
+        sourceCode += _indent + "System.out.println(\"</"
+                    + _xt.getConnectionTag() + ">\");\n";
+        return sourceCode;
+    }
+}
diff --git a/dol/src/dol/helper/flattener/SaxDocumentParser.java b/dol/src/dol/helper/flattener/SaxDocumentParser.java
new file mode 100644 (file)
index 0000000..2394991
--- /dev/null
@@ -0,0 +1,107 @@
+/* $Id: SaxDocumentParser.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+
+import org.apache.xerces.parsers.SAXParser;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ */
+class SaxDocumentParser implements ContentHandler{
+
+  public ErrorHandler bc = new BugCatcher();
+  public SAXParser sp = null;
+  protected boolean foundIterator = false;
+
+  public SaxDocumentParser() {
+    try {
+      sp = new SAXParser();
+      sp.setFeature("http://xml.org/sax/features/validation",true);
+      sp.setFeature("http://apache.org/xml/features/validation/schema", true);
+      sp.setFeature("http://apache.org/xml/features/validation/schema-full-checking", true);
+      sp.setErrorHandler(bc);
+      sp.setContentHandler(this);
+      sp.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation",
+                     dol.util.SchemaLocation.getInternalSchemaLocation());
+    }
+    catch (Exception ex) {
+      ex.printStackTrace();
+    }
+  }
+
+  public boolean parseDocument(String pathToFile){
+    return parseDocument(new File(pathToFile));
+  }
+
+  public boolean parseDocument(File file){
+    try{
+        InputStream is = new FileInputStream(file);
+        InputSource iss = new InputSource(is);
+        sp.parse(iss);
+    }
+    catch (Exception e){
+        e.printStackTrace();
+    }
+    return true;//foundIterator;
+  }
+
+    /**
+     * Action to be done while parsing a start element of an XML
+     *
+     * @param  elementName Description of the Parameter
+     * @param  attributes Description of the Parameter
+     * @exception  SAXException MyException If such and such occurs
+     */
+    public void startElement(String namespaceURI, String localName, String elementName, Attributes attributes) throws SAXException {
+
+      if (elementName.equals("iterator")) {
+          //System.out.println();
+          //System.out.println("Iterator found in document");
+          foundIterator = true;
+      }
+      else {
+          System.out.print(".");
+      }
+    }
+
+
+    public void startDocument() throws SAXException {
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws  SAXException {
+    }
+
+    public void endDocument() throws SAXException {
+    }
+
+    public void endElement(String namespaceURI, String localName, String elementName) throws SAXException {
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+    }
+
+    public void characters(char buf[], int offset, int len) throws SAXException {
+    }
+
+    public void skippedEntity(String string){
+    }
+
+    public void processingInstruction(String string1, String string2){
+    }
+
+    public void ignorableWhitespace(char[] characters,int int1,int int2){
+    }
+
+    public void setDocumentLocator(org.xml.sax.Locator dl){
+    }
+
+  }
+
diff --git a/dol/src/dol/helper/flattener/XMLFlattener.java b/dol/src/dol/helper/flattener/XMLFlattener.java
new file mode 100644 (file)
index 0000000..7aade7c
--- /dev/null
@@ -0,0 +1,71 @@
+/* $Id: XMLFlattener.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.flattener;
+
+import java.io.File;
+import java.io.FileWriter;
+
+import org.jdom.input.DOMBuilder;
+import org.w3c.dom.Document;
+
+/**
+ *
+ */
+public class XMLFlattener {
+
+  public static void main(String[] args) {
+
+    if (args.length != 2) {
+      System.out.println("Wrong number of arguments.");
+      System.out.println("Correct call:");
+      System.out.println("java XMLFlattener in.xml out.xml");
+      System.exit(-1);
+    }
+    else {
+      SaxDocumentParser sdp = new SaxDocumentParser();
+      boolean needsToBeFlattened = false;
+      needsToBeFlattened = sdp.parseDocument(args[0]);
+      if (needsToBeFlattened) {
+        // start also with DOM Parser and generate the XML-Generator
+        DomDocumentParser ddp = new DomDocumentParser();
+        Document doc = ddp.parseDocument(args[0]);
+
+        DOMBuilder db = new DOMBuilder();
+        org.jdom.Document document = db.build(doc);
+
+        String xmlns = document.getRootElement().getNamespaceURI();
+
+        String outString = "";
+
+        if (xmlns.endsWith("PROCESSNETWORK") ||
+            xmlns.endsWith("processnetwork")) {
+          PNFlattener flattener = new PNFlattener(args[1]);
+          outString = flattener.removeIterators(document);
+        }
+        else if (xmlns.endsWith("ARCHITECTURE")
+                 || xmlns.endsWith("ARCHITECTURE_OLD")
+                 || xmlns.endsWith("architecture")) {
+          ArchFlattener flattener = new ArchFlattener(args[1]);
+          outString = flattener.removeIterators(document);
+        }
+        else if (xmlns.endsWith("MAPPING")
+                 || xmlns.endsWith("MAPPING_OLD")
+                 || xmlns.endsWith("mapping")) {
+          MappingFlattener flattener = new MappingFlattener(args[1]);
+          outString = flattener.removeIterators(document);
+        }
+
+        
+        try {
+          FileWriter fw = new FileWriter(new File(args[1] + ".java"));
+          fw.write(outString);
+          fw.flush();
+          fw.close();
+        } catch (Exception ex) {
+        }
+      }
+      else {
+        System.out.println("Nothing to be done. Terminating...");
+      }
+    }
+  }
+}
diff --git a/dol/src/dol/helper/flattener/package.html b/dol/src/dol/helper/flattener/package.html
new file mode 100644 (file)
index 0000000..4f62fe4
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Flattener which unfolds all iterators inside XML files.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/helper/profiler/ChannelProfile.java b/dol/src/dol/helper/profiler/ChannelProfile.java
new file mode 100644 (file)
index 0000000..4de3cc7
--- /dev/null
@@ -0,0 +1,221 @@
+/* $Id: ChannelProfile.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
+package dol.helper.profiler;\r
+\r
+/**\r
+ * Functional simulation profile information for a channel.\r
+ */\r
+public class ChannelProfile {\r
+\r
+    /**\r
+     * Constructor.\r
+     *\r
+     * @param name name of the channel this profile belongs to\r
+     * @param capacity capacity of this channel\r
+     */\r
+    public ChannelProfile(String name, int capacity) {\r
+        _name = name;\r
+        _capacity = capacity;\r
+    }\r
+\r
+    /**\r
+     * Adds a read access. Reduces the fifo fill level accordingly. If the\r
+     * amount is larger than the current fifo size, the read is blocking.\r
+     * \r
+     * @param amount The amount of data in bytes.\r
+     */\r
+    public void readAccess(int amount) {\r
+        _numOfReads++;\r
+        _totalReadData += amount;\r
+\r
+        if (amount > _maxReadChunk)\r
+            _maxReadChunk = amount;\r
+\r
+        if (amount < _minReadChunk)\r
+            _minReadChunk = amount;\r
+\r
+        if (_fillLevel < amount) {\r
+            _numOfBlockingReads++;\r
+            _blockedReadSize = amount;\r
+        }\r
+        else {\r
+            _fillLevel -= amount;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Adds a write access. Enlarges the fifo size accordingly. If the\r
+     * amount plus the current size of the fifo is larger than the\r
+     * capacity, an overflow occurs (blocking write).\r
+     *\r
+     * @param amount The amount of data in bytes.\r
+     */\r
+    public void writeAccess(int amount) {\r
+        _numOfWrites++;\r
+        if (_fillLevel + amount > _capacity) {\r
+            _numOfBlockingWrites++;\r
+        }\r
+\r
+        _fillLevel += amount;\r
+\r
+        if (amount > _maxWriteChunk)\r
+            _maxWriteChunk = amount;\r
+\r
+        if (amount < _minWriteChunk)\r
+            _minWriteChunk = amount;\r
+\r
+        if (_fillLevel > _maxFillLevel)\r
+            _maxFillLevel = _fillLevel;\r
+\r
+\r
+        if ((_fillLevel >= _blockedReadSize) && (_blockedReadSize != 0)) {\r
+            _fillLevel -= _blockedReadSize;\r
+            _blockedReadSize = 0;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Returns the maximum amount of data stored in the fifo.\r
+     * \r
+     * @return Maximum fill level in bytes.\r
+     */\r
+    public int getMaxFillLevel() {\r
+        return _maxFillLevel;\r
+    }\r
+\r
+    /**\r
+     * Returns the size of the largest chunk of data read in a single\r
+     * read access.\r
+     * \r
+     * @return Size of the largest read chunk in bytes.\r
+     */\r
+    public int getMaxReadChunk() {\r
+        return _maxReadChunk;\r
+    }\r
+\r
+    /**\r
+     * Returns the size of the smallest chunk of data read in a single\r
+     * read access.\r
+     * \r
+     * @return Size of the smallest read chunk in bytes.\r
+     */\r
+    public int getMinReadChunk() {\r
+        return _minReadChunk;\r
+    }\r
+\r
+    /**\r
+     * Returns the size of the largest chunk of data written in a single\r
+     * write access.\r
+     * \r
+     * @return Size of the largest written chunk in bytes.\r
+     */\r
+    public int getMaxWriteChunk() {\r
+        return _maxWriteChunk;\r
+    }\r
+\r
+    /**\r
+     * Returns the size of the smallest chunk of data written in a single\r
+     * write access.\r
+     * \r
+     * @return Size of the smallest written chunk in bytes.\r
+     */\r
+    public int getMinWriteChunk() {\r
+        return _minWriteChunk;\r
+    }\r
+\r
+    /**\r
+     * Returns the number of total read accesses.\r
+     * \r
+     * @return Number of total read accesses.\r
+     */\r
+    public int getNumOfReads() {\r
+        return _numOfReads;\r
+    }\r
+\r
+    /**\r
+     * Returns the number of total blocking reads.\r
+     * A blocking read occurs whenever there is an attempt to read more\r
+     * data from the fifo than the fifo contains.\r
+     * \r
+     * @return Number of total blocking reads\r
+     */\r
+    public int getNumOfBlockingReads() {\r
+        return _numOfBlockingReads;\r
+    }\r
+\r
+    /**\r
+     * Returns the total number of write accesses.\r
+     * \r
+     * @return Number of total write accesses.\r
+     */\r
+    public int getNumOfWrites() {\r
+        return _numOfWrites;\r
+    }\r
+\r
+    /**\r
+     * Returns the number of total blocking writes.\r
+     * A blocking write occurs, whenever a write access tries to write\r
+     * more data into the fifo than its capacity allows.\r
+     * \r
+     * @return Number of total overflows.\r
+     */\r
+    public int getNumOfOverflows() {\r
+        return _numOfBlockingWrites;\r
+    }\r
+\r
+    /**\r
+     * Returns the percentage of read accesses which were blocking.\r
+     * @return Percentage of blocking reads\r
+     */\r
+    public int getBlockingReadsPercentage() {\r
+        if (_numOfReads == 0)\r
+            return 0;\r
+        \r
+        return (_numOfBlockingReads * 100) / (_numOfReads);\r
+    }\r
+    /**\r
+     * Returns the percentage of write accesses, which led to an overflow.\r
+     * @return Percentage of overflows.\r
+     */\r
+    public int getBlockingWritesPercentage() {\r
+        if (_numOfWrites == 0)\r
+            return 0;\r
+        \r
+        return (_numOfBlockingWrites * 100) / (_numOfWrites);\r
+    }\r
+    \r
+    /**\r
+     * Returns the total amount of read data (in bytes).\r
+     * @return Amount in bytes.\r
+     */\r
+    public long getTotalReadData() {\r
+        return _totalReadData;\r
+    }\r
+\r
+    /**\r
+     * Return the name of the channel this profile belongs to.\r
+     * \r
+     * @return name of the channel this profile belongs to\r
+     */\r
+    public String getName() {\r
+        return _name;\r
+    }\r
+\r
+\r
+    protected String _name = "";\r
+    protected int _capacity = 0;\r
+\r
+    protected long _totalReadData = 0;\r
+    protected int _fillLevel = 0;\r
+    protected int _maxFillLevel = 0;\r
+\r
+    protected int _numOfReads = 0;\r
+    protected int _numOfBlockingReads = 0;\r
+    protected int _maxReadChunk = 0;\r
+    protected int _minReadChunk = Integer.MAX_VALUE;\r
+    protected int _blockedReadSize = 0;\r
+\r
+    protected int _numOfWrites = 0;\r
+    protected int _numOfBlockingWrites = 0;\r
+    protected int _maxWriteChunk = 0;\r
+    protected int _minWriteChunk = Integer.MAX_VALUE;\r
+}\r
diff --git a/dol/src/dol/helper/profiler/Constants.java b/dol/src/dol/helper/profiler/Constants.java
new file mode 100644 (file)
index 0000000..673e1b5
--- /dev/null
@@ -0,0 +1,13 @@
+/* $Id: Constants.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.helper.profiler;\r
+\r
+/**\r
+ * Keys for accessing profile properties.\r
+ */\r
+public class Constants {\r
+    public final static String processFires = "Process.Fires";\r
+    public final static String portAccesses = "Port.Accesses";\r
+    public final static String portTokenSize = "Port.TokenSize";\r
+    public final static String portInitialAccesses = "Port.InitialAccesses";\r
+    public final static String portInitialTokenSize = "Port.IntialTokensize";\r
+}\r
diff --git a/dol/src/dol/helper/profiler/PNProfileSummarizer.java b/dol/src/dol/helper/profiler/PNProfileSummarizer.java
new file mode 100644 (file)
index 0000000..66b1d58
--- /dev/null
@@ -0,0 +1,105 @@
+/* $Id: PNProfileSummarizer.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.helper.profiler;\r
+\r
+import java.util.HashMap;\r
+import java.util.StringTokenizer;\r
+\r
+import dol.datamodel.pn.Process;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.datamodel.pn.ProfilingConfiguration;\r
+import dol.parser.xml.pnschema.PNXmlParser;\r
+import dol.visitor.xml.PNXmlVisitor;\r
+\r
+/**\r
+ * Class to post-process profiling info in a process network XML file.\r
+ */\r
+public class PNProfileSummarizer {\r
+    /**\r
+     * Add up all WCED, BCED, and ACED numbers for each process in the\r
+     * given process network file. The computed numbers are back-annotated\r
+     * to a new file with the suffix _summary.\r
+     *\r
+     * @param filename filename of annotated process network XML file\r
+     */\r
+    public static void sumDemands(String filename) {\r
+        HashMap<String, ProfilingConfiguration> configs =\r
+            new HashMap<String, ProfilingConfiguration>();\r
+\r
+        //load process network specification from XML\r
+        PNXmlParser parserPn = new PNXmlParser();\r
+        ProcessNetwork pn = parserPn.doParse(filename);\r
+\r
+        for (Process process : pn.getProcessList()) {\r
+            //System.out.println(process.getName());\r
+            for (ProfilingConfiguration cfg :\r
+                    process.getProfilingList()) {\r
+                StringTokenizer tokenizer =\r
+                    new StringTokenizer(cfg.getName(), " ");\r
+                //System.out.println(cfg.getName());\r
+                if (tokenizer.countTokens() < 2) {\r
+                    continue;\r
+                }\r
+\r
+                String demandId = tokenizer.nextToken();\r
+                String processorName = tokenizer.nextToken();\r
+                String key = process.getName() + " " + demandId + " "\r
+                + processorName + " sum";\r
+                if (configs.get(key) == null) {\r
+                    ProfilingConfiguration config =\r
+                        new ProfilingConfiguration(demandId + " "\r
+                                + processorName + " sum");\r
+                    config.setValue("0");\r
+                    configs.put(key, config);\r
+                }\r
+                ProfilingConfiguration currentCfg = configs.get(key);\r
+                /*\r
+                System.out.print(currentCfg.getName() + ": "\r
+                        + currentCfg.getValue() + " / "\r
+                        + cfg.getName() + ": "\r
+                        + cfg.getValue());\r
+                */\r
+                currentCfg.setValue(\r
+                        Long.toString(Long.parseLong(\r
+                        currentCfg.getValue())\r
+                        + Long.parseLong(cfg.getValue())));\r
+                /*\r
+                System.out.println(currentCfg.getName() + ": "\r
+                        + currentCfg.getValue());\r
+                */\r
+            }\r
+        }\r
+\r
+        for(String key : configs.keySet()) {\r
+            ProfilingConfiguration value = configs.get(key);\r
+            String process = key.substring(0, key.indexOf(" "));\r
+            pn.getProcess(process).getProfilingList().add(value);\r
+        }\r
+\r
+        System.out.println("Write process network XML file");\r
+        StringBuffer buffer = new StringBuffer();\r
+        pn.accept(new PNXmlVisitor(buffer));\r
+        try {\r
+            java.io.BufferedWriter writer =\r
+                    new java.io.BufferedWriter(\r
+                    new java.io.FileWriter(\r
+                    filename.replaceAll(".xml", "_summary.xml")));\r
+            writer.write(buffer.toString());\r
+            writer.close();\r
+        } catch (java.io.IOException e) {\r
+            System.out.println("Caught an exception while "\r
+                    + "creating XML file: " + e.getMessage());\r
+            e.printStackTrace(System.out);\r
+        }\r
+        System.out.println(" -- Process network XML file [Finished]");\r
+    }\r
+\r
+\r
+    /**\r
+     * Run summarize operations on annotated process network.\r
+     *\r
+     * @param args filename of annotated process network XML file\r
+     */\r
+    public static void main(String args[]) throws Exception {\r
+        PNProfileSummarizer.sumDemands(args[0]);\r
+    }\r
+}\r
diff --git a/dol/src/dol/helper/profiler/PortProfile.java b/dol/src/dol/helper/profiler/PortProfile.java
new file mode 100644 (file)
index 0000000..cd040ab
--- /dev/null
@@ -0,0 +1,95 @@
+/* $Id: PortProfile.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
+package dol.helper.profiler;\r
+\r
+/**\r
+ * Functional simulation profile information for a port.\r
+ */\r
+public class PortProfile {\r
+\r
+    /**\r
+     * Constructor.\r
+     *\r
+     * @param name name of the port this profile belongs to\r
+     */\r
+    public PortProfile(String name, ProcessProfile processProfile) {\r
+        _name = name;\r
+        _processProfile = processProfile;\r
+        _accesses = new Range();\r
+        _tokenSize = new Range();\r
+        _currentTokenSize = new Range();\r
+    }\r
+\r
+    /**\r
+     * Return the name of the channel this profile belongs to.\r
+     *\r
+     * @return name of the channel this profile belongs to\r
+     */\r
+    public String getName() {\r
+        return _name;\r
+    }\r
+\r
+    /**\r
+     * Add a read or write access to this port.\r
+     *\r
+     * @param tokenSize number of bytes communicated in this access\r
+     */\r
+    public void addAccess(int tokenSize) {\r
+        _currentAccesses++;\r
+        _currentTokenSize.merge(tokenSize);\r
+    }\r
+\r
+    /**\r
+     * Add an initial read or write access to this port (access happened\r
+     * during init() phase).\r
+     *\r
+     * @param tokenSize number of bytes communicated in this access\r
+     */\r
+    public void addInitialAccess(int tokenSize) {\r
+        _initialAccesses++;\r
+        if (_initialTokenSize == null) {\r
+            _initialTokenSize = new Range(tokenSize);\r
+        } else {\r
+            _initialTokenSize.merge(tokenSize);\r
+        }\r
+    }\r
+\r
+    /**\r
+     *\r
+     */\r
+    public void update() {\r
+        _accesses.merge(_currentAccesses);\r
+        _tokenSize.merge(_currentTokenSize);\r
+\r
+        _currentAccesses = 0;\r
+        _currentTokenSize.reset();\r
+    }\r
+\r
+    public int getInitialAccesses() {\r
+        return _initialAccesses;\r
+    }\r
+\r
+    public Range getInitialTokenSize() {\r
+        if (_initialTokenSize == null) {\r
+            return new Range(0);\r
+        } else {\r
+            return _initialTokenSize;\r
+        }\r
+    }\r
+\r
+    public Range getAccesses() {\r
+        return _accesses;\r
+    }\r
+\r
+    public Range getTokenSize() {\r
+        return _tokenSize;\r
+    }\r
+\r
+    String _name;\r
+    Range _accesses;\r
+    Range _tokenSize;\r
+    int _currentAccesses;\r
+    Range _currentTokenSize;\r
+    int _initialAccesses;\r
+    Range _initialTokenSize = null;\r
+    ProcessProfile _processProfile;\r
+}\r
diff --git a/dol/src/dol/helper/profiler/ProcessProfile.java b/dol/src/dol/helper/profiler/ProcessProfile.java
new file mode 100644 (file)
index 0000000..f8e51a8
--- /dev/null
@@ -0,0 +1,97 @@
+/* $Id: ProcessProfile.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
+package dol.helper.profiler;\r
+\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+\r
+/**\r
+ * Functional simulation profile information for a process.\r
+ */\r
+public class ProcessProfile {\r
+\r
+    /** \r
+     * Constructor.\r
+     * \r
+     * @param name name of the process this profile belongs to \r
+     */\r
+    public ProcessProfile(String name) {\r
+        _name = name;\r
+        _portProfiles = new HashMap<String, PortProfile>();\r
+    }\r
+\r
+    /**\r
+     * Indicate that the process has entered fire().\r
+     */\r
+    public void start() {\r
+        _started = true;\r
+        _numOfFires++;\r
+    }\r
+    \r
+    /**\r
+     * Indicate that the process has leaved fire().\r
+     */\r
+    public void stop() {\r
+        if (!_started) {\r
+            return;\r
+        }\r
+        \r
+        _started = false;\r
+\r
+        Iterator<String> iterator = _portProfiles.keySet().iterator();\r
+\r
+        while (iterator.hasNext()) {\r
+            PortProfile profile = _portProfiles.get(iterator.next());\r
+            profile.update();\r
+        }\r
+    }\r
+   \r
+    /**\r
+     * Indicate a read or write access to a port.\r
+     * \r
+     * @param port the accessed port\r
+     * @param amount number of bytes communicated\r
+     */\r
+    public void portAccess(String port, int amount) {\r
+        if (_portProfiles.get(port) == null) {\r
+            PortProfile profile = new PortProfile(port, this);\r
+            _portProfiles.put(port, profile);\r
+        }\r
+        if (_started) {\r
+            _portProfiles.get(port).addAccess(amount);\r
+        } else {\r
+            _portProfiles.get(port).addInitialAccess(amount);\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Return the number of firings.\r
+     *\r
+     * @return the number of fire() calls of a process.\r
+     **/\r
+    public int getNumOfFires() {\r
+        return _numOfFires;\r
+    }\r
+    \r
+    /**\r
+     * Return the name of the process this profile belongs to.\r
+     * \r
+     * @return name of the process this profile belongs to\r
+     */\r
+    public String getName() {\r
+        return _name;\r
+    }\r
+\r
+    /**\r
+     * Return the profiles of all ports.\r
+     * \r
+     * @return profile of all ports\r
+     */\r
+    public HashMap<String, PortProfile> getPortProfiles() {\r
+        return _portProfiles;\r
+    }\r
+    \r
+    protected String _name;\r
+    boolean _started = false;\r
+    protected int _numOfFires = 0;\r
+    HashMap<String, PortProfile> _portProfiles;\r
+}\r
diff --git a/dol/src/dol/helper/profiler/ProfileParser.java b/dol/src/dol/helper/profiler/ProfileParser.java
new file mode 100644 (file)
index 0000000..5ad1304
--- /dev/null
@@ -0,0 +1,273 @@
+/* $Id: ProfileParser.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
+package dol.helper.profiler;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.FileReader;\r
+import java.io.IOException;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * Class for parsing a profile and collecting parameter statistics.\r
+ */\r
+public class ProfileParser {\r
+\r
+    /**\r
+     * Constructor.\r
+     **/\r
+    public ProfileParser(String filename) {\r
+        try {\r
+            _in = new BufferedReader(new FileReader(filename));\r
+        } catch (IOException e) {\r
+            System.err.println(e.getLocalizedMessage());\r
+        }\r
+\r
+        _processProfiles = new HashMap<String, ProcessProfile>();\r
+        _channelProfiles = new HashMap<String, ChannelProfile>();\r
+        _inPortToChannelMapping = new HashMap<String, String>();\r
+        _outPortToChannelMapping = new HashMap<String, String>();\r
+        _processCommOrder = new HashMap<String, Vector<String>>();\r
+    }\r
+\r
+    /**\r
+     * Parse the profile file and generate the profiles for processes and\r
+     * channels. After calling this function, use\r
+     * {@link #getProcessProfiles()} and {@link #getChannelProfiles()} to\r
+     * obtain the result of parsing.\r
+     *\r
+     * @see #getChannelProfiles()\r
+     * @see #getProcessProfiles()\r
+     */\r
+    public void parseProfile() {\r
+        String nextWord;\r
+        String line = null;\r
+\r
+        while (true) {\r
+            try {\r
+                //PERFORMANCE: do not read line-by-line but read in larger\r
+                //chunks from the file. has much more influence on the\r
+                //performance than the data structures in this class.\r
+                line = _in.readLine();\r
+                if (line == null) {\r
+                    _in.close();\r
+\r
+                    Iterator<String> iterator = _processProfiles.keySet().iterator();\r
+                    while (iterator.hasNext()) {\r
+                        _processProfiles.get(iterator.next()).stop();\r
+                    }\r
+                    return;\r
+                }\r
+            } catch (IOException e) {\r
+                System.err.println(e.getLocalizedMessage());\r
+                return;\r
+            }\r
+\r
+            StringTokenizer tokenizer = new StringTokenizer(line);\r
+            nextWord = tokenizer.nextToken();\r
+\r
+            if (nextWord.equals("c")) {\r
+                //'c' stands for a channel connection line. example:\r
+                //c filterchannel 8 o filter 0x23c738 i filter 0x23c6e8\r
+                String channelName = tokenizer.nextToken();\r
+                int capacity = Integer.parseInt(\r
+                        tokenizer.nextToken());\r
+                String portAType = tokenizer.nextToken();\r
+                String processAName = tokenizer.nextToken();\r
+                String portAName = tokenizer.nextToken();\r
+                String portBType = tokenizer.nextToken();\r
+                String processBName = tokenizer.nextToken();\r
+                String portBName = tokenizer.nextToken();\r
+                addChannelProfile(channelName, capacity,\r
+                        portAType, processAName, portAName,\r
+                        portBType, processBName, portBName);\r
+            } else {\r
+                //current line is an event. examples:\r
+                //examples:\r
+                //78 filter started.\r
+                //79 filter r 0x23c6c0 8\r
+                //80 filter w 0x23c738 8\r
+                //81 filter stopped.\r
+\r
+                int i = Integer.parseInt(nextWord);\r
+                if (i != _lineCounter) {\r
+                    System.err.println("Input file corrupt: line number "\r
+                            + "expected.");\r
+                    return;\r
+                }\r
+\r
+                //get process name\r
+                String processName = tokenizer.nextToken();\r
+                if (_processProfiles.get(processName) == null) {\r
+                    ProcessProfile processProfile = new ProcessProfile(\r
+                            processName);\r
+                    _processProfiles.put(processName, processProfile);\r
+                }\r
+                if(_processCommOrder.get(processName) == null) {\r
+                    _processCommOrder.put(processName, new Vector<String>());\r
+                }\r
+\r
+                nextWord = tokenizer.nextToken();\r
+                if(nextWord.equals("started.")) {\r
+                    _processProfiles.get(processName).start();\r
+                }\r
+                else if(nextWord.equals("stopped.")) {\r
+                    _processProfiles.get(processName).stop();\r
+                }\r
+                else if (nextWord.equals("r") || nextWord.equals("w")) {\r
+                    String accessType = nextWord;\r
+                    String portName = tokenizer.nextToken();\r
+                    int amount = Integer.parseInt(\r
+                            tokenizer.nextToken());\r
+                    try {\r
+                        _processProfiles.get(processName).\r
+                                portAccess(portName, amount);\r
+                        if (accessType.equals("r")) {\r
+                            String channelName =\r
+                                _inPortToChannelMapping.get(portName);\r
+                            _channelProfiles.get(channelName).\r
+                                    readAccess(amount);\r
+                            _processCommOrder.get(processName).add(channelName);\r
+\r
+                        } else {\r
+                            String channelName =\r
+                                _outPortToChannelMapping.get(portName);\r
+                            _channelProfiles.get(channelName).\r
+                                    writeAccess(amount);\r
+                            _processCommOrder.get(processName).add(channelName);\r
+                        }\r
+                    } catch (NullPointerException e) {\r
+                        System.err.println("Input file corrupt: cannot "\r
+                                + "find channel associated to port "\r
+                                + portName + "(line "\r
+                                + _lineCounter + ").");\r
+                        e.printStackTrace();\r
+                        return;\r
+                    }\r
+                } else {\r
+                    System.err.println("Input file corrupt: unknown "\r
+                            + "event type (line " + _lineCounter + ").");\r
+                    return;\r
+                }\r
+                _lineCounter++;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Return the profiles of all processes.\r
+     *\r
+     *  @return profile of all processes\r
+     */\r
+    public HashMap<String, ProcessProfile> getProcessProfiles() {\r
+        return _processProfiles;\r
+    }\r
+\r
+    /**\r
+     * Return the profiles of all channels.\r
+     *\r
+     *  @return profile of all channels\r
+     */\r
+    public HashMap<String, ChannelProfile> getChannelProfiles() {\r
+        return _channelProfiles;\r
+    }\r
+\r
+    /**\r
+     * Return the order in which processes write to channels.\r
+     *\r
+     *  @return profile of all processes\r
+     */\r
+    public HashMap<String, Vector<String>> getProcessCommOrder() {\r
+        return _processCommOrder;\r
+    }\r
+\r
+    /**\r
+     * Return the channel to which the port with the specified name is\r
+     * connected.\r
+     *\r
+     * @param port port name\r
+     * @return name of connected channel\r
+     */\r
+    public String getChannel(String port) {\r
+        if (_inPortToChannelMapping.get(port) != null) {\r
+            return _inPortToChannelMapping.get(port);\r
+        } else if (_outPortToChannelMapping.get(port) != null) {\r
+            return _outPortToChannelMapping.get(port);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Return the type of the channel with the specified name.\r
+     *\r
+     * @param port port name\r
+     * @return type of port\r
+     */\r
+    public String getPortType(String port) {\r
+        if (_inPortToChannelMapping.get(port) != null) {\r
+            return "INPUT";\r
+        } else if (_outPortToChannelMapping.get(port) != null) {\r
+            return "OUTPUT";\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Add a channel profile to the HashMap of channel profiles.\r
+     *\r
+     * @param channelName name of the channel\r
+     * @param capacity capacity of the channel\r
+     * @param portAType type of first port (either "o" or "i")\r
+     * @param processAName name of process connected to first port\r
+     * @param portAName name of first port\r
+     * @param portBType type of second port (either "o" or "i")\r
+     * @param processBName name of process connected to second port\r
+     * @param portBName name of second port\r
+     */\r
+    protected void addChannelProfile(String channelName, int capacity,\r
+            String portAType, String processAName, String portAName,\r
+            String portBType, String processBName, String portBName) {\r
+\r
+        ChannelProfile channelProfile =\r
+            new ChannelProfile(channelName, capacity);\r
+        _channelProfiles.put(channelName, channelProfile);\r
+\r
+        if (portAType.equals("o")) {\r
+            //first output port, then input port\r
+            _outPortToChannelMapping.put(portAName, channelName);\r
+            if (!(portBType.equals("i"))) {\r
+                System.err.println("Input file corrupt: each "\r
+                        + "channel needs one input- and one "\r
+                        + "output port.");\r
+                return;\r
+            }\r
+            _inPortToChannelMapping.put(portBName, channelName);\r
+        } else if (portAType.equals("i")) {\r
+            //first input port, then output port\r
+            _inPortToChannelMapping.put(portAName, channelName);\r
+            if (!(portBType.equals("o"))) {\r
+                System.err.println("Input file corrupt: each "\r
+                        + "channel needs one input- and one "\r
+                        + "output port.");\r
+                return;\r
+            }\r
+            _outPortToChannelMapping.put(portBName, channelName);\r
+        } else {\r
+            System.err.println("Input file corrupt: bad channel "\r
+                    + "specification:");\r
+            System.err.println(channelName + " " + capacity + " "\r
+                    + portAType + " " + processAName + " " + portAName\r
+                    + " "\r
+                    + portBType + " " + processBName + " " + portBName);\r
+        }\r
+    }\r
+\r
+    private BufferedReader _in = null;\r
+    protected int _lineCounter = 0;\r
+    HashMap<String, ProcessProfile> _processProfiles;\r
+    HashMap<String, ChannelProfile> _channelProfiles;\r
+    HashMap<String, String> _inPortToChannelMapping;\r
+    HashMap<String, String> _outPortToChannelMapping;\r
+    HashMap<String, Vector<String>> _processCommOrder;\r
+}\r
diff --git a/dol/src/dol/helper/profiler/Profiler.java b/dol/src/dol/helper/profiler/Profiler.java
new file mode 100644 (file)
index 0000000..e24d456
--- /dev/null
@@ -0,0 +1,212 @@
+/* $Id: Profiler.java 203 2010-10-11 08:59:47Z dchokshi $ */\r
+package dol.helper.profiler;\r
+\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.Vector;\r
+\r
+import dol.datamodel.XmlTag;\r
+import dol.datamodel.pn.Channel;\r
+import dol.datamodel.pn.Port;\r
+import dol.datamodel.pn.Process;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.datamodel.pn.ProfilingConfiguration;\r
+\r
+\r
+/**\r
+ * DOL profiler main class. Reads in profile data and generates the\r
+ * profiling information.\r
+ */\r
+public class Profiler {\r
+\r
+    /**\r
+     * Constructor\r
+     */\r
+    public Profiler() {\r
+    }\r
+\r
+    /**\r
+     * @param name Name of the trace file\r
+     * @param pn The process network need to be annotated\r
+     */\r
+    public void profilePN(String name, ProcessNetwork pn) {\r
+        ProfileParser profileParser = new ProfileParser(name);\r
+        profileParser.parseProfile();\r
+\r
+        HashMap<String, ChannelProfile> channelProfiles =\r
+            profileParser.getChannelProfiles();\r
+        Iterator<String> iterator = channelProfiles.keySet().iterator();\r
+\r
+        while (iterator.hasNext()) {\r
+            ChannelProfile profile = channelProfiles.get(iterator.next());\r
+            Channel channel = pn.getChannel(profile.getName());\r
+            ProfilingConfiguration c = channel.getProfilingCfg(\r
+                    _xt.getProfilingTotalReadData());\r
+            if (c == null) {\r
+                //no profiling present, add new one\r
+                c = new ProfilingConfiguration(\r
+                        _xt.getProfilingTotalReadData());\r
+                c.setValue(Long.toString(profile.getTotalReadData()));\r
+                channel.getProfilingList().add(c);\r
+            } else {\r
+                // profiling already present, extend existing one\r
+                Long curr = Long.decode(c.getValue());\r
+                curr += profile.getTotalReadData();\r
+                c.setValue(Long.toString(curr));\r
+            }\r
+\r
+            c = channel.getProfilingCfg(_xt.getProfilingNumOfReads());\r
+            if (c == null) {\r
+                c = new ProfilingConfiguration(\r
+                        _xt.getProfilingNumOfReads());\r
+                c.setValue(Integer.toString(profile.getNumOfReads()));\r
+                channel.getProfilingList().add(c);\r
+            } else {\r
+                Long curr = Long.decode(c.getValue());\r
+                curr += profile.getNumOfReads();\r
+                c.setValue(Long.toString(curr));\r
+            }\r
+\r
+            c = channel.getProfilingCfg(_xt.getProfilingNumOfWrites());\r
+            if (c == null) {\r
+                c = new ProfilingConfiguration(\r
+                        _xt.getProfilingNumOfWrites());\r
+                c.setValue(Integer.toString(profile.getNumOfWrites()));\r
+                channel.getProfilingList().add(c);\r
+            } else {\r
+                Long curr = Long.decode(c.getValue());\r
+                curr += profile.getNumOfWrites();\r
+                c.setValue( Long.toString(curr) );\r
+            }\r
+        }\r
+\r
+        HashMap<String, ProcessProfile> processProfiles =\r
+            profileParser.getProcessProfiles();\r
+        iterator = processProfiles.keySet().iterator();\r
+\r
+        while (iterator.hasNext()) {\r
+            ProcessProfile profile = processProfiles.get(iterator.next());\r
+            Process process = pn.getProcess(profile.getName());\r
+            ProfilingConfiguration c = process.getProfilingCfg(\r
+                    _xt.getProfilingNumOfFires());\r
+\r
+            if (c == null) {\r
+                c = new ProfilingConfiguration(\r
+                        _xt.getProfilingNumOfFires());\r
+                c.setValue(Integer.toString(profile.getNumOfFires()));\r
+                process.getProfilingList().add(c);\r
+            } else {\r
+                int curr = Integer.valueOf(c.getValue());\r
+                curr += profile.getNumOfFires();\r
+                c.setValue(Integer.toString(curr));\r
+            }\r
+\r
+            HashMap<String, PortProfile> portProfiles =\r
+                profile.getPortProfiles();\r
+            Iterator<String> iteratorB = portProfiles.keySet().iterator();\r
+\r
+            while (iteratorB.hasNext()) {\r
+                PortProfile portProfile =\r
+                    portProfiles.get(iteratorB.next());\r
+                String portName = getPNPortName(portProfile.getName(), profileParser, pn);\r
+                c = new ProfilingConfiguration(portName + ".accesses");\r
+                c.setValue(portProfile.getAccesses().toString());\r
+                process.getProfilingList().add(c);\r
+                c = new ProfilingConfiguration(portName + ".tokensize");\r
+                c.setValue(portProfile.getTokenSize().toString());\r
+                process.getProfilingList().add(c);\r
+                c = new ProfilingConfiguration(portName + ".initialAccesses");\r
+                c.setValue(Integer.toString(portProfile.getInitialAccesses()));\r
+                process.getProfilingList().add(c);\r
+                c = new ProfilingConfiguration(portName + ".initialtokensize");\r
+                c.setValue(portProfile.getInitialTokenSize().toString());\r
+                process.getProfilingList().add(c);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     *\r
+     */\r
+    protected String getPNPortName(String profilePortName,\r
+            ProfileParser parser, ProcessNetwork pn) {\r
+        Vector<Port> ports = pn.getChannel(parser.\r
+                getChannel(profilePortName)).getPortList();\r
+        for (int i = 0; i < ports.size(); i++) {\r
+            if (parser.getPortType(profilePortName).equals("INPUT") &&\r
+                    ports.elementAt(i).isOutPort()) {\r
+                    return ports.elementAt(i).getPeerPort().getName();\r
+            } else if (parser.getPortType(profilePortName).equals("OUTPUT") &&\r
+                    ports.elementAt(i).isInPort()) {\r
+                    return ports.elementAt(i).getPeerPort().getName();\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    /**\r
+     * Main function\r
+     *\r
+     * @param args command line arguments. args[0] is the filename of\r
+     * the profile file. args[1] is the filename of the process network\r
+     * XML file.\r
+     */\r
+    public static void main(String[] args) {\r
+        //check command line parameters\r
+        if (args.length != 2) {\r
+            System.out.println("Usage: Profiler <trace> <pn>");\r
+            System.out.println();\r
+            return;\r
+        }\r
+\r
+        ProfileParser profileParser = new ProfileParser(args[0]);\r
+\r
+        //parse input file\r
+        profileParser.parseProfile();\r
+\r
+        //print the results\r
+        System.out.println("----- Channel Analyzer Report -----");\r
+        System.out.println("<channel name> <maximum fill level> "\r
+                + "<total amount of transferred data> "\r
+                + "<num of reads> <num of writes>");\r
+\r
+        HashMap<String, ChannelProfile> channelProfiles =\r
+            profileParser.getChannelProfiles();\r
+        Iterator<String> iterator = channelProfiles.keySet().iterator();\r
+\r
+        while (iterator.hasNext()) {\r
+            ChannelProfile profile = channelProfiles.get(iterator.next());\r
+            System.out.println( "<" + profile.getName() +\r
+                    "> "\r
+                    + profile.getMaxFillLevel() + " "\r
+                    + profile.getTotalReadData() + " "\r
+                    + profile.getNumOfReads() + " "\r
+                    + profile.getNumOfWrites());\r
+        }\r
+        System.out.println();\r
+\r
+        System.out.println("----- Processnetwork Report -----");\r
+        System.out.println("<process name> <num of activations>");\r
+\r
+        HashMap<String, ProcessProfile> processProfiles =\r
+            profileParser.getProcessProfiles();\r
+        iterator = processProfiles.keySet().iterator();\r
+        while (iterator.hasNext()) {\r
+            ProcessProfile profile = processProfiles.get(iterator.next());\r
+            System.out.println( "<" + profile.getName()\r
+                    + "> " + profile.getNumOfFires());\r
+        }\r
+        System.out.println();\r
+\r
+        /*\r
+        //another test\r
+        PNXmlParser parserPN = new PNXmlParser();\r
+        ProcessNetwork pn = parserPN.doParse(args[1]);\r
+        Profiler p = new Profiler();\r
+        p.profilePN(args[0], pn);\r
+        pn.accept(new PNXmlVisitor("processnetwork.xml"));\r
+        */\r
+    }\r
+\r
+    protected XmlTag _xt = XmlTag.getInstance();\r
+}\r
diff --git a/dol/src/dol/helper/profiler/Range.java b/dol/src/dol/helper/profiler/Range.java
new file mode 100644 (file)
index 0000000..7c7721f
--- /dev/null
@@ -0,0 +1,176 @@
+/* $Id: Range.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.helper.profiler;\r
+\r
+import java.util.Collections;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * Tuple of numbers representing an integer range. Except for an\r
+ * uninitialized range when using the default constructor, the\r
+ * range values are sorted, such that {@link #getLower()} returns\r
+ * the lower bound and {@link #getUpper()} the upper bound of the\r
+ * range.\r
+ */\r
+public class Range {\r
+\r
+    protected int _lower = Integer.MAX_VALUE;\r
+    protected int _upper = Integer.MIN_VALUE;\r
+    protected int _initialLower = Integer.MAX_VALUE;\r
+    protected int _initialUpper = Integer.MIN_VALUE;\r
+    public static final String DELIMITER = "-";\r
+\r
+    /**\r
+     * Default constructor. When merging this range with another\r
+     * range, always the resulting range will have the values of\r
+     * the other range.\r
+     */\r
+    public Range() {\r
+    }\r
+\r
+    /**\r
+     * Construct a range with equal upper and lower bound.\r
+     *\r
+     * @param value upper and lower bound of range\r
+     */\r
+    public Range(int value) {\r
+        _lower = value;\r
+        _upper = value;\r
+        _initialLower = _lower;\r
+        _initialUpper = _upper;\r
+    }\r
+\r
+    /**\r
+     * Construct a range with the two given bounds.\r
+     *\r
+     * @param valueA upper or lower bound\r
+     * @param valueB upper or lower bound\r
+     */\r
+    public Range(int valueA, int valueB) {\r
+        _lower = Math.min(valueA, valueB);\r
+        _upper = Math.max(valueA, valueB);\r
+        _initialLower = _lower;\r
+        _initialUpper = _upper;\r
+    }\r
+\r
+    /**\r
+     * Construct a range with upper and lower bounds that are the minimum\r
+     * and maximum of the given vector.\r
+     *\r
+     * @param values vector whose minimum and maximum value are used as\r
+     *               bounds for the range\r
+     */\r
+    public Range(Vector<Integer> values) {\r
+        if (values == null || values.size() == 0) {\r
+            return;\r
+        }\r
+\r
+        _lower = Collections.min(values);\r
+        _upper = Collections.max(values);\r
+    }\r
+\r
+    /**\r
+     * Return lower bound of this range.\r
+     *\r
+     * @return lower bound\r
+     */\r
+    protected int getLower() {\r
+        return _lower;\r
+    }\r
+\r
+    /**\r
+     * Return upper bound of this range.\r
+     *\r
+     * @return upper bound\r
+     */\r
+    protected int getUpper() {\r
+        return _upper;\r
+    }\r
+\r
+    /**\r
+     * Combine range with another range. The lower bound of the range is\r
+     * the minimum of the lower bounds of this range and the other range.\r
+     * The upper bound of the range is the maximum of the upper bounds of\r
+     * this range and the other range.\r
+     *\r
+     * @param range to combine with this range\r
+     */\r
+    public void merge(Range range) {\r
+        if (range == null)\r
+            return;\r
+\r
+        _lower = Math.min(_lower, range.getLower());\r
+        _upper = Math.max(_upper, range.getUpper());\r
+    }\r
+\r
+    /**\r
+     * Combine range with a value. The lower bound of the range is\r
+     * the minimum of the lower bound of this range and the value.\r
+     * The upper bound of the range is the maximum of the upper bound of\r
+     * this range and the value.\r
+     *\r
+     * @param value integer value to combine with this range\r
+     */\r
+    public void merge(int value) {\r
+        _lower = Math.min(_lower, value);\r
+        _upper = Math.max(_upper, value);\r
+    }\r
+\r
+    /**\r
+     * Create a string representation of the range.\r
+     *\r
+     * @return string representation of the range\r
+     */\r
+    public String toString() {\r
+        if (_upper == _lower)\r
+            return Integer.toString(_upper);\r
+        return _lower + DELIMITER + _upper;\r
+    }\r
+\r
+    /**\r
+     * Create a range based on a string representation of a range.\r
+     *\r
+     * @param string representation of a range\r
+     * @return range\r
+     * @throws IllegalArgumentException\r
+     */\r
+    public static Range valueOf(String string) throws IllegalArgumentException {\r
+        java.util.regex.Pattern pattern =\r
+                java.util.regex.Pattern.compile(\r
+                "([-]?[0-9]+)[" + DELIMITER + "]?([-]?[0-9]+)?");\r
+        java.util.regex.Matcher m = pattern.matcher(string);\r
+        if (!m.matches()) {\r
+            throw new IllegalArgumentException("String does not " +\r
+                    "represent a range.");\r
+        }\r
+        return new Range(Integer.valueOf(m.group(1)),\r
+                Integer.valueOf(m.group(2)));\r
+    }\r
+\r
+    /**\r
+     * Reset this range to the values it had when it has been constructed.\r
+     */\r
+    public void reset() {\r
+        _lower = _initialLower;\r
+        _upper = _initialUpper;\r
+    }\r
+\r
+    /**\r
+     * Test cases for range class.\r
+     */\r
+    public static void main(String args[]) throws Exception {\r
+        Range a = new Range(1);\r
+        System.out.println(a);\r
+\r
+        Range b = new Range(1, 3);\r
+        System.out.println(b);\r
+\r
+        Range c = new Range(4, 3);\r
+        System.out.println(c);\r
+\r
+        b.merge(c);\r
+        System.out.println(b);\r
+\r
+        Range d = Range.valueOf("-123" + Range.DELIMITER + "-456");\r
+        System.out.println(d);\r
+    }\r
+}
\ No newline at end of file
diff --git a/dol/src/dol/helper/profiler/VSPLogFileProfiler.java b/dol/src/dol/helper/profiler/VSPLogFileProfiler.java
new file mode 100644 (file)
index 0000000..dc3b827
--- /dev/null
@@ -0,0 +1,73 @@
+/* $Id: VSPLogFileProfiler.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.helper.profiler;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.FileReader;\r
+import java.io.IOException;\r
+import java.util.StringTokenizer;\r
+\r
+import dol.datamodel.pn.Process;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.datamodel.pn.ProfilingConfiguration;\r
+\r
+/**\r
+ * Class for parsing a file with profiling info and annotate it to a\r
+ * process network.\r
+ */\r
+public class VSPLogFileProfiler {\r
+\r
+    /**\r
+     * Parse the given file and annotate the data to the given process\r
+     * network.\r
+     *\r
+     * @param filename file with profiling info\r
+     * @param pn processnetwork to annotate\r
+     */\r
+    public static void annotateProcessNetwork(String filename,\r
+                                              ProcessNetwork pn) {\r
+        try {\r
+            BufferedReader reader = new BufferedReader(\r
+                    new FileReader(filename));\r
+            String line;\r
+            while ((line = reader.readLine()) != null) {\r
+                StringTokenizer tokenizer =\r
+                            new StringTokenizer(line, " ");\r
+                if (tokenizer.countTokens() == 2) {\r
+                    continue;\r
+                }\r
+                else if (tokenizer.countTokens() <= 2) {\r
+                    System.out.println("Warning: Each line in the log "\r
+                            + "file should have the following form:"\r
+                            + System.getProperty("line.separator")\r
+                            + "processname config_name config_value"\r
+                            + System.getProperty("line.separator")\r
+                            + "Ignoring the non-conforming line:"\r
+                            + System.getProperty("line.separator")\r
+                            + line);\r
+                    continue;\r
+                }\r
+                String processname = tokenizer.nextToken();\r
+                Process process = pn.getProcess(processname);\r
+                if (process == null) {\r
+                    System.out.println("Warning: Could not find process "\r
+                            + processname + " in processnetwork "\r
+                            + pn.getName() + ". Ignore configuration "\r
+                            + "statement in file " + filename + ".");\r
+                    continue;\r
+                }\r
+                ProfilingConfiguration config =\r
+                        new ProfilingConfiguration(tokenizer.nextToken());\r
+                String value = "";\r
+                while (tokenizer.hasMoreTokens()) {\r
+                    value += tokenizer.nextToken() + " ";\r
+                }\r
+                config.setValue(value.trim());\r
+                config.setParentResource(process);\r
+                process.getProfilingList().add(config);\r
+            }\r
+        }\r
+        catch (IOException e) {\r
+            System.out.println(e);\r
+        }\r
+    }\r
+}\r
diff --git a/dol/src/dol/helper/profiler/WorkloadAnnotator.java b/dol/src/dol/helper/profiler/WorkloadAnnotator.java
new file mode 100644 (file)
index 0000000..fb6b19d
--- /dev/null
@@ -0,0 +1,102 @@
+/* $Id: WorkloadAnnotator.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.profiler;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Vector;
+
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.ProfilingConfiguration;
+import dol.parser.xml.pnschema.PNXmlParser;
+import dol.visitor.xml.PNXmlVisitor;
+
+public class WorkloadAnnotator {
+
+    /**
+     * 
+     * @param args
+     */
+    public static void main(String[] args) {
+        String logFile = "workload.txt";
+        String pnFileIn = "processnetwork.xml";
+        String pnFileOut = "processnetwork.xml";
+
+        try {
+            if (args.length > 2) {
+                pnFileIn = args[0];
+                logFile = args[1];
+                pnFileOut = args[1];
+            } else if (args.length == 2) {
+                pnFileIn = args[0];
+                logFile = args[1];
+            } else if (args.length == 1) {
+                pnFileIn = args[0];
+            }
+
+            PNXmlParser parserPN = new PNXmlParser();
+            ProcessNetwork pn = parserPN.doParse(pnFileIn);
+
+            WorkloadAnnotator.annotateProcessNetwork(logFile, pn);
+            StringBuffer b = new StringBuffer();
+            pn.accept(new PNXmlVisitor(b));
+            FileWriter out = new FileWriter(pnFileOut);
+            out.write(b.toString());
+            out.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 
+     * @param workloadFileName
+     * @param pn
+     * @throws IOException
+     */
+    public static void annotateProcessNetwork(String workloadFileName,
+            ProcessNetwork pn) throws IOException {
+        for (Process p : pn.getProcessList()) {
+            Vector<ProfilingConfiguration> v = p.getProfilingList();
+            if (v == null) {
+                p.setProfilingList(new Vector<ProfilingConfiguration>());
+            }
+        }
+
+        BufferedReader in = new BufferedReader(new FileReader(workloadFileName));
+        String line, process, name, value;
+        while ((line = in.readLine()) != null) {
+            if (line.startsWith("wced_")) {
+                process = line.substring("wced_".length()).trim();
+                name = "WCET";
+
+            } else if (line.startsWith("bced_")) {
+                process = line.substring("bced_".length()).trim();
+                name = "BCET";
+
+            } else if (line.startsWith("workload_upper_")) {
+                process = line.substring("workload_upper_".length()).
+                        trim();
+                name = "WORKLOAD_UPPER";
+
+            } else if (line.startsWith("workload_lower_")) {
+                process = line.substring("workload_lower_".length()).
+                        trim();
+                name = "WORKLOAD_LOWER";
+
+            } else {
+                continue;
+            }
+            process = process.substring(0, process.length() - 1).trim();
+
+            in.readLine();
+            value = in.readLine().trim();
+
+            ProfilingConfiguration pc = new ProfilingConfiguration(name);
+            pc.setValue(value);
+            pn.getProcess(process).getProfilingList().add(pc);
+        }
+    }
+}
diff --git a/dol/src/dol/helper/profiler/package.html b/dol/src/dol/helper/profiler/package.html
new file mode 100644 (file)
index 0000000..77be30d
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Profiler to extract parameters from a profiling file.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/helper/validator/XMLValidator.java b/dol/src/dol/helper/validator/XMLValidator.java
new file mode 100644 (file)
index 0000000..b65b9a8
--- /dev/null
@@ -0,0 +1,77 @@
+/* $Id: XMLValidator.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.helper.validator;
+
+import java.io.IOException;
+
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+/**
+ * Class to check well-formedness and validity of XML documents.
+ */
+public class XMLValidator {
+
+    /**
+     * Check the well-formedness and validity of an XML document.
+     * The file is checked against the schema which is referenced from
+     * within the file. When the document is an XML schema, it is checked
+     * against <a href="http://www.w3.org/2001/XMLSchema.xsd"
+     * target="_blank">http://www.w3.org/2001/XMLSchema.xsd</a>.
+     *
+     * @param filename filename of the file to be checked
+     */
+    public static boolean isValid(String filename) {
+        SAXBuilder builder = new SAXBuilder(true);
+        builder.setFeature("http://xml.org/sax/features/validation",
+                true);
+        builder.setFeature("http://apache.org/xml/features/validation/"
+                + "schema", true);
+        builder.setFeature("http://apache.org/xml/features/validation/"
+                + "schema-full-checking", true);
+        builder.setProperty("http://apache.org/xml/properties/schema/"
+                + "external-schemaLocation",
+                "http://www.w3.org/2001/XMLSchema "
+                + "http://www.w3.org/2001/XMLSchema.xsd "
+                + dol.util.SchemaLocation.getExternalSchemaLocation());
+        try {
+            builder.build(filename);
+        }
+        catch (JDOMException e) {
+            System.out.println("Found an error in " + filename + ".");
+            System.out.println(e.getMessage());
+            System.out.println("");
+            return false;
+        }
+        catch (IOException e) {
+            System.out.println("Found an error in " + filename + ".");
+            System.out.println(e.getMessage());
+            System.out.println("");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Main function. We might extend the validator to validate different
+     * kind of XMLs based on different schemas.
+     *
+     * @param args The command line argument.
+     */
+    public static void main(String[] args) {
+
+        /* Check command line parameters */
+        /* maybe add options to check both external/internal schema */
+        if (args.length != 1) {
+            System.out.println("Usage: XMLValidator <file>");
+            System.out.println();
+            return;
+        }
+
+        if (XMLValidator.isValid(args[0])){
+            System.out.println(args[0] + " is valid.");
+        } else {
+            System.exit(1);
+        }
+    }
+}
diff --git a/dol/src/dol/helper/validator/package.html b/dol/src/dol/helper/validator/package.html
new file mode 100644 (file)
index 0000000..b9e7084
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Utilities to check well-formedness and validity of XML documents.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/main/Main.java b/dol/src/dol/main/Main.java
new file mode 100644 (file)
index 0000000..6d0cd95
--- /dev/null
@@ -0,0 +1,263 @@
+/* $Id: Main.java 203 2010-10-11 08:59:47Z dchokshi $ */
+package dol.main;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import dol.check.SanityCheck;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.helper.profiler.Profiler;
+import dol.helper.profiler.VSPLogFileProfiler;
+import dol.helper.profiler.WorkloadAnnotator;
+import dol.parser.xml.archischema.ArchiXmlParser;
+import dol.parser.xml.mapschema.MapXmlParser;
+import dol.parser.xml.pnschema.PNXmlParser;
+import dol.util.CodePrintStream;
+import dol.visitor.PipeAndFilter.PipeAndFilterVisitor;
+import dol.visitor.cell.CellVisitor;
+import dol.visitor.dot.ArchDotVisitor;
+import dol.visitor.dot.MapDotVisitor;
+import dol.visitor.dot.PNDotVisitor;
+import dol.visitor.hds.HdsVisitor;
+import dol.visitor.hdsd.HdsdVisitor;
+import dol.visitor.protothread.ProtothreadVisitor;
+import dol.visitor.rtems.RtemsVisitor;
+import dol.visitor.systemC.PNSystemCVisitor;
+import dol.visitor.xml.PNXmlVisitor;
+import dol.visitor.yapi.YapiVisitor;
+
+/**
+ * Distributed Operating Layer (DOL)
+ *
+ * This class is the main controlling part of DOL. In this class, the
+ * command line options are processed, the input and output files are set,
+ * and the complete compilation cycle is done. Also, this class is the
+ * final responder to exceptions occurring within the DOL.
+ */
+public class Main {
+
+    /**
+     * The main method of this class
+     *
+     * @param args The arguments to provide to DOL.
+     */
+    public static void main(String[] args) {
+
+        _ui = UserInterface.getInstance();
+
+        try {
+            new Options(args);
+        } catch (NumberFormatException e) {
+            System.out.println("Error in Command line options: "
+                               + " the numerial format for an argument is"
+                               + " incorrect. Message: "
+                               + e.getMessage());
+            System.exit(-1);
+        } catch (IllegalArgumentException e) {
+            System.out.println("Error in Command line option: "
+                               + e.getMessage());
+            System.exit(-1);
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            System.exit(-1);
+        }
+
+        try {
+            //loader
+
+            //load process network specification from XML
+            if (_ui.getNetworkFileName() != null) {
+                PNXmlParser parserPN = new PNXmlParser();
+                _pn = parserPN.doParse(_ui.getNetworkFileName());
+            }
+
+            //load architecture specification from XML
+            if (_ui.getPlatformFileName() != null) {
+                ArchiXmlParser parserArch = new ArchiXmlParser();
+                _architecture = parserArch.doParse(
+                        _ui.getPlatformFileName());
+
+                //not useful (archiPathFinderVisitor not functional)
+                //_architecture.setArchiConnections();
+                //_architecture.accept(new dol.visitor.pathFinder.
+                //        archiPathFinderVisitor());
+                //_architecture.accept(new dol.visitor.pathFinder.
+                //        archiPathPrinterVisitor());
+            }
+
+            //load mapping specification from XML
+            if ((_pn != null) && (_architecture != null)
+                    && _ui.getMappingFileName() != null) {
+                MapXmlParser parserMap = new MapXmlParser(_pn, _architecture);
+                _mapping = parserMap.doParse(_ui.getMappingFileName());
+            }
+
+            //sanity check
+            if (_ui.getCheckFlag()){
+                System.out.println("Consistency check:");
+                //check process network
+                if (_pn != null)
+                    SanityCheck.getInstance().checkPN(_pn);
+
+                //check architecture
+                if (_architecture != null)
+                    SanityCheck.getInstance().checkArch(_architecture);
+
+                //check mapping
+                if (_mapping != null)
+                    SanityCheck.getInstance().checkMap(_mapping);
+
+                System.out.println(" -- Consistency check [Finished]");
+                System.out.println();
+            }
+
+            // analyze profiling data and fill into pn
+            if (_ui.getProfilingFlag() && (_pn != null)) {
+                System.out.println(" -- ProcessNetwork profiling");
+                Profiler p = new Profiler();
+                p.profilePN(_ui.getTraceName(), _pn);
+                System.out.println(" -- Profiling [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getVspLogFlag() && (_pn != null)) {
+                System.out.println("VSP log file back-annotation:");
+                VSPLogFileProfiler.annotateProcessNetwork(
+                        _ui.getVspLogFileName(), _pn);
+                System.out.println(" -- Back-annotation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getWorkloadFlag() && (_pn != null)) {
+                System.out.println("Workload file back-annotation:");
+                WorkloadAnnotator.annotateProcessNetwork(
+                        _ui.getWorkloadFileName(), _pn);
+                System.out.println(" -- Back-annotation [Finished]");
+                System.out.println();
+            }
+
+            //Generator
+            CodePrintStream printStream;
+
+            if (_ui.getDottyFlag()) {
+                OutputStream file = new FileOutputStream(_ui.getDottyFileName());
+                printStream = new CodePrintStream(file);
+                if (_mapping != null)
+                {
+                    System.out.println("Generating Mapping in Dotty format:");
+                    _mapping.accept(new MapDotVisitor(printStream));
+                }
+                else if (_pn != null)
+                {
+                    System.out.println("Generating ProcessNetwork in Dotty format:");
+                    _pn.accept(new PNDotVisitor(printStream));
+                }
+                else if (_architecture!=null) {
+                    System.out.println("Generating Architecture in Dotty format:");
+                    _architecture.registerRWPath2Resource();
+                    _architecture.accept(new ArchDotVisitor(printStream));
+                }
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getXmlGenFlag() && (_pn != null)) {
+                System.out.println("Generating ProcessNetwork in XML format:");
+                StringBuffer buffer = new StringBuffer();
+                _pn.accept(new PNXmlVisitor(buffer));
+                try {
+                    java.io.BufferedWriter writer =
+                            new java.io.BufferedWriter(
+                            new java.io.FileWriter(_ui.getOutputFileName()));
+                    writer.write(buffer.toString());
+                    writer.close();
+                } catch (java.io.IOException e) {
+                    System.out.println(" -- DOL caught an exception while "
+                            + "creating XML file: " + e.getMessage());
+                    e.printStackTrace(System.out);
+                }
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getSystemCFlag() && (_pn != null)) {
+                System.out.println("Generating SystemC package:");
+                _pn.accept(new PNSystemCVisitor(_ui.getCodeDirectoryName()));
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getPipeAndFilterFlag() && (_pn != null)) {
+                System.out.println("Generating PipeAndFilter package:");
+                _pn.accept(new PipeAndFilterVisitor(
+                        _ui.getPipeAndFilterCodeDirectoryName()));
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getProtothreadFlag() && (_pn != null)) {
+                System.out.println("Generating protothread package:");
+                _pn.accept(new ProtothreadVisitor(
+                        _ui.getProtothreadCodeDirectoryName()));
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getRtemsFlag() && (_pn != null)) {
+                String bsp = _ui.getRtemsBSP();
+                System.out.println("Generating RTEMS-" + bsp + " package:");
+                _pn.accept(new RtemsVisitor(
+                    _ui.getRtemsCodeDirectoryName()));
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getCbeFlag() && (_pn != null)) {
+                System.out.println("Generating Cell-package:");
+                _pn.accept(new CellVisitor(
+                    _ui.getCbeCodeDirectoryName()));
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+            if (_ui.getYapiFlag() && (_pn != null)) {
+                System.out.println("Generating YAPI-package:");
+                _pn.accept(new YapiVisitor(
+                    _ui.getYapiCodeDirectoryName()));
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+            
+            if (_ui.getHdsFlag() && (_pn != null)) {
+                System.out.println("Generating HdS package:");
+                if ((_pn!=null) && (_architecture!=null) && (_mapping!=null)) {
+                    System.out.println("Generating distributed HdS package:");
+                    // Hds with networking supportSAXException
+                    _mapping.accept(new HdsdVisitor(_ui.getHdsCodeDirectoryName()));
+
+                } else {
+                    // Hds without networking support
+                    _pn.accept(new HdsVisitor(_ui.getHdsCodeDirectoryName()));
+                }
+                System.out.println(" -- Generation [Finished]");
+                System.out.println();
+            }
+
+        }
+        catch (NumberFormatException e) {
+            System.out.println(" ERROR Occured in DOL: " + e.getMessage());
+            e.printStackTrace(System.out);
+        }
+        catch (Exception e) {
+            System.out.println(" DOL caught an exception: " + e.getMessage());
+            e.printStackTrace(System.out);
+        }
+    }
+
+    protected static ProcessNetwork _pn = null;
+    protected static Architecture _architecture = null;
+    protected static Mapping _mapping = null;
+    protected static UserInterface _ui = null;
+}
diff --git a/dol/src/dol/main/Options.java b/dol/src/dol/main/Options.java
new file mode 100644 (file)
index 0000000..b284d90
--- /dev/null
@@ -0,0 +1,207 @@
+/* $Id: Options.java 203 2010-10-11 08:59:47Z dchokshi $ */
+package dol.main;
+
+/**
+ * This class handles the command line options. It checks if an option is
+ * valid, and if so, it calls the appropriate method in the UserInterface,
+ * that reflects the global setting of DOL.
+ */
+public class Options {
+
+    /**
+     * Parse the command-line arguments, creating models as specified. Then
+     * execute each model that contains a manager.
+     *
+     * @param args
+     *            The command-line arguments.
+     * @exception IllegalArgumentException
+     *            MyException If such and such occurs
+     * @throws IllegalArgumentException
+     *             if an illegal argument is found on the command line.
+     */
+    public Options(String args[]) throws IllegalArgumentException, NumberFormatException {
+        _ui = UserInterface.getInstance();
+        if(args != null) {
+            _parseArgs(args);
+        }
+    }
+
+    /**
+     * Parse the command-line arguments.
+     *
+     * @param args The arguments to be parsed
+     *
+     * @throws IllegalArgumentException
+     *             if an illegal argument is found on the command line.
+     */
+    protected void _parseArgs(String args[]) throws IllegalArgumentException,
+        NumberFormatException {
+        if(args.length > 0) {
+            for(int i = 0; i < args.length; i++ ) {
+                String arg = args[i];
+                if(_parseArg(arg) == false ) {
+                    if(arg.startsWith("-") && i < args.length - 1 ) {
+                        if(arg.equals("--platform") || arg.equals("-p") ) {
+                            _ui.setPlatformFileName(args[++i]);
+                        } else if(arg.equals("--processnetwork") || arg.equals("-P") ) {
+                            _ui.setNetworkFileName(args[++i]);
+                        } else if(arg.equals("--mapping") || arg.equals("-m") ) {
+                            _ui.setMappingFileName(args[++i]);
+                        } else if(arg.equals("--scheduler") || arg.equals("-s") ) {
+                            _ui.setSchedulerFileName(args[++i]);
+                        } else if(arg.equals("--systemC") || arg.equals("-C") ) {
+                            _ui.setCodeDirectoryName(args[++i]);
+                            _ui.setSystemCFlag();
+                        } else if(arg.equals("--HdS") || arg.equals("-H") ) {
+                            _ui.setHdsCodeDirectoryName(args[++i]);
+                            _ui.setHdsFlag();
+                        } else if(arg.startsWith("--rtems") || arg.startsWith("-R") ) {
+                            String bsp = arg;
+                            bsp = bsp.replaceAll("--rtems" , "");
+                            bsp = bsp.replaceAll("-R", "");
+                            if (bsp.equals("")) {
+                                _ui.setRtemsBSP("pc386");
+                            } else if (bsp.equals("pc386") || bsp.equals("mparm")) {
+                                _ui.setRtemsBSP(bsp);
+                            } else {
+                                throw new IllegalArgumentException(
+                                        "Board support package \"" + bsp
+                                        + "\" not supported by code generation.");
+                            }
+                            _ui.setRtemsCodeDirectoryName(args[++i]);
+                            _ui.setRtemsFlag();
+                        } else if(arg.equals("--PaF") || arg.equals("-PF") ) {
+                            _ui.setPipeAndFilterCodeDirectoryName(args[++i]);
+                            _ui.setPipeAndFilterFlag();
+                        } else if(arg.equals("--protothread") || arg.equals("-PT") ) {
+                            _ui.setProtothreadCodeDirectoryName(args[++i]);
+                            _ui.setProtothreadFlag();
+                        } else if(arg.equals("--dotty") || arg.equals("-D")) {
+                            _ui.setDottyFileName(args[++i]);
+                        } else if(arg.equals("--profiling") || arg.equals("-T")) {
+                            _ui.setTraceName(args[++i]);
+                            _ui.setProfilingFlag();
+                        } else if (arg.equals("--vsplog") || arg.equals("-L")) {
+                            _ui.setVspLogFileName(args[++i]);
+                            _ui.setVspLogFlag();
+                        } else if (arg.equals("--workload") || arg.equals("-W")) {
+                            _ui.setWorkloadFileName(args[++i]);
+                            _ui.setWorkloadFlag();
+                        } else if(arg.equals("--xmlGen") || arg.equals("-G")) {
+                            _ui.setOutputFileName(args[++i]);
+                            _ui.setXmlGenFlag();
+                        } else if(arg.equals("--cbe") || arg.equals("-CBE")) {
+                               _ui.setCbeCodeDirectoryName(args[++i]); 
+                               _ui.setCbeFlag(); 
+                        } else if(arg.equals("--yapi") || arg.equals("-Y")) {
+                            _ui.setYapiCodeDirectoryName(args[++i]); 
+                            _ui.setYapiFlag(); 
+                        } else {
+                            throw new IllegalArgumentException("Unrecognized option: " + arg);
+                        }
+                    } else {
+                        throw new IllegalArgumentException("Unrecognized option: " + arg);
+                    }
+                }
+            }
+        } else {
+            throw new IllegalArgumentException(_usage());
+        }
+    }
+
+    /**
+     * Parse a single commandline argument.
+     *
+     * @param arg commandline argument
+     * @return true if the argument is understood, false otherwise
+     * @throws IllegalArgumentExcecption thrown if an illegal argument is
+     *                                   found on the command line.
+     */
+    protected boolean _parseArg(String arg) throws IllegalArgumentException {
+        if(arg.equals("--help") || arg.equals("-h") ) {
+            //throw new IllegalArgumentException(_usage());
+            System.out.println(_usage() );
+            System.exit(0);
+        } else if(arg.equals("--version") || arg.equals("-V") ) {
+            System.out.println("DOL version 0.0.1\n");
+            System.exit(0);
+        } else if(arg.equals("--verbose") || arg.equals("-v") ) {
+            _ui.setVerboseFlag();
+        } else if(arg.equals("--check") || arg.equals("-c")) {
+            _ui.setCheckFlag();
+        } else if(arg.equals("--debug")) {
+            _ui.setDebugFlag();
+        } else if(arg.equals("")) { // Ignore blank argument.
+        } else { // Argument not recognized.
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Return a string summarizing the command-line arguments.
+     *
+     * @return A usage string.
+     */
+    protected String _usage() {
+        String result = "Usage: " + _commandTemplate + "\n\n"
+            + "Options:\n";
+
+        int i;
+        for(i = 0; i < _commandOptions.length; i++) {
+            result += " " + _commandOptions[i][0] + "\tabbr["
+                + _commandOptions[i][1] + " " + _commandOptions[i][2]
+                + "]\n";
+        }
+        result += "\nBoolean flags:\n";
+        for(i = 0; i < _commandFlags.length; i++) {
+            result += " " + _commandFlags[i][0] + "\tabbr["
+                + _commandFlags[i][1] + "]\n";
+        }
+        return result;
+    }
+
+    /**
+     * The command-line options that are either present or not. Give the full
+     * name preceded with '--' and abbreviated version.
+     */
+    protected String _commandFlags[][] = {
+        { "--check     ", "-c" },
+        { "--flatten   ", "-F" },
+        { "--help      ", "-h" },
+        { "--version   ", "-V" },
+        { "--verbose   ", "-v" },
+        { "--debug     ", "none" },
+    };
+
+    /**
+     * The command-line options that take arguments.
+     */
+    protected String _commandOptions[][] = {
+        { "--platform      ", "-p ",  "<FileName>" },
+        { "--processnetwork", "-P ",  "<FileName>" },
+        { "--mapping       ", "-m ",  "<FileName>" },
+        { "--scheduler     ", "-s ",  "<FileName>" },
+        { "--dotty         ", "-D ",  "<FileName>" },
+        { "--xmlGen        ", "-G",   "<FileName>" },
+        { "--systemC       ", "-C ",  "<DirectoryName>" },
+        { "--HdS           ", "-H ",  "<DirectoryName>" },
+        { "--PaF           ", "-PF",  "<DirectoryName>" },
+        { "--rtems         ", "-R",   "<DirectoryName>" },
+        { "--protothread   ", "-PT",  "<DirectoryName>" },
+        { "--profiling     ", "-T",   "<trace FileName>" },
+        { "--vsplog        ", "-L",   "<log FileName>" },
+        { "--cbe           ", "-CBE", "<DirectoryName>" },
+        { "--yapi          ", "-Y",   "<DirectoryName>" }
+    };
+
+    /**
+     * The form of the command line.
+     */
+    protected String _commandTemplate = "dol [ options ]";
+
+    /**
+     * The UserInterface object.
+     */
+    protected UserInterface _ui = null;
+}
diff --git a/dol/src/dol/main/UserInterface.java b/dol/src/dol/main/UserInterface.java
new file mode 100644 (file)
index 0000000..f9145ea
--- /dev/null
@@ -0,0 +1,771 @@
+/* $Id: UserInterface.java 203 2010-10-11 08:59:47Z dchokshi $ */
+package dol.main;
+
+import java.util.ResourceBundle;
+
+/**
+ * Class to store commandline arguments and flags.
+ */
+public class UserInterface {
+
+    /**
+     * Get a single instance of the UserInterface object.
+     */
+    private final static UserInterface _instance = new UserInterface();
+
+
+    // the platform file name
+    private String _platformFileName = null;
+
+    // the process network file name
+    private String _networkFileName = null;
+
+    // the mapping file name
+    private String _mappingFileName = null;
+
+    // the scheduler file name
+    private String _schedulerFileName = null;
+
+    // the dotty file name
+    private String _dottyFileName = "dotty.dot";
+
+    // the systemc directory name
+    private String _codeDirectoryName = "nonamePackage";
+
+    // the pipeandfilter directory name
+    private String _pipeCodeDirectoryName = "nonamePipePackage";
+
+    // the hds directory name
+    private String _hdsCodeDirectoryName = "nonameHdsPackage";
+
+    // the RTEMS directory name
+    private String _rtemsCodeDirectoryName = "nonameHdsPackage";
+
+    // the RTEMS board support package for which code is generated
+    private String _rtemsBSP = "pc386";
+
+    // the protothread directory name
+    private String _protothreadCodeDirectoryName = "nonameHdsPackage";
+
+    // the CBE directory name
+    private String _cbeCodeDirectoryName = "nonameCbePackage";
+
+    // the Yapi directory name
+    private String _yapiCodeDirectoryName = "nonameYapiPackage";
+
+
+    // trace filename
+    private String _traceName = "";
+
+    // the xml generation flag
+    private boolean _xmlGen = false;
+
+    // the trace flag
+    private boolean _profiling = false;
+
+    // the verbose flag
+    private boolean _verbose = false;
+
+    // the vsp log flag
+    private boolean _vsplog = false;
+
+    // the name of the vsp log file
+    private String _vspLogFileName = "";
+
+    // the workload annotation flag
+    private boolean _workload = false;
+
+    // the name of the workload file produces by Matlab
+    private String _workloadFileName = "";
+
+    // the SystemC flag
+    private boolean _systemC = false;
+
+    // the PipeAndFilter flag
+    private boolean _pipeAndFilter = false;
+
+    // the HdS flag
+    private boolean _hds = false;
+
+    // the RTEMS flag
+    private boolean _rtems = false;
+
+    // the CBE flag
+    private boolean _cbe = false;
+
+    // the YAPI flag
+    private boolean _yapi = false;
+
+    // the RTEMS flag
+    private boolean _protothread = false;
+
+    // the debug flag
+    private boolean _debug = false;
+
+    // the dotty flag
+    private boolean _dotty = false;
+
+    // the check flag
+    private boolean _check = false;
+
+    // the path finder flag
+    private boolean _archiPaths = true;
+
+    // the basepath name
+    private String _basePath = ".";
+
+    // the filename
+    private String _outputFileName = "";
+
+    // ResourceBundle
+    private ResourceBundle _rb;
+    private String _rbFileName = "dol";
+
+
+    public final String getMySystemCLib() {
+        /*
+        return _rb.getString("DOL_path") + getDelimiter()
+                + "src" + getDelimiter() + "dol" + getDelimiter()
+                + "visitor" + getDelimiter() + "systemC" + getDelimiter()
+                + "lib";
+        */
+
+        return this.getClass().getResource(
+            "/dol/visitor/systemC/lib").getFile();
+    }
+
+   public final String getVisitorDir(){
+        return this.getClass().getResource("/dol/visitor/").getFile();
+    }
+
+    public final String getDOLPath() { return _rb.getString("DOL_path"); }
+    public final String getSystemCINC(){return _rb.getString("SYSTEMC_INC");}
+    public final String getSystemCLIB(){return _rb.getString("SYSTEMC_LIB");}
+
+    /**
+     * returns the singleton instance of this class.
+     *
+     * @return The instance value
+     */
+    public final static UserInterface getInstance() {
+        return _instance;
+    }
+
+    /**
+     * Get the name of the platform file.
+     *
+     * @return The platformFileName value
+     */
+    public final String getPlatformFileName() {
+        return _platformFileName;
+    }
+
+    /**
+     * Set the name of the platform file.
+     *
+     * @param platformFileName
+     *            The new platformFileName value
+     */
+    public final void setPlatformFileName(String platformFileName) {
+        _platformFileName = platformFileName;
+    }
+
+    /**
+     * Get the name of the process network file.
+     *
+     * @return The networkFileName value
+     */
+    public final String getNetworkFileName() {
+        return _networkFileName;
+    }
+
+    /**
+     * Set the name of the process network file.
+     *
+     * @param networkFileName
+     *            The new networkFileName value
+     */
+    public final void setNetworkFileName(String networkFileName) {
+        _networkFileName = networkFileName;
+    }
+
+    /**
+     * Get the name of the mapping file.
+     *
+     * @return The mappingFileName value
+     */
+    public final String getMappingFileName() {
+        return _mappingFileName;
+    }
+
+    /**
+     * Set the name of the mapping file.
+     *
+     * @param mappingFileName
+     *            The new mappingFileName value
+     */
+    public final void setMappingFileName(String mappingFileName) {
+        _mappingFileName = mappingFileName;
+    }
+
+
+    /**
+     * Get the name of the scheduler file.
+     *
+     * @return The schedulerFileName value
+     */
+    public final String getSchedulerFileName() {
+        return _schedulerFileName;
+    }
+
+    /**
+     * Set the name of the scheduler file.
+     *
+     * @param schedulerFileName
+     *            The new schedulerFileName value
+     */
+    public final void setSchedulerFileName(String schedulerFileName) {
+        _schedulerFileName = schedulerFileName;
+    }
+
+
+    /**
+     * Get the name of the dotty file..
+     *
+     * @return The dottyFileName value
+     */
+    public final String getDottyFileName() {
+        return _dottyFileName;
+    }
+
+    /**
+     * Set the name of the directory where the SystemC code shall be generated.
+     *
+     * @param dottyFileName The dotty file name.
+     */
+    public final void setDottyFileName(String dottyFileName) {
+        _dottyFileName = dottyFileName;
+        setDottyFlag();
+    }
+
+
+    /**
+     * Get the name of the SystemC directory.
+     *
+     * @return The directory name of the SystemC directory
+     */
+    public final String getCodeDirectoryName() {
+        return _codeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the SystemC code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setCodeDirectoryName(String codeDirectoryName) {
+        _codeDirectoryName = codeDirectoryName;
+    }
+
+    /**
+     * Get the name of the PipeAndFilter directory.
+     *
+     * @return The directory name of the PipeAndFilter directory
+     */
+    public final String getPipeAndFilterCodeDirectoryName() {
+        return _pipeCodeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the Hds code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setPipeAndFilterCodeDirectoryName(String codeDirectoryName) {
+        _pipeCodeDirectoryName = codeDirectoryName;
+    }
+
+    /**
+     * Get the name of the Hds directory.
+     *
+     * @return The directory name of the Hds directory
+     */
+    public final String getHdsCodeDirectoryName() {
+        return _hdsCodeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the Hds code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setHdsCodeDirectoryName(String codeDirectoryName) {
+        _hdsCodeDirectoryName = codeDirectoryName;
+    }
+
+    /**
+     * Get the name of the protothread directory.
+     *
+     * @return The directory name of the protohread directory
+     */
+    public final String getProtothreadCodeDirectoryName() {
+        return _protothreadCodeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the protothread code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setProtothreadCodeDirectoryName(String codeDirectoryName) {
+        _protothreadCodeDirectoryName = codeDirectoryName;
+    }
+
+    /**
+     * Get the name of the CBE directory.
+     *
+     * @return The directory name of the CBE directory
+     */
+    public final String getCbeCodeDirectoryName() {
+        return _cbeCodeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the CBE code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setCbeCodeDirectoryName(String codeDirectoryName) {
+        _cbeCodeDirectoryName = codeDirectoryName;
+    }
+
+    /**
+     * Get the name of the YAPI directory.
+     *
+     * @return The directory name of the CBE directory
+     */
+    public final String getYapiCodeDirectoryName() {
+        return _yapiCodeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the YAPI code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setYapiCodeDirectoryName(String codeDirectoryName) {
+        _yapiCodeDirectoryName = codeDirectoryName;
+    }
+    
+    /**
+     * Get the name of the RTEMS directory.
+     *
+     * @return The directory name of the RTEMS directory
+     */
+    public final String getRtemsCodeDirectoryName() {
+        return _rtemsCodeDirectoryName;
+    }
+
+    /**
+     * Set the name of the directory where the RTEMS code shall be generated.
+     *
+     * @param codeDirectoryName The code directory
+     */
+    public final void setRtemsCodeDirectoryName(String codeDirectoryName) {
+        _rtemsCodeDirectoryName = codeDirectoryName;
+    }
+
+    /**
+     * Get the name of the RTEMS board support package.
+     *
+     * @return The name of the board support package
+     */
+    public final String getRtemsBSP() {
+        return _rtemsBSP;
+    }
+
+    /**
+     * Set the name of the board support package for which RTEMS code shall
+     * be generated.
+     *
+     * @param bsp board support package for which code is generated
+     *            currently supported: pc386, mparm
+     */
+    public final void setRtemsBSP(String bsp) {
+        _rtemsBSP = bsp;
+    }
+
+    /**
+     * Get the status of the Verbose flag.
+     *
+     * @return verbose flag value
+     */
+    public final boolean getVerboseFlag() {
+        return _verbose;
+    }
+
+    /**
+     * Set the Verbose flag.
+     */
+    public final void setVerboseFlag() {
+        _verbose = true;
+    }
+
+    /**
+     * Get the status of the Debug flag.
+     *
+     * @return debug flag value
+     */
+    public final boolean getDebugFlag() {
+        return _debug;
+    }
+
+    /**
+     * Set the debug flag.
+     */
+    public final void setDebugFlag() {
+        _debug = true;
+    }
+
+    /**
+     * Get the status of the SystemC flag
+     *
+     * @return The systemC flag value
+     */
+    public final boolean getSystemCFlag() {
+        return _systemC;
+    }
+
+    /**
+     * Set the SystemC flag.
+     */
+    public final void setSystemCFlag() {
+        _systemC = true;
+    }
+
+    /**
+     * Get the status of the PipeAndFilter flag.
+     *
+     * @return PipeAndFilter flag value
+     */
+    public final boolean getPipeAndFilterFlag() {
+        return _pipeAndFilter;
+    }
+
+    /**
+     * Set the PipeAndFilter flag.
+     */
+    public final void setPipeAndFilterFlag() {
+        _pipeAndFilter = true;
+    }
+
+    /**
+     * Get the status of the protothread flag.
+     *
+     * @return PipeAndFilter flag value
+     */
+    public final boolean getProtothreadFlag() {
+        return _protothread;
+    }
+
+    /**
+     * Set the protothread flag.
+     */
+    public final void setProtothreadFlag() {
+        _protothread = true;
+    }
+
+    /**
+     * Get the status of the HdS flag.
+     *
+     * @return The HdS flag value
+     */
+    public final boolean getHdsFlag() {
+        return _hds;
+    }
+
+    /**
+     * Set the HdS flag.
+     */
+    public final void setHdsFlag() {
+        _hds = true;
+    }
+
+    /**
+     * Get the status of the RTEMS flag.
+     *
+     * @return The HdS flag value
+     */
+    public final boolean getRtemsFlag() {
+        return _rtems;
+    }
+
+    /**
+     * Set the RTEMS flag.
+     */
+    public final void setRtemsFlag() {
+        _rtems = true;
+    }
+
+    /**
+     * Get the status of the CBE flag.
+     *
+     * @return The CBE flag value
+     */
+    public final boolean getCbeFlag() {
+        return _cbe;
+    }
+
+    /**
+     * Set the CBE flag.
+     */
+    public final void setCbeFlag() {
+        _cbe = true;
+    }
+
+    /**
+     * Set the YAPI flag.
+     */
+    public final void setYapiFlag() {
+        _yapi = true;
+    }
+
+    /**
+     * Get the status of the YAPI flag.
+     *
+     * @return The YAPI flag value
+     */
+    public final boolean getYapiFlag() {
+        return _yapi;
+    }
+
+    /**
+     * Get the status of the dotty flag
+     *
+     * @return The dotty Flag value
+     */
+    public final boolean getDottyFlag() {
+        return _dotty;
+    }
+
+    /**
+     * Sets the dotty flag
+     */
+    public final void setDottyFlag() {
+        _dotty = true;
+    }
+
+    /**
+     * Get the status of the profiling flag
+     *
+     * @return The profiling Flag value
+     */
+    public final boolean getProfilingFlag() {
+        return _profiling;
+    }
+
+    /**
+     * Sets the profiling flag
+     */
+    public final void setProfilingFlag() {
+        _profiling = true;
+    }
+
+    /**
+     * Get the status of the vsp log flag.
+     *
+     * @return The vsp log value
+     */
+    public final boolean getVspLogFlag() {
+        return _vsplog;
+    }
+
+    /**
+     * Sets the vsp log flag.
+     */
+    public final void setVspLogFlag() {
+        _vsplog = true;
+    }
+
+    /**
+     * Get the status of the workload annotation flag.
+     *
+     * @return workload flag
+     */
+    public final boolean getWorkloadFlag() {
+        return _workload;
+    }
+
+    /**
+     * Sets the workload flag.
+     */
+    public final void setWorkloadFlag() {
+        _workload = true;
+    }
+
+    /**
+     * Get the status of the xml generation flag
+     *
+     * @return The xmlGen Flag value
+     */
+    public final boolean getXmlGenFlag() {
+        return _xmlGen;
+    }
+
+    /**
+     * Sets the xml generation flag
+     */
+    public final void setXmlGenFlag() {
+        _xmlGen = true;
+    }
+
+    /**
+     * Get the status of the check flag
+     *
+     * @return The check Flag value
+     */
+    public final boolean getCheckFlag() {
+        return _check;
+    }
+
+    /**
+     * Sets the check flag
+     */
+    public final void setCheckFlag() {
+        _check = true;
+    }
+
+    /**
+     * Get the status of the path finder flag
+     *
+     * @return The path finder Flag value
+     */
+    public final boolean getPathsFlag() {
+        return _archiPaths;
+    }
+
+    /**
+     * Sets the check flag
+     */
+    public final void setPathsFlag() {
+        _archiPaths = true;
+    }
+
+    /**
+     * Print a message to screen if the verbose flag has been selected with an
+     * end-of-line.
+     *
+     * @param s description that needs to printed.
+     */
+    public void printVerbose(String s) {
+        if ( getVerboseFlag() ) {
+            System.out.print(s);
+        }
+    }
+
+    /**
+     * Print a message to screen if the verbose flag has been selected.
+     *
+     * @param s description that needs to printed.
+     */
+    public void printlnVerbose(String s) {
+        if( getVerboseFlag() ) {
+            System.out.println(s);
+        }
+    }
+
+
+    /**
+     * get the name of the output file name.
+     *
+     * @return The outputFileName value
+     */
+    public final String getOutputFileName() {
+        return _outputFileName;
+    }
+
+    /**
+     * set the name of the input file name.
+     *
+     * @param filename The new outputFileName value
+     */
+    public final void setOutputFileName(String filename) {
+        _outputFileName = filename;
+    }
+
+    /**
+     * get the base path name.
+     *
+     * @return The basePath value
+     */
+    public final String getBasePath() { return _basePath; }
+
+    /**
+     * sets the base path name.
+     *
+     * @param name
+     *            The new basePath value
+     */
+    public final void setBasePath(String name) { _basePath = name; }
+
+    /**
+     * get the trace filename.
+     *
+     * @return The name value of trace file
+     */
+    public final String getTraceName() { return _traceName; }
+
+    /**
+     * sets the trace Filename.
+     *
+     * @param name trace filename
+     */
+    public final void setTraceName(String name) {
+        _traceName = name;
+    }
+
+
+    /**
+     * Get the vsp log filename.
+     *
+     * @return name of the vsp log file
+     */
+    public final String getVspLogFileName() {
+        return _vspLogFileName;
+    }
+
+    /**
+     * Set the vsp log filename.
+     *
+     * @param name vsp log filename
+     */
+    public final void setVspLogFileName(String name) {
+        _vspLogFileName = name;
+    }
+
+    /**
+     * Get the workload filename.
+     *
+     * @return name workload filename
+     */
+    public final String getWorkloadFileName() {
+        return _workloadFileName;
+    }
+
+    /**
+     * Sets the workload filename.
+     *
+     * @param name workload filename
+     */
+    public final void setWorkloadFileName(String name) {
+        _workloadFileName = name;
+    }
+
+    /**
+     * Constructor. Private since only a single version may exist.
+     */
+    private UserInterface() {
+        _rb = ResourceBundle.getBundle(_rbFileName);
+    }
+}
+
diff --git a/dol/src/dol/main/package.html b/dol/src/dol/main/package.html
new file mode 100644 (file)
index 0000000..d7cb962
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+DOL main program (commandline handling and dispatching of functions).
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/parser/xml/XmlErrorHandler.java b/dol/src/dol/parser/xml/XmlErrorHandler.java
new file mode 100644 (file)
index 0000000..d1105bd
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id: XmlErrorHandler.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.parser.xml;
+
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ *  This class ...
+ */
+
+public class XmlErrorHandler extends DefaultHandler {
+
+    /**
+     * Empty constructor
+     */
+    public XmlErrorHandler() {
+        super();
+    }
+
+    /**
+     *  Treat validation errors as fatal
+     *
+     * @param  e Description of the Parameter
+     * @exception  SAXParseException MyException If such and such occurs
+     */
+    public void error(SAXParseException e)
+             throws SAXParseException {
+        System.out.println("Error found: " + e.getMessage());
+        throw e;
+    }
+
+    /**
+     *  Dump warnings too
+     *
+     * @param  err Description of the Parameter
+     * @exception  SAXParseException MyException If such and such occurs
+     */
+    public void warning(SAXParseException err)
+             throws SAXParseException {
+        System.out.println("** Warning"
+                + ", line " + err.getLineNumber()
+                + ", uri " + err.getSystemId());
+        System.out.println("   " + err.getMessage());
+    }
+}
diff --git a/dol/src/dol/parser/xml/XmlParser.java b/dol/src/dol/parser/xml/XmlParser.java
new file mode 100644 (file)
index 0000000..2032788
--- /dev/null
@@ -0,0 +1,84 @@
+/* $Id: XmlParser.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.parser.xml;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.xerces.parsers.SAXParser;
+import org.xml.sax.SAXException;
+
+import dol.main.UserInterface;
+
+/**
+ * Parser for DOL XML files.
+ */
+public class XmlParser extends org.xml.sax.helpers.DefaultHandler {
+
+    /**
+     * Constructor. Initializes the parser.
+     */
+    public XmlParser() {
+        super();
+        try {
+            _parser = new SAXParser();
+            _parser.setFeature("http://xml.org/sax/features/validation",
+                    true);
+            _parser.setFeature("http://apache.org/xml/features/"
+                    + "validation/schema", true);
+            _parser.setFeature("http://apache.org/xml/features/"
+                    + "validation/schema-full-checking", true);
+            _parser.setErrorHandler(new XmlErrorHandler());
+            _parser.setContentHandler(this);
+            _parser.setProperty("http://apache.org/xml/properties/schema/"
+                    + "external-schemaLocation",
+                    dol.util.SchemaLocation.getInternalSchemaLocation());
+            _parser.setContentHandler(this);
+            _parser.setErrorHandler(new XmlErrorHandler());
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    /**
+     * Return a absolute URL reference for the given URL.
+     *
+     * @param url url
+     * @return absolute URL reference
+     */
+    protected String _makeAbsoluteURL(String url)
+         throws MalformedURLException {
+        URL baseURL;
+        String fileSep = System.getProperty("file.separator");
+        String base = "";
+        
+        // Replace all separators in given URL
+        url = url.replace(fileSep.charAt(0), '/');
+        
+        // Add working directory if URL is not absolute
+        if (url.charAt(0) != '/' && !url.matches("^[A-Za-z]:/.*")) {
+            base = System.getProperty("user.dir") + '/';
+            base = base.replace(fileSep.charAt(0), '/');
+            if (base.charAt(0) != '/') {
+                base = "/" + base;
+            }
+        }
+        
+        // Add front slash to Windows style URLs
+        if (url.matches("^[A-Za-z]:/.*")) {
+            url = "/" + url;
+        }
+        
+        baseURL = new URL("file", null, base);
+        System.out.println(" -- full filename: "
+                + new URL(baseURL, url).toString());
+        return new URL(baseURL, url).toString();
+    }
+
+    /** XML parser */
+    protected SAXParser _parser;
+
+    /** user interface used for messages for users */
+    protected UserInterface _ui = UserInterface.getInstance();
+}
diff --git a/dol/src/dol/parser/xml/archischema/ArchiXmlParser.java b/dol/src/dol/parser/xml/archischema/ArchiXmlParser.java
new file mode 100644 (file)
index 0000000..38b1c05
--- /dev/null
@@ -0,0 +1,187 @@
+/* $Id: ArchiXmlParser.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.parser.xml.archischema;\r
+\r
+import java.util.Stack;\r
+\r
+import org.xml.sax.Attributes;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.SAXParseException;\r
+\r
+import dol.datamodel.XmlTag;\r
+import dol.datamodel.architecture.Architecture;\r
+import dol.parser.xml.XmlParser;\r
+\r
+/**\r
+ * Parse architecture XML file.\r
+ */\r
+public class ArchiXmlParser extends XmlParser {\r
+\r
+    /**\r
+     * Constructor.\r
+     */\r
+    public ArchiXmlParser() {\r
+        super();\r
+        _stack = new Stack<Object>();\r
+        _xml2Archi = new Xml2Archi();\r
+    }\r
+\r
+    /**\r
+     * Do the parsing of an XML file describing an architecture.\r
+     *\r
+     * @param url The input XML file\r
+     * @return the architecture\r
+     */\r
+    public Architecture doParse(String url)  {\r
+        Architecture architecture = null;\r
+        System.out.println("Read architecture from XML file");\r
+\r
+        try {\r
+            String uri = _makeAbsoluteURL(url);\r
+            _ui.printlnVerbose("-- processing XML file: " + uri);\r
+            _ui.printlnVerbose("-- read XML file: ");\r
+            _stack.clear();\r
+            _parser.parse(new InputSource(uri));\r
+            architecture = (Architecture) _stack.pop();\r
+            _ui.printlnVerbose(" [DONE] ");\r
+        } catch (SAXParseException err) {\r
+            System.out.println("** Parsing error, line "\r
+                + err.getLineNumber() + ", uri " + err.getSystemId());\r
+            System.out.println("   " + err.getMessage());\r
+        } catch (SAXException e) {\r
+            e.printStackTrace();\r
+        } catch (Throwable t) {\r
+            t.printStackTrace();\r
+        }\r
+\r
+        architecture.computePaths();\r
+\r
+        System.out.println(" -- Architecture model from XML "\r
+                + "[Finished]");\r
+        System.out.println();\r
+\r
+        return architecture;\r
+    }\r
+\r
+    /**\r
+     * Action to be done while parsing a start element of an XML.\r
+     *\r
+     * @param elementName Description of the Parameter\r
+     * @param attributes Description of the Parameter\r
+     * @exception  SAXException MyException If such and such occurs\r
+     */\r
+    public void startElement(String namespaceURI, String localName,\r
+            String elementName, Attributes attributes)\r
+            throws SAXException {\r
+        Object val = null;\r
+\r
+        if (elementName.equals(_xt.getArchiTag())) {\r
+            val = _xml2Archi.processArchitecture(attributes);\r
+        } else if (elementName.equals(_xt.getVariableTag())) {\r
+            val = _xml2Archi.processVariable(attributes);\r
+        } else if (elementName.equals(_xt.getProcessorTag())) {\r
+            val = _xml2Archi.processProcessor(attributes);\r
+        } else if (elementName.equals(_xt.getMemoryTag())) {\r
+            val = _xml2Archi.processMemory(attributes);\r
+        } else if (elementName.equals(_xt.getHWChannelTag())) {\r
+            val = _xml2Archi.processHWChannel(attributes);\r
+        } else if (elementName.equals(_xt.getConfigurationTag())) {\r
+            val = _xml2Archi.processConfiguration(attributes);\r
+        // simplified architecture\r
+        } else if (elementName.equals(_xt.getConnectionTag())) {\r
+            val = _xml2Archi.processConnection(attributes);\r
+        } else if (elementName.equals(_xt.getOriginTag())) {\r
+            val = _xml2Archi.processOrigin(attributes);\r
+        } else if (elementName.equals(_xt.getTargetTag())) {\r
+            val = _xml2Archi.processTarget(attributes);\r
+        } else if (elementName.equals(_xt.getNodeTag())) {\r
+            val = _xml2Archi.processNode(attributes);\r
+        } else if (elementName.equals(_xt.getPortTag())) {\r
+            val = _xml2Archi.processPort(attributes);\r
+        } else if (elementName.equals(_xt.getInPortTag())) {\r
+            val = _xml2Archi.processInputPort(attributes);\r
+        } else if (elementName.equals(_xt.getOutPortTag())) {\r
+            val = _xml2Archi.processOutputPort(attributes);\r
+        } else if (elementName.equals(_xt.getDuplexPortTag())) {\r
+            val = _xml2Archi.processInOutPort(attributes);\r
+        // detailed architecture\r
+        } else if (elementName.equals(_xt.getReadPathTag())) {\r
+            val = _xml2Archi.processReadPath(attributes);\r
+        } else if (elementName.equals(_xt.getWritePathTag())) {\r
+            val = _xml2Archi.processWritePath(attributes);\r
+        } else if (elementName.equals(_xt.getTXBufTag())) {\r
+            val = _xml2Archi.processTXBuf(attributes);\r
+        } else if (elementName.equals(_xt.getRXBufTag())) {\r
+            val = _xml2Archi.processRXBuf(attributes);\r
+        } else if (elementName.equals(_xt.getCHBufTag())) {\r
+            val = _xml2Archi.processCHBuf(attributes);\r
+        } else {\r
+            System.out.println("--Warning, DOL doesn't "\r
+                    + "understand tag <" + elementName + "> ");\r
+        }\r
+\r
+        if (val != null) {\r
+            _stack.push(val);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Action to be done while parsing an end element of an XML.\r
+     *\r
+     * @param elementName Description of the Parameter\r
+     * @exception SAXException MyException If such and such occurs\r
+     */\r
+    public void endElement(String namespaceURI, String localName,\r
+            String elementName) throws SAXException {\r
+        if (elementName.equals(_xt.getArchiTag())) {\r
+            _xml2Archi.processArchitecture(_stack);\r
+        } else if (elementName.equals(_xt.getVariableTag())) {\r
+            _xml2Archi.processVariable(_stack);\r
+        } else if (elementName.equals(_xt.getProcessorTag())) {\r
+            _xml2Archi.processProcessor(_stack);\r
+        } else if (elementName.equals(_xt.getMemoryTag())) {\r
+            _xml2Archi.processMemory(_stack);\r
+        } else if (elementName.equals(_xt.getHWChannelTag())) {\r
+            _xml2Archi.processHWChannel(_stack);\r
+        } else if (elementName.equals(_xt.getConfigurationTag())) {\r
+            _xml2Archi.processConfiguration(_stack);\r
+        // simplified architecture\r
+        } else if (elementName.equals(_xt.getConnectionTag())) {\r
+            _xml2Archi.processConnection(_stack);\r
+        } else if (elementName.equals(_xt.getOriginTag())) {\r
+            _xml2Archi.processOrigin(_stack);\r
+        } else if (elementName.equals(_xt.getTargetTag())) {\r
+            _xml2Archi.processTarget(_stack);\r
+        } else if (elementName.equals(_xt.getNodeTag())) {\r
+            _xml2Archi.processNode(_stack);\r
+        } else if (elementName.equals(_xt.getPortTag())) {\r
+            _xml2Archi.processPort(_stack);\r
+        } else if (elementName.equals(_xt.getInPortTag())) {\r
+            _xml2Archi.processInputPort(_stack);\r
+        } else if (elementName.equals(_xt.getOutPortTag())) {\r
+            _xml2Archi.processOutputPort(_stack);\r
+        } else if (elementName.equals(_xt.getDuplexPortTag())) {\r
+            _xml2Archi.processInOutPort(_stack);\r
+        // detailed architecture\r
+        } else if (elementName.equals(_xt.getReadPathTag())) {\r
+            _xml2Archi.processReadPath(_stack);\r
+        } else if (elementName.equals(_xt.getWritePathTag())) {\r
+            _xml2Archi.processWritePath(_stack);\r
+        } else if (elementName.equals(_xt.getTXBufTag())) {\r
+            _xml2Archi.processTXBuf(_stack);\r
+        } else if (elementName.equals(_xt.getRXBufTag())) {\r
+            _xml2Archi.processRXBuf(_stack);\r
+        } else if (elementName.equals(_xt.getCHBufTag())) {\r
+            _xml2Archi.processCHBuf(_stack);\r
+        }\r
+    }\r
+\r
+    /** stack containing the generated objects */\r
+    protected Stack<Object> _stack;\r
+\r
+    /** actions to be taken while parsing every XML element */\r
+    protected Xml2Archi _xml2Archi;\r
+\r
+    /** */\r
+    protected XmlTag _xt = XmlTag.getInstance();\r
+}\r
diff --git a/dol/src/dol/parser/xml/archischema/Xml2Archi.java b/dol/src/dol/parser/xml/archischema/Xml2Archi.java
new file mode 100644 (file)
index 0000000..49d7409
--- /dev/null
@@ -0,0 +1,630 @@
+/* $Id: Xml2Archi.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.parser.xml.archischema;
+
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+
+import dol.datamodel.architecture.ArchiConnection;
+import dol.datamodel.architecture.ArchiResource;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.Configuration;
+import dol.datamodel.architecture.HWChannel;
+import dol.datamodel.architecture.Memory;
+import dol.datamodel.architecture.Node;
+import dol.datamodel.architecture.PortNode;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.architecture.ReadPath;
+import dol.datamodel.architecture.Variable;
+import dol.datamodel.architecture.WritePath;
+
+/**
+ * Parse architecture XML file.
+ */
+public class Xml2Archi {
+
+    /**
+     * Constructor.
+     */
+    public Xml2Archi() {
+    }
+
+    /**
+     * Process the start of the Architecture tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return an Architecture object
+     */
+    public Architecture processArchitecture(Attributes attributes) {
+        Architecture arch = new Architecture(attributes.getValue("name"));
+        return arch;
+
+    }
+
+    /**
+     * Process the end of the Architecture tag in the XML.
+     *
+     * @param stack
+     */
+    public void processArchitecture(Stack<Object> stack) {
+    }
+
+    /**
+     * Process the start of a processor tag in the XML.
+     *
+     * @param attributes The attributes of the tag.
+     * @return a processor object.
+     */
+    public Processor processProcessor(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+        String type = (String) attributes.getValue("type");
+        Processor processor = new Processor(name);
+        if (basename != null) processor.setBasename(basename);
+        if (range != null) processor.setRange(range);
+        if (type != null) processor.setType(type);
+        return processor;
+    }
+
+    /**
+     * Process the end of a processor tag in the XML.
+     *
+     * @param stack
+     */
+    public void processProcessor(Stack<Object> stack) {
+        Processor p = (Processor) stack.pop();
+
+        if (stack.peek() instanceof ReadPath) {
+            ReadPath r = (ReadPath) stack.peek();
+            Processor pro = ((Architecture)stack.elementAt(0)).
+                    getProcessor(p.getName());
+            if (pro != null) {
+                r.setProcessor(pro);
+            }
+            else {
+                undefinedReference("ReadPath", r.getName(),
+                        "processor", p.getName());
+            }
+        } else if (stack.peek() instanceof WritePath) {
+            WritePath w = (WritePath) stack.peek();
+            Processor pro = ((Architecture)stack.elementAt(0)).
+                    getProcessor(p.getName());
+            if (pro != null) {
+                w.setProcessor(pro);
+            }
+            else {
+                undefinedReference("ReadPath", w.getName(),
+                        "processor", p.getName());
+            }
+        } else if (stack.peek() instanceof Architecture) {
+            Architecture a = (Architecture)stack.peek();
+            p.setParentResource(a);
+            a.getProcessorList().add(p);
+        }
+    }
+
+    /**
+     * Process the start of a memory tag in the XML.
+     *
+     * @param attributes The attributes of the tag.
+     * @return a memory object.
+     */
+    public Memory processMemory(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+        String type = (String) attributes.getValue("type");
+        Memory memory = new Memory(name);
+        if (basename != null) memory.setBasename(basename);
+        if (range != null) memory.setRange(range);
+        if (type != null) memory.setRange(type);
+        return memory;
+    }
+
+    /**
+     * Process the end of a memory tag in the XML.
+     *
+     * @param stack
+     */
+    public void processMemory(Stack<Object> stack) {
+        Memory m = (Memory) stack.pop();
+        Architecture a = (Architecture)stack.peek();
+        a.getMemoryList().add(m);
+        m.setParentResource(a);
+    }
+
+    /**
+     * Process the start of a hw_channel tag in the XML.
+     *
+     * @param attributes The attributes of the tag.
+     * @return a hw_chnannel object.
+     */
+    public HWChannel processHWChannel(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+        String type = (String) attributes.getValue("type");
+        HWChannel hw_channel = new HWChannel(name);
+        if (basename != null) hw_channel.setBasename(basename);
+        if (range != null) hw_channel.setRange(range);
+        if (type != null) hw_channel.setType(type);
+        return hw_channel;
+    }
+
+    /**
+     * Process the end of an hw_channel tag in the XML.
+     *
+     * @param stack
+     */
+    public void processHWChannel(Stack<Object> stack) {
+        HWChannel c = (HWChannel) stack.pop();
+        if (stack.peek() instanceof Architecture) {
+            Architecture a = (Architecture)stack.peek();
+            a.getHWChannelList().add(c);
+            c.setParentResource(a);
+        } else if (stack.peek() instanceof WritePath) {
+            WritePath w = (WritePath)stack.peek();
+            HWChannel ch = ((Architecture)stack.elementAt(0)).
+                    getHWChannel(c.getName());
+            if (ch != null) {
+                w.getHWChannelList().add(ch);
+            }
+            else {
+                undefinedReference("WritePath", w.getName(),
+                        "hwchannel", c.getName());
+            }
+        } else if (stack.peek() instanceof ReadPath) {
+            ReadPath r = (ReadPath)stack.peek();
+            HWChannel ch = ((Architecture)stack.elementAt(0)).
+                    getHWChannel(c.getName());
+            if (ch != null) {
+                r.getHWChannelList().add(ch);
+            }
+            else {
+                undefinedReference("ReadPath", r.getName(),
+                        "hwchannel", c.getName());
+            }
+        }
+    }
+
+    /**
+     * Process the start of a node tag in the XML.
+     *
+     * @param attributes The attributes of the tag.
+     * @return a node object.
+     */
+    public Node processNode(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+        Node node = new Node(name);
+        if (basename != null) node.setBasename(basename);
+        if (range != null) node.setRange(range);
+        return node;
+    }
+
+    /**
+     * Process the end of an node tag in the XML.
+     *
+     * @param stack
+     */
+    public void processNode(Stack<Object> stack) {
+        Node n = (Node) stack.pop();
+        ArchiResource r = (ArchiResource)stack.peek();
+        r.getNodeList().add(n);
+    }
+
+    /**
+     * Process the start of a origin tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ArchiResource object
+     */
+    public ArchiResource processOrigin(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        ArchiResource resource = new ArchiResource(name);
+        if (basename != null) resource.setBasename(basename);
+
+        return resource;
+    }
+
+    /**
+     * Process the end of a origin tag in the XML.
+     *
+     * @param stack
+     */
+    public void processOrigin(Stack<Object> stack) {
+        ArchiResource resource = (ArchiResource) stack.pop();
+        ArchiConnection connection = (ArchiConnection) stack.peek();
+        connection.setOrigin(resource);
+    }
+
+    /**
+     *  Process the start of a target tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ArchiResource object
+     */
+    public ArchiResource processTarget(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        ArchiResource resource = new ArchiResource(name);
+        if (basename != null) resource.setBasename(basename);
+  
+        return resource;
+    }
+
+    /**
+     * Process the end of a target tag in the XML.
+     *
+     * @param stack
+     */
+    public void processTarget(Stack<Object> stack) {
+        ArchiResource resource = (ArchiResource) stack.pop();
+        ArchiConnection connection = (ArchiConnection) stack.peek();
+        connection.setTarget(resource);
+    }
+
+    /**
+     * Process the start of a connection tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ArchiConnection object
+     */
+    public ArchiConnection processConnection(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        ArchiConnection connection = new ArchiConnection(name);
+        if (basename != null) connection.setBasename(basename);
+        return connection;
+    }
+
+    /**
+     * Process the end of a connection tag in the XML.
+     *
+     * @param stack
+     */
+    public void processConnection(Stack<Object> stack) {
+        ArchiConnection connection = (ArchiConnection) stack.pop();
+        Architecture architecture = (Architecture)stack.peek();
+        architecture.getConnectionList().add(connection);
+        connection.setParentResource(architecture);
+    }
+
+    /**
+     * Process the start of an inputport/outputport/port tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a PortNode object
+     */
+    public PortNode processInputPort(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+
+        PortNode port = new PortNode(name, PortNode.INPORT);
+
+        if (basename != null)
+            port.setBasename(basename);
+        else
+            port.setBasename(name);
+
+        if (range != null)
+            port.setRange(range);
+
+         return port;
+    }
+
+   public PortNode processOutputPort(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+
+        PortNode port = new PortNode(name, PortNode.OUTPORT);
+
+        if (basename != null)
+            port.setBasename(basename);
+        else
+            port.setBasename(name);
+
+        if (range != null)
+            port.setRange(range);
+
+        return port;
+    }
+
+    // duplexport
+    public PortNode processInOutPort(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+
+        PortNode port = new PortNode(name, PortNode.INOUTPORT);
+
+        if (basename != null)
+            port.setBasename(basename);
+        else
+            port.setBasename(name);
+
+        if (range != null)
+            port.setRange(range);
+
+        return port;
+    }
+
+   public PortNode processPort(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+
+        PortNode port = new PortNode(name);
+
+        if (basename != null)
+            port.setBasename(basename);
+        else
+            port.setBasename(name);
+
+        if (range != null)
+            port.setRange(range);
+
+        return port;
+    }
+
+    /**
+     * Process the end of an inputport/outputport/duplexport/port tag in the XML.
+     *
+     * @param stack
+     */
+    public void processInputPort(Stack<Object> stack) {
+        PortNode port = (PortNode) stack.pop();
+        Node node = (Node) stack.peek();
+        port.setNode(node);
+        node.getPortList().add(port);
+    }
+
+    public void processOutputPort(Stack<Object> stack) {
+        PortNode port = (PortNode) stack.pop();
+        Node node = (Node) stack.peek();
+        port.setNode(node);
+        node.getPortList().add(port);
+    }
+
+    public void processInOutPort(Stack<Object> stack) {
+        PortNode port = (PortNode) stack.pop();
+        Node node = (Node) stack.peek();
+        port.setNode(node);
+        node.getPortList().add(port);
+    }
+
+    public void processPort(Stack<Object> stack) {
+         PortNode port = (PortNode) stack.pop();
+         Node node = (Node) stack.peek();
+         port.setNode(node);
+         node.getPortList().add(port);
+     }
+
+    /**
+     * Process the start of a variable tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Variable object
+     */
+    public Variable processVariable(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        Variable variable = null;
+        variable = new Variable(name);
+        variable.setValue(Integer.parseInt(value));
+      
+        return variable;
+    }
+
+    /**
+     * Process the end of a variable tag in the XML.
+     *
+     * @param stack
+     */
+    public void processVariable(Stack<Object> stack) {
+        Variable variable = (Variable) stack.pop();
+        Architecture architecture = (Architecture)stack.peek();
+        variable.setParentResource(architecture);
+        architecture.getVarList().add(variable);
+    }
+
+    /**
+     * Process the start of a configuration tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Configuration object
+     */
+    public Configuration processConfiguration(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        Configuration config = new Configuration(name);
+        config.setValue(value);
+        return config;
+    }
+
+    /**
+     * Process the end of a configuration tag in the XML.
+     *
+     * @param stack
+     */
+    public void processConfiguration(Stack<Object> stack) {
+        Configuration config = (Configuration) stack.pop();
+        ArchiResource res = (ArchiResource)stack.peek();
+        res.getCfgList().add(config);
+    }
+
+    /**
+     * Process the start of a readPath tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ReadPath object
+     */
+    public ReadPath processReadPath(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        ReadPath readpath = new ReadPath(name);
+        return readpath;
+    }
+
+    /**
+     * Process the end of a readpath tag in the XML.
+     *
+     * @param stack
+     */
+    public void processReadPath(Stack<Object> stack) {
+        ReadPath readpath = (ReadPath) stack.pop();
+        Architecture res = (Architecture)stack.peek();
+        res.getReadPathList().add(readpath);
+    }
+
+    /**
+     * Process the start of a WritePath tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a WritePath object
+     */
+    public WritePath processWritePath(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        WritePath writepath = new WritePath(name);
+        return writepath;
+    }
+
+    /**
+     * Process the end of a WritePath tag in the XML.
+     *
+     * @param stack
+     */
+    public void processWritePath(Stack<Object> stack) {
+        WritePath writepath = (WritePath) stack.pop();
+        Architecture res = (Architecture)stack.peek();
+        res.getWritePathList().add(writepath);
+    }
+
+    /**
+     * Process the start of a TXBuf tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a TXBuf object
+     */
+    public String processTXBuf(Attributes attributes) {
+        return attributes.getValue("name");
+    }
+
+    /**
+     * Process the end of a TXBuf tag in the XML.
+     *
+     * @param stack
+     */
+    public void processTXBuf(Stack<Object> stack) {
+        String txBuf = (String) stack.pop();
+        WritePath res = (WritePath)stack.peek();
+        Memory mem = ((Architecture)res.getProcessor().getParentResource()).getMemory(txBuf);
+        if (mem != null) {
+            res.setTXBuf(mem);
+        }
+        else {
+            undefinedReference("ReadPath", res.getName(),
+                    "transmit buffer", txBuf);
+        }
+    }
+
+    /**
+     * Process the start of a RXBuf tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a RXBuf object
+     */
+    public String processRXBuf(Attributes attributes) {
+        return attributes.getValue("name");
+    }
+
+    /**
+     * Process the end of a RXBuf tag in the XML.
+     *
+     * @param stack
+     */
+    public void processRXBuf(Stack<Object> stack) {
+        String rxBuf = (String) stack.pop();
+        ReadPath res = (ReadPath)stack.peek();
+        Memory mem = ((Architecture)res.getProcessor().getParentResource()).getMemory(rxBuf);
+        if (mem != null) {
+            res.setRXBuf(mem);
+        }
+        else {
+            undefinedReference("ReadPath", res.getName(),
+                    "receive buffer", rxBuf);
+        }
+    }
+
+    /**
+     * Process the start of a CHBuf tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a CHBuf object
+     */
+    public String processCHBuf(Attributes attributes) {
+        return attributes.getValue("name");
+    }
+
+    /**
+     * Process the end of a CHBuf tag in the XML.
+     *
+     * @param stack
+     */
+    public void processCHBuf(Stack<Object> stack) {
+        String value= (String) stack.pop();
+        if (stack.peek() instanceof ReadPath) {
+            ReadPath res = (ReadPath)stack.peek();
+            Memory mem = ((Architecture)res.getProcessor().
+                    getParentResource()).getMemory(value);
+            if (mem != null) {
+                res.setCHBuf(mem);
+            }
+            else {
+                undefinedReference("ReadPath", res.getName(),
+                        "channel buffer", value);
+            }
+        }
+        else if (stack.peek() instanceof WritePath) {
+            WritePath res = (WritePath)stack.peek();
+            Memory mem = ((Architecture)res.getProcessor().
+                    getParentResource()).getMemory(value);
+            if (mem != null) {
+                res.setCHBuf(mem);
+            }
+            else {
+                undefinedReference("WritePath", res.getName(),
+                        "channel buffer", value);
+            }
+        }
+    }
+
+
+    /**
+     * Write an error message and terminate program in case an
+     * architecture element is referenced which does not exist.
+     *
+     * @param elementType type of architecture element in which the error
+     *                    occurred
+     * @param elementName name of architecture element in which the error
+     *                    occurred
+     * @param referenceType type of referenced architecture element
+     * @param referenceName name of referenced architecture element
+     */
+    protected void undefinedReference(String elementType,
+                                      String elementName,
+                                      String referenceType,
+                                      String referenceName) {
+        System.out.println("Error: " + elementType + " " + elementName
+                + " references " + referenceType + " " + referenceName
+                + " that has not been declared.");
+        System.out.println("Exit.");
+        System.exit(-1);
+    }
+
+}
diff --git a/dol/src/dol/parser/xml/archischema/package.html b/dol/src/dol/parser/xml/archischema/package.html
new file mode 100644 (file)
index 0000000..6a6b096
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Architecture XML schema parser.
+This package parses the architecture XML and stores the result in internal architectural data model.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/parser/xml/mapschema/MapXmlParser.java b/dol/src/dol/parser/xml/mapschema/MapXmlParser.java
new file mode 100644 (file)
index 0000000..4849601
--- /dev/null
@@ -0,0 +1,211 @@
+/* $Id: MapXmlParser.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.parser.xml.mapschema;
+
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import dol.datamodel.XmlTag;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.parser.xml.XmlParser;
+
+
+/**
+ * Parse mapping XML file.
+ */
+public class MapXmlParser extends XmlParser {
+
+    /**
+     * Constructor.
+     * @param pn the process network the mapping is referring to
+     * @param arch the architecture the mapping is referring to
+     */
+    public MapXmlParser(ProcessNetwork pn, Architecture arch) {
+        super();
+        _stack = new Stack<Object>();
+        _xml2Map = new Xml2Map(pn, arch);
+    }
+
+    /**
+     * Do the parsing of an XML file describing a mapping.
+     *
+     * @param  url The input XML file
+     * @return the mapping
+     */
+    public Mapping doParse(String url)  {
+        Mapping map = null;
+        System.out.println("Read mapping from XML file");
+
+        try {
+            String uri = _makeAbsoluteURL(url);
+            _ui.printlnVerbose("-- processing XML file: " + uri);
+            _ui.printlnVerbose("-- read XML file: ");
+            _stack.clear();
+            _parser.parse(new InputSource(uri));
+            map = (Mapping) _stack.pop();
+            _ui.printlnVerbose(" [DONE] ");
+        } catch (SAXParseException err) {
+            System.out.println("** Parsing error, line "
+                + err.getLineNumber() + ", uri " + err.getSystemId());
+            System.out.println("   " + err.getMessage());
+        } catch (SAXException e) {
+            //e.printStackTrace();
+            e.getMessage();
+            System.exit(-1);
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+
+        System.out.println(" -- Mapping from XML "
+                + "[Finished]");
+        System.out.println();
+
+        return map;
+    }
+
+    /**
+     * Action to be done while parsing a start element of an XML.
+     *
+     * @param  elementName Description of the Parameter
+     * @param  attributes Description of the Parameter
+     * @exception  SAXException MyException If such and such occurs
+     */
+    public void startElement(String namespaceURI, String localName,
+            String elementName, Attributes attributes)
+            throws SAXException {
+        Object val = null;
+
+        if (elementName.equals(_xt.getMappingTag())) {
+            val = _xml2Map.processMapping(attributes);
+        } else if (elementName.equals(_xt.getVariableTag())) {
+            val = _xml2Map.processVariable(attributes);
+        } else if (elementName.equals(_xt.getBindingTag())) {
+            val = _xml2Map.processBinding(attributes);
+        } else if (elementName.equals(_xt.getOriginTag())) {
+            val = _xml2Map.processOrigin(attributes);
+        } else if (elementName.equals(_xt.getProcessTag())) {
+            val = _xml2Map.processProcess(attributes);
+        } else if (elementName.equals(_xt.getProcessorTag())) {
+            val = _xml2Map.processProcessor(attributes);
+        } else if (elementName.equals(_xt.getSWChannelTag())) {
+            val = _xml2Map.processChannel(attributes);
+        } else if (elementName.equals(_xt.getReadPathTag())) {
+            val = _xml2Map.processReadPath(attributes);
+        } else if (elementName.equals(_xt.getWritePathTag())) {
+            val = _xml2Map.processWritePath(attributes);
+        } else if (elementName.equals(_xt.getScheduleTag())) {
+            val = _xml2Map.processSchedule(attributes);
+        } else if (elementName.equals(_xt.getResourceTag())) {
+            val = _xml2Map.processResource(attributes);
+        } else if (elementName.equals(_xt.getConfigurationTag())) {
+            val = _xml2Map.processConfiguration(attributes);
+        } else {
+            System.out.println(" -- Warning, DOL doesn't "
+                    + "understand tag <" + elementName + "> ");
+        }
+
+        if (val != null) {
+            _stack.push(val);
+        }
+
+        consistencyCheck(elementName, attributes, val);
+    }
+
+
+    /**
+     * Action to be done while parsing an end element of an XML.
+     *
+     * @param  elementName Description of the Parameter
+     * @exception  SAXException MyException If such and such occurs
+     */
+    public void endElement(String namespaceURI, String localName,
+            String elementName) throws SAXException {
+        if (elementName.equals(_xt.getMappingTag())) {
+            _xml2Map.processMapping(_stack);
+        } else if (elementName.equals(_xt.getVariableTag())) {
+            _xml2Map.processVariable(_stack);
+        } else if (elementName.equals(_xt.getBindingTag())) {
+            _xml2Map.processBinding(_stack);
+        } else if (elementName.equals(_xt.getOriginTag())) {
+            _xml2Map.processOrigin(_stack);
+        /*
+        } else if (elementName.equals(_xt.getTargetTag())) {
+            _xml2Map.processTarget(_stack);
+        */
+        } else if (elementName.equals(_xt.getProcessTag())) {
+            _xml2Map.processProcess(_stack);
+        } else if (elementName.equals(_xt.getProcessorTag())) {
+            _xml2Map.processProcessor(_stack);
+        } else if (elementName.equals(_xt.getSWChannelTag())) {
+            _xml2Map.processChannel(_stack);
+        } else if (elementName.equals(_xt.getReadPathTag())) {
+            _xml2Map.processReadPath(_stack);
+        } else if (elementName.equals(_xt.getWritePathTag())) {
+            _xml2Map.processWritePath(_stack);
+        } else if (elementName.equals(_xt.getScheduleTag())) {
+            _xml2Map.processSchedule(_stack);
+        } else if (elementName.equals(_xt.getResourceTag())) {
+            _xml2Map.processResource(_stack);
+        } else if (elementName.equals(_xt.getConfigurationTag())) {
+            _xml2Map.processConfiguration(_stack);
+        }
+    }
+
+    /**
+     *
+     */
+    protected void consistencyCheck(String elementName,
+            Attributes attributes, Object val) {
+        boolean isConsistent = true;
+
+        if (elementName.equals(_xt.getProcessorTag())
+                && val == null) {
+            System.out.println(" -- Error: Could not find processor \""
+                    + attributes.getValue("name") + "\" in "
+                    + "architecture.");
+            isConsistent = false;
+        } else if (elementName.equals(_xt.getProcessTag())
+                && val == null) {
+            System.out.println(" -- Error: Could not find process \""
+                    + attributes.getValue("name") + "\" in "
+                    + "process network.");
+            isConsistent = false;
+        } else if (elementName.equals(_xt.getSWChannelTag())
+                    && val == null) {
+                System.out.println(" -- Error: Could not find channel \""
+                        + attributes.getValue("name") + "\" in "
+                        + "process network.");
+                isConsistent = false;
+        } else if (elementName.equals(_xt.getReadPathTag())
+                && val == null) {
+            System.out.println(" -- Error: Could not find read path \""
+                    + attributes.getValue("name") + "\" in "
+                    + "architecture.");
+            isConsistent = false;
+        } else if (elementName.equals(_xt.getWritePathTag())
+                && val == null) {
+            System.out.println(" -- Error: Could not find write path \""
+                    + attributes.getValue("name") + "\" in "
+                    + "architecture.");
+            isConsistent = false;
+        }
+
+        if (!isConsistent) {
+            System.exit(-1);
+        }
+    }
+
+    /** stack containing the generated objects */
+    protected Stack<Object> _stack;
+
+    /** actions to be taken while parsing every XML element */
+    protected Xml2Map _xml2Map;
+
+    /** */
+    protected XmlTag _xt = XmlTag.getInstance();
+}
diff --git a/dol/src/dol/parser/xml/mapschema/Xml2Map.java b/dol/src/dol/parser/xml/mapschema/Xml2Map.java
new file mode 100644 (file)
index 0000000..4d15666
--- /dev/null
@@ -0,0 +1,381 @@
+package dol.parser.xml.mapschema;
+
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import dol.datamodel.architecture.ArchiResource;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.architecture.ReadPath;
+import dol.datamodel.architecture.WritePath;
+import dol.datamodel.mapping.Binding;
+import dol.datamodel.mapping.CommunicationBinding;
+import dol.datamodel.mapping.ComputationBinding;
+import dol.datamodel.mapping.Configuration;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.mapping.Schedule;
+import dol.datamodel.mapping.ScheduleEntry;
+import dol.datamodel.mapping.SchedulingPolicy;
+import dol.datamodel.mapping.Variable;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+
+
+/**
+ *
+ */
+public class Xml2Map {
+
+    /**
+     * Constructor.
+     * @param pn the process network the mapping is refering to
+     * @param arch the architecture the mapping is refering to
+     */
+    public Xml2Map(ProcessNetwork pn, Architecture arch) {
+        _pn = pn;
+        _arch = arch;
+    }
+
+    /**
+     * Process the start of the mapping tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Mapping object
+     */
+    public Mapping processMapping(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        Mapping map = new Mapping(name);
+        map.setArch(_arch);
+        map.setPN(_pn);
+        return map;
+    }
+
+    /**
+     * Process the end of the mapping tag in the XML.
+     *
+     * @param stack
+     */
+    public void processMapping(Stack<Object> stack) {
+    }
+
+    /**
+     * Process the start of a binding tag in the XML.
+     *
+     * @param  attributes The attributes of the tag.
+     * @return  a Binding object.
+     */
+    public Binding processBinding(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String type = (String) attributes.getValue(
+                "http://www.w3.org/2001/XMLSchema-instance", "type");
+        Binding b = null;
+        // Create ComputationBinding or CommunicationBinding object
+        if(type.equals(Binding.COMPUTATION)) {
+            b = new ComputationBinding(name);
+        } else if(type.equals(Binding.COMMUNICATION)) {
+            b = new CommunicationBinding(name);
+        }
+
+        if (basename != null) b.setBasename(basename);
+
+        return b;
+    }
+
+    /**
+     * Process the end of a binding tag in the XML.
+     *
+     * @param stack
+     */
+    public void processBinding(Stack<Object> stack) throws SAXException
+    {
+        Binding bind = (Binding)stack.pop();
+        Mapping map = (Mapping)stack.peek();
+        bind.setParentResource(map);
+
+        if(bind instanceof ComputationBinding) {
+            ComputationBinding cb = (ComputationBinding)bind;
+            Process process = cb.getProcess();
+            Processor processor = cb.getProcessor();
+            process.setProcessor(processor);
+            processor.getProcessList().add(process);
+
+            map.getCompBindList().add(cb);
+            map.getProcessList().add(process);
+            if (!map.getProcessorList().contains(processor)) {
+                map.getProcessorList().add(processor);
+            }
+
+        } else {
+            map.getCommBindList().add((CommunicationBinding)bind);
+        }
+    }
+
+    /**
+     * Process the start of a origin tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ScheduleEntry object
+     */
+    public ScheduleEntry processOrigin(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        ScheduleEntry schedEntry = new ScheduleEntry(name);
+
+        // A scheduled resource is either a PN process
+        // or a SW channel.
+        Process process = _pn.getProcess(name);
+        if(process != null) {
+            schedEntry.setConsumer(process);
+        } else {
+            Channel channel = _pn.getChannel(name);
+            schedEntry.setConsumer(channel);
+        }
+        return schedEntry;
+    }
+
+    /**
+     * Process the end of a origin tag in the XML.
+     *
+     * @param stack
+     */
+    public void processOrigin(Stack<Object> stack) {
+        ScheduleEntry schedProcess = (ScheduleEntry) stack.pop();
+        Schedule sched = (Schedule) stack.peek();
+        sched.getEntryList().add(schedProcess);
+        schedProcess.setParentResource(sched);
+    }
+
+    /**
+     * Process the start of a variable tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Variable object
+     */
+    public Variable processVariable(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        Variable variable = new Variable(name);
+        variable.setValue(Integer.parseInt(value));
+        return variable;
+    }
+
+    /**
+     * Process the end of a variable tag in the XML.
+     *
+     * @param stack
+     */
+    public void processVariable(Stack<Object> stack) {
+        Variable variable = (Variable) stack.pop();
+        Mapping map = (Mapping) stack.peek();
+        variable.setParentResource(map);
+        map.getVarList().add(variable);
+    }
+
+    /**
+     * Process the start of a process tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Process object
+     */
+    public Process processProcess(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        Process process = _pn.getProcess(name);
+        return process;
+    }
+
+    /**
+     * Process the end of a process tag in the XML.
+     *
+     * @param stack
+     */
+    public void processProcess(Stack<Object> stack) {
+        Process p = (Process) stack.pop();
+        ComputationBinding b = (ComputationBinding) stack.peek();
+        b.setProcess(p);
+    }
+
+    /**
+     * Process the start of a processor tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Processor object
+     */
+    public Processor processProcessor(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        Processor processor = _arch.getProcessor(name);
+        return processor;
+    }
+
+    /**
+     * Process the end of a processor tag in the XML.
+     *
+     * @param stack
+     */
+    public void processProcessor(Stack<Object> stack) {
+        Processor p = (Processor) stack.pop();
+        ComputationBinding b = (ComputationBinding) stack.peek();
+        b.setProcessor(p);
+    }
+
+    /**
+     * Process the start of a channel tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Channel object
+     */
+    public Channel processChannel(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        Channel channel = _pn.getChannel(name);
+        return channel;
+    }
+
+    /**
+     * Process the end of a channel tag in the XML.
+     *
+     * @param stack
+     */
+    public void processChannel(Stack<Object> stack) {
+        Channel chan = (Channel) stack.pop();
+        CommunicationBinding b = (CommunicationBinding) stack.peek();
+        b.setChannel(chan);
+    }
+
+    /**
+     * Process the start of a read path tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ReadPath object
+     */
+    public ReadPath processReadPath(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        ReadPath path = _arch.getReadPath(name);
+        return path;
+    }
+
+    /**
+     * Process the end of a read path tag in the XML.
+     *
+     * @param stack
+     */
+    public void processReadPath(Stack<Object> stack) {
+        ReadPath path = (ReadPath) stack.pop();
+        CommunicationBinding b = (CommunicationBinding) stack.peek();
+        b.setReadPath(path);
+    }
+
+    /**
+     * Process the start of a write path tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a WritePath object
+     */
+    public WritePath processWritePath(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        WritePath path = _arch.getWritePath(name);
+        return path;
+    }
+
+    /**
+     * Process the end of a write path tag in the XML.
+     *
+     * @param stack
+     */
+    public void processWritePath(Stack<Object> stack) {
+        WritePath path = (WritePath) stack.pop();
+        CommunicationBinding b = (CommunicationBinding) stack.peek();
+        b.setWritePath(path);
+    }
+
+    /**
+     * Process the start of a schedule tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Schedule object
+     */
+    public Schedule processSchedule(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String type = (String) attributes.getValue("type");
+        String basename = (String) attributes.getValue("basename");
+
+        Schedule schedule = new Schedule(name);
+        schedule.setSchedPolicy(SchedulingPolicy.fromString(type));
+
+        if (basename != null) schedule.setBasename(basename);
+
+        return schedule;
+    }
+
+    /**
+     * Process the end of a schedule tag in the XML.
+     *
+     * @param stack
+     */
+    public void processSchedule(Stack<Object> stack) {
+        Schedule sched = (Schedule) stack.pop();
+        Mapping map = (Mapping) stack.peek();
+        map.getScheduleList().add(sched);
+        sched.setParentResource(map);
+    }
+
+    /**
+     * Process the start of a resource tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ArchiResource object
+     */
+    public ArchiResource processResource(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        // We are either looking for a HW channel or for a processor.
+        ArchiResource resource = null;
+        if((resource = _arch.getHWChannel(name)) == null) {
+             resource = _arch.getProcessor(name);
+        }
+        return resource;
+    }
+
+    /**
+     * Process the end of a resource tag in the XML.
+     *
+     * @param stack
+     */
+    public void processResource(Stack<Object> stack) {
+        ArchiResource resource = (ArchiResource) stack.pop();
+        Schedule schedule = (Schedule) stack.peek();
+        schedule.setResource(resource);
+    }
+
+    /**
+     * Process the start of a configuration tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Configuration object
+     */
+    public Configuration processConfiguration(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        Configuration config = new Configuration(name, value);
+        return config;
+    }
+
+    /**
+     * Process the end of a configuration tag in the XML.
+     *
+     * @param stack
+     */
+    public void processConfiguration(Stack<Object> stack) {
+        Configuration config = (Configuration) stack.pop();
+        if(stack.peek() instanceof ScheduleEntry) {
+            ScheduleEntry schedProc = (ScheduleEntry) stack.peek();
+            schedProc.getCfgList().add(config);
+        } else if(stack.peek() instanceof Schedule) {
+            Schedule sched = (Schedule) stack.peek();
+            sched.getCfgList().add(config);
+        }
+    }
+
+    protected ProcessNetwork _pn = null;
+    protected Architecture _arch = null;
+}
diff --git a/dol/src/dol/parser/xml/mapschema/package.html b/dol/src/dol/parser/xml/mapschema/package.html
new file mode 100644 (file)
index 0000000..5fa0ab3
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Mapping XML schema parser.
+This package parses the mapping XML and stores the result in internal architectural data model.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/parser/xml/package.html b/dol/src/dol/parser/xml/package.html
new file mode 100644 (file)
index 0000000..50319b9
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Parser for DOL specific XML files.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/parser/xml/pnschema/PNXmlParser.java b/dol/src/dol/parser/xml/pnschema/PNXmlParser.java
new file mode 100644 (file)
index 0000000..70a4f8a
--- /dev/null
@@ -0,0 +1,158 @@
+/* $Id: PNXmlParser.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.parser.xml.pnschema;
+
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import dol.datamodel.XmlTag;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.parser.xml.XmlParser;
+
+/**
+ * Parse processnetwork XML file.
+ */
+public class PNXmlParser extends XmlParser {
+
+    /**
+     * Constructor.
+     */
+    public PNXmlParser() {
+        super();
+        _stack = new Stack<Object>();
+        _xml2PN = new Xml2PN();
+    }
+
+    /**
+     * Do the parsing of an XML file describing a processnetwork.
+     *
+     * @param url input XML file
+     * @return the processnetwork
+     */
+    public ProcessNetwork doParse(String url)  {
+        ProcessNetwork pn = null;
+        System.out.println("Read process network from XML file");
+
+        try {
+            String uri = _makeAbsoluteURL(url);
+            _ui.printlnVerbose("-- processing XML file: " + uri);
+            _ui.printlnVerbose("-- read XML file: ");
+            _stack.clear();
+            _parser.parse(new InputSource(uri));
+            pn = (ProcessNetwork) _stack.pop();
+            _ui.printlnVerbose(" [DONE] ");
+        } catch (SAXParseException err) {
+            System.out.println("** Parsing error, line "
+                + err.getLineNumber() + ", uri " + err.getSystemId());
+            System.out.println("   " + err.getMessage());
+        } catch (SAXException e) {
+            e.printStackTrace();
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+
+        try {
+            pn.fillPortPeerInfo();
+        } catch (Exception e) {
+            System.out.println("Exception\n " + e.getMessage());
+            e.printStackTrace(System.out);
+        }
+
+        System.out.println(" -- Process network model from XML "
+                + "[Finished]");
+        System.out.println();
+
+        return pn;
+    }
+
+    /**
+     * Action to be done while parsing a start element of an XML.
+     *
+     * @param namespaceURI
+     * @param localName
+     * @param elementName name of element
+     * @param attributes attributes of element
+     * @exception SAXException thrown when a parsing error occurs
+     */
+    public void startElement(String namespaceURI, String localName,
+            String elementName, Attributes attributes)
+            throws SAXException {
+        Object val = null;
+
+        if (elementName.equals(_xt.getPNTag())) {
+            val = _xml2PN.processPN(attributes);
+        } else if (elementName.equals(_xt.getVariableTag())) {
+            val = _xml2PN.processVariable(attributes);
+        } else if (elementName.equals(_xt.getProcessTag())) {
+            val = _xml2PN.processProcess(attributes);
+        } else if (elementName.equals(_xt.getSWChannelTag())) {
+            val = _xml2PN.processChannel(attributes);
+        } else if (elementName.equals(_xt.getConnectionTag())) {
+            val = _xml2PN.processConnection(attributes);
+        } else if (elementName.equals(_xt.getOriginTag())) {
+            val = _xml2PN.processOrigin(attributes);
+        } else if (elementName.equals(_xt.getTargetTag())) {
+            val = _xml2PN.processTarget(attributes);
+        } else if (elementName.equals(_xt.getPortTag())) {
+            val = _xml2PN.processPort(attributes);
+        } else if (elementName.equals(_xt.getSourceTag())) {
+            val = _xml2PN.processSource(attributes);
+        } else if (elementName.equals(_xt.getProfilingTag())) {
+            val = _xml2PN.processProfiling(attributes);
+        } else if (elementName.equals(_xt.getConfigurationTag())) {
+            val = _xml2PN.processConfiguration(attributes);
+        } else {
+            System.out.println("--Warning, DOL doesn't "
+                    + "understand tag <" + elementName + "> ");
+        }
+
+        if (val != null) {
+            _stack.push(val);
+        }
+    }
+
+    /**
+     * Action to be done while parsing an end element of an XML.
+     *
+     * @param  elementName Description of the Parameter
+     * @exception  SAXException MyException If such and such occurs
+     */
+    public void endElement(String namespaceURI, String localName,
+            String elementName) throws SAXException {
+        if (elementName.equals(_xt.getPNTag())) {
+            _xml2PN.processPN(_stack);
+        } else if (elementName.equals(_xt.getVariableTag())) {
+            _xml2PN.processVariable(_stack);
+        } else if (elementName.equals(_xt.getProcessTag())) {
+            _xml2PN.processProcess(_stack);
+        } else if (elementName.equals(_xt.getSWChannelTag())) {
+            _xml2PN.processChannel(_stack);
+        } else if (elementName.equals(_xt.getConnectionTag())) {
+            _xml2PN.processConnection(_stack);
+        } else if (elementName.equals(_xt.getOriginTag())) {
+            _xml2PN.processOrigin(_stack);
+        } else if (elementName.equals(_xt.getTargetTag())) {
+            _xml2PN.processTarget(_stack);
+        } else if (elementName.equals(_xt.getSourceTag())) {
+            _xml2PN.processSource(_stack);
+        } else if (elementName.equals(_xt.getProfilingTag())) {
+            _xml2PN.processProfiling(_stack);
+        } else if (elementName.equals(_xt.getConfigurationTag())) {
+            _xml2PN.processConfiguration(_stack);
+        } else if (elementName.equals(_xt.getPortTag())) {
+            _xml2PN.processPort(_stack);
+        }
+    }
+
+    /** stack containing the generated objects */
+    protected Stack<Object> _stack;
+
+    /** actions to be taken while parsing every XML element */
+    protected Xml2PN _xml2PN;
+
+    /** */
+    protected XmlTag _xt = XmlTag.getInstance();
+}
diff --git a/dol/src/dol/parser/xml/pnschema/Xml2PN.java b/dol/src/dol/parser/xml/pnschema/Xml2PN.java
new file mode 100644 (file)
index 0000000..5586c16
--- /dev/null
@@ -0,0 +1,457 @@
+/* $Id: Xml2PN.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.parser.xml.pnschema;
+
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Configuration;
+import dol.datamodel.pn.Connection;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.ProfilingConfiguration;
+import dol.datamodel.pn.Resource;
+import dol.datamodel.pn.SourceCode;
+import dol.datamodel.pn.Variable;
+
+/**
+ *
+ */
+public class Xml2PN {
+
+    /**
+     * Constructor.
+     */
+    public Xml2PN() {
+    }
+
+    /**
+     * Process the start of the process network tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a ProcessNetwork object
+     */
+    public ProcessNetwork processPN(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        ProcessNetwork p = new ProcessNetwork(name);
+        return p;
+    }
+
+    /**
+     * Process the end of the processnetwork tag in the XML.
+     *
+     * @param stack
+     */
+    public void processPN(Stack<Object> stack) {
+    }
+
+    /**
+     * Process the start of a process tag in the XML.
+     *
+     * @param  attributes The attributes of the tag.
+     * @return  a process object.
+     */
+    public Process processProcess(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+        Process process = new Process(name);
+        if (basename != null) process.setBasename(basename);
+        if (range != null) process.setRange(range);
+        return process;
+    }
+
+    /**
+     * Process the end of a process tag in the XML.
+     *
+     * @param stack
+     */
+    public void processProcess(Stack<Object> stack) {
+        Process p = (Process) stack.pop();
+        ProcessNetwork r = (ProcessNetwork)stack.peek();
+        r.getProcessList().add(p);
+    }
+
+    /**
+     * Process the start of a origin tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Resource object
+     */
+    public Resource processOrigin(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        Resource resource = new Resource(name);
+        if (basename != null) resource.setBasename(basename);
+        return resource;
+    }
+
+    /**
+     * Process the end of a origin tag in the XML.
+     *
+     * @param stack
+     */
+    public void processOrigin(Stack<Object> stack) {
+        Port port = (Port)stack.pop();
+        Resource resource = (Resource)stack.pop();
+        Connection connection = (Connection)stack.peek();
+
+        if(port != null) {
+            if (!port.isOutPort()) {
+                System.out.println("Error: Connection "
+                        + connection.getName()
+                        + " must be defined in the direction of the "
+                        + " data flow!");
+                System.out.println("Exit.");
+                System.exit(-1);
+            }
+            connection.setOriginPort(port);
+        } else {
+            undefinedReference("Connection", connection.getName(),
+                    "element", resource.getName());
+        }
+
+        Process process = ((ProcessNetwork)stack.elementAt(0)).
+                getProcess(resource.getName());
+        Channel channel = ((ProcessNetwork)stack.elementAt(0)).
+                getChannel(resource.getName());
+
+        if (process != null) {
+            connection.setOrigin(process);
+        }
+        else if (channel != null) {
+            connection.setOrigin(channel);
+        }
+        else {
+            undefinedReference("Connection", connection.getName(),
+                    "element", resource.getName());
+        }
+    }
+
+    /**
+     *  Process the start of a target tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Resource object
+     */
+    public Resource processTarget(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        Resource resource = new Resource(name);
+        if (basename != null) resource.setBasename(basename);
+        return resource;
+    }
+
+    /**
+     * Process the end of a target tag in the XML.
+     *
+     * @param stack
+     */
+    public void processTarget(Stack<Object> stack) {
+        Port port = (Port)stack.pop();
+        Resource resource = (Resource)stack.pop();
+        Connection connection = (Connection)stack.peek();
+
+        if(port != null) {
+            if (!port.isInPort()) {
+                System.out.println("Error: Connection "
+                        + connection.getName()
+                        + " must be defined in the direction of the "
+                        + " data flow!");
+                System.out.println("Exit.");
+                System.exit(-1);
+            }
+            connection.setTargetPort(port);
+        } else {
+            undefinedReference("Connection", connection.getName(),
+                    "element", resource.getName());
+        }
+
+        Process process = ((ProcessNetwork)stack.elementAt(0)).
+                getProcess(resource.getName());
+        Channel channel = ((ProcessNetwork)stack.elementAt(0)).
+                getChannel(resource.getName());
+
+        if (process != null) {
+            connection.setTarget(process);
+        }
+        else if (channel != null) {
+            connection.setTarget(channel);
+        }
+        else {
+            undefinedReference("Connection", connection.getName(),
+                    "element", resource.getName());
+        }
+    }
+
+    /**
+     * Process the start of a connection tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Connection object
+     */
+    public Connection processConnection(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String basename = (String) attributes.getValue("basename");
+        Connection connection = new Connection(name);
+        if (basename != null) connection.setBasename(basename);
+        return connection;
+    }
+
+    /**
+     * Process the end of a connection tag in the XML.
+     *
+     * @param stack
+     */
+    public void processConnection(Stack<Object> stack) {
+        Connection connection = (Connection) stack.pop();
+        ProcessNetwork pn = (ProcessNetwork)stack.peek();
+        pn.getConnectionList().add(connection);
+    }
+
+    /**
+     * Process the start of a port tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Port object
+     */
+    public Port processPort(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String type = (String) attributes.getValue("type");
+        String basename = (String) attributes.getValue("basename");
+        String range = (String) attributes.getValue("range");
+
+        Port port = null;
+
+        if (type != null) {
+            if( type.equals("input") ) {
+                port = new Port(name, Port.INPORT);
+            } else if( type.equals("output") ) {
+                port = new Port(name, Port.OUTPORT);
+            }
+        } else {
+            port = new Port(name);
+        }
+
+        if (basename != null)
+            port.setBasename(basename);
+        else
+            port.setBasename(name);
+
+        if (range != null) port.setRange(range);
+
+        return port;
+    }
+
+    /**
+     * Process the end of a port tag in the XML.
+     *
+     * @param stack
+     */
+    public void processPort(Stack<Object> stack) {
+        Port port = (Port)stack.pop();
+        Resource resource = (Resource)stack.peek();
+
+        //check if this is a port or just a port reference
+        if (!(stack.elementAt(stack.size() - 2) instanceof Connection)) {
+            port.setResource(resource);
+            resource.getPortList().add(port);
+        }
+        //port reference
+        else {
+            Process process = ((ProcessNetwork)stack.elementAt(0)).
+                    getProcess(resource.getName());
+            Channel channel = ((ProcessNetwork)stack.elementAt(0)).
+                    getChannel(resource.getName());
+
+            Resource refResource = null;
+
+            if (process != null) {
+                refResource = process;
+            }
+            else if (channel != null) {
+                refResource = channel;
+            }
+            else {
+                undefinedReference("Connection",
+                        ((Connection)stack.peek()).getName(),
+                        "element", resource.getName());
+            }
+
+            Port refPort = refResource.getPort(port.getName());
+
+            if (refPort == null) {
+                undefinedReference("Connection",
+                        ((Connection)stack.peek()).getName(),
+                        "port", port.getName());
+            }
+
+            // Put real port back on the stack. Will be popped in
+            // processOrigin and processTarget respectively
+            stack.push(refPort);
+
+        }
+    }
+
+    /**
+     * Process the start of a channel tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Channel object
+     */
+    public Channel processChannel(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String size = (String) attributes.getValue("size");
+        String type = (String) attributes.getValue("type");
+        String tSize = (String) attributes.getValue("tokensize");
+        Channel channel = new Channel(name);
+        channel.setSize(new Integer(size));
+        channel.setTokenSize(new Integer(tSize));
+        channel.setType(type);
+        return channel;
+    }
+
+    /**
+     * Process the end of a channel tag in the XML.
+     *
+     * @param stack
+     */
+    public void processChannel(Stack<Object> stack) {
+        Channel channel = (Channel) stack.pop();
+        ProcessNetwork r = (ProcessNetwork)stack.peek();
+        r.getChannelList().add(channel);
+    }
+
+    /**
+     * Process the end of a configuration tag in the XML.
+     *
+     * @param stack
+     */
+    public void processConfiguration(Stack<Object> stack) {
+        Configuration configuration = (Configuration) stack.pop();
+        Resource r = (Resource) stack.peek();
+        configuration.setParentResource(r);
+        r.getCfgList().add(configuration);
+    }
+
+    /**
+     * Process the start of a configuration tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Configuration object
+     */
+    public Configuration processConfiguration(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        Configuration code = new Configuration(name);
+        code.setName(name);
+        code.setValue(value);
+        return code;
+    }
+
+    /**
+     * Process the end of a profiling tag in the XML.
+     *
+     * @param stack
+     */
+    public void processProfiling(Stack<Object> stack) {
+        ProfilingConfiguration configuration = ( ProfilingConfiguration) stack.pop();
+        Resource r = (Resource) stack.peek();
+        configuration.setParentResource(r);
+        r.getProfilingList().add(configuration);
+    }
+
+    /**
+     * Process the start of a profiling tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a profiling object
+     */
+    public Configuration processProfiling(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        ProfilingConfiguration code = new  ProfilingConfiguration(name);
+        code.setName(name);
+        code.setValue(value);
+        return code;
+    }
+
+    /**
+     * Process the start of a channel source tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a SourceCode object
+     */
+    public SourceCode processSource(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String type = (String) attributes.getValue("type");
+        String l = (String) attributes.getValue("location");
+        SourceCode code = new SourceCode(name);
+        code.setType(type);
+        code.setLocality(l);
+        return code;
+    }
+
+    /**
+     * Process the end of a source tag in the XML.
+     *
+     * @param stack
+     */
+    public void processSource(Stack<Object> stack) {
+        SourceCode source = (SourceCode) stack.pop();
+        Process process = (Process) stack.peek();
+        source.setProcess(process);
+        process.getSrcList().add(source);
+    }
+
+    /**
+     * Process the start of a variable tag in the XML.
+     *
+     * @param attributes attributes of the tag
+     * @return a Variable object
+     */
+    public Variable processVariable(Attributes attributes) {
+        String name = (String) attributes.getValue("name");
+        String value = (String) attributes.getValue("value");
+        Variable variable = null;
+        variable = new Variable(name);
+        variable.setValue(Integer.parseInt(value));
+        return variable;
+    }
+
+    /**
+     * Process the end of a variable tag in the XML.
+     *
+     * @param stack
+     */
+    public void processVariable(Stack<Object> stack) {
+        Variable variable = (Variable) stack.pop();
+        ProcessNetwork pn = (ProcessNetwork)stack.peek();
+        variable.setParentResource(pn);
+        pn.getVarList().add(variable);
+    }
+
+    /**
+     * Write an error message and terminate program in case an
+     * processnetwork element is referenced which does not exist.
+     *
+     * @param elementType type of processnetwork element in which the error
+     *                    occurred
+     * @param elementName name of processnetwork element in which the error
+     *                    occurred
+     * @param referenceType type of referenced processnetwork element
+     * @param referenceName name of referenced processnetwork element
+     */
+    protected void undefinedReference(String elementType,
+                                      String elementName,
+                                      String referenceType,
+                                      String referenceName) {
+        System.out.println("Error: " + elementType + " " + elementName
+                + " references " + referenceType + " " + referenceName
+                + " that has not been declared.");
+        System.out.println("Exit.");
+        System.exit(-1);
+    }
+}
diff --git a/dol/src/dol/parser/xml/pnschema/package.html b/dol/src/dol/parser/xml/pnschema/package.html
new file mode 100644 (file)
index 0000000..97ca537
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Process network XML schema parser.
+This package parses the process network XML and stores the result in internal data model for the process network.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/util/ApplicationGenerator.java b/dol/src/dol/util/ApplicationGenerator.java
new file mode 100644 (file)
index 0000000..a193614
--- /dev/null
@@ -0,0 +1,914 @@
+/* $Id: ApplicationGenerator.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.util;\r
+\r
+import java.io.BufferedWriter;\r
+import java.io.File;\r
+import java.io.FileWriter;\r
+import java.util.Random;\r
+import java.util.Vector;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import dol.datamodel.architecture.Processor;\r
+import dol.datamodel.architecture.ReadPath;\r
+import dol.datamodel.architecture.WritePath;\r
+import dol.datamodel.mapping.CommunicationBinding;\r
+import dol.datamodel.mapping.ComputationBinding;\r
+import dol.datamodel.mapping.Mapping;\r
+import dol.datamodel.mapping.Schedule;\r
+import dol.datamodel.mapping.ScheduleEntry;\r
+import dol.datamodel.mapping.SchedulingPolicy;\r
+import dol.datamodel.pn.Channel;\r
+import dol.datamodel.pn.Connection;\r
+import dol.datamodel.pn.Port;\r
+import dol.datamodel.pn.Process;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.datamodel.pn.ProfilingConfiguration;\r
+import dol.datamodel.pn.SourceCode;\r
+import dol.visitor.xml.MapXmlVisitor;\r
+import dol.visitor.xml.PNXmlVisitor;\r
+\r
+/**\r
+ *\r
+ */\r
+public class ApplicationGenerator {\r
+    /*\r
+    protected String _processes[] =\r
+        {"producer", "consumer"};\r
+\r
+    protected int _computation[] =\r
+        {1000, 1000};\r
+\r
+    protected int _communication[][] =\r
+        {{0, 4}, {-4, 0}};\r
+\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_0.arm"};\r
+\r
+    protected int _iterations = 1000;\r
+    */\r
+\r
+    /*\r
+    protected String _processes[] =\r
+        {"producer", "forwarder", "consumer"};\r
+\r
+    protected int _computation[] =\r
+        {1000, 1000, 1000};\r
+\r
+    protected int _communication[][] =\r
+        {{ 0,  4,  0},\r
+         {-4,  0,  4},\r
+         { 0, -4,  0}};\r
+\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_0.arm", "tile_0.arm"};\r
+\r
+    protected int _iterations = 10;\r
+    */\r
+\r
+    /*\r
+    protected String _processes[] =\r
+        {"stageA", "stageB", "stageC", "stageD",\r
+         "stageE", "stageF", "stageG", "stageH",\r
+         "stageI", "stageJ", "stageK", "stageL",\r
+         "stageM", "stageN", "stageO", "stageP"};\r
+\r
+    protected int _computation[] =\r
+        {1, 2, 3, 4, 5, 6, 7, 8,\r
+         9, 10, 11, 12, 13, 14, 15, 16};\r
+\r
+    protected int _communication[][] =\r
+        {{    0,  1024,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {-1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0, -1024,     0,  1024},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0, -1024,     0}};\r
+\r
+\r
+    //protected String _binding[] =\r
+    //    {"tile_0.arm", "tile_0.arm", "tile_1.arm", "tile_1.arm",\r
+    //     "tile_2.arm", "tile_2.arm", "tile_3.arm", "tile_3.arm",\r
+    //     "tile_4.arm", "tile_4.arm", "tile_5.arm", "tile_5.arm",\r
+    //     "tile_6.arm", "tile_6.arm", "tile_7.arm", "tile_7.arm"};\r
+\r
+    //protected String _binding[] =\r
+    //    {"tile_0.arm", "tile_1.arm", "tile_2.arm", "tile_3.arm",\r
+    //     "tile_4.arm", "tile_5.arm", "tile_6.arm", "tile_7.arm",\r
+    //     "tile_0.arm", "tile_1.arm", "tile_2.arm", "tile_3.arm",\r
+    //     "tile_4.arm", "tile_5.arm", "tile_6.arm", "tile_7.arm"};\r
+\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_1.arm", "tile_2.arm", "tile_3.arm",\r
+         "tile_4.arm", "tile_5.arm", "tile_6.arm", "tile_7.arm",\r
+         "tile_7.arm", "tile_6.arm", "tile_5.arm", "tile_4.arm",\r
+         "tile_3.arm", "tile_2.arm", "tile_1.arm", "tile_0.arm"};\r
+\r
+    protected int _iterations = 10;\r
+    */\r
+\r
+    protected String _processes[] =\r
+        {"splitAA", "splitBA", "splitBB",\r
+         "pipeAA", "pipeBA", "pipeCA", "pipeDA",\r
+         "pipeEA", "pipeFA", "pipeAB", "pipeBB",\r
+         "pipeCB", "pipeDB", "pipeEB", "pipeFB",\r
+         "mergeBA", "mergeBB", "mergeAA"};\r
+\r
+    protected int _armComputation[] =\r
+        {1, 2, 3, 4, 5, 6, 7, 8,\r
+         9, 10, 11, 12, 13, 14, 15, 16, 17, 18};\r
+    protected int _magicComputation[] =\r
+        {1, 2, 3, 4, 5, 6, 7, 8,\r
+         9, 10, 11, 12, 13, 14, 15, 16, 17, 18};\r
+\r
+\r
+    protected int _communication[][] =\r
+        {{    0,     4,     4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {   -4,     0,     0,     4,     4,     4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {   -4,     0,     0,     0,     0,     0,     4,     4,     4,     0,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,    -4,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0,     0,     0,     0,     0,     0},\r
+         {    0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0,     0,     0,     0,     0},\r
+         {    0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0,     0,     0,     0},\r
+         {    0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0,     0,     0},\r
+         {    0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0,     0},\r
+         {    0,     0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0},\r
+         {    0,     0,     0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0},\r
+         {    0,     0,     0,     0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0,     0},\r
+         {    0,     0,     0,     0,     0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     0,     4,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,    -4,     0,     0,     0,     0,     0,     0,     0,     4,     0},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,    -4,    -4,    -4,     0,     0,     0,     0,     0,     4},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -4,    -4,    -4,     0,     0,     4},\r
+         {    0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,    -4,    -4,     0}};\r
+\r
+\r
+    //working\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_1.arm", "tile_4.arm",\r
+         "tile_1.arm", "tile_2.arm", "tile_3.arm", "tile_4.arm",\r
+         "tile_5.arm", "tile_6.arm", "tile_1.arm", "tile_2.arm",\r
+         "tile_3.arm", "tile_4.arm", "tile_5.arm", "tile_6.arm",\r
+         "tile_3.arm", "tile_7.arm", "tile_0.arm"};\r
+\r
+    /*\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_1.arm", "tile_3.arm",\r
+         "tile_1.arm", "tile_1.arm", "tile_2.arm", "tile_2.arm",\r
+         "tile_3.arm", "tile_3.arm", "tile_4.arm", "tile_4.arm",\r
+         "tile_5.arm", "tile_5.arm", "tile_6.arm", "tile_6.arm",\r
+         "tile_7.arm", "tile_7.arm", "tile_0.arm"};\r
+\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_1.arm", "tile_7.arm",\r
+         "tile_1.arm", "tile_1.arm", "tile_2.arm", "tile_2.arm",\r
+         "tile_3.arm", "tile_3.arm", "tile_4.arm", "tile_4.arm",\r
+         "tile_5.arm", "tile_5.arm", "tile_6.arm", "tile_6.arm",\r
+         "tile_7.arm", "tile_3.arm", "tile_0.arm"};\r
+    */\r
+\r
+    //not working\r
+    /*\r
+    protected String _binding[] =\r
+        {"tile_0.arm", "tile_1.arm", "tile_2.arm", "tile_3.arm",\r
+         "tile_4.arm", "tile_5.arm", "tile_6.arm", "tile_7.arm",\r
+         "tile_7.arm", "tile_6.arm", "tile_5.arm", "tile_4.arm",\r
+         "tile_3.arm", "tile_2.arm", "tile_1.arm", "tile_0.arm",\r
+         "tile_0.arm", "tile_0.arm"};\r
+    */\r
+\r
+    protected int _iterations = 10;\r
+\r
+    public String getStringEncoding(int i, int total) {\r
+        if (total > 26 * 26) {\r
+            System.out.println("\"total\" needs to be less than "\r
+                    + 26 * 26 + ".");\r
+            return "";\r
+        } else if (total <= 26) {\r
+            return  Character.toString((char)('A' + (i % 26)));\r
+        }\r
+        return Character.toString((char)('A' + (i / 26)))\r
+            + Character.toString((char)('A' + (i % 26)));\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param stages\r
+     * @param communication\r
+     */\r
+    public void generateIndependentTasks(int numberOfTasks) {\r
+          _processes = new String[numberOfTasks];\r
+          _armComputation = new int[numberOfTasks];\r
+          _magicComputation = new int[numberOfTasks];\r
+          _communication = new int[numberOfTasks][numberOfTasks];\r
+          _binding = new String[numberOfTasks];\r
+          _iterations = 1000;\r
+\r
+          for (int i = 0; i < numberOfTasks; i++) {\r
+              _processes[i] = ((i < numberOfTasks / 2) ? "armProcess"\r
+                  : "magicProcess")\r
+                  + getStringEncoding(i, numberOfTasks);\r
+              System.out.println(_processes[i]);\r
+              _armComputation[i] =\r
+                  (i < numberOfTasks / 2) ? 100000000 : 200000000;\r
+              _magicComputation[i] =\r
+                  (i < numberOfTasks / 2) ? 200000000 : 100000000;\r
+              _binding[i] = (i < numberOfTasks / 2) ? "tile_0.arm"\r
+                      : "tile_0.magic";\r
+          }\r
+\r
+          //no communication\r
+          for (int i = 0; i < numberOfTasks; i++) {\r
+              for (int j = 0; j < numberOfTasks; j++) {\r
+                  _communication[i][j] = 0;\r
+              }\r
+          }\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param pipelines\r
+     * @param stages\r
+     * @param communication\r
+     */\r
+    public void generateIndpendentPipelines(int pipelines, int stages, int communication) {\r
+        Random random = new Random();\r
+        _processes = new String[stages * pipelines];\r
+        _armComputation = new int[stages * pipelines];\r
+        _magicComputation = new int[stages * pipelines];\r
+        _communication = new int[stages * pipelines][stages * pipelines];\r
+        _binding = new String[stages * pipelines];\r
+        _iterations = 1000;\r
+\r
+        for (int i = 0; i < pipelines; i++) {\r
+            for (int j = 0; j < stages; j++) {\r
+               _processes[i * stages + j] =\r
+                   ((i < pipelines / 2) ? "arm" : "magic")\r
+                   + "stage"\r
+                   + getStringEncoding(i, pipelines) + "x"\r
+                   + getStringEncoding(j, stages);\r
+               System.out.println(_processes[i * stages + j]);\r
+              _armComputation[i * stages + j] =\r
+                  0 * random.nextInt(10000000) +\r
+                  ((i < pipelines / 2) ? 100000000 : 200000000);\r
+              _magicComputation[i * stages + j] =\r
+                  0 * random.nextInt(10000000) +\r
+                  ((i < pipelines / 2) ? 200000000 : 100000000);\r
+              _binding[i * stages + j] = "tile_0.arm";\r
+            }\r
+        }\r
+\r
+        for (int i = 0; i < pipelines; i++) {\r
+            for (int j = 0; j < stages; j++) {\r
+                for (int k = 0; k < pipelines; k++) {\r
+                    for (int l = 0; l < stages; l++) {\r
+                        _communication[i * stages + j][k * stages + l] = 0;\r
+                        if (i == k && l == j + 1) {\r
+                            _communication[i * stages + j][k * stages + l] = communication;\r
+                        } else if (i == k && j == l + 1) {\r
+                            _communication[i * stages + j][k * stages + l] = -communication;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     *\r
+     * @param pipelines\r
+     * @param stages\r
+     * @param communication\r
+     */\r
+    public void generateIndpendentPipelines2(int pipelines, int stages, int communication) {\r
+        Random random = new Random();\r
+        _processes = new String[stages * pipelines];\r
+        _armComputation = new int[stages * pipelines];\r
+        _magicComputation = new int[stages * pipelines];\r
+        _communication = new int[stages * pipelines][stages * pipelines];\r
+        _binding = new String[stages * pipelines];\r
+        _iterations = 1000;\r
+\r
+        for (int i = 0; i < pipelines; i++) {\r
+            for (int j = 0; j < stages; j++) {\r
+               _processes[i * stages + j] =\r
+                   ((j < stages / 2) ? "arm" : "magic")\r
+                   + "stage"\r
+                   + getStringEncoding(i, pipelines) + "x"\r
+                   + getStringEncoding(j, stages);\r
+               System.out.println(_processes[i * stages + j]);\r
+              _armComputation[i * stages + j] =\r
+                  0 * random.nextInt(10000000) +\r
+                  ((j < stages / 2) ? 100000000 : 200000000);\r
+              _magicComputation[i * stages + j] =\r
+                  0 * random.nextInt(10000000) +\r
+                  ((j < stages / 2) ? 200000000 : 100000000);\r
+              _binding[i * stages + j] = "tile_0.arm";\r
+            }\r
+        }\r
+\r
+        for (int i = 0; i < pipelines; i++) {\r
+            for (int j = 0; j < stages; j++) {\r
+                for (int k = 0; k < pipelines; k++) {\r
+                    for (int l = 0; l < stages; l++) {\r
+                        _communication[i * stages + j][k * stages + l] = 0;\r
+                        if (i == k && l == j + 1) {\r
+                            _communication[i * stages + j][k * stages + l] = communication;\r
+                        } else if (i == k && j == l + 1) {\r
+                            _communication[i * stages + j][k * stages + l] = -communication;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     *\r
+     * @param stages\r
+     * @param communication\r
+     */\r
+    public void generatePipeline(int stages, int communication) {\r
+        _processes = new String[stages];\r
+        _armComputation = new int[stages];\r
+        _magicComputation = new int[stages];\r
+        _communication = new int[stages][stages];\r
+        _binding = new String[stages];\r
+        //_iterations = 1000;\r
+        _iterations = 1000;\r
+\r
+        for (int i = 0; i < stages; i++) {\r
+            _processes[i] = ((i % 8 < 4) ? "arm" : "magic")\r
+                + "stage" + getStringEncoding(i, stages);\r
+            System.out.println(_processes[i]);\r
+            _armComputation[i] =\r
+                (i % 8 < 4) ? 100 : 200;\r
+            _magicComputation[i] =\r
+                (i % 8 < 4) ? 200 : 100;\r
+            _binding[i] = "tile_0.arm";\r
+        }\r
+\r
+        for (int i = 0; i < stages; i++) {\r
+            for (int j = 0; j < stages; j++) {\r
+                _communication[i][j] = 0;\r
+                if (j == i + 1) {\r
+                    _communication[i][j] = communication;\r
+                } else if (i == j + 1) {\r
+                    _communication[i][j] = -communication;\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     *\r
+     * @param pn\r
+     */\r
+    public void generateProcessNetwork(ProcessNetwork pn) {\r
+        System.out.print("Generate process network. ");\r
+        int numberOfProcesses = 0;\r
+        int numberOfChannels = 0;\r
+\r
+        for (int j = 0; j < _processes.length; j++) {\r
+            String processName = _processes[j];\r
+            Process p = new Process(processName);\r
+            SourceCode srcCode = new SourceCode(processName);\r
+            srcCode.setLocality(processName + ".c");\r
+            srcCode.setType("c");\r
+            p.getSrcList().add(srcCode);\r
+            pn.getProcessList().add(p);\r
+            numberOfProcesses++;\r
+            for (int i = 0; i < 8; i++) {\r
+                ProfilingConfiguration c = new ProfilingConfiguration(\r
+                        "BCED tile_" + i + ".arm");\r
+                c.setValue(Integer.toString(_armComputation[j]));\r
+                p.getProfilingList().add(c);\r
+                c = new ProfilingConfiguration(\r
+                        "BCED tile_" + i + ".magic");\r
+                c.setValue(Integer.toString(_magicComputation[j]));\r
+                p.getProfilingList().add(c);\r
+            }\r
+        }\r
+\r
+        //check whether communication matrix is symmetric\r
+        if (_communication[0].length != numberOfProcesses) {\r
+            System.out.println();\r
+            System.out.println("Error: Size of communication matrix ("\r
+                    + _communication[0].length + " columns) must match "\r
+                    + "number of processes (" + numberOfProcesses + ").");\r
+            System.exit(-1);\r
+        }\r
+        for (int row = 0; row < numberOfProcesses; row++) {\r
+            for (int col = 0; col < numberOfProcesses; col++) {\r
+                if (row == col && _communication[row][col] != 0) {\r
+                    System.out.println();\r
+                    System.out.println("Error: No self-channels allowed. "\r
+                            + "Problem for process " + row + " ("\r
+                            + _processes[row] + ").");\r
+                    System.exit(-1);\r
+                }\r
+                if (_communication[row][col] !=\r
+                    -_communication[col][row]) {\r
+                    System.out.println();\r
+                    System.out.println("Error: Communication matrix "\r
+                            + "needs to be symmetric. Mismatch for row "\r
+                            + row + " column " + col + ".");\r
+                    System.exit(-1);\r
+                }\r
+            }\r
+        }\r
+\r
+        for (int row = 0; row < numberOfProcesses; row++) {\r
+            for (int col = row; col < numberOfProcesses; col++) {\r
+                if (_communication[row][col] == 0) {\r
+                    continue;\r
+                }\r
+                int src = row;\r
+                int dst = col;\r
+\r
+                if (_communication[row][col] < 0) {\r
+                    src = col;\r
+                    dst = row;\r
+                }\r
+\r
+                Channel c = new Channel("channel" + _processes[src]\r
+                        + _processes[dst]);\r
+                c.setSize(Math.abs(2 * _communication[src][dst]));\r
+                c.setType("fifo");\r
+                ProfilingConfiguration p = new ProfilingConfiguration(\r
+                        "TotalReadData");\r
+                p.setValue(Integer.toString(_communication[row][col]));\r
+                c.getProfilingList().add(p);\r
+                pn.getChannelList().add(c);\r
+                numberOfChannels++;\r
+\r
+                Port channelPort0 = new Port("0", Port.INPORT);\r
+                Port channelPort1 = new Port("1", Port.OUTPORT);\r
+                c.getPortList().add(channelPort0);\r
+                c.getPortList().add(channelPort1);\r
+\r
+                Connection c1 = new Connection(\r
+                        "c1" + _processes[src] + _processes[dst]);\r
+                Connection c2 = new Connection(\r
+                        "c2" + _processes[src] + _processes[dst]);\r
+                pn.getConnectionList().add(c1);\r
+                pn.getConnectionList().add(c2);\r
+\r
+                Port p0 = new Port(Integer.toString(pn.getProcess(\r
+                        _processes[src]).getPortList().size()),\r
+                        Port.OUTPORT);\r
+                Port p1 = new Port(Integer.toString(pn.getProcess(\r
+                        _processes[dst]).getPortList().size()),\r
+                        Port.INPORT);\r
+                pn.getProcess(_processes[src]).getPortList().add(p0);\r
+                pn.getProcess(_processes[dst]).getPortList().add(p1);\r
+\r
+                c1.setOriginPort(p0);\r
+                c1.setTargetPort(channelPort0);\r
+                c1.setOrigin(pn.getProcess(_processes[src]));\r
+                c1.setTarget(c);\r
+                p0.setPeerResource(c);\r
+                p0.setPeerPort(channelPort0);\r
+                channelPort0.setPeerResource(pn.getProcess(\r
+                        _processes[src]));\r
+                channelPort0.setPeerPort(p0);\r
+\r
+                c2.setOriginPort(channelPort1);\r
+                c2.setTargetPort(p1);\r
+                c2.setOrigin(c);\r
+                c2.setTarget(pn.getProcess(_processes[dst]));\r
+                channelPort1.setPeerResource(pn.getProcess(\r
+                        _processes[dst]));\r
+                channelPort1.setPeerPort(p1);\r
+                p1.setPeerResource(c);\r
+                p1.setPeerPort(channelPort1);\r
+\r
+                c.setOrigin(pn.getProcess(_processes[src]));\r
+                c.setTarget(pn.getProcess(_processes[dst]));\r
+            }\r
+        }\r
+\r
+        System.out.println("Finished.");\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param pn\r
+     */\r
+    public void generateProcessNetworkXml(ProcessNetwork pn,\r
+            String filename) {\r
+        System.out.print("Generate process network XML. ");\r
+        StringBuffer buffer = new StringBuffer();\r
+        pn.accept(new PNXmlVisitor(buffer));\r
+        try {\r
+            java.io.BufferedWriter writer =\r
+                    new java.io.BufferedWriter(\r
+                    new java.io.FileWriter(filename));\r
+            writer.write(buffer.toString());\r
+            writer.close();\r
+        } catch (java.io.IOException e) {\r
+            System.out.println();\r
+            System.out.println("Error: Could not write XML file.");\r
+            System.exit(-1);\r
+        }\r
+        System.out.println("Finished.");\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param pn\r
+     * @param path\r
+     */\r
+    public void generateCode(ProcessNetwork pn, String path) {\r
+        System.out.print("Generate source code of processes. ");\r
+\r
+        String newline = System.getProperty("line.separator");\r
+        int maxProcessNameLength = 0;\r
+        for (String processName : _processes) {\r
+            maxProcessNameLength = Math.max(maxProcessNameLength,\r
+                    processName.length());\r
+        }\r
+\r
+        String global = "";\r
+        global += "#ifndef GLOBAL_H" + newline;\r
+        global += "#define GLOBAL_H" + newline;\r
+        global += newline;\r
+\r
+        global += "#define ITERATIONS    " + _iterations + newline;\r
+        global += newline;\r
+\r
+        for (int i = 0; i < _processes.length; i++) {\r
+            global += "#define LOOPS_ARM_" + _processes[i].toUpperCase()\r
+                + "    " + _armComputation[i] + newline;\r
+            global += "#define LOOPS_MAGIC_" + _processes[i].toUpperCase()\r
+                + "    " + _magicComputation[i] + newline;\r
+        }\r
+\r
+        for (int row = 0; row < _communication[0].length; row++) {\r
+            for (int col = row; col < _communication[0].length; col++) {\r
+                if (_communication[row][col] == 0) {\r
+                    continue;\r
+                }\r
+                int src = row;\r
+                int dst = col;\r
+\r
+                if (_communication[row][col] < 0) {\r
+                    src = col;\r
+                    dst = row;\r
+                }\r
+\r
+                global += "#define TOKEN_SIZE_"\r
+                        + _processes[src].toUpperCase() + "_"\r
+                        + _processes[dst].toUpperCase() + "    "\r
+                        + _communication[src][dst] + newline;\r
+            }\r
+        }\r
+        global += newline;\r
+        global += "#endif" + newline;\r
+\r
+        try {\r
+            BufferedWriter out = new BufferedWriter(\r
+                    new FileWriter(path + "global.h"));\r
+            out.write(global);\r
+            out.close();\r
+        } catch (Exception e) {\r
+            System.out.println();\r
+            System.out.println("Error: While writing global.h file.");\r
+            System.exit(-1);\r
+        }\r
+\r
+\r
+        for (Process p : pn.getProcessList()) {\r
+            String state = p.getName().substring(0, 1).toUpperCase()\r
+                    + p.getName().substring(1) + "_State";\r
+\r
+            String h = "";\r
+            h += "#ifndef " + p.getName().toUpperCase() + "_H" + newline;\r
+            h += "#define " + p.getName().toUpperCase() + "_H" + newline;\r
+            h += newline;\r
+            h += "#include <dol.h>" + newline;\r
+            h += newline;\r
+            for (Port port : p.getPortList()) {\r
+                h += "#define PORT_" + p.getName().toUpperCase() + "_"\r
+                       + (port.isInPort() ? "IN_" : "OUT_" )\r
+                       + port.getName() + " " + port.getName() + newline;\r
+            }\r
+            h += newline;\r
+            h += "typedef struct {" + newline;\r
+            h += "    int iterations;" + newline;\r
+            h += "} " + state + ";" + newline;\r
+            h += newline;\r
+            h += "void " + p.getName() + "_init(DOLProcess *p);"\r
+                    + newline;\r
+            h += "int " + p.getName() + "_fire(DOLProcess *p);" + newline;\r
+            h += newline;\r
+            h += "#endif" + newline;\r
+\r
+            String c = "";\r
+            String printPrefix = String.format("    printf(\"[%-"\r
+                    + maxProcessNameLength + "s] ", p.getName());\r
+            c += "#include <stdio.h>" + newline;\r
+            c += newline;\r
+            c += "#include \"" + p.getName() + ".h\"" + newline;\r
+            c += "#include \"global.h\"" + newline;\r
+            c += newline;\r
+            c += "void " + p.getName() + "_init(DOLProcess *p) {"\r
+                    + newline;\r
+            c += "    " + state + " *state = (" + state + "*)p->local;"\r
+                    + newline;\r
+            c += "    state->iterations = 0;" + newline;\r
+            c += "}" + newline;\r
+            c += newline;\r
+            c += "int " + p.getName() + "_fire(DOLProcess *p) {"\r
+                    + newline;\r
+\r
+            int processIndex = getProcessIndex(p.getName());\r
+            int maxBuffer = 0;\r
+            for (int i = 0; i < _communication[processIndex].length; i++) {\r
+                maxBuffer = Math.max(maxBuffer,\r
+                        Math.abs(_communication[processIndex][i]));\r
+            }\r
+            c += "    int buffer[" + ((maxBuffer + (4 - 1)) / 4) + "];" + newline;\r
+            c += "    int i;" + newline;\r
+            c += "    " + state + " *state = (" + state + "*)p->local;";\r
+            c += newline + newline;\r
+\r
+            for (Port port : p.getPortList()) {\r
+                if (port.isInPort()) {\r
+                    int originIndex = getProcessIndex(\r
+                        ((Channel)port.getPeerResource()).getOrigin()\r
+                        .getName());\r
+                    String tokenSize = "TOKEN_SIZE_"\r
+                        + _processes[originIndex].toUpperCase() + "_"\r
+                        + _processes[processIndex].toUpperCase();\r
+                    c += printPrefix + "read %d bytes from "\r
+                        + _processes[originIndex] + ".\\n\", " + tokenSize\r
+                        + ");" + newline;\r
+                    c += "    DOL_read((void*)"\r
+                        + "PORT_" + p.getName().toUpperCase() + "_IN_"\r
+                        + port.getName() + ", buffer, " + tokenSize\r
+                        + ", p);" + newline;\r
+                }\r
+            }\r
+            c += newline;\r
+            //c += "    printf(\"[%-20s ] iteration %d/n\", \""\r
+            //        + p.getName() + "\", state->iterations);" + newline;\r
+            c += printPrefix + "iteration %d.\\n\" , "\r
+                    + "state->iterations);" + newline;\r
+            c += newline;\r
+            c += "#ifdef __arm__" + newline;\r
+            c += "    for (i = 0; i < LOOPS_ARM_" + p.getName().toUpperCase()\r
+                + "; i++) { ; }" + newline;\r
+            c += "#else" + newline;\r
+            c += "    for (i = 0; i < LOOPS_MAGIC_" + p.getName().toUpperCase()\r
+                + "; i++) { ; }" + newline;\r
+            c += "#endif" + newline;\r
+            for (Port port : p.getPortList()) {\r
+                if (port.isOutPort()) {\r
+                    int targetIndex = getProcessIndex(\r
+                            ((Channel)port.getPeerResource()).getTarget()\r
+                            .getName());\r
+                    String tokenSize = "TOKEN_SIZE_"\r
+                        + _processes[processIndex].toUpperCase() + "_"\r
+                        + _processes[targetIndex].toUpperCase();\r
+                    c += printPrefix + "write %d bytes to "\r
+                        + _processes[targetIndex] + ".\\n\", " + tokenSize\r
+                        + ");" + newline;\r
+                    c += "    DOL_write((void*)"\r
+                        + "PORT_" + p.getName().toUpperCase() + "_OUT_"\r
+                        + port.getName() + ", buffer, "+ tokenSize\r
+                        + ", p);" + newline;\r
+                }\r
+            }\r
+            c += newline;\r
+            c += "    state->iterations++;" + newline;\r
+            c += "    if (state->iterations >= ITERATIONS) {"\r
+                    + newline;\r
+            c += "        DOL_detach(p);" + newline;\r
+            c += "        return -1;" + newline;\r
+            c += "    }" + newline;\r
+            c += newline;\r
+            c += "    return 0;" + newline;\r
+            c += "}" + newline;\r
+\r
+            try {\r
+                BufferedWriter out = new BufferedWriter(\r
+                        new FileWriter(path + p.getName() + ".h"));\r
+                out.write(h);\r
+                out.close();\r
+                out = new BufferedWriter(\r
+                        new FileWriter(path + p.getName() + ".c"));\r
+                out.write(c);\r
+                out.close();\r
+            } catch (Exception e) {\r
+                System.out.println();\r
+                System.out.println("Error: While writing source files.");\r
+                System.exit(-1);\r
+            }\r
+        }\r
+        System.out.println("Finished.");\r
+    }\r
+\r
+\r
+    /**\r
+     *\r
+     * @param map\r
+     * @param pn\r
+     */\r
+    public void generateMapping(ProcessNetwork pn, Mapping map) {\r
+        System.out.print("Generate mapping. ");\r
+        map.setPN(pn);\r
+\r
+        //binding of processes\r
+        Vector<Processor> processors = new Vector<Processor>();\r
+        for (int i = 0; i < _binding.length; i++) {\r
+            String processName =  _processes[i];\r
+            String processorName = _binding[i];\r
+            Processor processor = null;\r
+\r
+            boolean processorExists = false;\r
+            for (Processor proc : processors) {\r
+                if (proc.getName().equals(processorName)) {\r
+                    processor = proc;\r
+                    processorExists = true;\r
+                    break;\r
+                }\r
+            }\r
+\r
+            if (!processorExists) {\r
+                processor = new Processor(processorName);\r
+                processors.add(processor);\r
+            }\r
+\r
+            ComputationBinding compBinding = new ComputationBinding(\r
+                    processName + "binding");\r
+            compBinding.setProcess(pn.getProcess(processName));\r
+            compBinding.setProcessor(processor);\r
+            processor.getProcessList().add(pn.getProcess(processName));\r
+            map.getCompBindList().add(compBinding);\r
+        }\r
+\r
+        //schedules\r
+        for (Processor p : processors) {\r
+            Schedule s = new Schedule(p.getName() + "schedule");\r
+            s.setSchedPolicy(SchedulingPolicy.FIFO);\r
+            s.setResource(p);\r
+            for (Process process : p.getProcessList()) {\r
+                ScheduleEntry entry = new ScheduleEntry(\r
+                        process.getName());\r
+                entry.setConsumer(process);\r
+                s.getEntryList().add(entry);\r
+            }\r
+            map.getScheduleList().add(s);\r
+        }\r
+\r
+        //binding of channels\r
+        for (Channel c : pn.getChannelList()) {\r
+            String originProcess = c.getOrigin().getName();\r
+            String targetProcess = c.getTarget().getName();\r
+\r
+            String originBinding = _binding[getProcessIndex(\r
+                    originProcess)];\r
+            String targetBinding = _binding[getProcessIndex(\r
+                    targetProcess)];\r
+\r
+            Pattern pattern0 = Pattern.compile(\r
+                    "tile_(\\d)\\.(arm)|tile_(\\d)\\.(magic)");\r
+            Matcher matcher0 = pattern0.matcher(originBinding);\r
+            Pattern pattern1 = Pattern.compile(\r
+                    "tile_(\\d)\\.(arm)|tile_(\\d)\\.(magic)");\r
+            Matcher matcher1 = pattern1.matcher(targetBinding);\r
+\r
+            if (!matcher0.matches() || !matcher1.matches()) {\r
+                System.out.println("binding needs to comply to the"\r
+                        + " following regular expression: "\r
+                        + "tile_(\\d)\\.(arm)|tile_(\\d)\\.(magic)");\r
+                System.exit(-1);\r
+            }\r
+\r
+            int srcIndex = Integer.valueOf(matcher0.group(1));\r
+            int dstIndex = Integer.valueOf(matcher1.group(1));\r
+            String srcProcessor = matcher0.group(2);\r
+            String dstProcessor = matcher1.group(2);\r
+\r
+            String writePath = "";\r
+            String readPath = "";\r
+\r
+            if (srcIndex == dstIndex) {\r
+                if (srcProcessor.equals("arm")) {\r
+                    writePath = "tile_" + srcIndex + ".rdmtodxm";\r
+                } else {\r
+                    writePath = "tile_" + srcIndex + ".ddmtodxm";\r
+                }\r
+            } else {\r
+                if (srcProcessor.equals("arm")) {\r
+                    writePath = "tile_" + srcIndex + ".rdmtodnp_"\r
+                            + dstIndex;\r
+                } else {\r
+                    writePath = "tile_" + srcIndex + ".ddmtodnp_"\r
+                            + dstIndex;\r
+                }\r
+            }\r
+\r
+            if (dstProcessor.equals("arm")) {\r
+                readPath = "tile_" + dstIndex + ".rdmfromdxm";\r
+            } else {\r
+                readPath = "tile_" + dstIndex + ".ddmfromdxm";\r
+            }\r
+\r
+            CommunicationBinding commBinding = new CommunicationBinding(\r
+                    c.getName() + "binding");\r
+            commBinding.setChannel(c);\r
+            commBinding.setWritePath(new WritePath(writePath));\r
+            commBinding.setReadPath(new ReadPath(readPath));\r
+            map.getCommBindList().add(commBinding);\r
+        }\r
+        System.out.println("Finished.");\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param processName\r
+     * @return\r
+     */\r
+    protected int getProcessIndex(String processName) {\r
+        for (int i = 0; i < _processes.length; i++) {\r
+            if (_processes[i].equals(processName)) {\r
+                return i;\r
+            }\r
+        }\r
+        System.out.println("Error: Could not find process "\r
+                + processName + ".");\r
+        System.exit(-1);\r
+        return 0;\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param map\r
+     */\r
+    public void generateMappingXml(Mapping map, String filename) {\r
+        System.out.print("Generate mapping XML. ");\r
+        StringBuffer buffer = new StringBuffer();\r
+        map.accept(new MapXmlVisitor(buffer));\r
+        try {\r
+            java.io.BufferedWriter writer =\r
+                    new java.io.BufferedWriter(\r
+                    new java.io.FileWriter(filename));\r
+            writer.write(buffer.toString());\r
+            writer.close();\r
+        } catch (java.io.IOException e) {\r
+            System.out.println("Could not write XML file.");\r
+            System.exit(-1);\r
+        }\r
+        System.out.println("Finished.");\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param args\r
+     */\r
+    public static void main(String args[]) {\r
+        /*\r
+        Pattern pattern = Pattern.compile("tile_(\\d)\\.");\r
+        Matcher matcher = pattern.matcher("tile_3.");\r
+        matcher.matches();\r
+        System.out.println(matcher.group(1));\r
+        */\r
+\r
+        String appName = "exampleAuto";\r
+        String path = System.getProperty("user.dir") + "/" + appName + "/";\r
+        File dir = new File(path);\r
+        dir.mkdirs();\r
+        dir = new File(path + "src/");\r
+        dir.mkdirs();\r
+\r
+        System.out.println("Generate application \"" + appName + "\""\r
+                + " in directory \"" + path + "\".");\r
+        ApplicationGenerator appGen = new ApplicationGenerator();\r
+        //appGen.generateIndpendentPipelines2(16, 4, 10000000);\r
+        appGen.generatePipeline(64, 10);\r
+        //appGen.generateIndependentTasks(64);\r
+        ProcessNetwork pn = new ProcessNetwork(appName);\r
+        appGen.generateProcessNetwork(pn);\r
+        appGen.generateProcessNetworkXml(pn, path + appName + ".xml");\r
+        appGen.generateCode(pn, path + "src/");\r
+        Mapping map = new Mapping("mapping");\r
+        appGen.generateMapping(pn, map);\r
+        appGen.generateMappingXml(map, path + "mapping.xml");\r
+        System.out.println("Done.");\r
+    }\r
+}
\ No newline at end of file
diff --git a/dol/src/dol/util/CheckXMLs.java b/dol/src/dol/util/CheckXMLs.java
new file mode 100644 (file)
index 0000000..71ff63f
--- /dev/null
@@ -0,0 +1,45 @@
+/* $Id: CheckXMLs.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.util;\r
+\r
+import dol.datamodel.architecture.Architecture;\r
+import dol.datamodel.mapping.Mapping;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.parser.xml.archischema.ArchiXmlParser;\r
+import dol.parser.xml.mapschema.MapXmlParser;\r
+import dol.parser.xml.pnschema.PNXmlParser;\r
+\r
+\r
+public class CheckXMLs {\r
+    public static void main(String args[]) {\r
+\r
+        /*\r
+        String pnFile = "D:\\shapes\\pa\\tools\\exampleTest.xml";\r
+        String archFile = "D:\\shapes\\pa\\tools\\rdt8.xml";\r
+        String mapFile = "D:\\shapes\\pa\\tools\\mapping_2tiles.xml";\r
+        */\r
+        String pnFile = "processnetwork.xml";\r
+        String archFile = "rdt8.xml";\r
+        String mapFile = "mapping.xml";\r
+\r
+        if (args.length == 3) {\r
+            pnFile = args[0];\r
+            archFile = args[1];\r
+            mapFile = args[2];\r
+        }\r
+\r
+        System.out.println("Process network: " + pnFile);\r
+        System.out.println("Architecture:    " + archFile);\r
+        System.out.println("Mapping:         " + mapFile);\r
+        PNXmlParser parserPn = new PNXmlParser();\r
+        ProcessNetwork pn = parserPn.doParse(pnFile);\r
+\r
+        ArchiXmlParser parserArch = new ArchiXmlParser();\r
+        Architecture arch = parserArch.doParse(archFile);\r
+\r
+        MapXmlParser parserMap = new MapXmlParser(pn, arch);\r
+        Mapping mapping = parserMap.doParse(mapFile);\r
+\r
+        mapping.getArch();\r
+        System.out.println("XML files seem to be consistent.");\r
+    }\r
+}
\ No newline at end of file
diff --git a/dol/src/dol/util/CodePrintStream.java b/dol/src/dol/util/CodePrintStream.java
new file mode 100644 (file)
index 0000000..2a3a80b
--- /dev/null
@@ -0,0 +1,115 @@
+/* $Id: CodePrintStream.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.util;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * Class to print code that is correctly indented.
+ */
+public class CodePrintStream extends PrintStream {
+
+    /**
+     *
+     */
+    public CodePrintStream(OutputStream out) {
+        super(out);
+    }
+
+    /**
+     *
+     */
+    public CodePrintStream(OutputStream out, boolean autoFlush) {
+        super(out, autoFlush);
+    }
+
+    /**
+    *
+    */
+   public void print(String x) {
+       super.print(x);
+   }
+   
+    /**
+    *
+    */
+    public void println(String x) {
+        super.println(x);
+    }
+  
+    /**
+     *
+     */
+    public void printPrefix(String x) {
+        super.print(_prefix + x);
+    }
+    
+    /**
+     *
+     */
+    public void printPrefix() {
+        super.print(_prefix);
+    }
+
+    /**
+     *
+     */
+    public void printPrefixln(String x) {
+        super.println(_prefix + x);
+    }
+
+    /**
+     *
+     */
+    public void printPrefixln() {
+        super.println();
+    }
+
+    /**
+     * Print an opening curly brace and increase the indentation.
+     */
+    public void printLeftBracket() {
+        printPrefix();
+        println("{");
+        prefixInc();
+    }
+
+    /**
+     * Decrease the indentation and print a closing curly brace.
+     */
+    public void printRightBracket() {
+        prefixDec();
+        printPrefixln("}");
+    }
+
+    /**
+     *  Decrement the indentation.
+     */
+    public void prefixDec() {
+        if( _prefix.length() >= _offset.length() ) {
+            _prefix = _prefix.substring(_offset.length());
+        }
+    }
+
+    /**
+     *  Increment the indentation.
+     */
+    public void prefixInc() {
+        _prefix += _offset;
+    }
+
+    /**
+     *
+     */
+    public static void main(String[] args) {
+        CodePrintStream ps = new CodePrintStream(System.out);
+        ps.println("aa");
+        ps.print("bb");
+    }
+
+    private static String _offset = "    ";
+    private String _prefix = "";
+}
+
+
+
diff --git a/dol/src/dol/util/CodePrintString.java b/dol/src/dol/util/CodePrintString.java
new file mode 100644 (file)
index 0000000..b7ab780
--- /dev/null
@@ -0,0 +1,129 @@
+/* $Id: CodePrintString.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.util;
+
+/**
+ * Class to print code that is correctly indented.
+ */
+public class CodePrintString {
+
+    /**
+     * Default constructor.
+     * 
+     * @param stringBuffer string buffer where the result is stored
+     */
+    public CodePrintString(StringBuffer stringBuffer) {
+        _code = stringBuffer;
+    }
+
+    /**
+     * Print a line without indentation.
+     */
+    public void print(String string) {
+        _code.append(string);
+    }
+
+    /**
+     * Add a line break to the current line. Results in an empty
+     * line if the current line is empty.
+     */
+   public void println() {
+       _code.append(System.getProperty("line.separator"));
+   }
+
+   /**
+     * Print a line without indentation and add a line break.
+     * @param string string to print
+     */
+    public void println(String string) {
+        _code.append(string + System.getProperty("line.separator"));
+    }
+
+    /**
+     * Print spaces according to current level of indentation.
+     */
+    public void printPrefix() {
+        _code.append(_prefix);
+    }
+
+    /**
+     * Print a line at the current level of indentation.
+     * @param string string to print
+     */
+    public void printPrefix(String string) {
+        _code.append(_prefix + string);
+    }
+
+    /**
+     * Print a line at the current level of indentation and a line break.
+     * @param string string to print
+     */
+    public void printPrefixln(String string) {
+        _code.append(_prefix + string
+                + System.getProperty("line.separator"));
+    }
+
+    /**
+     * Print the opening tag for the given XML tag name and increase
+     * the indentation.
+     * @param tagName name of the XML tag
+     */
+    public void printOpeningTag(String tagName) {
+        printPrefix();
+        print("<" + tagName);
+        prefixInc();
+    }
+
+    /**
+     * Decrease the indentation and print the closing tag for the given
+     * XML tag name. 
+     * @param tagName name of the XML tag
+     */
+    public void printClosingTag(String tagName) {
+        prefixDec();
+        printPrefixln("</" + tagName + ">");
+    }
+
+    /**
+     * Decrement the indentation.
+     */
+    public void prefixDec() {
+        if( _prefix.length() >= _offset.length() ) {
+            _prefix = _prefix.substring(_offset.length());
+        }
+    }
+
+    /**
+     * Increment the indentation.
+     */
+    public void prefixInc() {
+        _prefix += _offset;
+    }
+
+    /**
+     * Get the formatted output string.
+     * @return output string
+     */
+    public String toString()  {
+        return _code.toString();
+    }
+
+    /**
+     * Test the CodePrintString implementation.
+     */
+    public static void main(String[] args) {
+        StringBuffer buffer = new StringBuffer();
+        CodePrintString ps = new CodePrintString(buffer);
+        ps.printOpeningTag("tag");
+        ps.println(">");
+        ps.printPrefixln("<abc/>");
+        ps.printClosingTag("tag");
+        System.out.println(ps.toString());
+    }
+
+    protected static String _offset = "    ";
+    protected String _prefix = "";
+    protected StringBuffer _code = null;
+}
+
+
+
diff --git a/dol/src/dol/util/Copier.java b/dol/src/dol/util/Copier.java
new file mode 100644 (file)
index 0000000..cb230d7
--- /dev/null
@@ -0,0 +1,155 @@
+/* $Id: Copier.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.util.jar.JarFile;
+
+/**
+ * Class to recursively copy a directory.
+ */
+public class Copier {
+
+    String _destination; //target directory
+
+    /**
+     * Copy a file.
+     *
+     * @param from source file
+     * @param to destination file
+     */
+    public void copyFile(File from, File to)
+            throws IOException {
+
+        FileChannel srcChannel = new FileInputStream(from).getChannel();
+        FileChannel dstChannel = new FileOutputStream(to).getChannel();
+        try {
+            dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
+            srcChannel.close();
+            dstChannel.close();
+        }
+        finally {
+          if (srcChannel != null)
+              srcChannel.close();
+
+          if (dstChannel != null)
+              dstChannel.close();
+        }
+    }
+
+    /**
+     * Method which defines what is done for each file found in the
+     * directory tree: It is copied to the corresponding target directory.
+     *
+     * @param filename file to process
+     * @param directory the subdirectory currently processed
+     */
+    protected void processFile(String filename, String directory)
+            throws IOException {
+        File from = new File(filename);
+        File to = new File(_destination + directory + from.getName());
+        copyFile(from, to);
+        //System.out.println("Copied " + from.getPath() + " to "
+        //        + to.getPath());
+    }
+
+    /**
+     * Iterate through the given directory tree. For each file found in
+     * the file, the method
+     * {@link #processFile(java.lang.String, java.lang.String)} is called.
+     *
+     * @param path the path of the directory to be browsed
+     * @param currentDir the subdirectory currently explored
+     */
+    protected void browseDirectoryTree(String path, String currentDir)
+            throws IOException {
+        File file = new File(path);
+
+        if (!file.exists()) return;
+        if (!file.isDirectory()) return;
+
+        //loop through files in directory
+        String[] files = file.list();
+
+        for (int k = 0; k < files.length; k++) {
+            File newfile = new File(file.getPath(), files[k]);
+            if (newfile.isFile())
+                processFile(path + System.getProperty("file.separator")
+                        + files[k], currentDir);
+            else if (newfile.isDirectory()) {
+                File newDirectory = new File(_destination + currentDir
+                        + files[k]);
+                newDirectory.mkdirs();
+                //System.out.println("Created directory "
+                //        + newDirectory.getPath());
+                browseDirectoryTree(file.getPath()
+                        + System.getProperty("file.separator")
+                        + files[k], currentDir + files[k]
+                        + System.getProperty("file.separator"));
+            }
+        }
+    }
+
+    /**
+     * Recursively copy a directory.
+     *
+     * @param source source directory
+     * @param destination target directory
+     */
+    public void copy(File source, File destination)
+            throws IOException {
+        try {
+            //treat jar archives differently
+            if (source.toString().contains("dol.jar!")) {
+                String jarName = source.toString();
+                jarName = jarName.substring(jarName.indexOf("file:") + 5, jarName.lastIndexOf("!"));
+                String sourceName = source.toString();
+                sourceName = sourceName.substring(
+                        sourceName.lastIndexOf("!") + 2);
+                sourceName = sourceName.replaceAll("\\\\", "/");
+                
+                JarFile jar = new JarFile(jarName);
+                JarCopier copier = new JarCopier();
+                copier.copy(jar, sourceName, destination.toString());
+                return;
+            }
+
+            _destination = destination.getPath();
+
+            if (!source.isDirectory())
+                throw (new IOException("Source is not a directory."));
+
+            File destinationDir = new File(_destination);
+            destinationDir.mkdirs();
+
+            browseDirectoryTree(source.getPath(),
+                    System.getProperty("file.separator"));
+        }
+        catch (IOException e) {
+            System.out.println("An error has occured while copying \""
+                    + source.getPath() + "\" to \""
+                    + destination.getPath() + "\":");
+            System.out.println(e.getMessage());
+            throw e;
+        }
+    }
+
+    /**
+     * Test the implementation.
+     *
+     * @param args args[0] specifies the source directory,
+     *             args[1] specifies the destination directory
+     */
+    public static void main(String args[])
+            throws Exception {
+        Copier copier = new Copier();
+        if (args.length == 2)
+            copier.copy(new File(args[0]), new File(args[1]));
+        else
+            System.out.println("usage: java Copier "
+                    + "sourceDirectory targetDirectory");
+    }
+}
diff --git a/dol/src/dol/util/JarCopier.java b/dol/src/dol/util/JarCopier.java
new file mode 100644 (file)
index 0000000..aeff404
--- /dev/null
@@ -0,0 +1,114 @@
+/* $Id: JarCopier.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.util;\r
+\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+import java.util.jar.JarEntry;\r
+import java.util.jar.JarFile;\r
+\r
+/**\r
+ * Class to copy files from a jar archive.\r
+ */\r
+public class JarCopier {\r
+\r
+    /**\r
+     * Copy a file from the specified jar file to the specified\r
+     * destination file. The file path must be specified using forward\r
+     * slashes, for instance, META-INF/MANIFEST.MF.\r
+     *\r
+     * @param jar jar archive\r
+     * @param from file to extract from jar archive\r
+     * @param to file to copy the file to\r
+     */\r
+    public void copyFile(JarFile jar, String from, String to) {\r
+        try {\r
+            InputStream in = jar.getInputStream(jar.getEntry(from));\r
+            OutputStream out = new FileOutputStream(new File(to));\r
+            int c;\r
+            while ((c = in.read()) != -1) {\r
+                out.write(c);\r
+            }\r
+            in.close();\r
+            out.close();\r
+        }\r
+        catch (IOException e) {\r
+            System.out.println("An error has occured while copying \""\r
+                    + from + "\" to \"" + to + "\":");\r
+            System.out.println(e.getMessage());\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get all files located in the given path of the given jar archive.\r
+     * The path must be specified with forward slashes.\r
+     *\r
+     * @param jar jar archive\r
+     * @param path path to search for files\r
+     * @return vector of all files in the specified path\r
+     */\r
+    public Vector<String> getFilesInDirectory(JarFile jar, String path) {\r
+        Vector<String> filelist = new Vector<String>();\r
+        Enumeration<JarEntry> entries = jar.entries();\r
+\r
+        while (entries.hasMoreElements()) {\r
+            String entry = entries.nextElement().toString();\r
+            if (entry.startsWith(path)) {\r
+                filelist.add(entry);\r
+            }\r
+        }\r
+        return filelist;\r
+    }\r
+\r
+    /**\r
+     * Recursively copy a directory from the specified jar archive.\r
+     *\r
+     * @param jar jar archive\r
+     * @param srcDir source directory\r
+     * @param destDir target directory\r
+     */\r
+    public void copy(JarFile jar, String srcDir, String destDir)\r
+            throws IOException {\r
+        File directory = new File(destDir);\r
+        if (!directory.exists()) {\r
+            directory.mkdirs();\r
+        }\r
+        for (String file : getFilesInDirectory(jar, srcDir)) {\r
+            String dir = file.substring(0, file.lastIndexOf("/"));\r
+            directory = new File(destDir\r
+                    + System.getProperty("file.separator")\r
+                    + dir.substring(srcDir.length()));\r
+            if (!directory.exists()) {\r
+                directory.mkdirs();\r
+            }\r
+            if (!file.endsWith("/")) {\r
+                copyFile(jar, file, destDir\r
+                        + System.getProperty("file.separator")\r
+                        + file.substring(srcDir.length() + 1));\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Copy the specified directory from the jar archive to the specified\r
+     * destination.\r
+     *\r
+     * @param args args[0] specifies the jar file to read from,\r
+     *             args[1] specifies the source directory,\r
+     *             args[2] specifies the destination directory\r
+     */\r
+    public static void main(String args[])\r
+            throws Exception {\r
+        JarCopier copier = new JarCopier();\r
+        JarFile jar = new JarFile(args[0]);\r
+        if (args.length == 3)\r
+            copier.copy(jar, args[1], args[2]);\r
+        else\r
+            System.out.println("usage: java JarCopier "\r
+                    + "jarFile sourceDirectory targetDirectory");\r
+    }\r
+}
\ No newline at end of file
diff --git a/dol/src/dol/util/SchemaLocation.java b/dol/src/dol/util/SchemaLocation.java
new file mode 100644 (file)
index 0000000..de46cef
--- /dev/null
@@ -0,0 +1,137 @@
+/* $Id: SchemaLocation.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.util;
+
+/**
+ * Class to get the location of schemas.
+ */
+public class SchemaLocation {
+
+    protected static final String PN_NAMESPACE =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK";
+    protected static final String PN_LOCATION =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/processnetwork.xsd";
+    protected static final String ARCH_NAMESPACE =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE";
+    protected static final String ARCH_LOCATION =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd";
+    protected static final String ARCH_NAMESPACE_OLD =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE_OLD";
+    protected static final String MAP_NAMESPACE =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING";
+    protected static final String MAP_LOCATION =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/mapping.xsd";
+    protected static final String MAP_NAMESPACE_OLD =
+            "http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING_OLD";
+
+    /** singleton instance */
+    protected final static SchemaLocation _schemaLocation =
+        new SchemaLocation();
+
+    /**
+     * Default constructor.
+     */
+    public SchemaLocation() {
+    }
+
+    /**
+     * Return the process network namespace.
+     *
+     * @return process network namespace
+     */
+    public static String getProcessNetworkNamespace() {
+        return PN_NAMESPACE;
+    }
+
+    /**
+     * Return the process network schema location.
+     *
+     * @return process network schema location
+     */
+    public static String getProcessNetworkSchemaLocation() {
+        return PN_LOCATION;
+    }
+
+    /**
+     * Return the architecture namespace.
+     *
+     * @return architecture namespace
+     */
+    public static String getArchitectureNamespace() {
+        return ARCH_NAMESPACE;
+    }
+
+    /**
+     * Return the architecture schema location.
+     *
+     * @return architecture schema location
+     */
+    public static String getArchitectureSchemaLocation() {
+        return ARCH_LOCATION;
+    }
+
+    /**
+     * Return the mapping namespace.
+     *
+     * @return mapping namespace
+     */
+    public static String getMappingNamespace() {
+        return MAP_NAMESPACE;
+    }
+
+    /**
+     * Return the mapping schema location.
+     *
+     * @return mapping schema location
+     */
+    public static String getMappingSchemaLocation() {
+        return MAP_LOCATION;
+    }
+
+    /**
+     * Return a string with the references to the external schema files.
+     *
+     * @return references to external schemas
+     */
+    public static String getExternalSchemaLocation() {
+        String loc = PN_NAMESPACE + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/processnetwork.xsd");
+        loc += " " + ARCH_NAMESPACE + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/architecture.xsd");
+        loc += " " + ARCH_NAMESPACE_OLD + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/architecture_old.xsd");
+        loc += " " + MAP_NAMESPACE + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/mapping.xsd");
+        return loc;
+    }
+
+    /**
+     * Return a string with the references to the internal schema files.
+     *
+     * @return references to internal schemas
+     */
+    public static String getInternalSchemaLocation() {
+        String loc = PN_NAMESPACE + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/internal/processnetwork_internal.xsd");
+        loc += " " + ARCH_NAMESPACE + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/internal/architecture_internal.xsd");
+        loc += " " + ARCH_NAMESPACE_OLD + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/internal/architecture_old_internal.xsd");
+        loc += " " + MAP_NAMESPACE + " ";
+        loc += _schemaLocation.getClass().getResource(
+                "/schema/internal/mapping_internal.xsd");
+        loc += " " + MAP_NAMESPACE_OLD + " ";
+        loc += _schemaLocation.getClass().getResource(
+               "/schema/internal/mapping_old_internal.xsd");
+        return loc;
+    }
+}
+
+
+
diff --git a/dol/src/dol/util/Sed.java b/dol/src/dol/util/Sed.java
new file mode 100644 (file)
index 0000000..ae610f6
--- /dev/null
@@ -0,0 +1,133 @@
+/* $Id: Sed.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.util;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.BufferedWriter;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileWriter;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+\r
+/**\r
+ * Class to find and replace strings in a files of a directory.\r
+ * The intention is to get a behavior similar to UNIX's sed (stream\r
+ * editor).\r
+ */\r
+public class Sed {\r
+\r
+    /**\r
+     * In the given file, search for occurences of the given search\r
+     * pattern and replace it by the given replacement.\r
+     * searchPattern, replacementPattern will be used in a call of\r
+     * String.replaceAll(searchPattern, replacementPattern).\r
+     *\r
+     * @param filename file to search\r
+     * @param searchPattern regular expression to search for\r
+     * @param replacementPattern replacement\r
+     */\r
+    protected void readReplace(String filename, String searchPattern,\r
+            String replacementPattern) throws IOException {\r
+        String line;\r
+        StringBuffer buffer = new StringBuffer();\r
+        FileInputStream fileInputStream = new FileInputStream(filename);\r
+        BufferedReader reader = new BufferedReader(\r
+                new InputStreamReader(fileInputStream));\r
+        while((line = reader.readLine()) != null) {\r
+            String newline = line.replaceAll(searchPattern, replacementPattern);\r
+            /*\r
+            if (!newline.equals(line)) {\r
+                System.out.println("Found pattern in " + filename\r
+                        + ". New line: " + newline);\r
+            }\r
+            */\r
+            buffer.append(newline + "\n");\r
+        }\r
+        reader.close();\r
+        BufferedWriter out = new BufferedWriter(new FileWriter(filename));\r
+        out.write(buffer.toString());\r
+        out.close();\r
+    }\r
+\r
+    /**\r
+     * Iterate through the given directory tree. For each file found in\r
+     * the file, the method\r
+     * {@link #processFile(java.lang.String)} is called.\r
+     *\r
+     * @param path the path of the directory to be browsed\r
+     * @param currentDir the subdirectory currently explored\r
+     */\r
+    protected void browseDirectoryTree(String path)\r
+            throws IOException {\r
+        File file = new File(path);\r
+\r
+        if (!file.exists()) return;\r
+        if (!file.isDirectory()) return;\r
+\r
+        //loop through files in directory\r
+        String[] files = file.list();\r
+\r
+        for (int k = 0; k < files.length; k++) {\r
+            File newfile = new File(file.getPath(), files[k]);\r
+            if (newfile.isFile())\r
+                readReplace(path + System.getProperty("file.separator")\r
+                        + files[k], _searchPattern, _replacementPattern);\r
+            else if (newfile.isDirectory()) {\r
+                browseDirectoryTree(file.getPath()\r
+                        + System.getProperty("file.separator")\r
+                        + files[k]);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * In the given file or in the files located in the given directory,\r
+     * search for occurences of the given search pattern and replace it\r
+     * by the given replacement. searchPattern, replacementPattern will\r
+     * be used in a call of\r
+     * String.replaceAll(searchPattern, replacementPattern).\r
+     *\r
+     * @param path file or path to search\r
+     * @param searchPattern regular expression to search for\r
+     * @param replacementPattern replacement\r
+     */\r
+    public void sed(String path, String searchPattern,\r
+            String replacementPattern) throws IOException {\r
+        File file = new File(path);\r
+        _searchPattern = searchPattern;\r
+        _replacementPattern = replacementPattern;\r
+        if (!file.exists()) return;\r
+        if (file.isFile()) {\r
+            readReplace(path, searchPattern, replacementPattern);\r
+        }\r
+        else if (file.isDirectory()) {\r
+            browseDirectoryTree(path);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Test the implementation.\r
+     *\r
+     * @param args args[0] file or directory to search\r
+     *             args[1] regular expression to search for\r
+     *             args[2] replacement\r
+     */\r
+    public static void main(String args[]) {\r
+        if (args.length == 3) {\r
+            try {\r
+                new Sed().sed(args[0], args[1], args[2]);\r
+            }\r
+            catch (IOException e) {\r
+                System.out.println("Sed: An error occured:");\r
+                System.out.println(e.getMessage());\r
+            }\r
+        }\r
+        else {\r
+            System.out.println("usage: java Sed directory|file "\r
+                    + "searchPattern replacementPattern");\r
+        }\r
+    }\r
+\r
+    String _searchPattern = "";\r
+    String _replacementPattern = "";\r
+}\r
diff --git a/dol/src/dol/util/package.html b/dol/src/dol/util/package.html
new file mode 100644 (file)
index 0000000..bb9fea5
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Collection of tools for file operations.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/visitor/ArchiVisitor.java b/dol/src/dol/visitor/ArchiVisitor.java
new file mode 100644 (file)
index 0000000..b72c2d2
--- /dev/null
@@ -0,0 +1,47 @@
+/* $Id: ArchiVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor;
+
+import dol.datamodel.architecture.ArchiConnection;
+import dol.datamodel.architecture.ArchiResource;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.Configuration;
+import dol.datamodel.architecture.HWChannel;
+import dol.datamodel.architecture.Memory;
+import dol.datamodel.architecture.Node;
+import dol.datamodel.architecture.PortNode;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.architecture.ReadPath;
+import dol.datamodel.architecture.Variable;
+import dol.datamodel.architecture.WritePath;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+
+/**
+ * This class is an abstract class for a visitor that is used to
+ * generate an Archietcture description.
+ */
+public abstract class ArchiVisitor implements Visitor {
+
+    public ArchiVisitor() {
+        _ui = UserInterface.getInstance();
+    }
+
+    public void visitComponent(Architecture x) { }
+    public void visitComponent(ArchiResource x) { }
+    public void visitComponent(Processor x) { }
+    public void visitComponent(Memory x) { }
+    public void visitComponent(HWChannel x) { }
+    public void visitComponent(Configuration x) {}
+    public void visitComponent(Variable x) { }
+    public void visitComponent(Node x) { }
+    public void visitComponent(PortNode x) { }
+    public void visitComponent(ArchiConnection x) {}
+    public void visitComponent(ReadPath x) {}
+    public void visitComponent(WritePath x) {}
+
+    /**
+     *  Stream where the print output is sent to.
+     */
+    protected CodePrintStream _printStream = null;
+    protected UserInterface _ui = null;
+}
diff --git a/dol/src/dol/visitor/MapVisitor.java b/dol/src/dol/visitor/MapVisitor.java
new file mode 100644 (file)
index 0000000..b12e585
--- /dev/null
@@ -0,0 +1,41 @@
+/* $Id: MapVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor;
+
+import dol.datamodel.mapping.Binding;
+import dol.datamodel.mapping.CommunicationBinding;
+import dol.datamodel.mapping.ComputationBinding;
+import dol.datamodel.mapping.Configuration;
+import dol.datamodel.mapping.MapResource;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.mapping.Schedule;
+import dol.datamodel.mapping.ScheduleEntry;
+import dol.datamodel.mapping.Variable;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+
+/**
+ * This class is an abstract class for a visitor that is used to
+ * generate a mapping description.
+ */
+public abstract class MapVisitor implements Visitor {
+
+    public MapVisitor() {
+        _ui = UserInterface.getInstance();
+    }
+
+    public void visitComponent(Mapping x) { }
+    public void visitComponent(MapResource x) { }
+    public void visitComponent(Binding x) {}
+    public void visitComponent(ComputationBinding x) {}
+    public void visitComponent(CommunicationBinding x) {}
+    public void visitComponent(Schedule x) {}
+    public void visitComponent(ScheduleEntry x) {}
+    public void visitComponent(Variable x) {}
+    public void visitComponent(Configuration x) {}
+
+    /**
+     *  Stream where the print output is sent to.
+     */
+    protected CodePrintStream _printStream = null;
+    protected UserInterface _ui = null;
+}
diff --git a/dol/src/dol/visitor/PNVisitor.java b/dol/src/dol/visitor/PNVisitor.java
new file mode 100644 (file)
index 0000000..ec36dd3
--- /dev/null
@@ -0,0 +1,44 @@
+/* $Id: PNVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Configuration;
+import dol.datamodel.pn.Connection;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.ProfilingConfiguration;
+import dol.datamodel.pn.Resource;
+import dol.datamodel.pn.SourceCode;
+import dol.datamodel.pn.Variable;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+
+/**
+ * This class is an abstract class for a visitor that is used to
+ * generate a Process Network description.
+ */
+public abstract class PNVisitor implements Visitor {
+
+    public PNVisitor() {
+        _ui = UserInterface.getInstance();
+    }
+
+    public void visitComponent(ProcessNetwork x) { }
+    public void visitComponent(Resource x) { }
+    public void visitComponent(Process x) { }
+    public void visitComponent(Variable x) { }
+    public void visitComponent(Channel x) { }
+    public void visitComponent(Connection x) { }
+    public void visitComponent(Configuration x) { }
+    public void visitComponent(ProfilingConfiguration x) { }
+    public void visitComponent(Port x) { }
+    public void visitComponent(SourceCode x) { }
+
+    /**
+     *  Stream where the print output is sent to.
+     */
+    protected CodePrintStream _printStream = null;
+    protected UserInterface _ui = null;
+    protected String _delimiter = "/";
+}
diff --git a/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterMakefileVisitor.java b/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterMakefileVisitor.java
new file mode 100644 (file)
index 0000000..feb3257
--- /dev/null
@@ -0,0 +1,63 @@
+/* $Id: PipeAndFilterMakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.PipeAndFilter;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class PipeAndFilterMakefileVisitor extends PNVisitor {
+
+    /**
+     *
+     */
+    public PipeAndFilterMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("CXX = g++");
+            ps.println("CXXFLAGS = -g -Wall");
+            ps.println("COMPILE = ${CXX} ${CXXFLAGS} -c");
+            ps.println("LINK = ${CXX} -lpthread");
+            ps.println("LIB_INC = -Ilib -Iwrappers -Iprocesses");
+            ps.println();
+            ps.println("src := $(wildcard lib/*.cpp) "
+                    + "$(wildcard wrappers/*.cpp) $(wildcard *.cpp)");
+            ps.println("obj = $(src:.cpp=.o)");
+            ps.println();
+            ps.println("app : ${obj} ${src}");
+            ps.println("\t${LINK} -o " + _name + " $(obj)");
+            ps.println();
+            ps.println("%.o :");
+            ps.println("\t${COMPILE} -o $(*D)/$(*F).o $(*D)/$(*F).cpp $(LIB_INC)");
+            ps.println();
+            ps.println("clean :");
+            ps.println("\trm ${obj}");
+        }
+        catch (IOException e) {
+            System.out.println(" PipeAndFilter Makefile Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected String _name = "sc_application";
+
+}
+
diff --git a/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterModuleVisitor.java b/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterModuleVisitor.java
new file mode 100644 (file)
index 0000000..04d9f57
--- /dev/null
@@ -0,0 +1,311 @@
+/* $Id: PipeAndFilterModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.PipeAndFilter;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Resource;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class PipeAndFilterModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public PipeAndFilterModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "sc_application.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _code = new CodePrintStream(file);
+
+            _code.println("#include <iostream>");
+            _code.println();
+
+            _code.printPrefixln("#include \"lib/Fifo.h\"");
+            _code.printPrefixln("#include \"lib/Scheduler.h\"");
+            _code.printPrefixln("#include \"lib/WindowedFifo.h\"");
+            _code.println();
+            _code.printPrefixln("#include \"wrappers/wrappers.h\"");
+            _code.println();
+            _code.printPrefixln("#include \"processnetwork.h\"");
+            _code.println();
+            _code.printPrefixln("int main(void)");
+            _code.printLeftBracket();
+
+            _code.printPrefixln("std::map<std::string, "
+                    + "ProcessWrapper* > *processes");
+            _code.printPrefixln("        = new std::map<std::string, "
+                    + "ProcessWrapper* >();");
+            _code.println();
+
+            _code.printPrefixln("Scheduler *scheduler = "
+                    + "new Scheduler();");
+            _code.println();
+
+            //instantiate channels
+            for (Channel c : x.getChannelList()) {
+                if (c.getType().equals("fifo")) {
+                    printProcessNetwork("Fifo *" + c.getName()
+                        + " = new Fifo(\"" + c.getName()
+                        + "\", " + c.getSize() * c.getTokenSize()
+                        + ");");
+                } else if (c.getType().equals("wfifo")) {
+                    printProcessNetwork("WindowedFifo *" + c.getName()
+                            + " = new WindowedFifo(\"" + c.getName()
+                            + "\", " + c.getSize() * c.getTokenSize()
+                            + ");");
+                }
+            }
+            printProcessNetwork("");
+
+            // instantiate processes and connect to channels
+            for (Process p : x.getProcessList()) {
+                printProcessNetwork(p.getBasename() + "_wrapper *"
+                        + p.getName() + " = new "
+                        + p.getBasename() + "_wrapper(\""
+                        + p.getName() + "\");");
+                printProcessNetwork("processes->insert(std::pair"
+                        + "<std::string, ProcessWrapper* >(\""
+                        + p.getName() + "\", " + p.getName() + "));");
+                printProcessNetwork("");
+            }
+
+            //build the network
+            for (Channel ch : x.getChannelList()) {
+                ch.accept(this);
+            }
+
+            printProcessNetwork("}");
+
+            String headerfilename = _dir + _delimiter
+                     + "processnetwork.h";
+            OutputStream headerfile = new FileOutputStream(
+                     headerfilename);
+            CodePrintStream processnetworkHeader = new
+                     CodePrintStream(headerfile);
+            processnetworkHeader.printPrefixln(
+                     "#ifndef PROCESSNETWORK_H");
+            processnetworkHeader.printPrefixln(
+                    "#define PROCESSNETWORK_H");
+            processnetworkHeader.println();
+
+            for (int counter = 1; counter <= _processNetworkCounter;
+                    counter++) {
+                _code.printPrefixln("processnetwork_part"
+                        + String.format("%03d", counter) + "::create("
+                        + "processes);");
+                processnetworkHeader.println("#include "
+                        + "\"processnetwork_part"
+                        + String.format("%03d", counter) + ".h\"");
+            }
+            _code.println();
+
+            processnetworkHeader.println();
+            processnetworkHeader.printPrefixln("#endif");
+
+
+            //register processes
+            _code.printPrefixln("std::map<std::string, "
+                    + "ProcessWrapper* >::iterator process_iterator;");
+            _code.printPrefixln("for (process_iterator = "
+                   + "processes->begin();");
+            _code.printPrefixln("        process_iterator != "
+                   + "processes->end();");
+            _code.printPrefixln("        process_iterator++) {");
+            _code.printPrefixln("    scheduler->registerProcess("
+                   + "static_cast<ProcessWrapper* >");
+            _code.printPrefixln("        ((*process_iterator).second));");
+            _code.printPrefixln("}");
+            _code.println();
+
+            //run scheduler
+            _code.printPrefixln("scheduler->run();");
+            _code.println();
+
+            //clean up
+            _code.println();
+            _code.printPrefixln("for (process_iterator = "
+                    + "processes->begin();");
+            _code.printPrefixln("     process_iterator != "
+                    + "processes->end();");
+            _code.printPrefixln("     process_iterator++) {");
+            _code.printPrefixln("  delete static_cast<ProcessWrapper* >"
+                    + "((*process_iterator).second);");
+            _code.printPrefixln("}");
+            _code.println();
+            //_code.printPrefixln("std::cout << \"End.\" << std::endl;");
+            _code.printPrefixln("return 0;");
+            _code.printRightBracket();
+        }
+        catch (Exception e) {
+            System.out.println("PipeAndFilterModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void createProcessNetworkHeader(int part)
+            throws IOException {
+        String partString = String.format("%03d", part);
+        String filename = _dir + _delimiter + "processnetwork_part"
+                + partString + ".h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream header = new CodePrintStream(file);
+
+        header.println("#ifndef PROCESSNETWORK_PART"
+                + partString + "_H");
+        header.println("#define PROCESSNETWORK_PART"
+                + partString + "_H");
+        header.println();
+        header.println("#include <map>");
+        header.println("#include <string>");
+        header.println();
+        header.println("#include \"lib/ProcessWrapper.h\"");
+        header.println("#include \"lib/Fifo.h\"");
+        header.println("#include \"lib/WindowedFifo.h\"");
+        header.println();
+        header.println("#include \"wrappers/wrappers.h\"");
+        header.println();
+        header.println("class processnetwork_part" + partString + " {");
+        header.println("    public:");
+        header.println("        processnetwork_part"
+                + partString + "();");
+        header.println("        virtual ~processnetwork_part"
+                + partString + "();");
+        header.println("        static void create(");
+        header.println("                std::map<std::string, "
+                + "ProcessWrapper* > *processes);");
+        header.println("};");
+        header.println();
+        header.println("#endif");
+    }
+
+
+    /**
+     *
+     */
+    protected void printProcessNetwork(String nextLine)
+            throws IOException {
+         if (!_fileOpen ||
+                (_numberOfLines >= MAX_NUMBER_OF_LINES &&
+                !nextLine.contains("->insert") &&
+                !nextLine.equals("") &&
+                !nextLine.contains("Port(") &&
+                !nextLine.contains("<std::string, Port* >"))) {
+
+            if (_fileOpen) {
+              _pn.printRightBracket();
+            }
+
+            _processNetworkCounter++;
+            _numberOfLines = 0;
+            createProcessNetworkHeader(_processNetworkCounter);
+            String partString = String.format("%03d",
+                    _processNetworkCounter);
+            String processNetworkFilename = _dir + _delimiter
+                    + "processnetwork_part" + partString + ".cpp";
+
+            _file = new FileOutputStream(processNetworkFilename);
+            _pn = new CodePrintStream(_file);
+            _fileOpen = true;
+
+            _pn.printPrefixln("#include \"processnetwork_part"
+                    + partString + ".h\"");
+            _pn.println();
+
+            _pn.printPrefixln("processnetwork_part" + partString
+                    + "::processnetwork_part" + partString + "() {");
+            _pn.printPrefixln("    //nothing to do");
+            _pn.printPrefixln("}");
+            _pn.println();
+            _pn.printPrefixln("processnetwork_part" + partString
+                    + "::~processnetwork_part" + partString + "() {");
+            _pn.printPrefixln("    //nothing to do");
+            _pn.printPrefixln("}");
+            _pn.println();
+            _pn.printPrefixln("void processnetwork_part" + partString
+                    + "::create(");
+            _pn.printPrefixln("        std::map<std::string, "
+                    + "ProcessWrapper* > *processes)");
+            _pn.printLeftBracket();
+        }
+
+        _pn.printPrefixln(nextLine);
+        _numberOfLines++;
+    }
+
+    /**
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        try {
+            for (Port p : x.getPortList()) {
+                Port peerPort = (Port)(p.getPeerPort());
+                Resource peerResource = p.getPeerResource();
+                String codeLine = "";
+                if (peerPort.getRange() != null) {
+                    if (p.isOutPort()) {
+                        codeLine = peerResource.getName()
+                                + "->INPORT_"
+                                + peerPort.getBasename()
+                                + peerPort.getName().replaceAll(
+                                "_([0-9]+)", "[$1]").replaceFirst(
+                                peerPort.getBasename(), "");
+                    }
+                    else if (p.isInPort()) {
+                        codeLine = peerResource.getName()
+                                + "->OUTPORT_"
+                                + peerPort.getBasename()
+                                + peerPort.getName().replaceAll(
+                                "_([0-9]+)", "[$1]").replaceFirst(
+                                peerPort.getBasename(), "");
+                    }
+                }
+                else {
+                    if (p.isOutPort()) {
+                        codeLine = peerResource.getName()
+                                + "->INPORT_" + peerPort.getName();
+                    }
+                    else if (p.isInPort()) {
+                        codeLine = peerResource.getName()
+                                + "->OUTPORT_" + peerPort.getName();
+                    }
+                }
+                printProcessNetwork(codeLine + " = " + x.getName() + ";");
+            }
+        }
+        catch (Exception e) {
+            System.out.println("PipeAndFilterModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected CodePrintStream _code = null;
+    protected String _dir = null;
+    protected boolean _fileOpen = false;
+    protected int _processNetworkCounter = 0;
+    protected int _numberOfLines = 0;
+    protected static final int MAX_NUMBER_OF_LINES = 1000;
+    protected OutputStream _file;
+    protected CodePrintStream _pn;
+}
+
diff --git a/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterProcessVisitor.java b/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterProcessVisitor.java
new file mode 100644 (file)
index 0000000..a1ec83b
--- /dev/null
@@ -0,0 +1,60 @@
+/* $Id: PipeAndFilterProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.PipeAndFilter;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+import dol.visitor.hds.HdsProcessVisitor;
+
+/**
+ *
+ */
+public class PipeAndFilterProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public PipeAndFilterProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork x) {
+        HdsProcessVisitor visitor = new HdsProcessVisitor(_dir);
+        x.accept(visitor);
+
+        try {
+            String filename = _dir + _delimiter + "wrappers.h";
+            OutputStream file = new FileOutputStream(filename);
+            _wrapperHeader = new CodePrintStream(file);
+            _wrapperHeader.printPrefixln("#ifndef WRAPPERS_H");
+            _wrapperHeader.printPrefixln("#define WRAPPERS_H");
+            _wrapperHeader.println();
+            Vector<String> pList = new Vector<String>();
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    _wrapperHeader.printPrefixln("#include \""
+                            + p.getBasename() + "_wrapper.h\"");
+                }
+            }
+            _wrapperHeader.println();
+            _wrapperHeader.printPrefixln("#endif");
+        } catch (Exception e) {
+            System.out.println("Process Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+        
+    protected String _dir = null;
+    CodePrintStream _wrapperHeader;
+}
diff --git a/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterVisitor.java b/dol/src/dol/visitor/PipeAndFilter/PipeAndFilterVisitor.java
new file mode 100644 (file)
index 0000000..c545a77
--- /dev/null
@@ -0,0 +1,96 @@
+/* $Id: PipeAndFilterVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.PipeAndFilter;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class PipeAndFilterVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public PipeAndFilterVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _generateDirHierarchy();
+
+            x.accept(new PipeAndFilterMakefileVisitor(_srcDir));
+            x.accept(new PipeAndFilterModuleVisitor(_srcDir));
+            x.accept(new PipeAndFilterProcessVisitor(_wrapperDir));
+
+        } catch (Exception e) {
+            System.out.println(" SystemC PN Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     *
+     */
+    private void _generateDirHierarchy()
+        throws IOException, FileNotFoundException {
+
+        File dir = new File(_packageName);
+        dir.mkdirs();
+
+        _srcDir = _packageName + _delimiter + _srcDirName;
+        dir = new File(_srcDir);
+        dir.mkdirs();
+
+        _libDir = _srcDir + _delimiter + _libDirName;
+        dir = new File(_libDir);
+        dir.mkdirs();
+
+        _processDir = _srcDir + _delimiter + _processDirName;
+        dir = new File(_processDir);
+        dir.mkdirs();
+
+        _wrapperDir = _srcDir + _delimiter + _wrapperDirName;
+        dir = new File(_wrapperDir);
+        dir.mkdirs();
+
+        // copy library
+        String libraryPath = _ui.getMySystemCLib();
+        libraryPath = libraryPath.replaceAll("systemC",
+                "PipeAndFilter");
+        File source = new File(libraryPath);
+        File destination = new File(_libDir);
+        new Copier().copy(source, destination);
+
+        //copy process src code
+        source = new File(_srcDirName);
+        destination = new File(_processDir);
+        new Copier().copy(source, destination);
+    }
+
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+
+    protected String _libDir = "";
+    protected static String _libDirName = "lib";
+
+    protected String _processDir = "";
+    protected static String _processDirName = "processes";
+
+    protected String _wrapperDir = "";
+    protected static String _wrapperDirName = "wrappers";
+}
+
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Condition.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/Condition.cpp
new file mode 100644 (file)
index 0000000..4525b37
--- /dev/null
@@ -0,0 +1,31 @@
+#include "Condition.h"\r
+\r
+Condition::Condition(Mutex *mutex) {\r
+    //std::cout << "Create Condition." << std::endl;\r
+    _mutex = mutex;\r
+    _condition = new pthread_cond_t;\r
+    pthread_cond_init(_condition, NULL);\r
+}\r
+\r
+\r
+Condition::~Condition() {\r
+    //std::cout << "Delete Condition." << std::endl;\r
+    pthread_cond_destroy(_condition);\r
+    delete _condition;\r
+    //std::cout << "Deleted Condition." << std::endl;\r
+}\r
+\r
+\r
+void Condition::notify() {\r
+    pthread_cond_signal(_condition);\r
+}\r
+\r
+\r
+void Condition::notifyAll() {\r
+    pthread_cond_broadcast(_condition);\r
+}\r
+\r
+\r
+void Condition::wait() {\r
+    pthread_cond_wait(_condition, _mutex->getPThreadMutex());\r
+}\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Condition.h b/dol/src/dol/visitor/PipeAndFilter/lib/Condition.h
new file mode 100644 (file)
index 0000000..c669892
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _CONDITION_H_\r
+#define _CONDITION_H_\r
+\r
+#include <iostream>\r
+#include <pthread.h>\r
+#include "Mutex.h"\r
+\r
+class Condition {\r
+    public:\r
+        Condition(Mutex *mutex);\r
+        virtual ~Condition();\r
+        virtual void notify();\r
+        virtual void notifyAll();\r
+        virtual void wait();\r
+\r
+    protected:\r
+        Mutex *_mutex;\r
+        pthread_cond_t *_condition;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Event.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/Event.cpp
new file mode 100644 (file)
index 0000000..52490b2
--- /dev/null
@@ -0,0 +1,73 @@
+#include "Event.h"\r
+\r
+Event::Event() {\r
+    _name = "Event";\r
+    //std::cout << "Create " << _name << "." << std::endl;\r
+    _mutex = new Mutex();\r
+    _condition = new Condition(_mutex);\r
+    _waitMutex = new Mutex();\r
+    _waitCondition = new Condition(_waitMutex);\r
+    _pendingWait = false;\r
+}\r
+\r
+\r
+Event::Event(std::string name) {\r
+    _name = "Event " + name;\r
+    //std::cout << "Create " << _name << "." << std::endl;\r
+    _mutex = new Mutex();\r
+    _condition = new Condition(_mutex);\r
+    _waitMutex = new Mutex();\r
+    _waitCondition = new Condition(_waitMutex);\r
+    _pendingWait = false;\r
+}\r
+\r
+\r
+Event::~Event() {\r
+    //std::cout << "Delete " << _name << "." << std::endl;\r
+    delete _condition;\r
+    delete _waitCondition;\r
+    delete _mutex;\r
+    delete _waitMutex;\r
+    //std::cout << "Deleted " << _name << "." << std::endl;\r
+}\r
+\r
+\r
+void Event::notify() {\r
+    _mutex->lock();\r
+    _condition->notify();\r
+    _mutex->unlock();\r
+}\r
+\r
+\r
+void Event::notifyAll() {\r
+    _mutex->lock();\r
+    _condition->notifyAll();\r
+    _mutex->unlock();\r
+}\r
+\r
+\r
+void Event::wait() {\r
+    _mutex->lock();\r
+    _pendingWait = true;\r
+    _waitMutex->lock();\r
+    _waitCondition->notify();\r
+    _waitMutex->unlock();\r
+    _condition->wait();\r
+    _pendingWait = false;\r
+    _mutex->unlock();\r
+}\r
+\r
+\r
+void Event::notifyAfterWait() {\r
+    _mutex->lock();\r
+\r
+    if (!_pendingWait) {\r
+        _waitMutex->lock();\r
+        _mutex->unlock();\r
+        _waitCondition->wait();\r
+        _mutex->lock();\r
+        _waitMutex->unlock();\r
+    }\r
+    _condition->notify();\r
+    _mutex->unlock();\r
+}\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Event.h b/dol/src/dol/visitor/PipeAndFilter/lib/Event.h
new file mode 100644 (file)
index 0000000..51d14e8
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _EVENT_H_\r
+#define _EVENT_H_\r
+\r
+#include <iostream>\r
+#include <string>\r
+#include <pthread.h>\r
+#include "Mutex.h"\r
+#include "Condition.h"\r
+\r
+class Event {\r
+    public:\r
+        Event();\r
+        Event(std::string name);\r
+        Event(Mutex *mutex);\r
+        virtual ~Event();\r
+        virtual void notify();\r
+        virtual void notifyAll();\r
+        virtual void wait();\r
+        virtual void notifyAfterWait();\r
+\r
+    protected:\r
+        Mutex *_mutex;\r
+        Condition *_condition;\r
+        Mutex *_waitMutex;\r
+        Condition *_waitCondition;\r
+        bool _pendingWait;\r
+        std::string _name;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Fifo.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/Fifo.cpp
new file mode 100644 (file)
index 0000000..a88fd98
--- /dev/null
@@ -0,0 +1,229 @@
+#include "Fifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::Fifo(char* name, unsigned size = 18) {\r
+    //std::cout << "Create Fifo." << std::endl;\r
+    //except at the beginning, _head and _tail must never overlap,\r
+    //otherwise one does not know whether the buffer is full or\r
+    //empty. to have nevertheless a buffer with the given capacity,\r
+    //a buffer with one more element is allocated.\r
+    _size = size + 1;\r
+    _buffer = new char[_size];\r
+    _head = 0;\r
+    _tail = 0;\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+    _mutex = new Mutex();\r
+    _readCondition = new Condition(_mutex);\r
+    _writeCondition = new Condition(_mutex);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::~Fifo() {\r
+    //std::cout << "Delete Fifo." << std::endl;\r
+    if (_buffer) {\r
+        delete _buffer;\r
+    }\r
+    if (_name) {\r
+        delete _name;\r
+    }\r
+    if (_readCondition) {\r
+        delete _readCondition;\r
+    }\r
+    if (_writeCondition) {\r
+        delete _writeCondition;\r
+    }\r
+    if (_mutex) {\r
+        delete _mutex;\r
+    }\r
+\r
+    _buffer = 0;\r
+    _head = 0;\r
+    _tail = 0;\r
+    _name = 0;\r
+    _readCondition = 0;\r
+    _writeCondition = 0;\r
+    _mutex = 0;\r
+    //std::cout << "Deleted Fifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::read(void *destination, unsigned len) {\r
+    char* buffer = (char*)destination;\r
+    unsigned read = 0;\r
+    //std::cout << "Try to read " << len << " bytes from Fifo " << _name << "." << std::endl;\r
+\r
+    while (read < len) {\r
+        _mutex->lock();\r
+        while (used() == 0) {\r
+            _writeCondition->wait();\r
+        }\r
+        _mutex->unlock();\r
+\r
+        if ((len - read) < used()) {\r
+            while (read < len) {\r
+                _mutex->lock();\r
+                unsigned tocopy = (len - read + _tail >= _size) ? _size - _tail : len - read;\r
+                memcpy(buffer, _buffer + _tail, tocopy);\r
+                _tail = (_tail + tocopy) % _size;\r
+                read += tocopy;\r
+                buffer += tocopy;\r
+                _mutex->unlock();\r
+            }\r
+            _readCondition->notify();\r
+        } else {\r
+            _mutex->lock();\r
+            *buffer++ = *(_buffer + _tail % _size);\r
+            _tail = (_tail + 1) % _size;\r
+            read++;\r
+            _mutex->unlock();\r
+            _readCondition->notify();\r
+        }\r
+    }\r
+\r
+    //std::cout << "Read " << read << " bytes from Fifo " << _name << "." << std::endl;\r
+    return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::write(const void *source, unsigned len) {\r
+    char* buffer = (char*)source;\r
+    unsigned write = 0;\r
+    //std::cout << "Try to write " << len << " bytes to Fifo " << _name << std::endl;\r
+\r
+    while (write < len) {\r
+        _mutex->lock();\r
+        while (unused() == 0) {\r
+            _readCondition->wait();\r
+        }\r
+        _mutex->unlock();\r
+\r
+        if ((len - write) < unused()) {\r
+            while (write < len) {\r
+                unsigned tocopy = (len - write + _head >= _size) ? _size - _head : len - write;\r
+                _mutex->lock();\r
+                memcpy(_buffer + _head, buffer, tocopy);\r
+                _head = (_head + tocopy) % _size;\r
+                write += tocopy;\r
+                buffer += tocopy;\r
+                _mutex->unlock();\r
+            }\r
+            _writeCondition->notify();\r
+        } else {\r
+            _mutex->lock();\r
+            *(_buffer + (unsigned)(_head) % _size) = *buffer++;\r
+            _head = (_head + 1) % _size;\r
+            write++;\r
+            _mutex->unlock();\r
+            _writeCondition->notify();\r
+        }\r
+    }\r
+    //std::cout << "Wrote " << write << " bytes to Fifo " << _name << "." << std::endl;\r
+    return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::size() const {\r
+    return (_size - 1);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::unused() const {\r
+    return (_size - 1) - used();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::used() const {\r
+    if (_head >= _tail) {\r
+        return _head - _tail;\r
+    }\r
+    return _head + _size - _tail;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+char* Fifo::getName() const {\r
+    return _name;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+#include <iostream>\r
+void* producer(void *fifo)\r
+{\r
+    const char *str =\r
+        "Visit www.systemc.org and see what SystemC can do for you today!\n";\r
+\r
+    while (*str) {\r
+        //printf("%c", *str);\r
+        ((Fifo*)fifo)->write((void*)str++, 4);\r
+    }\r
+    printf("\nproducer returns.\n");\r
+    return 0;\r
+}\r
+\r
+void* consumer(void *fifo)\r
+{\r
+    char c;\r
+    while (c != '\n') {\r
+        ((Fifo*)fifo)->read(&c, 4);\r
+        std::cout << c << std::flush;\r
+\r
+        if (((Fifo*)fifo)->used() == 1)\r
+            std::cout << "<1>" << std::flush;\r
+        if (((Fifo*)fifo)->used() == 9)\r
+            std::cout << "<9>" << std::flush;\r
+    }\r
+    printf("\nconsumer returns.\n");\r
+    return 0;\r
+}\r
+\r
+\r
+int main() {\r
+    Fifo *fifo = new Fifo("fifo", 3);\r
+    pthread_t *producer_thread = new pthread_t;\r
+    pthread_t *consumer_thread = new pthread_t;\r
+\r
+    pthread_attr_t attributes;\r
+    pthread_attr_init(&attributes);\r
+    pthread_attr_setstacksize(&attributes, 131072);\r
+\r
+    if (pthread_create(consumer_thread, &attributes, consumer, fifo)) {\r
+        std::cout << "Error: Could not start consumer." << std::endl;\r
+        std::cout << "Exit." << std::endl;\r
+        exit(1);\r
+    }\r
+    pthread_attr_destroy(&attributes);\r
+\r
+    pthread_attr_init(&attributes);\r
+    pthread_attr_setstacksize(&attributes, 131072);\r
+    if (pthread_create(producer_thread, &attributes, producer, fifo)) {\r
+        std::cout << "Error: Could not start producer." << std::endl;\r
+        std::cout << "Exit." << std::endl;\r
+        exit(1);\r
+    }\r
+    pthread_attr_destroy(&attributes);\r
+\r
+\r
+    pthread_join(*consumer_thread, 0);\r
+    delete fifo;\r
+    return 0;\r
+}\r
+*/\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Fifo.h b/dol/src/dol/visitor/PipeAndFilter/lib/Fifo.h
new file mode 100644 (file)
index 0000000..e1adb03
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _FIFO_H_\r
+#define _FIFO_H_\r
+\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include "Mutex.h"\r
+#include "Condition.h"\r
+\r
+class Fifo {\r
+    public:\r
+        Fifo(char* name, unsigned size);\r
+        virtual ~Fifo();\r
+\r
+        virtual unsigned read(void *destination, unsigned len);\r
+        virtual unsigned write(const void *source, unsigned len);\r
+        virtual unsigned used() const;\r
+        virtual unsigned unused() const;\r
+        virtual unsigned size() const;\r
+        virtual char* getName() const;\r
+\r
+    protected:\r
+        char *_buffer;\r
+        unsigned _head;\r
+        unsigned _tail;\r
+        unsigned _size;\r
+        char *_name;\r
+        Mutex *_mutex;\r
+        Condition *_readCondition, *_writeCondition;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Mutex.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/Mutex.cpp
new file mode 100644 (file)
index 0000000..b943ff3
--- /dev/null
@@ -0,0 +1,48 @@
+#include "Mutex.h"\r
+\r
+Mutex::Mutex() {\r
+    //std::cout << "Create Mutex." << std::endl;\r
+    _mutex = new pthread_mutex_t;\r
+    pthread_mutex_init(_mutex, NULL); //_mutexAttribute);\r
+\r
+    _localMutex = new pthread_mutex_t;\r
+    pthread_mutex_init(_localMutex, NULL);\r
+\r
+    _lockCondition = new pthread_cond_t;\r
+    pthread_cond_init(_lockCondition, NULL);\r
+}\r
+\r
+\r
+Mutex::~Mutex() {\r
+    //std::cout << "Delete Mutex." << std::endl;\r
+    pthread_mutex_destroy(_mutex);\r
+    delete _mutex;\r
+\r
+    pthread_mutex_destroy(_localMutex);\r
+    delete _localMutex;\r
+\r
+    pthread_cond_destroy(_lockCondition);\r
+    delete _lockCondition;\r
+    //std::cout << "Deleted Mutex." << std::endl;\r
+}\r
+\r
+\r
+int Mutex::trylock() {\r
+    int success = pthread_mutex_trylock(_mutex);\r
+    return success;\r
+}\r
+\r
+\r
+void Mutex::lock() {\r
+    pthread_mutex_lock(_mutex);\r
+}\r
+\r
+\r
+void Mutex::unlock() {\r
+    pthread_mutex_unlock(_mutex);\r
+}\r
+\r
+\r
+pthread_mutex_t *Mutex::getPThreadMutex() const {\r
+    return _mutex;\r
+}\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Mutex.h b/dol/src/dol/visitor/PipeAndFilter/lib/Mutex.h
new file mode 100644 (file)
index 0000000..a88268c
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _MUTEX_H_\r
+#define _MUTEX_H_\r
+\r
+#include <iostream>\r
+#include <pthread.h>\r
+\r
+class Mutex {\r
+    public:\r
+        Mutex();\r
+        virtual ~Mutex();\r
+        virtual void lock();\r
+        virtual void unlock();\r
+        virtual int trylock();\r
+        virtual pthread_mutex_t *getPThreadMutex() const;\r
+\r
+    protected:\r
+        pthread_mutex_t *_mutex;\r
+        pthread_mutex_t *_localMutex;\r
+        pthread_cond_t *_lockCondition;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/ProcessWrapper.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/ProcessWrapper.cpp
new file mode 100644 (file)
index 0000000..fbba359
--- /dev/null
@@ -0,0 +1,128 @@
+#include "ProcessWrapper.h"\r
+#include "dolSupport.h"\r
+\r
+/**\r
+ *\r
+ */\r
+ProcessWrapper::ProcessWrapper(char* name) {\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+\r
+    _isDetached = false;\r
+    for (int i = 0; i < 4; i++) {\r
+        _iteratorIndex[i] = getIndex(_name, "_", i);\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+ProcessWrapper::~ProcessWrapper() {\r
+    if (_name) {\r
+        delete _name;\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void ProcessWrapper::initialize() {\r
+    _process.init(&_process);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+int ProcessWrapper::fire()\r
+{\r
+    return _process.fire(&_process);\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void ProcessWrapper::detach() {\r
+    _isDetached = true;\r
+}\r
+\r
+\r
+/**\r
+ * Gets an index of a string, where the index must be separated by\r
+ * a character specified in tokens.\r
+ * Returns -1, when an error occurs.\r
+ *\r
+ * Example:\r
+ * getIndex("name_1_2", "_", 0) will return 1.\r
+ * getIndex("name_1_2", "_", 1) will return 2.\r
+ *\r
+ * @param string string to parse\r
+ * @param tokens delimiter of indices\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int ProcessWrapper::getIndex(const char* string, char* tokens,\r
+        int indexNumber) const {\r
+    char* string_copy;\r
+    char* token_pointer;\r
+    int index = 0;\r
+\r
+    string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));\r
+    if (!string_copy) {\r
+        fprintf(stderr, "getIndex(): could not allocate memory.\n");\r
+        return -1;\r
+    }\r
+\r
+    strcpy(string_copy, string);\r
+\r
+    token_pointer = strtok(string_copy, tokens);\r
+    do {\r
+        token_pointer = strtok(NULL, tokens);\r
+        index++;\r
+    } while (index <= indexNumber && token_pointer != 0);\r
+\r
+    if (token_pointer) {\r
+        index = atoi(token_pointer);\r
+        free(string_copy);\r
+        return index;\r
+    }\r
+\r
+    return -1;\r
+}\r
+\r
+\r
+/**\r
+ * Get the index of this process.\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int ProcessWrapper::getIndex(unsigned indexNumber) const {\r
+    if (indexNumber < 4) {\r
+        return _iteratorIndex[indexNumber];\r
+    }\r
+    return -1;\r
+}\r
+\r
+\r
+/**\r
+ * Get the name of this process.\r
+ */\r
+char* ProcessWrapper::getName() const {\r
+    return _name;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+#ifdef INCLUDE_PROFILER\r
+void ProcessWrapper::addToProfile(const char *event, void *port,\r
+    int length) {\r
+    if (profiler_output_file != NULL) {\r
+        fprintf(profiler_output_file, "%u %s %s %p %d\n",\r
+                profiler_event_counter++, _name, event, port,\r
+                length);\r
+\r
+    } else {\r
+        printf("profiler_output_file does not exist");\r
+    }\r
+}\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/ProcessWrapper.h b/dol/src/dol/visitor/PipeAndFilter/lib/ProcessWrapper.h
new file mode 100644 (file)
index 0000000..da7335f
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef _PROCESSWRAPPER_H_\r
+#define _PROCESSWRAPPER_H_\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include "dol.h"\r
+#include "Fifo.h"\r
+#include "WindowedFifo.h"\r
+\r
+#ifdef INCLUDE_PROFILER\r
+extern FILE *profiler_output_file;\r
+extern unsigned int profiler_event_counter;\r
+#endif\r
+\r
+class ProcessWrapper\r
+{\r
+    public:\r
+        ProcessWrapper(char* name);\r
+        virtual ~ProcessWrapper();\r
+        virtual void initialize();\r
+        virtual int fire();\r
+        virtual bool isDetached() { return _isDetached; }\r
+        virtual void detach();\r
+        virtual int getIndex(unsigned indexNumber) const;\r
+        virtual char* getName() const;\r
+\r
+#ifdef INCLUDE_PROFILER\r
+        virtual void addToProfile(const char *event, void *port,\r
+                int length);\r
+#endif\r
+\r
+#ifdef INCLUDE_TRACE\r
+        int start_line;\r
+        int end_line;\r
+        char channel_name[NAME_LENGTH];\r
+#endif\r
+\r
+#ifdef INCLUDE_PERFORMANCE\r
+        int start_line;\r
+        int end_line;\r
+        CURRENT_TIME start_time;\r
+        CURRENT_TIME end_time;\r
+#endif\r
+\r
+    protected:\r
+        char* _name;\r
+        DOLProcess _process;\r
+        bool _isDetached;\r
+        int _iteratorIndex[4];\r
+        virtual int getIndex(const char* string, char* tokens,\r
+                int indexNumber) const;\r
+};\r
+\r
+#endif\r
+\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Scheduler.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/Scheduler.cpp
new file mode 100644 (file)
index 0000000..260729a
--- /dev/null
@@ -0,0 +1,185 @@
+#include "Scheduler.h"
+
+typedef struct {
+    Scheduler *scheduler;
+    ProcessWrapper *process;
+} ProcessArgs;
+
+
+void* runProcessWrapperWrapper(void* arg) {
+    ProcessArgs *args = (ProcessArgs*)arg;
+    (args->scheduler)->runProcessWrapper(args->process);
+    delete args;
+    return 0;
+}
+
+
+void *scheduleWrapper(void *arg) {
+    ((Scheduler*)arg)->schedule();
+    return 0;
+}
+
+
+Scheduler::Scheduler() {
+    //std::cout << "Create Scheduler." << std::endl;
+    _listsMutex = new Mutex();
+    _listsCondition = new Condition(_listsMutex);
+    _mapsMutex = new Mutex();
+    _mapsCondition = new Condition(_mapsMutex);
+    _processMap = new std::map<ProcessWrapper*, pthread_t* >();
+    _notificationEventMap = new std::map<ProcessWrapper*, Event* >();
+    _scheduleList = new std::list<ProcessWrapper* >();
+    _detachList = new std::list<ProcessWrapper* >();
+    _stopScheduler = false;
+    _allStarted = false;
+}
+
+
+Scheduler::~Scheduler() {
+    delete _listsCondition;
+    delete _listsMutex;
+    delete _mapsCondition;
+    delete _mapsMutex;
+    delete _processMap;
+    delete _notificationEventMap;
+    delete _scheduleList;
+    delete _detachList;
+}
+
+
+void Scheduler::registerProcess(ProcessWrapper *process) {
+    pthread_t *newThread = new pthread_t;
+    _processMap->insert(std::pair<ProcessWrapper*, pthread_t* >
+            (process, newThread));
+    Event *newNotificationEvent =
+            new Event("notificationEvent for " + std::string(process->getName()));
+    _notificationEventMap->insert(std::pair<ProcessWrapper*, Event* >
+            (process, newNotificationEvent));
+    process->initialize();
+}
+
+
+void Scheduler::run() {
+    _mapsMutex->lock();
+
+    pthread_t scheduleThread;
+    if (pthread_create(&scheduleThread, NULL, scheduleWrapper, this)) {
+        std::cout << "Error: Could not start scheduler thread."
+                << std::endl;
+        std::cout << "Exit." << std::endl;
+        exit(1);
+    }
+    std::map<ProcessWrapper*, pthread_t* >::iterator iterator;
+    for (iterator = _processMap->begin();
+         iterator != _processMap->end();
+         iterator++) {
+
+        pthread_t *thread = (*iterator).second;
+
+        pthread_attr_t attributes;
+        pthread_attr_init(&attributes);
+        pthread_attr_setstacksize(&attributes, 131072);
+
+        ProcessArgs *args = new ProcessArgs;
+        args->scheduler = this;
+        args->process = (*iterator).first;
+        //std::cout << "Starting process "
+        //        << ((ProcessWrapper*)args->process)->getName()
+        //        << "." << std::endl;
+        if (pthread_create(thread, &attributes, runProcessWrapperWrapper, args)) {
+            std::cout << "Error: Could not start thread for process "
+                    << ((ProcessWrapper*)(args->process))->getName()
+                    << "." << std::endl;
+            std::cout << "Exit." << std::endl;
+            exit(1);
+        }
+        pthread_attr_destroy(&attributes);
+
+        //std::cout << "Started process "
+        //        << ((ProcessWrapper*)(args->process))->getName()
+        //        << "." << std::endl;
+    }
+    _mapsMutex->unlock();
+
+    //std::cout << "Started all registered processes." << std::endl;
+    _allStarted = true;
+    _listsCondition->notify();
+    //std::cout << "Wait until scheduler has stopped." << std::endl;
+
+    //wait until all processes have been detached
+    pthread_join(scheduleThread, 0);
+
+    //std::cout << "Scheduler has stopped." << std::endl;
+}
+
+
+void Scheduler::runProcessWrapper(ProcessWrapper *process) {
+    Event *_notificationEvent = (*_notificationEventMap)[process];
+
+    while (!process->isDetached()) {
+        _listsMutex->lock();
+        _scheduleList->push_back(process);
+        _listsCondition->notify();
+        _listsMutex->unlock();
+        _notificationEvent->wait();
+        process->fire();
+    }
+
+    _listsMutex->lock();
+    _detachList->push_back(process);
+    _listsMutex->unlock();
+    _listsCondition->notify();
+}
+
+
+void Scheduler::detachProcess(ProcessWrapper *process) {
+    _mapsMutex->lock();
+    pthread_t *threadToKill = (*_processMap)[process];
+    pthread_join(*threadToKill, 0);
+    delete threadToKill;
+    _processMap->erase(process);
+
+    Event *notificationEventToKill = (*_notificationEventMap)[process];
+    delete notificationEventToKill;
+    _notificationEventMap->erase(process);
+
+    if (_processMap->empty()) {
+        //std::cout << "No processes left in process map. Terminate."
+        //    << std::endl;
+        _stopScheduler = true;
+    }
+    _mapsMutex->unlock();
+}
+
+
+void Scheduler::schedule() {
+    _listsMutex->lock();
+
+    while(!_stopScheduler) {
+        _listsCondition->wait();
+
+        if (_allStarted) {
+            std::list<ProcessWrapper* >::iterator listIterator;
+            for (listIterator = _detachList->begin();
+                 listIterator != _detachList->end();
+                 listIterator++) {
+                ProcessWrapper *process = (*listIterator);
+                detachProcess(process);
+                //std::cout << "Scheduler detached process "
+                //        << process->getName() << "." << std::endl;
+            }
+            _detachList->clear();
+
+            for (listIterator = _scheduleList->begin();
+                 listIterator != _scheduleList->end();
+                 listIterator++) {
+                ProcessWrapper *process = (*listIterator);
+                ((Event*)(*_notificationEventMap)[process])->notifyAfterWait();
+            }
+            _scheduleList->clear();
+        }
+    }
+
+    _listsMutex->unlock();
+    //std::cout << "Stopped scheduler." << std::endl;
+}
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/Scheduler.h b/dol/src/dol/visitor/PipeAndFilter/lib/Scheduler.h
new file mode 100644 (file)
index 0000000..791f6f0
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _SCHEDULER_H_
+#define _SCHEDULER_H_
+
+#include <iostream>
+#include <list>
+#include <map>
+#include "Event.h"
+#include "ProcessWrapper.h"
+
+class Scheduler
+{
+    public:
+        Scheduler();
+        virtual ~Scheduler();
+
+        void registerProcess(ProcessWrapper *process);
+        void run();
+        void runProcessWrapper(ProcessWrapper *process);
+        void detachProcess(ProcessWrapper *process);
+        void schedule();
+
+    protected:
+        Mutex *_listsMutex;
+        Condition *_listsCondition;
+        Mutex *_mapsMutex;
+        Condition *_mapsCondition;
+        std::map<ProcessWrapper*, pthread_t* > *_processMap;
+        std::map<ProcessWrapper*, Event* > *_notificationEventMap;
+        std::list<ProcessWrapper* > *_scheduleList;
+        std::list<ProcessWrapper* > *_detachList;
+        bool _stopScheduler;
+        bool _allStarted;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/WindowedFifo.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/WindowedFifo.cpp
new file mode 100644 (file)
index 0000000..ddeb970
--- /dev/null
@@ -0,0 +1,304 @@
+#include "WindowedFifo.h"\r
+#include <string.h>\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::WindowedFifo(char* name, unsigned size = 20) {\r
+    //std::cout << "Create WindowedFifo." << std::endl;\r
+    _size = size;\r
+    _buffer = new char[_size];\r
+    _head = 0;\r
+    _tail = 0;\r
+    _headRoom = 0;\r
+    _tailRoom = 0;\r
+    _use = 0;\r
+    //indicates whether Fifo is empty or full if _head == _tail\r
+    //_isFull = false;\r
+    _isHeadReserved = false;\r
+    _isTailReserved = false;\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+    _mutex = new Mutex();\r
+    _readCondition = new Condition(_mutex);\r
+    _writeCondition = new Condition(_mutex);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::~WindowedFifo() {\r
+    //std::cout << "Delete WindowedFifo." << std::endl;\r
+    if (_buffer) {\r
+        delete _buffer;\r
+    }\r
+    if (_name) {\r
+        delete _name;\r
+    }\r
+    if (_readCondition) {\r
+        delete _readCondition;\r
+    }\r
+    if (_writeCondition) {\r
+        delete _writeCondition;\r
+    }\r
+    if (_mutex) {\r
+        delete _mutex;\r
+    }\r
+    _buffer = 0;\r
+    _head = 0;\r
+    _tail = 0;\r
+    _name = 0;\r
+    _use = 0;\r
+    _readCondition = 0;\r
+    _writeCondition = 0;\r
+    _mutex = 0;\r
+    //std::cout << "Deleted WindowedFifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::reserve(void** dest, unsigned len) {\r
+    char** destination = (char**)dest;\r
+    //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;\r
+\r
+    //can only reserve once piece at a time\r
+    if (_isHeadReserved) {\r
+        *destination = 0;\r
+        return 0;\r
+    }\r
+\r
+    _mutex->lock();\r
+    while (unused() == 0) {\r
+      _readCondition->wait();\r
+    }\r
+\r
+    //reserve at most as much memory as still available in the buffer\r
+    unsigned write = (len <= _size - _use ? len : _size - _use);\r
+\r
+    if ( write > 0 ) {\r
+        //if wrap-around in buffer: return only buffer for the\r
+        //contiguous buffer space\r
+        if (_head + write > _size) {\r
+            write = _size - _head;\r
+        }\r
+\r
+        _headRoom = (_head + write) == _size? 0 : _head + write;\r
+        *destination = &(_buffer[_head]);\r
+        _isHeadReserved = true;\r
+\r
+        //the following comparison is unsafe in a multi-threaded\r
+        //environment and potentially leads to race-conditions\r
+        /*if (_headRoom == _tail) {\r
+            _isFull = true;\r
+        } else {\r
+            _isFull = false;\r
+        }*/\r
+    }\r
+    _writeReserve = write; \r
+    _mutex->unlock();\r
+\r
+    //std::cout << "Reserved " << write << " bytes." << std::endl;\r
+    return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::release() {\r
+    if (_isHeadReserved) {\r
+        //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;\r
+        _head = _headRoom;\r
+        _use += _writeReserve;\r
+        _isHeadReserved = false;\r
+        _writeCondition->notify();\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::capture(void **dest, unsigned len) {\r
+    char** destination = (char**)dest;\r
+    //std::cout << "Attempt to capture " << len << " bytes." << std::endl;\r
+\r
+    if (_isTailReserved) {\r
+        //std::cout << "Only one attempt to capture allowed." << std::endl;\r
+        *destination = 0;\r
+        return 0;\r
+    }\r
+\r
+    _mutex->lock();\r
+    while (used() == 0) {\r
+      _writeCondition->wait();\r
+    }\r
+\r
+    //capture at most as much data as available in the buffer\r
+    unsigned read = (len <= _use ? len : _use);\r
+\r
+    if (read > 0) {\r
+        //if wrap-around in buffer: return only buffer for the\r
+        //contiguous buffer space\r
+        if (_tail + read> _size) {\r
+            read = _size - _tail;\r
+        }\r
+\r
+        _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;\r
+        *destination = &(_buffer[_tail]);\r
+        _isTailReserved = true;\r
+    }\r
+    _readReserve = read; \r
+    _mutex->unlock();\r
+    //std::cout << "Captured " << read << " bytes." << std::endl;\r
+\r
+    return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::consume() {\r
+    _mutex->lock();\r
+    if (_isTailReserved) {\r
+        //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;\r
+        _tail = _tailRoom;\r
+        //_isFull = false;\r
+        _use -= _readReserve;\r
+        _isTailReserved = false;\r
+        _readCondition->notify();\r
+    }\r
+    _mutex->unlock();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::size() const {\r
+    return _size;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::unused() const {\r
+    return _size - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::used() const {\r
+       return _use;\r
+    /*if (_headRoom > _tail) {\r
+        return _headRoom - _tail;\r
+    } else if (_headRoom == _tail) {\r
+        if (_isFull == true) {\r
+            return _size;\r
+        } else {\r
+            return 0;\r
+        }\r
+    }\r
+    return _headRoom + _size - _tail;*/\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+char* WindowedFifo::getName() const {\r
+    return _name;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+#include <iostream>\r
+#include <iomanip>\r
+#define LENGTH 10\r
+\r
+void* producer(void *fifo)\r
+{\r
+    WindowedFifo* wfifo = (WindowedFifo*)fifo;\r
+    for (int j = 0; j < LENGTH; j++) {\r
+        //std::cout << "write " << i << " to Fifo.    ";\r
+        int *buf1;\r
+        int write = wfifo->reserve((void**)&buf1, sizeof(int));\r
+\r
+        if (write == sizeof(int)) {\r
+            *buf1 = j;\r
+            wfifo->release();\r
+            //std::cout << "used: " << std::setw(2) << wfifo->used()\r
+            //        << ", unused: " << std::setw(2) << wfifo->unused()\r
+            //        << ", size: "  << std::setw(2) << wfifo->size()\r
+            //        << std::endl;\r
+        } else {\r
+            std::cout << "Not successful: " << write << std::endl;\r
+        }\r
+    }\r
+    printf("producer returns.\n");\r
+    return 0;\r
+}\r
+\r
+void* consumer(void *fifo)\r
+{\r
+    WindowedFifo* wfifo = (WindowedFifo*)fifo;\r
+    for (int j = 0; j < LENGTH; j++) {\r
+        int* buf3;\r
+        int read = wfifo->capture((void**)&buf3, sizeof(int));\r
+        if (read == sizeof(int)) {\r
+            std::cout << "read " << (unsigned)*buf3 << "  from WindowedFifo   ";\r
+            std::cout << "used: " << std::setw(2) << wfifo->used()\r
+                    << ", unused: " << std::setw(2) << wfifo->unused()\r
+                    << ", size: "  << std::setw(2) << wfifo->size()\r
+                    << std::endl;\r
+            wfifo->consume();\r
+        } else {\r
+            std::cout << "Read nothing from WindowedFifo." << std::endl;\r
+        }\r
+    }\r
+    printf("consumer returns.\n");\r
+    return 0;\r
+}\r
+\r
+int main() {\r
+    WindowedFifo *wfifo = new WindowedFifo("fifo", 12);\r
+\r
+    int* buf1;\r
+    int* buf2;\r
+    wfifo->reserve((void**)&buf1, 8);\r
+    *buf1 = 10;\r
+    *(buf1 + 1) = 20;\r
+    wfifo->release();\r
+    wfifo->capture((void**)&buf2, 8);\r
+    std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl;\r
+    wfifo->consume();\r
+\r
+    pthread_t *producer_thread = new pthread_t;\r
+    pthread_t *consumer_thread = new pthread_t;\r
+\r
+    pthread_attr_t attributes;\r
+    pthread_attr_init(&attributes);\r
+    pthread_attr_setstacksize(&attributes, 131072);\r
+\r
+    if (pthread_create(consumer_thread, &attributes, consumer, wfifo)) {\r
+        std::cout << "Error: Could not start consumer." << std::endl;\r
+        std::cout << "Exit." << std::endl;\r
+        exit(1);\r
+    }\r
+    pthread_attr_destroy(&attributes);\r
+\r
+    pthread_attr_init(&attributes);\r
+    pthread_attr_setstacksize(&attributes, 131072);\r
+    if (pthread_create(producer_thread, &attributes, producer, wfifo)) {\r
+        std::cout << "Error: Could not start producer." << std::endl;\r
+        std::cout << "Exit." << std::endl;\r
+        exit(1);\r
+    }\r
+    pthread_attr_destroy(&attributes);\r
+\r
+\r
+    pthread_join(*consumer_thread, 0);\r
+    delete wfifo;\r
+    return 0;\r
+}\r
+*/\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/WindowedFifo.h b/dol/src/dol/visitor/PipeAndFilter/lib/WindowedFifo.h
new file mode 100644 (file)
index 0000000..edab527
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef _WINDOWEDFIFO_H_\r
+#define _WINDOWEDFIFO_H_\r
+\r
+#include "Mutex.h"\r
+#include "Condition.h"\r
+\r
+class WindowedFifo {\r
+    public:\r
+        WindowedFifo(char* name, unsigned size);\r
+        virtual ~WindowedFifo();\r
+\r
+        virtual unsigned reserve(void** destination, unsigned len);\r
+        virtual void release();\r
+\r
+        virtual unsigned capture(void** destination, unsigned len);\r
+        virtual void consume();\r
+\r
+        virtual unsigned used() const;\r
+        virtual unsigned unused() const;\r
+        virtual unsigned size() const;\r
+        virtual char* getName() const;\r
+\r
+    protected:\r
+        char *_buffer;\r
+        unsigned _head;\r
+        unsigned _tail;\r
+        unsigned _headRoom;\r
+        unsigned _tailRoom;\r
+        unsigned _size;\r
+        unsigned _use;\r
+        unsigned _writeReserve;  
+        unsigned _readReserve; 
+        //bool _isFull;\r
+        bool _isHeadReserved;\r
+        bool _isTailReserved;\r
+        char *_name;\r
+        Mutex *_mutex;\r
+        Condition *_readCondition, *_writeCondition;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/dol.h b/dol/src/dol/visitor/PipeAndFilter/lib/dol.h
new file mode 100644 (file)
index 0000000..8fbefe4
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef DOL_H
+#define DOL_H
+
+/************************************************************************
+ * do not add code to this header
+ ************************************************************************/
+
+/**
+ *  Define the DOL process handler scheme.
+ *  - Local variables are defined in structure LocalState. Local
+ *    variables may vary from different processes.
+ *  - The ProcessInit function pointer points to a function which
+ *    initializes a process.
+ *  - The ProcessFire function pointer points to a function which
+ *    performs the actual computation. The communication between
+ *    processes is inside the ProcessFire function.
+ *  - The WPTR is a placeholder for callback. One can just
+ *    leave it blank.
+ */
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//additional behavioral functions could be declared here
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+//process handler
+struct _process;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr; //placeholder for wrapper instance
+} DOLProcess;
+
+#endif
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/dolSupport.cpp b/dol/src/dol/visitor/PipeAndFilter/lib/dolSupport.cpp
new file mode 100644 (file)
index 0000000..1359379
--- /dev/null
@@ -0,0 +1,133 @@
+#include "dolSupport.h"\r
+#include "ProcessWrapper.h"\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned write(void *port, void *buf, unsigned len, DOLProcess *process)\r
+{\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    char *str = static_cast<char*>(buf);\r
+    fifo->write((void*)str, len);\r
+    return len;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned read(void *port, void *buf, unsigned len, DOLProcess *process) {\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    char *str = static_cast<char*>(buf);\r
+    fifo->read((void*)str, len);\r
+    return len;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+int wtest(void *port, unsigned len, DOLProcess *process) {\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    return (fifo->unused() >= len) ? 1 : 0;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+int rtest(void *port, unsigned len, DOLProcess *process) {\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    return (fifo->used() >= len) ? 1 : 0;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p) {\r
+    return ((WindowedFifo*)fifo)->reserve(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void release(void* fifo, DOLProcess* p) {\r
+    ((WindowedFifo*)fifo)->release();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p) {\r
+    return ((WindowedFifo*)fifo)->capture(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void consume(void* fifo, DOLProcess* p) {\r
+    ((WindowedFifo*)fifo)->consume();\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void DOL_detach(DOLProcess* p) {\r
+    static_cast<ProcessWrapper *>(p->wptr)->detach();\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0) {\r
+    *port = (void**)((void**)base)[index0];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1) {\r
+    *port = (void**)((void**)base)[index0 * range1 + index1];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2\r
+                       + index1 * range2 + index2];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2 * range3\r
+                       + index1 * range2 * range3\r
+                       + index2 * range3\r
+                       + index3];\r
+}\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/lib/dolSupport.h b/dol/src/dol/visitor/PipeAndFilter/lib/dolSupport.h
new file mode 100644 (file)
index 0000000..3430033
--- /dev/null
@@ -0,0 +1,151 @@
+#ifndef DOLSUPPORT_H\r
+#define DOLSUPPORT_H\r
+\r
+#include "dol.h"\r
+#include "Fifo.h"\r
+#ifdef INCLUDE_PERFORMANCE\r
+#include "Performance_Extraction.h"\r
+#elif INCLUDE_TRACE\r
+#include "functional_trace.h"\r
+#endif\r
+\r
+#ifdef INCLUDE_PERFORMANCE\r
+#define DOL_write(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    end_time));\\r
+    performance_extraction.add_computation_performance(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line,\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->start_time),\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->end_time));\\r
+    write(port, buf, len, process);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    start_time)); }\r
+#define DOL_read(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    end_time));\\r
+    performance_extraction.add_computation_performance(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line,\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->start_time),\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->end_time));\\r
+    read(port, buf, len, process);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    start_time)); }\r
+#elif INCLUDE_TRACE\r
+#define DOL_write(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    dol_functional_trace.create_computation_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line);\\r
+    write(port, buf, len, process);\\r
+    dol_functional_trace.create_write_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(), len,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->channel_name);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__; }\r
+#define DOL_read(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    dol_functional_trace.create_computation_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line);\\r
+    read(port, buf, len, process);\\r
+    dol_functional_trace.create_read_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(), len,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->channel_name);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__; }\r
+#else\r
+    #define DOL_write(port, buf, len, process) \\r
+    write(port, buf, len, process)\r
+    #define DOL_read(port, buf, len, process) \\r
+    read(port, buf, len, process)\r
+#endif\r
+\r
+#define DOL_reserve(port, buf, size, process) \\r
+    reserve(port, (void**)buf, size, process);\r
+\r
+#define DOL_release(port, process) \\r
+    release(port, process);\r
+\r
+#define DOL_capture(port, buf, size, process) \\r
+    capture(port, (void**)buf, size, process);\r
+\r
+#define DOL_consume(port, process) \\r
+    consume(port, process);\r
+\r
+#define DOL_wtest(port, len, process) wtest(port, len, process)\r
+\r
+#define DOL_rtest(port, len, process) rtest(port, len, process)\r
+\r
+void DOL_detach(DOLProcess* p);\r
+\r
+//fifo access functions\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+int wtest(void *port, unsigned len, DOLProcess *process);\r
+int rtest(void *port, unsigned len, DOLProcess *process);\r
+\r
+//windowed fifo access functions\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void release(void* fifo, DOLProcess* p);\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void consume(void* fifo, DOLProcess* p);\r
+\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3);\r
+\r
+#define GETINDEX(dimension) \\r
+  static_cast<ProcessWrapper *>(p->wptr)->getIndex(dimension)\r
+\r
+/**\r
+ * macro to create a variable to store a port name\r
+ *\r
+ * @param name name of the variable\r
+ */\r
+#define CREATEPORTVAR(name) Fifo *name\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+  createPort((void**)(&port), base, number_of_indices, index_range_pairs)\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/PipeAndFilter/package.html b/dol/src/dol/visitor/PipeAndFilter/package.html
new file mode 100644 (file)
index 0000000..91e4bd2
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Code generator for functional simulation using threads for execution (no SystemC required).
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/visitor/Visitor.java b/dol/src/dol/visitor/Visitor.java
new file mode 100644 (file)
index 0000000..3af1dd8
--- /dev/null
@@ -0,0 +1,9 @@
+/* $Id: Visitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor;
+
+/**
+ * This class is a marker Class, to indicate that derived classes are all
+ * visitor.
+ */
+public interface Visitor {
+}
diff --git a/dol/src/dol/visitor/cbe/CbeBuildFileVisitor.java b/dol/src/dol/visitor/cbe/CbeBuildFileVisitor.java
new file mode 100644 (file)
index 0000000..4500d91
--- /dev/null
@@ -0,0 +1,109 @@
+/* $Id: CbeBuildFileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.visitor.cbe;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.OutputStream;\r
+import java.io.PrintStream;\r
+import java.util.Vector;\r
+\r
+import dol.datamodel.pn.Process;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.visitor.PNVisitor;\r
+\r
+/**\r
+ * This class is a class for a visitor that is used to generate the build\r
+ * file for the application on the CBE (i.e. a bash file for the CBE)\r
+ *\r
+ * @author lschor, 2008-10-30\r
+ *\r
+ * Revision:\r
+ * 2008-10-30: Updated the file for the CBE\r
+ * 2008-11-08: Add double buffering\r
+ */\r
+public class CbeBuildFileVisitor extends PNVisitor {\r
+\r
+    /**\r
+     * Constructor.\r
+     *\r
+     * @param dir path of the Makefile\r
+     */\r
+    public CbeBuildFileVisitor(String dir) {\r
+        _dir = dir;\r
+    }\r
+\r
+    /**\r
+     * Create a Makefile for the given process network.\r
+     *\r
+     * @param pn process network\r
+     */\r
+    public void visitComponent(ProcessNetwork pn) {\r
+        try {\r
+            String filename = _dir + _delimiter + "pncbe.sh";\r
+            OutputStream file = new FileOutputStream(filename);\r
+            PrintStream ps = new PrintStream(file);\r
+\r
+            // General information / notes and commands\r
+            ps.println("#!/bin/bash");\r
+            ps.println("clear");\r
+            ps.println();\r
+            ps.println("# Bash file to run a DOL application on the CBE");\r
+            ps.println("# Start the CBE-Simulator and enter the "\r
+                    + "following commands: ");\r
+            ps.println("# callthru source <Absolute path to the folder "\r
+                    + "of this file>/pncbe.sh > pncbe.sh");\r
+            ps.println("# for example: callthru source /opt/cell/sdk/src/"\r
+                    + "tutorial/pn_test/pncbe.sh > pncbe.sh");\r
+            ps.println("# chmod +x pncbe.sh");\r
+            ps.println();\r
+            ps.println("# To run the DOL application, use the following "\r
+                    + "command: ");\r
+            ps.println("# ./pncbe.sh");\r
+            ps.println();\r
+            ps.println("# Folder in which the application is stored");\r
+            ps.println("FOLDER=/opt/cell/sdk/src/tutorial/pn_test");\r
+            ps.println();\r
+\r
+            // Go through each process and copy its data to the Cell\r
+            String subdirectory = "";\r
+            String applicationName = "";\r
+            Vector<String> pList = new Vector<String>();\r
+\r
+            for (Process process : pn.getProcessList()) {\r
+                String basename = process.getBasename();\r
+                if (!pList.contains(basename)\r
+                        && process.getNumOfInports() > 0\r
+                        && process.getNumOfOutports() > 0) {\r
+                    subdirectory = "spu_" + basename;\r
+                    applicationName = subdirectory + "/spu_"\r
+                            + basename + "_wrapper";\r
+\r
+                    ps.println("# " + basename);\r
+                    ps.println("if [ ! -d " + subdirectory + " ]; then");\r
+                    ps.println("\tmkdir " + subdirectory);\r
+                    ps.println("fi;");\r
+                    ps.println("callthru source $FOLDER/"\r
+                            + applicationName + " > " + applicationName);\r
+                    ps.println("chmod +x " + applicationName);\r
+                    ps.println();\r
+                    pList.add(basename);\r
+                }\r
+            }\r
+\r
+            // Load also the main application to the CBE\r
+            ps.println("# Main program");\r
+            ps.println("callthru source $FOLDER/ppu_main > ppu_main");\r
+            ps.println("chmod +x ppu_main");\r
+            ps.println();\r
+\r
+            // Run the main program\r
+            ps.println("# run the main program");\r
+            ps.println("./ppu_main");\r
+        } catch (Exception e) {\r
+            System.out.println("CbeMakefileVisitor: exception occured: "\r
+                    + e.getMessage());\r
+            e.printStackTrace();\r
+        }\r
+    }\r
+\r
+    protected String _dir = null;\r
+}\r
diff --git a/dol/src/dol/visitor/cbe/CbeConstantVisitor.java b/dol/src/dol/visitor/cbe/CbeConstantVisitor.java
new file mode 100644 (file)
index 0000000..594673b
--- /dev/null
@@ -0,0 +1,102 @@
+/* $Id: CbeConstantVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.cbe;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a constant file
+ *
+ * @author lschor, 2008-11-08
+ *
+ * Revision:
+ * 2008-11-08: Created
+ */
+public class CbeConstantVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public CbeConstantVisitor(String dir, HashMap<Port, Integer> portMap) {
+        _dir = dir;
+        _portMap = portMap;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _ui = UserInterface.getInstance();
+            String filename = _dir + _delimiter + "lib" + _delimiter
+                    + "constant.h";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            int numSpes = 0;
+
+            for (Process p : x.getProcessList())
+            {
+                if (p.getNumOfInports() > 0 && p.getNumOfOutports() > 0)
+                    numSpes++;
+            }
+
+            //create header section
+            _mainPS.println("// ========================");
+            _mainPS.println("// constant.c file");
+            _mainPS.println("// ========================");
+
+            //includes
+            _mainPS.println("#include <stdio.h>");
+
+            //define the number of FIFO queues and the number of processes
+            _mainPS.println("#ifndef _CONSTANT_H_");
+            _mainPS.println("#define _CONSTANT_H_");
+            _mainPS.println("");
+            _mainPS.println("#define NUM_PROCS "
+                    + x.getProcessList().size());
+            _mainPS.println("#define NUM_SPES " + numSpes);
+            _mainPS.println("#define NUM_FIFO "
+                    + x.getChannelList().size());
+            _mainPS.println("");
+            _mainPS.println("#endif // _CONSTANT_H_ ");
+            _mainPS.println("");
+        }
+        catch (Exception e) {
+            System.out.println("CbeModuleVisitor: exception occured: "
+                               + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param x process that needs to be processed
+     */
+    public void visitComponent(Process x) {
+    }
+
+    /**
+     *
+     * @param x channel that needs to be processed
+     */
+    public void visitComponent(Channel x) {
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected HashMap<Port, Integer> _portMap;
+}
diff --git a/dol/src/dol/visitor/cbe/CbeMakefileVisitor.java b/dol/src/dol/visitor/cbe/CbeMakefileVisitor.java
new file mode 100644 (file)
index 0000000..45a4f2a
--- /dev/null
@@ -0,0 +1,151 @@
+/* $Id: CbeMakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.cbe;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate a CBE
+ * package Makefile.
+ */
+public class CbeMakefileVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of the Makefile
+     */
+    public CbeMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * Create a Makefile for the given process network.
+     *
+     * @param pn process network
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("##############################################");
+            ps.println("# Main Makefile for DOL application on the CBE");
+            ps.println("##############################################");
+            ps.println();
+            ps.println("# Subdirectories");
+
+            String subdirectories = "";
+            Vector<String> pList = new Vector<String>();
+            for (Process process : pn.getProcessList()) {
+                String basename = process.getBasename();
+                if (!pList.contains(basename)) {
+                    if (process.getNumOfInports() > 0
+                            && process.getNumOfOutports() > 0) {
+                        subdirectories += "spu_" + basename + " ";
+                    }
+                    pList.add(basename);
+                }
+            }
+            pList.clear();
+
+            String linkList = "";
+            String srcList = "";
+            for (Process process : pn.getProcessList()) {
+                String basename = process.getBasename();
+                if (!pList.contains(basename)) {
+                    if (!(process.getNumOfInports() > 0
+                            && process.getNumOfOutports() > 0)) {
+                        linkList += "ppu_" + basename + "/ppu_" + basename
+                                + ".o ";
+                        srcList += "$(wildcard ppu_" + basename
+                                + "/*.c) ";
+
+                    }
+                    pList.add(basename);
+                }
+            }
+            pList.clear();
+
+            ps.println("DIRS\t := " + subdirectories);
+            ps.println("");
+
+            ps.println("# General definitions:");
+            ps.println("CC = ppu-g++");
+            ps.println("CCFLAGS = -ftree-vectorize -O3 -maltivec "
+                    + "-funroll-loops -mabi=altivec -mcpu=cell");
+            ps.println("COMPILE = $(CC) $(CCFLAGS) -c");
+            ps.println("LINK = $(CC) -lspe2 -lpthread");
+            ps.println("CBE_INCLUDE = /opt/cell/sdk/src/include/ppu");
+            ps.println("LIB_INC = -I lib -I . -I $(CBE_INCLUDE)");
+            ps.println("RM = rm");
+            ps.println("ECHO = echo");
+            ps.println("EXE = ppu_main");
+            ps.println("");
+            ps.println("src := $(wildcard lib/*.c) $(wildcard *.c)");
+            ps.println("srcAll := $(wildcard lib/*.c) "
+                    + "$(wildcard lib/*.c) " + srcList);
+            ps.println("obj = $(src:.c=.o)");
+            ps.println("");
+            ps.println("$(EXE): $(obj) $(srcAll)");
+            ps.println("\tfor d in $(DIRS); do (cd $$d; $(MAKE) ); done");
+
+            for (Process process : pn.getProcessList()) {
+                String basename = process.getBasename();
+                if (!pList.contains(basename)) {
+                    if (!(process.getNumOfInports() > 0
+                            && process.getNumOfOutports() > 0)) {
+                        ps.println("\tcd ppu_" + basename
+                                + "; $(COMPILE) -o ppu_" + basename
+                                + ".o ppu_" + basename
+                                + "_wrapper.c -I .. -I ../lib;");
+                    }
+                    pList.add(basename);
+                }
+            }
+            pList.clear();
+
+            ps.println("\t$(LINK) -o $(EXE) " + linkList + " $(obj)");
+            ps.println("");
+            ps.println("%.o :");
+            ps.println("\t$(COMPILE) -o $(*D)/$(*F).o $(*D)/$(*F).c "
+                    + "$(LIB_INC)");
+            ps.println("");
+            ps.println("clean:");
+            ps.println("\tfor d in $(DIRS); do (cd $$d; $(MAKE) clean );"
+                    + " done");
+            ps.println("\trm $(obj) ");
+
+            for (Process process : pn.getProcessList()) {
+                String basename = process.getBasename();
+                if (!pList.contains(basename)) {
+                    if (!(process.getNumOfInports() > 0
+                            && process.getNumOfOutports() > 0))
+                    {
+                        ps.println("\trm ppu_" + basename + "/ppu_"
+                                + basename + ".o");
+                    }
+                    pList.add(basename);
+                }
+            }
+            pList.clear();
+
+            ps.println("\trm ppu_main");
+            ps.println("");
+
+        } catch (Exception e) {
+            System.out.println("CbeMakefileVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/cbe/CbeModuleVisitor.java b/dol/src/dol/visitor/cbe/CbeModuleVisitor.java
new file mode 100644 (file)
index 0000000..7987bfc
--- /dev/null
@@ -0,0 +1,417 @@
+/* $Id: CbeModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.cbe;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ *
+ * @author lschor, 2008-10-30
+ *
+ * Revision:
+ * 2008-10-30: Updated the file for the CBE
+ * 2008-11-08: Add double buffering
+ * 2008-11-16: Add new fifo implementation and defines for measurement
+ * 2008-11-21: Sink/Source do not run on the SPE, but on the PPE (as Linux
+ *             thread)
+ */
+public class CbeModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public CbeModuleVisitor(String dir, HashMap<Port, Integer> portMap) {
+        _dir = dir;
+        _portMap = portMap;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _ui = UserInterface.getInstance();
+            String filename = _dir + _delimiter + "ppu_main.c";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            //create header section
+            _mainPS.println("// ========================");
+            _mainPS.println("// ppu_main.c file");
+            _mainPS.println("// ========================");
+            _mainPS.println("");
+
+            // Includes
+            _mainPS.println("#include \"ppu_main.h\"");
+            _mainPS.println("");
+
+            _mainPS.println("");
+            _mainPS.println("// include main function for a workloop");
+            _mainPS.println("#include \"ppu_main_workloop.h\"");
+            _mainPS.println("");
+
+            // Function to create and run one SPE thread
+            _mainPS.println("// create and run one SPE thread");
+            _mainPS.println("void *spu_pthread(void *arg) {");
+            _mainPS.println("\t spu_data_t *datp = (spu_data_t *)arg;");
+            _mainPS.println("\t uint32_t entry = SPE_DEFAULT_ENTRY;");
+            _mainPS.println("\t printf(\")PPE: spe thread starts\\n\");");
+            _mainPS.println("\t if (spe_context_run(datp->spe_ctx, "
+                    + "&entry, 0, datp->argp, NULL, NULL) < 0) {");
+            _mainPS.println("\t\t perror (\"Failed running context\"); "
+                    + "exit (1);");
+            _mainPS.println("\t}");
+            _mainPS.println("\t printf(\")PPE: spe thread stops\\n\");");
+            _mainPS.println("\t pthread_exit(NULL);");
+            _mainPS.println("}");
+            _mainPS.println("");
+
+            // Declaration of the Header function for the PPE-Wrappers
+            Vector<String> processList = new Vector<String>();
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!processList.contains(basename)) {
+                    processList.add(basename);
+                    if (!(p.getNumOfInports() > 0
+                            && p.getNumOfOutports() > 0))
+                        _mainPS.println("void *" + basename
+                                + "_wrapper( void *ptr );");
+                }
+            }
+            _mainPS.println();
+
+            // Create the port_id and the port_queue_id arrays to send
+            // over the DMA
+            for (Process process : x.getProcessList()) {
+                String processName = process.getName();
+                _mainPS.println("volatile uint32_t "+ processName
+                        + "_port_id["
+                        + roundDMA(process.getPortList().size())
+                        + "] __attribute__ ((aligned(16))); ");
+                _mainPS.println("volatile uint32_t " + processName
+                        + "_port_queue_id["
+                        + roundDMA(process.getPortList().size())
+                        + "] __attribute__ ((aligned(16)));");
+                _mainPS.println("volatile char " + processName
+                        + "_name[256] __attribute__ ((aligned(16)));");
+            }
+            _mainPS.println();
+
+            // Create the main function
+            _mainPS.println("int main()");
+            _mainPS.println("{");
+
+            // For Measure
+            _mainPS.println("#ifdef MEASURE_APPLICATION");
+            _mainPS.println("\tstruct timeval t_ppe_start, t_ppe_end;");
+            _mainPS.println("\tgettimeofday(&t_ppe_start,NULL);");
+            _mainPS.println("#endif");
+            _mainPS.println();
+
+            _mainPS.println("#ifdef MEASURE_SET_UP_SPE_THREAD");
+            _mainPS.println("\tstruct timeval t_ppe_setup_start, "
+                    + "t_ppe_setup_end;");
+            _mainPS.println("\tgettimeofday(&t_ppe_setup_start,NULL);");
+            _mainPS.println("#endif");
+            _mainPS.println();
+
+            // List with all process to be open
+            _mainPS.println("\tchar spe_names[NUM_SPES][60] = {");
+            int count = 0;
+            for (Process process : x.getProcessList()) {
+                if (process.getNumOfInports() > 0
+                        && process.getNumOfOutports() > 0) {
+                    count++;
+                    String processName = process.getBasename();
+                    _mainPS.println("\t\t\"spu_" + processName + "/spu_"
+                            + processName + "_wrapper\""
+                            + (count == x.getProcessList().size()
+                            ? "" : ", ") );
+                }
+            }
+            _mainPS.println("\t};");
+            _mainPS.println();
+            _mainPS.println("\t// Initialize the fifo, we use");
+            _mainPS.println("\tint j; ");
+            _mainPS.println("\tfor (j = 0; j < NUM_FIFO; j++)");
+            _mainPS.println("\t{");
+            _mainPS.println("\t\tlocBuf[j] = "
+                    + "(char*)malloc(MAXELEMENT * sizeof(char));");
+            _mainPS.println("\t\tlocBufCount[j] = 0;");
+            _mainPS.println("\t\tlocBufStart[j] = 0;");
+            _mainPS.println("\t\tpthread_mutex_init(&(mutex[j]), NULL);");
+            _mainPS.println("\t}");
+
+            //connect ports to channels
+            HashMap<Channel, Integer> channel_map =
+                new HashMap<Channel, Integer>();
+
+            int j = 0;
+            for (Channel c : x.getChannelList()) {
+                channel_map.put(c, j++);
+            }
+
+            // Init the SPE control structure
+            _mainPS.println("\t//Initiate SPEs control structure");
+            _mainPS.println("\tint num = 0; ");
+            _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("\t\tdata[num].argp = (void *)&(ctx[num]);");
+            _mainPS.println("\t}");
+            _mainPS.println();
+
+            // Add to each process the ports and the queues
+            _mainPS.println("\t //Add to each process the ports and the "
+                    + "queues");
+            j = 0;
+            for (Process process : x.getProcessList()) {
+                String processName = process.getName();
+                int i = 0;
+                for (Port port : process.getPortList()) {
+                    Channel c = (Channel)(port.getPeerResource());
+
+                    _mainPS.println("\t" + processName + "_port_id["
+                                    + i + "] = "
+                                    + _portMap.get(port) + ";");
+                    _mainPS.println("\t" + processName + "_port_queue_id["
+                                    + i + "] = "
+                                    + channel_map.get(c) + ";");
+                    i++;
+                }
+
+                // Normal process
+                if (process.getNumOfInports() > 0
+                        && process.getNumOfOutports() > 0) {
+                    _mainPS.println("\tctx[" + j + "]"
+                                    + ".port_id = (uint64_t)"
+                                    + processName + "_port_id;");
+                    _mainPS.println("\tctx[" + j + "]"
+                                    + ".port_queue_id = (uint64_t)"
+                                    + processName + "_port_queue_id;");
+                    _mainPS.println("\tctx[" + j + "]"
+                                    + ".number_of_ports = " + i + ";");
+                    _mainPS.println("\tctx[" + j + "]"
+                                    + ".is_detached = 0;");
+                    _mainPS.println("\tstrcpy((char *)" + processName
+                            + "_name, " + "\""
+                            + processName + "\");");
+                    _mainPS.println("\tctx[" + j + "]"
+                            + ".processName = (uint64_t) " + processName
+                            + "_name;");
+                    _mainPS.println("\tctx[" + j + "]"
+                            + ".processNameLen = ((strlen((char *)"
+                            + processName + "_name) + 15) & ~15);");
+                    _mainPS.println();
+                    j++;
+                }
+                // Process is Sink or source
+                else {
+                    _mainPS.println("\tProcessWrapper *"
+                            + process.getName()
+                            + "_Process_Wrapper = (ProcessWrapper*)"
+                            + "malloc(sizeof(ProcessWrapper)); ");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->port_id = " + processName
+                            + "_port_id;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->port_queue_id = "
+                            + processName + "_port_queue_id;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->number_of_ports = "
+                            + i + ";");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->is_detached = 0;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->name = (char*)malloc("
+                            + "strlen(\"" + processName + "\"));");
+                    _mainPS.println("\tstrcpy(" + process.getName()
+                            + "_Process_Wrapper->name, \"" + processName
+                            + "\");");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->locBuf = locBuf;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->MAXELEMENT = "
+                            + "MAXELEMENT;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->locBufCount = "
+                            + "locBufCount;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->locBufStart = "
+                            + "locBufStart;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->processFinished = "
+                            + "&processFinished;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->mutex = mutex;");
+                    _mainPS.println("\t" + process.getName()
+                            + "_Process_Wrapper->mutexProcessNr = "
+                            + "&mutexProcessNr;");
+                    _mainPS.println();
+                }
+            }
+
+            _mainPS.println("\t// Loop on all SPEs and for each perform "
+                    + "three steps:");
+            _mainPS.println("\t// - create SPE context");
+            _mainPS.println("\t// - open images of SPE programs into main "
+                    + "storage");
+            _mainPS.println("\t//         <spe_names> variable store the "
+                    + "executable name");
+            _mainPS.println("\t// - Load SPEs objects into SPE context "
+                    + "local store");
+            _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("\t\tif ((data[num].spe_ctx = "
+                    + "spe_context_create(0, NULL)) == NULL) {");
+            _mainPS.println("\t\t\tperror(\"Failed creating context\"); "
+                    + "exit(1);");
+            _mainPS.println("\t\t}");
+            _mainPS.println("\t\tif (!(program[num] = spe_image_open("
+                    + "&spe_names[num][0]))) {");
+            _mainPS.println("\t\t\t perror(\"Fail opening image\"); "
+                    + "exit(1);");
+            _mainPS.println("\t\t}");
+            _mainPS.println("\t\tif (spe_program_load(data[num].spe_ctx, "
+                    + "program[num])) {");
+            _mainPS.println("\t\t\tperror(\"Failed loading program\"); "
+                    + "exit(1);");
+            _mainPS.println("\t\t}      ");
+            _mainPS.println("\t}");
+            _mainPS.println("");
+
+            _mainPS.println("\t// create PPE pthreads");
+            for (Process process : x.getProcessList()) {
+                if (!(process.getNumOfInports() > 0
+                        && process.getNumOfOutports() > 0)) {
+                    _mainPS.println("\tpthread_t thread_"
+                            + process.getName() + ";");
+                    _mainPS.println("\tpthread_create( &thread_"
+                            + process.getName() + ", NULL, "
+                            + process.getBasename() + "_wrapper, "
+                            + process.getName() + "_Process_Wrapper);");
+                }
+            }
+            _mainPS.println("\t");
+
+            _mainPS.println("\t// create SPE pthreads");
+            _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("\t\tif(pthread_create(&data[num].pthread, "
+                    + "NULL, &spu_pthread, &data[num])){");
+            _mainPS.println("\t\t\tperror(\"Failed creating thread\"); "
+                    + "exit(1);");
+            _mainPS.println("\t\t}");
+            _mainPS.println("\t}");
+
+            _mainPS.println();
+            _mainPS.println("#ifdef MEASURE_SET_UP_SPE_THREAD");
+            _mainPS.println("\tgettimeofday(&t_ppe_setup_end, NULL);");
+            _mainPS.println("\tprintf(\"PPE_SETUP;%f\\n\", "
+                    + "(t_ppe_setup_end.tv_sec "
+                    + "- t_ppe_setup_start.tv_sec) + 0.000001 "
+                    + "* (t_ppe_setup_end.tv_usec "
+                    + "- t_ppe_setup_start.tv_usec));");
+            _mainPS.println("#endif");
+            _mainPS.println();
+
+            _mainPS.println("\t//Start the main loop");
+            _mainPS.println("\tworkloop();");
+            _mainPS.println("");
+
+            _mainPS.println("\t// Loop on all SPEs and for each perform "
+                    + "two steps:");
+            _mainPS.println("\t//   - wait for all the SPE pthread to "
+                    + "complete");
+            _mainPS.println("\t//   - destroy the SPE contexts");
+            _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("\t\tif(pthread_join(data[num].pthread, "
+                    + "NULL)) {");
+            _mainPS.println("\t\t\tperror(\"Failed joining thread\"); "
+                    + "exit(1);");
+            _mainPS.println("\t\t}");
+            _mainPS.println("\t\t");
+            _mainPS.println("\t\tif (spe_context_destroy("
+                    + "data[num].spe_ctx)) {");
+            _mainPS.println("\t\t\tperror(\"Failed "
+                    + "spe_context_destroy\"); exit(1);");
+            _mainPS.println("\t\t}");
+            _mainPS.println("\t}");
+            _mainPS.println("\tprintf(\")PPE:) Complete running "
+                    + "all SPEs\\n\");");
+            _mainPS.println("");
+            _mainPS.println("\tfor (j = 0; j < NUM_FIFO; j++)");
+            _mainPS.println("\t{");
+            _mainPS.println("\t\tfree(locBuf[j]);");
+            _mainPS.println("\t\tpthread_mutex_destroy (&(mutex[j]));");
+            _mainPS.println("\t}");
+            _mainPS.println("");
+            _mainPS.println("#ifdef MEASURE_APPLICATION");
+            _mainPS.println("\tgettimeofday(&t_ppe_end, NULL);");
+            _mainPS.println("\tprintf(\"PPE;%f\\n\",(t_ppe_end.tv_sec "
+                    + "- t_ppe_start.tv_sec) + 0.000001 "
+                    + "* (t_ppe_end.tv_usec - t_ppe_start.tv_usec));");
+            _mainPS.println("#endif");
+            _mainPS.println("");
+            _mainPS.println("\treturn (0);");
+            _mainPS.println("}");
+        }
+        catch (Exception e) {
+            System.out.println("CbeDBModuleVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param x process that needs to be processed
+     */
+    public void visitComponent(Process x) {
+    }
+
+    /**
+     *
+     * @param x channel that needs to be processed
+     */
+    public void visitComponent(Channel x) {
+    }
+
+    /**
+     * Round the parameter to the next DMA-number up.
+     * Example: 23 gives 32.
+     * @param number number to round up
+     * @return next DMA-number
+     */
+    protected int roundDMA(int number) {
+        if (number > 16) {
+            return number + 16 - (number % 16);
+        } else if (number > 8) {
+            return 16;
+        } else if (number > 4) {
+            return 8;
+        } else if (number > 2) {
+            return 4;
+        } else if (number > 1) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected HashMap<Port, Integer> _portMap;
+}
diff --git a/dol/src/dol/visitor/cbe/CbeProcessVisitor.java b/dol/src/dol/visitor/cbe/CbeProcessVisitor.java
new file mode 100644 (file)
index 0000000..17044e0
--- /dev/null
@@ -0,0 +1,340 @@
+/* $Id: CbeProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.cbe;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Copier;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate the main
+ * makefile for the application.
+ *
+ * @author lschor, 2008-10-30
+ *
+ * Revision:
+ * 2008-10-30: Updated the file for the CBE
+ * 2008-11-08: Add double buffering
+ */
+public class CbeProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public CbeProcessVisitor(String dir, HashMap<Port, Integer> portMap) {
+        _dir = dir;
+        _portMap = portMap;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be processed
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> pList = new Vector<String>();
+
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    p.accept(this);
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("CbeProcessVisitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Visit process.
+     *
+     * @param p process that needs to be processed
+     */
+    public void visitComponent(Process p)
+    {
+        // Differ if the process is a source/sink or a normal process
+        // - Source/Sink: Mapped to the PPE
+        // - Normal process: Mapped to the SPE
+
+        if (p.getNumOfInports() > 0 && p.getNumOfOutports() > 0)
+        {
+            createSPEWrapper(p);
+        }
+        else
+        {
+            createPPEWrapper(p);
+        }
+    }
+
+    /**
+     * Creates a Wrapper for an SPE process
+     *
+     * @param p process that needs to be processed
+     */
+    protected void createSPEWrapper(Process p)
+    {
+        try {
+
+            // Create of each process an own folder
+            // add to this folder the source, the wrapper and a makefile
+            String processDir = _dir + _delimiter + "spu_"
+                    + p.getBasename();
+            File dir = new File(processDir);
+            dir.mkdirs();
+
+            // Create the filename for the new wrapper
+            String filename = processDir + _delimiter + "spu_"
+                    + p.getBasename() + "_wrapper.c";
+            File process_file = new File(filename);
+            File pattern_file = new File(_dir + _delimiter + _tempDirName
+                    + _delimiter + "spu_process_wrapper_template.c");
+            new Copier().copyFile(pattern_file, process_file);
+
+            String includes = "";
+            for (SourceCode code : p.getSrcList()) {
+                includes += "#include \"" + code.getLocality() + "\""
+                        + System.getProperty("line.separator");
+            }
+
+            Sed sed = new Sed();
+            // Replace the include of the main c-file
+            sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
+            // Replace the process-name in the whole file
+            sed.sed(filename, "@PROCESSNAME@", p.getBasename());
+
+            // Go through all source files
+            for (SourceCode sourceCode : p.getSrcList()) {
+                // Copy the files to the new folder
+                String oldFilename = _dir
+                        + _delimiter
+                        + sourceCode.getLocality().replaceAll(
+                                "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+                filename = processDir
+                        + _delimiter
+                        + sourceCode.getLocality().replaceAll(
+                                "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                if (new File(filename).exists()) {
+                    new File(filename).delete();
+                }
+
+                new File(oldFilename).renameTo(new File(filename));
+
+                // Copy also the c-files
+                if ((oldFilename.substring(oldFilename.length() - 2))
+                        .equals(".h")) {
+                    String newFileNameC = filename.substring(0, filename
+                            .length() - 2) + ".c";
+                    if (new File(newFileNameC).exists()) {
+                        new File(newFileNameC).delete();
+                    }
+                    new File(oldFilename.substring(
+                            0, oldFilename.length() - 2)
+                            + ".c").renameTo(new File(newFileNameC));
+                }
+
+                // Update the files for the DOL project
+                sed.sed(filename, "<dol.h>", "\"dol.h\"");
+
+                // Create the port list
+                for (Port port : p.getPortList()) {
+                    Integer portId = _portMap.get(port);
+                    if (!port.getBasename().equals(port.getName())) {
+                        for (Port port2 : p.getPortList()) {
+                            if (port2.getBasename().equals(
+                                    port.getBasename())) {
+                                if (_portMap.get(port2) <
+                                        _portMap.get(port)) {
+                                    portId = _portMap.get(port2);
+                                }
+                            }
+                        }
+                    }
+
+                    // Update the port list with the base names
+                    sed.sed(filename, "(#define[ ]+PORT_\\w*[ ]+)\"?"
+                            + port.getBasename() + "\"?", "$1 " + portId);
+                }
+
+                // Create the makefile for the process
+                createMakefile(p);
+            }
+        } catch (Exception e) {
+            System.out.println("CbeProcessVisitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Creates a Wrapper for an SPE process
+     *
+     * @param p process that needs to be processed
+     */
+    protected void createPPEWrapper(Process p)
+    {
+        try {
+            // Create of each process an own folder
+            // add to this folder the source, the wrapper and a makefile
+            String processDir = _dir + _delimiter + "ppu_"
+                    + p.getBasename();
+            File dir = new File(processDir);
+            dir.mkdirs();
+
+            // Create the filename for the new wrapper
+            String filename = processDir + _delimiter + "ppu_"
+                    + p.getBasename() + "_wrapper.c";
+            File process_file = new File(filename);
+            File pattern_file = new File(_dir + _delimiter + _tempDirName
+                    + _delimiter + "ppu_process_wrapper_template.c");
+            new Copier().copyFile(pattern_file, process_file);
+
+            String includes = "";
+            for (SourceCode code : p.getSrcList()) {
+                includes += "#include \"" + code.getLocality() + "\""
+                        + System.getProperty("line.separator");
+            }
+
+            Sed sed = new Sed();
+            // Replace the include of the main c-file
+            sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
+            // Replace the process-name in the whole file
+            sed.sed(filename, "@PROCESSNAME@", p.getBasename());
+
+            // Go through all source files
+            for (SourceCode sourceCode : p.getSrcList()) {
+                // Copy the files to the new folder
+                String oldFilename = _dir
+                        + _delimiter
+                        + sourceCode.getLocality().replaceAll(
+                                "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+                filename = processDir
+                        + _delimiter
+                        + sourceCode.getLocality().replaceAll(
+                                "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                if (new File(filename).exists()) {
+                    new File(filename).delete();
+                }
+
+                new File(oldFilename).renameTo(new File(filename));
+
+                // Copy also the c-files
+                if ((oldFilename.substring(oldFilename.length() - 2))
+                        .equals(".h")) {
+                    String newFileNameC = filename.substring(0, filename
+                            .length() - 2)
+                            + ".c";
+                    if (new File(newFileNameC).exists()) {
+                        new File(newFileNameC).delete();
+                    }
+                    new File(oldFilename.substring(
+                            0, oldFilename.length() - 2)
+                            + ".c").renameTo(new File(newFileNameC));
+                }
+
+                // Update the files for the DOL project
+                sed.sed(filename, "<dol.h>", "\"dol.h\"");
+
+                // Create the port list
+                for (Port port : p.getPortList()) {
+                    Integer portId = _portMap.get(port);
+                    if (!port.getBasename().equals(port.getName())) {
+                        for (Port port2 : p.getPortList()) {
+                            if (port2.getBasename().equals(
+                                    port.getBasename())) {
+                                if (_portMap.get(port2) <
+                                        _portMap.get(port)) {
+                                    portId = _portMap.get(port2);
+                                }
+                            }
+                        }
+                    }
+
+                    // Update the port list with the base names
+                    sed.sed(filename, "(#define[ ]+PORT_\\w*[ ]+)\"?"
+                            + port.getBasename() + "\"?", "$1 " + portId);
+                }
+
+            }
+        } catch (Exception e) {
+            System.out.println("CbeProcessVisitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create the makefile for a special process -> Each subprocess
+     * gets its own makefile
+     *
+     * @param p process for which the makefile should be created
+     */
+    protected void createMakefile(Process p) {
+        try {
+            // Directory of the process
+            String processDir = _dir + _delimiter + "spu_"
+                    + p.getBasename();
+
+            // Create the filename for the new wrapper
+            String filename = processDir + _delimiter + "Makefile";
+            // File makefile = new File(filename);
+
+            OutputStream file;
+
+            file = new FileOutputStream(filename);
+
+            PrintStream _makefilePS = new CodePrintStream(file);
+
+            _makefilePS.println("# Makefile for process " + p.getName());
+            _makefilePS.println("");
+
+            String dependency = "all: spu_" + p.getBasename()
+                    + "_wrapper.c ../lib/ProcessWrapper.h "
+                    + "../lib/ProcessFifo.h";
+
+            for (SourceCode code: p.getSrcList())
+            {
+                dependency += " " + code.getLocality();
+            }
+
+            _makefilePS.println(dependency);
+            _makefilePS.println("\t spu-g++ -I .. -I ../lib -g -o spu_"
+                    + p.getBasename() + "_wrapper spu_" + p.getBasename()
+                    + "_wrapper.c -ftree-vectorize -lm -mtune=cell -O3 "
+                    + "-fmodulo-sched -funroll-loops -ffast-math");
+            _makefilePS.println("clean: ");
+            _makefilePS.println("\t rm spu_" + p.getBasename()
+                    + "_wrapper");
+            _makefilePS.println();
+
+        } catch (FileNotFoundException e) {
+            System.out.println("CbeProcessVisitor - Makefile: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected HashMap<Port, Integer> _portMap;
+
+    protected static String _libDirName = "lib";
+    protected static String _tempDirName = "template";
+}
diff --git a/dol/src/dol/visitor/cbe/CbeVisitor.java b/dol/src/dol/visitor/cbe/CbeVisitor.java
new file mode 100644 (file)
index 0000000..d70b347
--- /dev/null
@@ -0,0 +1,183 @@
+/* $Id: CbeVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.cbe;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a CBE package.
+ */
+public class CbeVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param packageName name of the Cbe directory
+     */
+    public CbeVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param pn process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            File dir = new File(_packageName);
+            dir.mkdirs();
+
+            // Create the library
+            File lib = new File(_packageName + _delimiter + "lib");
+            lib.mkdirs();
+
+            //copy library files
+            File source = new File(_ui.getMySystemCLib().
+                    replaceAll("systemC", "cbe").replace("%20", " "));
+            new Copier().copy(source, lib);
+
+            // Create the template
+            File template = new File(_packageName + _delimiter
+                    + "template");
+            template.mkdirs();
+
+            //copy the templates
+            source = new File(_ui.getMySystemCLib().
+                    replaceAll("systemC", "cbe").
+                    replace("lib", "template").replace("%20", " "));
+            new Copier().copy(source, template);
+
+            // Some library files must be copied to the main directory
+            (new File(lib.getPath() + _delimiter + "ppu_main.h")).
+                    renameTo(new File (dir.getPath() + _delimiter
+                    + "ppu_main.h"));
+
+            //copy process source code
+            source = new File(_srcDirName.replace("%20", " "));
+            new Copier().copy(source, dir);
+
+            createPortMap(pn);
+            pn.accept(new CbeMakefileVisitor(_packageName));
+            pn.accept(new CbeBuildFileVisitor(_packageName));
+            pn.accept(new CbeProcessVisitor(_packageName, _portMap));
+            pn.accept(new CbeModuleVisitor(_packageName, _portMap));
+            pn.accept(new CbeConstantVisitor(_packageName, _portMap));
+        }
+        catch (Exception e) {
+            System.out.println("CbeVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create a hashmap which maps each port of the given process network
+     * to an integer. For each process, ports are numbered with integers
+     * starting from 0.
+     *
+     * @param pn process network for which the map should be generated
+     */
+    protected void createPortMap(ProcessNetwork pn) {
+        _portMap = new HashMap<Port, Integer>();
+
+        for (Process process : pn.getProcessList()) {
+            int portCount = 0;
+            Vector<Port> portList = process.getPortList();
+            Vector<String> portNameList = new Vector<String>();
+            portNameList.clear();
+            HashMap<String, Integer> portMap =
+                new HashMap<String, Integer>();
+            portMap.clear();
+
+            for (int i = 0; i < portList.size(); i++) {
+                //treat single ports differently than iterated ports
+                String portName = portList.elementAt(i).getName();
+                String baseName = portList.elementAt(i).getBasename();
+
+                if (portName.equals(baseName)) {
+                    portNameList.add(portName);
+                    portMap.put(portName, portCount++);
+                } else {
+                    String range_indices =
+                            portList.elementAt(i).getRange();
+                    Vector<Integer> range_indices_values =
+                            getIndex(range_indices, ";");
+
+                    String port_indices = portName;
+                    port_indices.replaceAll(baseName, "");
+                    Vector<Integer> port_indices_values =
+                            getIndex(port_indices, "_");
+
+                    if (!portNameList.contains(baseName)) {
+                        portNameList.add(baseName);
+                        portMap.put(baseName, portCount);
+
+                        int size = 1;
+                        for (int j = 0;
+                                j < range_indices_values.size(); j++) {
+                            size *= range_indices_values.elementAt(j);
+                        }
+                        portCount += size;
+                    }
+
+                    int portId = portMap.get(baseName);
+                    for (int j = 0; j < port_indices_values.size(); j++) {
+                        int weight = 1;
+                        for (int k = j + 1;
+                                k < range_indices_values.size(); k++) {
+                            weight *= range_indices_values.elementAt(k);
+                        }
+                        portId += port_indices_values.elementAt(j)
+                                * weight;
+                    }
+                    portMap.put(portName, portId);
+                }
+            }
+
+            for (int i = 0; i < portList.size(); i++) {
+                _portMap.put(portList.elementAt(i),
+                        portMap.get(portList.elementAt(i).getName()));
+            }
+        }
+    }
+
+    /**
+     * Gets vector of indices of a string, where the index must be
+     * separated by the specified separator.
+     * examples:
+     * getIndex("name_1_2", "_", 0) will return 1.
+     * getIndex("name_1_2", "_", 1) will return 2.
+     *
+     * @param range string to parse
+     * @param separator delimiter of indices
+     * @return vector of indices
+     */
+    protected Vector<Integer> getIndex(String range, String separator) {
+        Vector<Integer> indices = new Vector<Integer>();
+        String[] subranges = range.split(separator);
+        for (int i = 0; i < subranges.length; i++) {
+            try {
+                int value = Integer.valueOf(subranges[i]);
+                indices.add(value);
+            } catch (Exception e) {
+                continue;
+            }
+        }
+        return indices;
+    }
+
+    protected HashMap<Port, Integer> _portMap;
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+}
diff --git a/dol/src/dol/visitor/cbe/lib/ProcessFifo.h b/dol/src/dol/visitor/cbe/lib/ProcessFifo.h
new file mode 100644 (file)
index 0000000..8054cd2
--- /dev/null
@@ -0,0 +1,219 @@
+/**************************************************************** \r
+ *     FIFO Functions\r
+ *     Creator: lschor, 2008-10-30\r
+ *     Description: Defines Main functions for a FIFO in the Local Store of a SPE\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-08: Created\r
+ *     - 2008-11-15: Added Performance Estimation methods\r
+ */\r
+\r
+#ifndef _PROCESS_FIFO_H_\r
+#define _PROCESS_FIFO_H_\r
+\r
+// Maximum data allowed in the FIFO\r
+static const int MAXELEMENT = 1024; \r
+\r
+// Varialbes to store a fifo-read process\r
+uint32_t tag_id_read = 99;\r
+uint32_t lenRead = 0; \r
+uint32_t queueRead = 0; \r
+char * resultRead; \r
+\r
+char *locBuf[NUM_FIFO];\r
+int locBufCount[NUM_FIFO]; \r
+int locBufStart[NUM_FIFO]; \r
+\r
+// How many is free in a fifo\r
+uint32_t freespaceQueue(int queue)\r
+{\r
+       return MAXELEMENT - locBufCount[queue]; \r
+}\r
+\r
+\r
+// Init all fifos\r
+void initQueues()\r
+{\r
+       int j; \r
+       for (j = 0; j < NUM_FIFO; j++)\r
+       {\r
+               locBuf[j] = NULL;\r
+               locBufCount[j] = 0;\r
+               locBufStart[j] = 0;\r
+       }\r
+}\r
+\r
+// Init a special queue\r
+void initLocBuf(int queue)\r
+{\r
+       locBuf[queue] = NULL;\r
+       locBufCount[queue] = 0;\r
+       locBufStart[queue] = 0;\r
+}\r
+\r
+// Gives the memory of the buffers free\r
+void deinitLocBuf()\r
+{\r
+       int j; \r
+       for (j = 0; j < NUM_FIFO; j++)\r
+       {\r
+               if (locBuf[j] != NULL)\r
+               {\r
+                       free(locBuf[j]);\r
+               }\r
+       }\r
+}\r
+\r
+void updateLocBuf(int queue)\r
+{\r
+       // If the buffer is used the first time, allocate him\r
+       if (locBuf[queue]== NULL)\r
+       {\r
+               locBuf[queue] = (char *)malloc(MAXELEMENT * sizeof(char));\r
+       }\r
+#ifdef MEASURE_DOL_READ_START_DMA\r
+       double t_dol_read_start_dma = spu_read_decrementer();\r
+#endif\r
+\r
+       // Double-Buffering --> Try to close the old read-process\r
+       if (tag_id_read != 99)\r
+       {\r
+               waittag(tag_id_read); \r
+               // Write the data you read into the queue; \r
+               int i;  \r
+\r
+               #ifdef MEASURE_DOL_READ_DOUBLEBUF\r
+                       double t_dol_read_doublebuf = spu_read_decrementer();\r
+               #endif\r
+\r
+               // Has to write all elements at the beginning or write all elements at the end of the buffer\r
+               if (locBufStart[queueRead] + locBufCount[queueRead] > MAXELEMENT || locBufStart[queueRead] + locBufCount[queueRead] + lenRead < MAXELEMENT)\r
+               {\r
+                       memcpy(&(locBuf[queueRead][(locBufStart[queueRead] + locBufCount[queueRead]) % MAXELEMENT]), resultRead, lenRead);\r
+               }\r
+               \r
+               // Otherwise something at the end and something at the beginning\r
+               else\r
+               {\r
+                       // At the end of the buffer\r
+                       memcpy(&(locBuf[queueRead][(locBufStart[queueRead] + locBufCount[queueRead])]), resultRead, MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]);\r
+                       \r
+                       // At the beginning\r
+                       memcpy(locBuf[queueRead], &(resultRead[MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]]), lenRead - (MAXELEMENT - locBufStart[queueRead] - locBufCount[queueRead]));\r
+               }\r
+\r
+               locBufCount[queueRead]+=lenRead;\r
+\r
+               #ifdef MEASURE_DOL_READ_DOUBLEBUF\r
+                       t_dol_read_doublebuf -= spu_read_decrementer();\r
+                       printf("DOL_READ_DOUBLEBUF_DMA;%f\n",t_dol_read_doublebuf * 1 / MEASURE_CPU);\r
+               #endif\r
+\r
+               mfc_tag_release(tag_id_read); // release tag ID before exiting\r
+               _free_align(resultRead);\r
+\r
+               // Send a okey about the data to the PPE\r
+               spu_write_out_mbox((uint32_t)(SPE_READ_SUC << 28)); // stalls mailbox is full.\r
+               tag_id_read = 99; \r
+       }\r
+       \r
+       uint32_t message = (SPE_READ_DEMAND << 28) | (queue << 16) | (freespaceQueue(queue));\r
+\r
+#ifdef MEASURE_DOL_READ_HANDSHAKE\r
+       double t_dol_read_handshake = spu_read_decrementer();\r
+#endif\r
+\r
+       spu_write_out_mbox((uint32_t)(message)); \r
+                       \r
+       message = spu_read_in_mbox(); \r
+       uint32_t request = message >> 28; \r
+       lenRead = (0xffff & message);\r
+\r
+       if (request != (uint32_t) 1)\r
+       {\r
+               return; \r
+       }\r
+       \r
+       if((tag_id_read=mfc_tag_reserve())==MFC_TAG_INVALID){\r
+               printf("SPE: ERROR - can't reserve a tag ID\n"); return;\r
+       }\r
+       \r
+       // Wait for the response of the PPE --> The address where to read\r
+       uint32_t ea_mfc_h, ea_mfc_l;\r
+       uint64_t ea_mfc;\r
+                       \r
+       ea_mfc_h  = spu_read_in_mbox(); \r
+       ea_mfc_l  = spu_read_in_mbox();\r
+       ea_mfc = mfc_hl2ea(ea_mfc_h, ea_mfc_l); \r
+\r
+#ifdef MEASURE_DOL_READ_HANDSHAKE\r
+       t_dol_read_handshake -= spu_read_decrementer();\r
+       printf("DOL_READ_HANDSHAKE;%f\n",t_dol_read_handshake * 1 / MEASURE_CPU);\r
+#endif\r
+\r
+#ifdef MEASURE_DOL_READ_START_DMA\r
+       t_dol_read_start_dma -= spu_read_decrementer();\r
+       printf("DOL_READ_START_DMA;%f\n",t_dol_read_start_dma * 1 / MEASURE_CPU);\r
+#endif\r
+\r
+       resultRead = (char *)_malloc_align(lenRead, 4); \r
+\r
+#ifdef MEASURE_DOL_READ_DMA\r
+       double t_dol_read_dma = spu_read_decrementer();\r
+#endif\r
+       \r
+       // Read the data from the address we got from the PPE\r
+       mfc_get(&(resultRead[0]), ea_mfc, lenRead, tag_id_read, 0, 0); \r
+#ifdef MEASURE_DOL_READ_DMA\r
+       t_dol_read_dma -= spu_read_decrementer();\r
+       printf("DOL_READ_DMA;%f\n",t_dol_read_dma * 1 / MEASURE_CPU);\r
+#endif\r
+\r
+       queueRead = queue; \r
+}\r
+\r
+// Read from the local buffer\r
+void readLocBuf(int queue, void *destination, int len)\r
+{\r
+#ifdef MEASURE_DOL_READ_LOCBUF\r
+       double t_dol_read_locbuf = spu_read_decrementer();\r
+#endif\r
+       int count = 0;\r
+       int newLen = 0;\r
+       char* buffer = (char*) destination;\r
+       int i; \r
+\r
+       while (count < len)\r
+       {\r
+               newLen = (len - count) > MAXELEMENT? MAXELEMENT : len - count;\r
+               \r
+               while (locBufCount[queue] < newLen)\r
+               {\r
+                       updateLocBuf(queue); \r
+               }\r
+\r
+               // Can directly read all elements from the end of the buffer\r
+               if (locBufStart[queue] + newLen < MAXELEMENT)\r
+               {\r
+                       memcpy(buffer,  &(locBuf[queue][locBufStart[queue]]), newLen);\r
+               }\r
+\r
+               // Has to write from the end and from the beginning of the buffer\r
+               else\r
+               {\r
+                       memcpy(&(buffer[count]), &(locBuf[queue][locBufStart[queue]]), MAXELEMENT - locBufStart[queue]);\r
+                       memcpy(&(buffer[count + MAXELEMENT - locBufStart[queue]]), locBuf[queue], newLen - MAXELEMENT + locBufStart[queue]);\r
+               }\r
+\r
+               locBufCount[queue] -= newLen;\r
+               locBufStart[queue] = (locBufStart[queue] + newLen) % MAXELEMENT;                \r
+               count += newLen;\r
+       }\r
+#ifdef MEASURE_DOL_READ_LOCBUF\r
+       t_dol_read_locbuf -= spu_read_decrementer();\r
+       printf("DOL_READ_LOCBUF;%f\n",t_dol_read_locbuf * 1 / MEASURE_CPU);\r
+#endif\r
+}\r
+\r
+\r
+#endif // _PROCESS_FIFO_H_ \r
diff --git a/dol/src/dol/visitor/cbe/lib/ProcessWrapper.h b/dol/src/dol/visitor/cbe/lib/ProcessWrapper.h
new file mode 100644 (file)
index 0000000..c06075d
--- /dev/null
@@ -0,0 +1,248 @@
+/**************************************************************** \r
+ *     Process Wrapper Functions\r
+ *     Creator: lschor, 2008-10-30\r
+ *     Description: General process wrapper file, includes DOL_read and DOL_write as main functions\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-10-30: Created\r
+ *     - 2008-11-08: Update to Double Buffering\r
+ *     - 2008-11-15: Added Performance Estimation methods\r
+ */\r
+\r
+#ifndef __PROCESS_WRAPPER_H__\r
+#define __PROCESS_WRAPPER_H__\r
+\r
+#include <spu_intrinsics.h>\r
+#include <spu_mfcio.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include <stdarg.h>            // Used for va_list\r
+#include <stdlib.h>\r
+#include "lib/malloc_align.h"   // Malloc for DMA\r
+#include "lib/free_align.h"     // Free for DMA\r
+#include "dol.h"\r
+#include "common.h"\r
+#include "estimation.h"\r
+\r
+//Cell Macros\r
+#define waittag(tag_id) mfc_write_tag_mask(1<<tag_id); mfc_read_tag_status_all();\r
+\r
+//DOL macros\r
+#define GETINDEX(dimension) \\r
+    ((ProcessWrapper*)(p->wptr))->index[dimension]\r
+\r
+#define CREATEPORTVAR(name) \\r
+    int name\r
+\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+    createPort(&port, base, number_of_indices, index_range_pairs)\r
+\r
+// Include the FIFO Functions\r
+#include "lib/ProcessFifo.h"\r
+\r
+// Include some help functions\r
+#include "lib/ProcessWrapperHelp.h"\r
+\r
+// Struct for a process\r
+typedef struct _process_wrapper {\r
+       char*           name;\r
+       uint32_t*       index;\r
+       uint32_t        is_detached;\r
+       uint32_t*       port_id;\r
+       uint32_t*       port_queue_id;\r
+       uint32_t        number_of_ports;\r
+} ProcessWrapper;\r
+\r
+// Tag address for the write process\r
+uint32_t tag_id_write = 99; \r
+\r
+// Pointer to the current data buffer\r
+char * resultWrite; \r
+\r
+/**\r
+ * Finish a DOL_write process\r
+ */\r
+void finish_DOL_write()\r
+{\r
+       if (tag_id_write != 99)\r
+       {\r
+               #ifdef MEASURE_DOL_WRITE_FINISH\r
+                       double t_dol_write_finish = spu_read_decrementer();\r
+               #endif\r
+\r
+               // Wait until the write process is finished\r
+               waittag(tag_id_write);\r
+               mfc_tag_release(tag_id_write); // release tag ID before exiting\r
+               _free_align(resultWrite);\r
+               // Send a okey about the data to the PPE\r
+               spu_write_out_mbox((uint32_t)(SPE_WRITE_SUC << 28)); // stalls mailbox is full.\r
+               tag_id_write = 99; \r
+               //queueWrite = -1;\r
+\r
+               #ifdef MEASURE_DOL_WRITE_FINISH\r
+                       t_dol_write_finish -= spu_read_decrementer();\r
+                       printf("DOL_WRITE_FINISH;%f\n",t_dol_write_finish * 1 / MEASURE_CPU);\r
+               #endif\r
+\r
+       }\r
+}\r
+\r
+/**\r
+ * Read from the FIFO\r
+ */\r
+void DOL_read(void *port, void *buf, int len, DOLProcess *process)\r
+{\r
+#ifdef MEASURE_DOL_READ\r
+       double t_dol_read = spu_read_decrementer();\r
+#endif\r
+\r
+       ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr;\r
+       int i; \r
+\r
+       for (i = 0; i < process_wrapper->number_of_ports; i++) \r
+       {\r
+               if (process_wrapper->port_id[i] == (int)port) \r
+               {\r
+                       int queue = process_wrapper->port_queue_id[i];\r
+\r
+                       finish_DOL_write(); \r
+                       \r
+                       // Try to get new data into the local Buffer\r
+                       updateLocBuf(queue); \r
+                       \r
+                       // Read from the Buffer\r
+                       readLocBuf(queue, buf, len); \r
+                       \r
+                       break; \r
+               }\r
+       }\r
+#ifdef MEASURE_DOL_READ\r
+       t_dol_read -= spu_read_decrementer();\r
+       printf("DOL_READ;%f\n",t_dol_read * 1 / MEASURE_CPU);\r
+#endif\r
+\r
+}\r
+\r
+\r
+/**\r
+ * Write data into the FIFO\r
+ */\r
+void DOL_write(void *port, void *buf, int len, DOLProcess *process)\r
+{\r
+#ifdef MEASURE_DOL_WRITE\r
+       double t_dol_write = spu_read_decrementer();\r
+#endif\r
+\r
+       ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr;\r
+       int i; \r
+       \r
+       for (i = 0; i < process_wrapper->number_of_ports; i++) \r
+       {\r
+               if (process_wrapper->port_id[i] == (int)port) \r
+               {\r
+                       // This is our queue\r
+                       int queue = process_wrapper->port_queue_id[i];\r
+                       \r
+               #ifdef MEASURE_DOL_WRITE_START_DMA\r
+                       double t_dol_write_start_dma = spu_read_decrementer();\r
+               #endif\r
+\r
+                       // There has been a writing process. Is it already finished? \r
+                       finish_DOL_write(); \r
+\r
+                       // Create the new write process\r
+                       \r
+                       // reserve DMA tag ID\r
+                       if((tag_id_write=mfc_tag_reserve())==MFC_TAG_INVALID){\r
+                               printf("SPE: ERROR - can't reserve a tag ID\n"); return;\r
+                       }\r
+\r
+                       // Create the message we like to send, format: \r
+                       // 4 bit:  code (total 16 possibilities)\r
+                       // 12 bit: queue (total 4096 possibilities)\r
+                       // 16 bit: len  (total maximal size of 512 KB which could be send)\r
+                       uint32_t message = (SPE_WRITE_DEMAND << 28) | (queue << 16) | (len); \r
+\r
+               #ifdef MEASURE_DOL_WRITE_HANDSHAKE\r
+                       double t_dol_write_handshake = spu_read_decrementer();\r
+               #endif\r
+                       // Demand the PPE for an address\r
+                       spu_write_out_mbox(message); \r
+\r
+                       // Copy the data into the right data-alignment\r
+                       resultWrite = (char *)_malloc_align(roundDMA(len), 4); \r
+                       memcpy(resultWrite, buf, len); \r
+                       \r
+                       // Is there enough free space to write into the queues? \r
+                       uint32_t messageIn = spu_read_in_mbox(); \r
+                       uint32_t request = messageIn >> 28; \r
+                       \r
+                       while (request != (uint32_t) 1)\r
+                       {\r
+                               spu_write_out_mbox(message); \r
+                               messageIn = spu_read_in_mbox(); \r
+                               request = messageIn >> 28; \r
+                       }\r
+\r
+                       // Wait for the response of the PPE, i.e. the address for the FIFO element\r
+                       uint32_t ea_mfc_h, ea_mfc_l;\r
+                       uint64_t ea_mfc;\r
+                       ea_mfc_h  = spu_read_in_mbox();\r
+                       ea_mfc_l  = spu_read_in_mbox();\r
+                       ea_mfc = mfc_hl2ea(ea_mfc_h, ea_mfc_l);\r
+\r
+               #ifdef MEASURE_DOL_WRITE_HANDSHAKE\r
+                       t_dol_write_handshake -= spu_read_decrementer();\r
+                       printf("DOL_WRITE_HANDSHAKE;%f\n",t_dol_write_handshake * 1 / MEASURE_CPU);\r
+               #endif\r
+\r
+\r
+               #ifdef MEASURE_DOL_WRITE_START_DMA\r
+                       t_dol_write_start_dma -= spu_read_decrementer();\r
+                       printf("DOL_WRITE_START_DMA;%f\n",t_dol_write_start_dma * 1 / MEASURE_CPU);\r
+               #endif\r
+\r
+               #ifdef MEASURE_DOL_WRITE_DMA\r
+                       double t_dol_write_dma = spu_read_decrementer();\r
+               #endif\r
+               \r
+                       // Write the data to the address we got from the PPE\r
+                       mfc_put((void *)&(resultWrite[0]), ea_mfc, roundDMA(len), tag_id_write, 0, 0); \r
+\r
+               #ifdef MEASURE_DOL_WRITE_DMA\r
+                       t_dol_write_dma -= spu_read_decrementer();\r
+                       printf("DOL_WRITE_DMA;%f\n",t_dol_write_dma * 1 / MEASURE_CPU);\r
+               #endif\r
+\r
+\r
+                       break;\r
+               }\r
+       }\r
+#ifdef MEASURE_DOL_WRITE\r
+       t_dol_write -= spu_read_decrementer();\r
+       printf("DOL_WRITE;%f\n",t_dol_write * 1 / MEASURE_CPU);\r
+#endif\r
+}\r
+\r
+/**\r
+ * Detach the DOL Process\r
+ */\r
+void DOL_detach(DOLProcess *process) {\r
+       //printf("[%s] DOL_detach.\n", (char*)(((ProcessWrapper*)process->wptr)->name));\r
+\r
+       // Check if all write processes are finished\r
+       if (tag_id_write != 99)\r
+       {\r
+               waittag(tag_id_write);\r
+               mfc_tag_release(tag_id_write); // release tag ID before exiting\r
+               _free_align(resultWrite); \r
+               spu_write_out_mbox((uint32_t)(2 << 28)); // stalls mailbox is full.\r
+       }\r
+\r
+       uint32_t message = (SPE_DETACH << 28); \r
+       spu_write_out_mbox(message); \r
+       deinitLocBuf();\r
+    ((ProcessWrapper*)process->wptr)->is_detached = 1;\r
+}\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cbe/lib/ProcessWrapperHelp.h b/dol/src/dol/visitor/cbe/lib/ProcessWrapperHelp.h
new file mode 100644 (file)
index 0000000..7d2a117
--- /dev/null
@@ -0,0 +1,100 @@
+/**************************************************************** \r
+ *     Process Wrapper Help functions\r
+ *     Creator: lschor, 2008-11-21\r
+ *     Description: General process wrapper fucntions\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-21: Created\r
+ */\r
+\r
+#ifndef __PROCESS_WRAPPER_HELP_H__\r
+#define __PROCESS_WRAPPER_HELP_H__\r
+\r
+#include <stdarg.h>    // Used for va_list\r
+\r
+/**\r
+ * Gets an index of a string, where the index must be separated by\r
+ * a character specified in tokens.\r
+ * Returns -1, when an error occurs.\r
+ *\r
+ * Example:\r
+ * getIndex("name_1_2", "_", 0) will return 1.\r
+ * getIndex("name_1_2", "_", 1) will return 2.\r
+ *\r
+ * @param string string to parse\r
+ * @param tokens delimiter of indices\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int getIndex(const char* string, char* tokens, int indexNumber) {\r
+    char* string_copy;\r
+    char* token_pointer;\r
+    int index = 0;\r
+\r
+    string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));\r
+    if (!string_copy) {\r
+        fprintf(stderr, "getIndex(): could not allocate memory.\n");\r
+        return -1;\r
+    }\r
+\r
+    strcpy(string_copy, string);\r
+\r
+    token_pointer = strtok(string_copy, tokens);\r
+    do {\r
+        token_pointer = strtok(NULL, tokens);\r
+        index++;\r
+    } while (index <= indexNumber && token_pointer != 0);\r
+\r
+    if (token_pointer) {\r
+        index = atoi(token_pointer);\r
+        free(string_copy);\r
+        return index;\r
+    }\r
+\r
+    free(string_copy);\r
+    return -1;\r
+}\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+int *createPort(int *port, int base, int number_of_indices,\r
+                int index_range_pairs, ...) {\r
+    int index[4];\r
+    int range[4];\r
+    int i;\r
+    int value;\r
+\r
+    va_list marker;\r
+    va_start(marker, index_range_pairs);\r
+\r
+    value = index_range_pairs;\r
+    for (i = 0; i < number_of_indices; i++) {\r
+        index[i] = value;\r
+        value = va_arg(marker, int);\r
+        range[i] = value;\r
+        if (i < number_of_indices - 1) {\r
+            value = va_arg(marker, int);\r
+        }\r
+    }\r
+\r
+    *port = base;\r
+    for (i = 0; i < number_of_indices; i++) {\r
+        int j;\r
+        int weight = 1;\r
+        for (j = 1; j < number_of_indices - i; j ++) {\r
+            weight *= range[j];\r
+        }\r
+        *port += index[i] * weight;\r
+    }\r
+\r
+    return port;\r
+}\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cbe/lib/ProcessWrapperPPE.c b/dol/src/dol/visitor/cbe/lib/ProcessWrapperPPE.c
new file mode 100644 (file)
index 0000000..f94c7ea
--- /dev/null
@@ -0,0 +1,150 @@
+/**************************************************************** \r
+ *     Process Wrapper Functions\r
+ *     Creator: lschor, 2008-10-30\r
+ *     Description: General process wrapper file, includes DOL_read and DOL_write as main functions\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-10-30: Created\r
+ *     - 2008-11-08: Update to Double Buffering\r
+ *     - 2008-11-15: Added Performance Estimation methods\r
+ */\r
+\r
+#ifndef __PROCESS_WRAPPER_PPE_H__\r
+#define __PROCESS_WRAPPER_PPE_H__\r
+\r
+#include <pthread.h>\r
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdlib.h>\r
+#include <time.h>\r
+\r
+#include "common_ppu.h"\r
+#include "dol.h"\r
+#include "ProcessWrapperHelp.h"\r
+\r
+\r
+/**\r
+ * Read from the FIFO\r
+ */\r
+void DOL_read(void *port, void *buf, int len, DOLProcess *process)\r
+{\r
+       ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr;\r
+       int i; \r
+\r
+       for (i = 0; i < process_wrapper->number_of_ports; i++) \r
+       {\r
+               if (process_wrapper->port_id[i] == (uint64_t)port) \r
+               {\r
+                       int queue = process_wrapper->port_queue_id[i];\r
+                       int i = 0;      \r
+                       struct timespec t;\r
+                       t.tv_sec = 0;\r
+                       t.tv_nsec = 5;\r
+               \r
+\r
+                       while (process_wrapper->locBufCount[queue] < len)\r
+                       {\r
+                               nanosleep(&t, NULL);\r
+                       };\r
+\r
+                       char *buffer = (char *)buf;\r
+\r
+                       pthread_mutex_lock( &(process_wrapper->mutex[queue]) );\r
+\r
+                       // Can directly read all elements from the end of the buffer\r
+                       if (process_wrapper->locBufStart[queue] + len < process_wrapper->MAXELEMENT)\r
+                       {\r
+                               memcpy(buffer, &(process_wrapper->locBuf[queue][process_wrapper->locBufStart[queue]]), len);\r
+                       }\r
+\r
+                       // Has to write from the end and from the beginning of the buffer\r
+                       else\r
+                       {\r
+                               memcpy(&(buffer[0]), &(process_wrapper->locBuf[queue][process_wrapper->locBufStart[queue]]), process_wrapper->MAXELEMENT - process_wrapper->locBufStart[queue]);\r
+                               memcpy(&(buffer[process_wrapper->MAXELEMENT - process_wrapper->locBufStart[queue]]), process_wrapper->locBuf[queue], len - process_wrapper->MAXELEMENT + process_wrapper->locBufStart[queue]);\r
+                       }\r
+\r
+                       process_wrapper->locBufCount[queue] -= len;\r
+                       process_wrapper->locBufStart[queue] = (process_wrapper->locBufStart[queue] + len) % process_wrapper->MAXELEMENT;\r
+\r
+                       pthread_mutex_unlock( & (process_wrapper->mutex[queue]) );\r
+\r
+\r
+                       break; \r
+               }\r
+       }\r
+}\r
+\r
+\r
+/**\r
+ * Write data into the FIFO\r
+ */\r
+void DOL_write(void *port, void *buf, int len, DOLProcess *process)\r
+{\r
+       ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr;\r
+       int i; \r
+       \r
+       for (i = 0; i < process_wrapper->number_of_ports; i++) \r
+       {\r
+               if (process_wrapper->port_id[i] == (uint64_t)port) \r
+               {\r
+                       // This is our queue\r
+                       int queue = process_wrapper->port_queue_id[i];\r
+\r
+                       struct timespec t;\r
+                       t.tv_sec = 0;\r
+                       t.tv_nsec = 5;\r
+\r
+                       // Wait if there is not enough space in the fifo                        \r
+                       while (process_wrapper->MAXELEMENT - process_wrapper->locBufCount[queue] < len)\r
+                       {\r
+                               nanosleep(&t, NULL);\r
+                       };\r
+\r
+                       char *buffer = (char *)buf;\r
+\r
+                       pthread_mutex_lock( &(process_wrapper->mutex[queue]) );\r
+\r
+                       // Has to write all elements at the beginning or write all elements at the end of the buffer\r
+                       if (process_wrapper->locBufStart[queue] + process_wrapper->locBufCount[queue] > process_wrapper->MAXELEMENT || process_wrapper->locBufStart[queue] + process_wrapper->locBufCount[queue] + len < process_wrapper->MAXELEMENT)\r
+                       {\r
+                               memcpy(&(process_wrapper->locBuf[queue][(process_wrapper->locBufStart[queue] + process_wrapper->locBufCount[queue]) % process_wrapper->MAXELEMENT]), buffer, len);\r
+                       }\r
+\r
+                       // Otherwise something at the end and something at the beginning\r
+                       else\r
+                       {\r
+                               // At the end of the buffer\r
+                               memcpy(&(process_wrapper->locBuf[queue][(process_wrapper->locBufStart[queue] + process_wrapper->locBufCount[queue])]), buffer, process_wrapper->MAXELEMENT - process_wrapper->locBufStart[queue] - process_wrapper->locBufCount[queue]);\r
+\r
+                               // At the beginning\r
+                               memcpy(process_wrapper->locBuf[queue], &(buffer[process_wrapper->MAXELEMENT - process_wrapper->locBufStart[queue] - process_wrapper->locBufCount[queue]]), len - (process_wrapper->MAXELEMENT - process_wrapper->locBufStart[queue] - process_wrapper->locBufCount[queue]));\r
+                       }\r
+\r
+                       process_wrapper->locBufCount[queue]+=len;\r
+\r
+                       pthread_mutex_unlock( & (process_wrapper->mutex[queue]) );\r
+\r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ * Detach the DOL Process\r
+ */\r
+void DOL_detach(DOLProcess *process) {\r
+       ProcessWrapper* process_wrapper = (ProcessWrapper*)process->wptr;\r
+       printf("[%s] DOL_detach.\n", (char*)(((ProcessWrapper*)process->wptr)->name));\r
+       \r
+       pthread_mutex_lock( (process_wrapper->mutexProcessNr) );\r
+       (* process_wrapper->processFinished)++;\r
+       pthread_mutex_unlock( (process_wrapper->mutexProcessNr) );\r
+\r
+       ((ProcessWrapper*)process->wptr)->is_detached = 1;\r
+}\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cbe/lib/common.h b/dol/src/dol/visitor/cbe/lib/common.h
new file mode 100644 (file)
index 0000000..9370673
--- /dev/null
@@ -0,0 +1,59 @@
+/**************************************************************** \r
+ *     COMMON.H\r
+ *     Creator: lschor, 2008-10-30\r
+ *     Description: Specifies some structs and Constants for the CBE-DOL-Implementation\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-10-30: Created\r
+ */\r
+\r
+#ifndef _COMMON_H_\r
+#define _COMMON_H_\r
+\r
+#include "dol.h"\r
+#include "lib/constant.h"\r
+\r
+#define SPE_WRITE_DEMAND 0\r
+#define SPE_READ_DEMAND 1\r
+#define SPE_WRITE_SUC 2\r
+#define SPE_READ_SUC 3\r
+#define SPE_DETACH 4\r
+\r
+// the context that PPE forward to SPE\r
+typedef struct{\r
+       uint64_t port_id;\r
+       uint64_t port_queue_id; \r
+\r
+       uint64_t processName;   // Address for the name of the process\r
+       uint64_t processNameLen;  // Len of the process Name\r
+\r
+       uint32_t number_of_ports; \r
+       uint32_t is_detached; \r
+       uint32_t padd[2]; // dummy - for alignment --> It always has to be a multiple of 128 bit! \r
+} parm_context; // aligned to 16B \r
+\r
+typedef struct{\r
+       uint32_t d; \r
+       uint32_t padd[31]; //padd to cache line\r
+} status_s;\r
+\r
+\r
+// Round a number ot the right DMA number --> Is used for DMA transfers\r
+uint32_t roundDMA(uint32_t number)\r
+{\r
+       if (number > 16)\r
+               return number + 16 - (number % 16);\r
+       else if (number > 8)\r
+               return 16; \r
+       else if (number > 4)\r
+               return 8; \r
+       else if (number > 2)\r
+               return 4; \r
+       else if (number > 1)\r
+               return 2; \r
+       else \r
+               return 1; \r
+}\r
+\r
+#endif // _COMMON_H_ \r
+\r
diff --git a/dol/src/dol/visitor/cbe/lib/common_ppu.h b/dol/src/dol/visitor/cbe/lib/common_ppu.h
new file mode 100644 (file)
index 0000000..7ee1ed0
--- /dev/null
@@ -0,0 +1,41 @@
+/**************************************************************** \r
+ *     Common structs for the PPU\r
+ *     Creator: lschor, 2008-11-21\r
+ *     Description: Common structs for the PPU\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-21: Created\r
+ */\r
+\r
+#ifndef __COMMON_PPU_H__\r
+#define __COMMON_PPU_H__\r
+\r
+//DOL macros\r
+#define GETINDEX(dimension) \\r
+    ((ProcessWrapper*)(p->wptr))->index[dimension]\r
+\r
+#define CREATEPORTVAR(name) \\r
+    int name\r
+\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+    createPort(&port, base, number_of_indices, index_range_pairs)\r
+\r
+\r
+// Struct for a process\r
+typedef struct _process_wrapper {\r
+    char*                                      name;\r
+    uint32_t*                          index;\r
+    uint32_t                           is_detached;\r
+    volatile uint32_t*      port_id;\r
+    volatile uint32_t*      port_queue_id;\r
+    uint32_t                           number_of_ports;\r
+       char **                                 locBuf;\r
+       int *                                   locBufCount;\r
+       int *                                   locBufStart;\r
+       int                                     MAXELEMENT;\r
+       int *                                   processFinished;\r
+       pthread_mutex_t *               mutex;\r
+       pthread_mutex_t *               mutexProcessNr;\r
+} ProcessWrapper;\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cbe/lib/dol.h b/dol/src/dol/visitor/cbe/lib/dol.h
new file mode 100644 (file)
index 0000000..2838938
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __DOL_H__
+#define __DOL_H__
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//structure for process
+struct _process;
+
+//
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr;
+} DOLProcess;
+
+void DOL_read(void *port, void *buf, int len, DOLProcess *process);
+void DOL_write(void *port, void *buf, int len, DOLProcess *process);
+void DOL_detach(DOLProcess *process);
+int getIndex(const char* string, char* tokens, int indexNumber); 
+int *createPort(int *port, int base, int number_of_indices, int index_range_pairs, ...); 
+
+#endif
diff --git a/dol/src/dol/visitor/cbe/lib/estimation.h b/dol/src/dol/visitor/cbe/lib/estimation.h
new file mode 100644 (file)
index 0000000..667f60b
--- /dev/null
@@ -0,0 +1,50 @@
+/**************************************************************** \r
+ *     Estimation Defintions\r
+ *     Creator: lschor, 2008-11-15\r
+ *     Description: File with includes for time measurements\r
+ *  Principle: if 1 then this point will be measured, if 0 then this point will not be measured\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-15: Created\r
+ */\r
+\r
+// \r
+#ifndef __ESTIMATION_H__\r
+#define __ESTIMATION_H__\r
+\r
+// What to measure?\r
+//#define              MEASURE                                                 0       // Measure activeted\r
+\r
+#ifdef MEASURE\r
+       //#define       MEASURE_DOL_READ                        0       // Measure DOL READ\r
+       //#define       MEASURE_DOL_READ_FINISH         0       // Measure FINISH DOL Read\r
+       //#define               MEASURE_DOL_READ_START_DMA      0       // Measure Time from start until the DMA process has started\r
+       //#define               MEASURE_DOL_READ_HANDSHAKE      0       // Measure Time of the whole handshake\r
+       //#define               MEASURE_DOL_READ_DMA            0       // Measure Time of DMA Setup\r
+       //#define               MEASURE_DOL_READ_LOCBUF         0       // Measure Time for LocBuf read\r
+       //#define               MEASURE_DOL_READ_DOUBLEBUF      0       // Measure Time for writing into the buffer\r
+\r
+       //#define       MEASURE_DOL_WRITE                       0       // Measure DOL WRITE\r
+       //#define       MEASURE_DOL_WRITE_FINISH        0       // Measure FINISH DOL Write\r
+       //#define               MEASURE_DOL_WRITE_START_DMA     0       // Measure Time from start until the DMA process has started\r
+       //#define               MEASURE_DOL_WRITE_HANDSHAKE     0       // Measure Time of the whole handshake\r
+       //#define               MEASURE_DOL_WRITE_DMA           0       // Measure Time of DMA Setup\r
+\r
+       //#define       MEASURE_DOL_FIRE                        0       // Measure DOL FIRE\r
+       //#define       MEASURE_DOL_INIT                        0       // Measure DOL INIT\r
+       //#define       MEASURE_SPE                                     0       // Measure whole SPE process\r
+\r
+       //#define       MEASURE_APPLICATION                     0       // Measure whole execution time\r
+       //#define       MEASURE_SET_UP_SPE_THREAD       0       // Measure time to set up the SPE-threads\r
+       //#define       MEASURE_SPE_WRITE_DEMAND        0       // Measure time of write demand\r
+       //#define       MEASURE_SPE_READ_DEMAND         0       // Measure time of read demand\r
+       //#define       MEASURE_SPE_WRITE_SUC           0       // Measure time of write successful\r
+       //#define       MEASURE_SPE_READ_SUC            0       // Measure time of read successful\r
+\r
+#endif\r
+\r
+// Some constants\r
+#define        MEASURE_START                                   0xFFFFFFFF      // Start decrementer at this value\r
+#define                MEASURE_CPU                                             79800000.0      // Timebase PS3 (in Hz)\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cbe/lib/free_align.h b/dol/src/dol/visitor/cbe/lib/free_align.h
new file mode 100644 (file)
index 0000000..5924871
--- /dev/null
@@ -0,0 +1,65 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2006,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _FREE_ALIGN_H_
+#define _FREE_ALIGN_H_ 1
+
+#include <stdlib.h>
+
+/* Function
+ *
+ *     void free_align(void *ptr)
+ *
+ * Description
+ *     The free_align routine frees a memory buffer allocate by the
+ *     malloc_align routine. See malloc_align for complete details.
+ */
+
+static __inline void _free_align(void *ptr)
+{
+  void * real;
+
+  if (ptr) {
+    real = *((void **)(ptr)-1);
+    free(real);
+  }
+}
+
+#endif /* _FREE_ALIGN_H_ */
diff --git a/dol/src/dol/visitor/cbe/lib/malloc_align.h b/dol/src/dol/visitor/cbe/lib/malloc_align.h
new file mode 100644 (file)
index 0000000..0a19068
--- /dev/null
@@ -0,0 +1,105 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+
+#ifndef _MALLOC_ALIGN_H_
+#define _MALLOC_ALIGN_H_       1
+
+#include <stdlib.h>
+
+/* Function
+ *
+ *     void * malloc_align(size_t size, unsigned int log2_align)
+ *
+ * Description
+ *     The malloc_align routine allocates a memory buffer of <size>
+ *     bytes aligned to the power of 2 alignment specified by <log2_align>.
+ *     For example, malloc_align(4096, 7) will allocate a memory heap 
+ *     buffer of 4096 bytes aligned on a 128 byte boundary.
+ *
+ *     The aligned malloc routine allocates an enlarged buffer
+ *     from the standard memory heap. Space for the real allocated memory
+ *     pointer is reserved on the front of the memory buffer.
+ *
+ *           ----------------- <--- start of allocated memory
+ *          |    pad 0 to     |
+ *          |(1<<log2_align)-1|
+ *          |     bytes       |
+ *          |-----------------|
+ *          | allocation size |
+ *          |-----------------|
+ *          | real buffer ptr |
+ *          |-----------------|<---- returned aligned memory pointer
+ *          |                 |
+ *          |    requested    |
+ *          |     memory      |
+ *          |     buffer      |
+ *          |      size       |
+ *          |      bytes      |
+ *          |_________________|
+ *
+ *      Memory allocated by this routine must be freed using the free_align
+ *     routine.
+ *
+ *     The size of the allocation is saved for special cases where the 
+ *     data must be mored during a realloc_align.
+ */
+
+static __inline void * _malloc_align(size_t size, unsigned int log2_align)
+{
+  void *ret;
+  char *real;
+  unsigned long offset;
+  unsigned long align;
+  
+  align = 1 << log2_align;
+  real = (char *)malloc(size + 2*sizeof(void *) + (align-1));
+  if (real) {
+    offset = (align - (unsigned long)(real + 2*sizeof(void *))) & (align-1);
+    ret = (void *)((real + 2*sizeof(void *)) + offset);
+    *((size_t *)(ret)-2) = size;
+    *((void **)(ret)-1) = (void *)(real);
+  } else {
+    ret = (void *)(real);
+  }
+  return (ret);
+}
+
+#endif /* _MALLOC_ALIGN_H_ */
diff --git a/dol/src/dol/visitor/cbe/lib/ppu_main.h b/dol/src/dol/visitor/cbe/lib/ppu_main.h
new file mode 100644 (file)
index 0000000..5fd2a26
--- /dev/null
@@ -0,0 +1,76 @@
+/**************************************************************** \r
+ *     Header for the main function\r
+ *     Creator: lschor, 2008-11-21\r
+ *     Description: Header file for the main function of the PPU\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-21: Created\r
+ */\r
+\r
+#ifndef __PPU_MAIN_H__\r
+#define __PPU_MAIN_H__\r
+\r
+// System includes\r
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdlib.h>\r
+#include <libspe2.h>\r
+#include <pthread.h>\r
+#include <sys/time.h>\r
+\r
+// Local includes\r
+#include "lib/malloc_align.h"\r
+#include "lib/free_align.h"\r
+#include "common.h"\r
+#include "lib/estimation.h"\r
+#include "common_ppu.h"\r
+#include "cbe_mfc.h"\r
+\r
+// Handler for the SPE\r
+extern spe_program_handle_t spu;\r
+\r
+// Program context for the SPEs\r
+volatile parm_context ctx[NUM_SPES] __attribute__ ((aligned(16)));\r
+\r
+// The SPE-program-handler\r
+spe_program_handle_t *program[NUM_SPES];\r
+\r
+// data structure for running SPE thread \r
+typedef struct spu_data {\r
+       spe_context_ptr_t spe_ctx;\r
+       pthread_t pthread;\r
+       void *argp;\r
+} spu_data_t;\r
+\r
+// Data for the SPEs\r
+spu_data_t data[NUM_SPES];\r
+\r
+// Struct which stores a fifo entry temporary\r
+struct fifoEntry {\r
+       uint64_t ea; \r
+       int length;\r
+       int queue;\r
+};\r
+\r
+// Two temporary store elements\r
+struct fifoEntry tmpFifoEntryRead[NUM_SPES]; \r
+struct fifoEntry tmpFifoEntryWrite[NUM_SPES]; \r
+\r
+// Initialize the fifo, we use\r
+const int MAXELEMENT = 262144;\r
+char *locBuf[NUM_FIFO];\r
+int locBufCount[NUM_FIFO]; \r
+int locBufStart[NUM_FIFO]; \r
+\r
+// Mutex-variables for the read/write process of the Queues\r
+pthread_mutex_t mutex [NUM_FIFO];\r
+pthread_mutex_t mutexProcessNr = PTHREAD_MUTEX_INITIALIZER;\r
+\r
+// Number of process that have been finished\r
+int processFinished = 0; \r
+\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cbe/lib/ppu_main_workloop.h b/dol/src/dol/visitor/cbe/lib/ppu_main_workloop.h
new file mode 100644 (file)
index 0000000..874bf32
--- /dev/null
@@ -0,0 +1,235 @@
+/**************************************************************** \r
+ *     Main Loop function\r
+ *     Creator: lschor, 2008-11-21\r
+ *     Description: Includes the main loop function for the ppu_main function\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-21: Created\r
+ */\r
+\r
+void workloop()\r
+{\r
+       // Buffer to an address for sending to to the PPE\r
+       volatile char *dataToWriteP __attribute__ ((aligned(128))); \r
+\r
+       // Number of corrent working process\r
+       int processNr; \r
+\r
+       // General variables that have been used in the main workloop\r
+       uint32_t message;\r
+       uint32_t request;\r
+       uint32_t len;\r
+       uint32_t queue;\r
+\r
+       struct timespec t;\r
+       t.tv_sec = 0;\r
+       t.tv_nsec = 5;\r
+\r
+       while (1)\r
+       {\r
+               // Goes through all nodes and check if they like to send some data\r
+               // - Which node has some information\r
+               // - Run through all nodes and if one has some work, do that\r
+               for (processNr = 0; processNr < NUM_SPES; processNr++)\r
+               {\r
+                       if (!spe_out_mbox_status(data[processNr].spe_ctx)) continue; \r
+       \r
+                       // Get the data\r
+                       spe_out_mbox_read(data[processNr].spe_ctx, &message, 1);\r
+                       \r
+                       request = message >> 28;\r
+                       len = (0xffff & message);\r
+                       queue = (message >> 16) & 0xfff;\r
+                       \r
+                       // What type of request are the data? \r
+                       if (request == SPE_WRITE_DEMAND)        // Want an address to write\r
+                       {\r
+\r
+                               // If there is not enough space in the queue\r
+                               if (MAXELEMENT - locBufCount[queue] < len)\r
+                               {\r
+                                       int message = (0 << 28) | (queue << 16) | locBufCount[queue];\r
+                                       spe_in_mbox_write(data[processNr].spe_ctx, (uint32_t*)&message, 1, SPE_MBOX_ANY_NONBLOCKING);\r
+                               }\r
+\r
+                               // There is enough space in the queue\r
+                               else\r
+                               {\r
+                               #ifdef MEASURE_SPE_WRITE_DEMAND\r
+                                       struct timeval t_ppe_write_demand_start, t_ppe_write_demand_end;\r
+                                       gettimeofday(&t_ppe_write_demand_start,NULL);\r
+                               #endif\r
+                                       int message = (1 << 28) | (queue << 16) | len;\r
+                                       spe_in_mbox_write(data[processNr].spe_ctx, (uint32_t*)&message, 1, SPE_MBOX_ANY_NONBLOCKING);\r
+\r
+                                       // Create the memory for the element\r
+                                       dataToWriteP = (char *)malloc(roundDMA(len));\r
+                                       \r
+                                       // Create the address to send\r
+                                       uint64_t ea;\r
+                                       ea = (uint64_t)dataToWriteP;\r
+                                       \r
+                                       // Enter the information into the temporary Buffer\r
+                                       tmpFifoEntryWrite[processNr].ea = ea;\r
+                                       tmpFifoEntryWrite[processNr].length=len;\r
+                                       tmpFifoEntryWrite[processNr].queue = queue;\r
+                                       \r
+                                       // Send the address\r
+                                       spe_in_mbox_write(data[processNr].spe_ctx, (uint32_t*)&ea, 2,SPE_MBOX_ANY_NONBLOCKING);\r
+                               #ifdef MEASURE_SPE_WRITE_DEMAND\r
+                                       gettimeofday(&t_ppe_write_demand_end, NULL);\r
+                                       printf("PPE_WRITE_DEMAND;%f\n",(t_ppe_write_demand_end.tv_sec - t_ppe_write_demand_start.tv_sec) + 0.000001 * (t_ppe_write_demand_end.tv_usec - t_ppe_write_demand_start.tv_usec));\r
+                               #endif\r
+                               }\r
+                       }\r
+\r
+                       /***************************************************************************************************************/\r
+                       else if (request == SPE_READ_DEMAND)    // Want an address to read\r
+                       {\r
+                               // If no element is in the fifo queue\r
+                               if (locBufCount[queue] <= 0)\r
+                               {\r
+                                       int message = (0 << 28) | (queue << 16) | locBufCount[queue];\r
+                                       spe_in_mbox_write(data[processNr].spe_ctx, (uint32_t*)&message, 1, SPE_MBOX_ANY_NONBLOCKING);\r
+                               }\r
+\r
+                               // Has some elements in the fifo queue\r
+                               else\r
+                               {\r
+                               #ifdef MEASURE_SPE_READ_DEMAND\r
+                                       struct timeval t_ppe_read_demand_start, t_ppe_read_demand_end;\r
+                                       gettimeofday(&t_ppe_read_demand_start,NULL);\r
+                               #endif\r
+\r
+                                       pthread_mutex_lock( &(mutex[queue]) );\r
+                                       \r
+                                       len = len > locBufCount[queue] ? locBufCount[queue] : len;\r
+\r
+                                       // Can only send special sizes over the DMA\r
+                                       // 1, 2, 4, 8, 16, ..., 16*x\r
+\r
+                                       if (len >= 16)\r
+                                               len = len - (len % 16);\r
+                                       else if (len >= 8)\r
+                                               len = 8;\r
+                                       else if (len >= 4)\r
+                                               len = 4;\r
+                                       else if (len >= 2)\r
+                                               len = 2;\r
+                                       else\r
+                                               len = 1;\r
+\r
+                                       int message = (1 << 28) | (queue << 16) | len;\r
+                                       spe_in_mbox_write(data[processNr].spe_ctx, (uint32_t*)&message, 1, SPE_MBOX_ANY_NONBLOCKING);\r
+\r
+                                       char *buf = (char *)_malloc_align(sizeof(char) * len, 4);\r
+\r
+                                       // Can directly read all elements from the end of the buffer\r
+                                       if (locBufStart[queue] + len < MAXELEMENT)\r
+                                       {\r
+                                               memcpy(buf, &(locBuf[queue][locBufStart[queue]]), len);\r
+                                       }\r
+\r
+                                       // Has to write from the end and from the beginning of the buffer\r
+                                       else\r
+                                       {\r
+                                               memcpy(&(buf[0]), &(locBuf[queue][locBufStart[queue]]), MAXELEMENT - locBufStart[queue]);\r
+                                               memcpy(&(buf[MAXELEMENT - locBufStart[queue]]), locBuf[queue], len - MAXELEMENT + locBufStart[queue]);\r
+                                       }\r
+\r
+                                       locBufCount[queue] -= len;\r
+                                       locBufStart[queue] = (locBufStart[queue] + len) % MAXELEMENT;\r
+\r
+                                       pthread_mutex_unlock( & (mutex[queue]) );\r
+\r
+                                       // Create the address to send\r
+                                       uint64_t ea;\r
+                                       ea = (uint64_t)buf;\r
+\r
+                                       // Enter the information into the temporary Buffer\r
+                                       tmpFifoEntryRead[processNr].ea = ea;\r
+                                       tmpFifoEntryRead[processNr].length = len;\r
+                                       tmpFifoEntryRead[processNr].queue = queue; \r
+\r
+                                       spe_in_mbox_write(data[processNr].spe_ctx, (uint32_t*)&(tmpFifoEntryRead[processNr].ea), 2,SPE_MBOX_ANY_NONBLOCKING);\r
+                               #ifdef MEASURE_SPE_READ_DEMAND\r
+                                       gettimeofday(&t_ppe_read_demand_end, NULL);\r
+                                       printf("PPE;%f\n",(t_ppe_read_demand_end.tv_sec - t_ppe_read_demand_start.tv_sec) + 0.000001 * (t_ppe_read_demand_end.tv_usec - t_ppe_read_demand_start.tv_usec));\r
+                               #endif\r
+                               }\r
+                       }\r
+\r
+                       /***************************************************************************************************************/\r
+                       else if (request == SPE_WRITE_SUC)      // Has finished writing\r
+                       {\r
+                       #ifdef MEASURE_SPE_WRITE_SUC\r
+                               struct timeval t_ppe_write_suc_start, t_ppe_write_suc_end;\r
+                               gettimeofday(&t_ppe_write_suc_start,NULL);\r
+                       #endif\r
+                               // Enter the data into the FIFO\r
+                               int queueW = tmpFifoEntryWrite[processNr].queue;\r
+                               int lenW = tmpFifoEntryWrite[processNr].length; \r
+                               char *bufferW = (char *)(tmpFifoEntryWrite[processNr].ea); \r
+                               \r
+                               pthread_mutex_lock( &(mutex[queueW]) );\r
+\r
+                               // Has to write all elements at the beginning or write all elements at the end of the buffer\r
+                               if (locBufStart[queueW] + locBufCount[queueW] > MAXELEMENT || locBufStart[queueW] + locBufCount[queueW] + lenW < MAXELEMENT)\r
+                               {\r
+                                       memcpy(&(locBuf[queueW][(locBufStart[queueW] + locBufCount[queueW]) % MAXELEMENT]), bufferW, lenW);\r
+                               }\r
+\r
+                               // Otherwise something at the end and something at the beginning\r
+                               else\r
+                               {\r
+                                       // At the end of the buffer\r
+                                       memcpy(&(locBuf[queueW][(locBufStart[queueW] + locBufCount[queueW])]), bufferW, MAXELEMENT - locBufStart[queueW] - locBufCount[queueW]);\r
+\r
+                                       // At the beginning\r
+                                       memcpy(locBuf[queueW], &(bufferW[MAXELEMENT - locBufStart[queueW] - locBufCount[queueW]]), lenW - (MAXELEMENT - locBufStart[queueW] - locBufCount[queueW]));\r
+                               }\r
+\r
+                               locBufCount[queueW]+=lenW;\r
+\r
+                               pthread_mutex_unlock( & (mutex[queueW]) );\r
+\r
+                               // Set the temporary entry to null\r
+                       #ifdef MEASURE_SPE_WRITE_SUC\r
+                               gettimeofday(&t_ppe_write_suc_end, NULL);\r
+                               printf("PPE;%f\n",(t_ppe_write_suc_end.tv_sec - t_ppe_write_suc_start.tv_sec) + 0.000001 * (t_ppe_write_suc_end.tv_usec - t_ppe_write_suc_start.tv_usec));\r
+                       #endif\r
+                       }\r
+\r
+                       /***************************************************************************************************************/\r
+                       else if (request == SPE_READ_SUC)       // Has finished reading\r
+                       {\r
+                       #ifdef MEASURE_SPE_READ_SUC\r
+                               struct timeval t_ppe_read_suc_start, t_ppe_read_suc_end;\r
+                               gettimeofday(&t_ppe_read_suc_start,NULL);\r
+                       #endif\r
+                       #ifdef MEASURE_SPE_READ_SUC\r
+                               gettimeofday(&t_ppe_read_suc_end, NULL);\r
+                               printf("PPE;%f\n",(t_ppe_read_suc_end.tv_sec - t_ppe_read_suc_start.tv_sec) + 0.000001 * (t_ppe_read_suc_end.tv_usec - t_ppe_read_suc_start.tv_usec));\r
+                       #endif\r
+                       }\r
+\r
+                       /***************************************************************************************************************/\r
+                       else if (request == SPE_DETACH) // A process has finished\r
+                       {\r
+                               pthread_mutex_lock( &(mutexProcessNr) );\r
+                               processFinished++;\r
+                               pthread_mutex_unlock( &(mutexProcessNr) );\r
+                       }\r
+\r
+                       /***************************************************************************************************************/\r
+                       else    // Did nothing\r
+                       {\r
+                               nanosleep(&t, NULL);\r
+                       }\r
+               }\r
+\r
+               // Check if we can stop the execution\r
+               if (processFinished >= NUM_PROCS) break; \r
+       }\r
+}\r
+\r
diff --git a/dol/src/dol/visitor/cbe/template/ppu_process_wrapper_template.c b/dol/src/dol/visitor/cbe/template/ppu_process_wrapper_template.c
new file mode 100644 (file)
index 0000000..a47b3db
--- /dev/null
@@ -0,0 +1,68 @@
+/**************************************************************** \r
+ *     Process Wrapper file for a PPE process\r
+ *     Creator: lschor, 2008-11-21\r
+ *     Description: Wrapper for a specific PPE process\r
+ *     \r
+ *     Revision: \r
+ *     - 2008-11-21: Created\r
+ */\r
+\r
+// Include the standard thread functions\r
+#include <pthread.h>\r
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdlib.h>\r
+\r
+#include "common_ppu.h"\r
+\r
+// Include of the process --> Because all is mapped to one file, each source file is only allow to appear once\r
+//#include "@PROCESSNAME@.c"\r
+\r
+/*\r
+ * The wrapper process\r
+ */\r
+void *@PROCESSNAME@_wrapper( void *ptr )\r
+{\r
+       // Create the wrapper process\r
+       ProcessWrapper *wrapper = (ProcessWrapper *)ptr;\r
+\r
+       //initialize the index array\r
+       int i;\r
+       wrapper->index = (uint32_t *)malloc(4 * sizeof(int));\r
+       for (i = 0; i < 4; i++) \r
+       {\r
+               wrapper->index[i] = getIndex(wrapper->name, "_", i);\r
+       }\r
+\r
+       // DOL process\r
+       DOLProcess* process;\r
+       struct _local_states *state;\r
+\r
+       process = (DOLProcess *)malloc(sizeof(DOLProcess));\r
+       state = (struct _local_states *)malloc(sizeof(struct _local_states));\r
+\r
+       memcpy(process, &@PROCESSNAME@, sizeof(DOLProcess));\r
+       memcpy(state, @PROCESSNAME@.local, sizeof(struct _local_states));\r
+       process->local = state;\r
+       process->wptr = wrapper;\r
+\r
+       // Init the process\r
+       process->init(process);\r
+\r
+       // Run the process\r
+       while (!wrapper->is_detached) \r
+       {\r
+               process->fire(process);\r
+       }\r
+\r
+       // Delete all malloc memory\r
+       free(state); \r
+       free(process); \r
+       free(wrapper->name); \r
+       free(wrapper); \r
+}\r
+\r
+\r
diff --git a/dol/src/dol/visitor/cbe/template/spu_process_wrapper_template.c b/dol/src/dol/visitor/cbe/template/spu_process_wrapper_template.c
new file mode 100644 (file)
index 0000000..703518e
--- /dev/null
@@ -0,0 +1,150 @@
+/****************************************************************\r
+ *     Process Wrapper file\r
+ *     Creator: lschor, 2008-10-30\r
+ *     Description: Wrapper for a specific SPE process\r
+ *\r
+ *     Revision:\r
+ *     - 2008-10-30: Created\r
+ *     - 2008-11-08: Update to Double Buffering\r
+ *     - 2008-11-15: Added Performance Estimation methods\r
+ */\r
+\r
+// General includes\r
+#include <spu_intrinsics.h>\r
+extern "C" {\r
+  #include <spu_mfcio.h>\r
+}\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+\r
+// Include to allocate/free using for DMA transfers\r
+#include "lib/malloc_align.h"\r
+#include "lib/free_align.h"\r
+\r
+// Local includes\r
+#include "common.h"\r
+#include "lib/ProcessWrapper.h"\r
+#include "lib/estimation.h"\r
+\r
+// Context file\r
+static parm_context ctx __attribute__ ((aligned (128)));\r
+\r
+// Include of the process\r
+//#include "@PROCESSNAME@.c"\r
+\r
+// Main application\r
+int main(int speid , uint64_t argp)\r
+{\r
+#ifdef MEASURE\r
+       // Start the decrementer for time measurement\r
+       spu_write_decrementer(MEASURE_START);\r
+#endif\r
+\r
+#ifdef MEASURE_SPE\r
+       double t_dol_spe = spu_read_decrementer();\r
+#endif\r
+\r
+       // reserve DMA tag ID\r
+       uint32_t tag_id;\r
+       if((tag_id=mfc_tag_reserve())==MFC_TAG_INVALID){\r
+               printf("SPE: ERROR - can't reserve a tag ID\n"); return 1;\r
+       }\r
+\r
+\r
+       // Get the context information for the whole system\r
+       mfc_get((void*) &ctx, argp, sizeof(ctx), tag_id, 0, 0);\r
+       mfc_write_tag_mask(1<<tag_id);\r
+       mfc_read_tag_status_all();\r
+\r
+       // Create the port / queue structs\r
+       uint32_t port_id[roundDMA(ctx.number_of_ports)] __attribute__ ((aligned (128)));\r
+       uint32_t port_queue_id[roundDMA(ctx.number_of_ports)] __attribute__ ((aligned (128)));\r
+\r
+       // Copy the port list / queue list\r
+       mfc_get((void*)port_id, ctx.port_id, sizeof(uint32_t) * roundDMA(ctx.number_of_ports), tag_id,0,0);\r
+       mfc_get((void*)port_queue_id, ctx.port_queue_id, sizeof(uint32_t) * roundDMA(ctx.number_of_ports), tag_id,0,0);\r
+\r
+\r
+       // Create the wrapper process\r
+       ProcessWrapper *wrapper = (ProcessWrapper *)malloc(sizeof(ProcessWrapper));\r
+       wrapper->number_of_ports = ctx.number_of_ports;\r
+       wrapper->port_id = port_id;\r
+       wrapper->port_queue_id = port_queue_id;\r
+       wrapper->is_detached = 0;\r
+       wrapper->name = (char *)_malloc_align((uint32_t)ctx.processNameLen, 4);\r
+       mfc_get((void *)wrapper->name, ctx.processName, ctx.processNameLen, tag_id, 0, 0);\r
+       waittag(tag_id);\r
+\r
+\r
+       //initialize the index array\r
+       int i;\r
+       wrapper->index = (uint32_t *)malloc(4 * sizeof(int));\r
+       for (i = 0; i < 4; i++)\r
+       {\r
+               wrapper->index[i] = getIndex(wrapper->name, "_", i);\r
+       }\r
+\r
+       // Init the queues for local buffering in the LS\r
+       // Only the queues we really need\r
+       initQueues();\r
+\r
+       // DOL process\r
+       DOLProcess* process;\r
+       struct _local_states *state;\r
+\r
+       process = (DOLProcess *)malloc(sizeof(DOLProcess));\r
+       state = (struct _local_states *)malloc(sizeof(struct _local_states));\r
+\r
+       memcpy(process, &@PROCESSNAME@, sizeof(DOLProcess));\r
+       memcpy(state, @PROCESSNAME@.local, sizeof(struct _local_states));\r
+       process->local = state;\r
+       process->wptr = wrapper;\r
+\r
+       // Init the process\r
+#ifdef MEASURE_DOL_INIT\r
+       double t_dol_init = spu_read_decrementer();\r
+#endif\r
+       process->init(process);\r
+#ifdef MEASURE_DOL_INIT\r
+       t_dol_init -= spu_read_decrementer();\r
+       printf("DOL_INIT;%f\n",t_dol_init * 1 / MEASURE_CPU);\r
+#endif\r
+\r
+       // Run the process\r
+       while (!wrapper->is_detached)\r
+       {\r
+       #ifdef MEASURE_DOL_FIRE\r
+               double t_dol_fire = spu_read_decrementer();\r
+       #endif\r
+\r
+               process->fire(process);\r
+\r
+       #ifdef MEASURE_DOL_FIRE\r
+               t_dol_fire -= spu_read_decrementer();\r
+               printf("DOL_FIRE;%f\n",t_dol_fire * 1 / MEASURE_CPU);\r
+       #endif\r
+       }\r
+\r
+       // Delete all malloc memory\r
+       free(state);\r
+       free(process);\r
+       _free_align(wrapper->name);\r
+       free(wrapper);\r
+\r
+       // release tag ID before exiting\r
+       mfc_tag_release(tag_id);\r
+\r
+\r
+       // Inform the main process that we have finished!\r
+       spu_write_out_mbox((uint32_t)(4));\r
+\r
+#ifdef MEASURE_SPE\r
+       t_dol_spe -= spu_read_decrementer();\r
+       printf("DOL_SPE_@PROCESSNAME@;%f\n",t_dol_spe * 1 / MEASURE_CPU);\r
+#endif\r
+\r
+       return 0;\r
+}\r
+\r
+\r
diff --git a/dol/src/dol/visitor/cell/CellBuildFileVisitor.java b/dol/src/dol/visitor/cell/CellBuildFileVisitor.java
new file mode 100644 (file)
index 0000000..31daef5
--- /dev/null
@@ -0,0 +1,110 @@
+package dol.visitor.cell;\r
+\r
+import java.io.FileOutputStream;\r
+import java.io.OutputStream;\r
+import java.io.PrintStream;\r
+import java.util.Vector;\r
+\r
+import dol.datamodel.pn.Process;\r
+import dol.datamodel.pn.ProcessNetwork;\r
+import dol.visitor.PNVisitor;\r
+\r
+/**\r
+ * This class is a class for a visitor that is used to generate the build file\r
+ * for the Application on the CBE (i.e. a bash file for the cell\r
+ * \r
+ * @author lschor, 2008-10-30\r
+ * \r
+ * Revision: \r
+ * 2008-10-30: Updated the file for the CBE\r
+ * 2008-11-08: Add double buffering\r
+ */\r
+public class CellBuildFileVisitor extends PNVisitor {\r
+\r
+       /**\r
+        * Constructor.\r
+        * \r
+        * @param dir\r
+        *            path of the Makefile\r
+        */\r
+       public CellBuildFileVisitor(String dir) {\r
+               _dir = dir;\r
+       }\r
+\r
+       /**\r
+        * Create a Makefile for the given process network.\r
+        * \r
+        * @param pn\r
+        *            process network\r
+        */\r
+       public void visitComponent(ProcessNetwork pn) {\r
+               try {\r
+                       String filename = _dir + _delimiter + "pncbe.sh";\r
+                       OutputStream file = new FileOutputStream(filename);\r
+                       PrintStream ps = new PrintStream(file);\r
+\r
+                       // General information / notes and commands\r
+                       ps.println("#!/bin/bash");\r
+                       ps.println("clear");\r
+                       ps.println();\r
+                       ps\r
+                                       .println("# Bash file to run the DOL application on the Cell processor");\r
+                       ps\r
+                                       .println("# Start the Cell-Simulator and enter the following commands: ");\r
+                       ps\r
+                                       .println("# callthru source <Absolute path to the folder of this file>/pncbe.sh > pncbe.sh");\r
+                       ps\r
+                                       .println("# for example: callthru source /opt/cell/sdk/src/tutorial/pn_test/pncbe.sh > pncbe.sh");\r
+                       ps.println("# chmod +x pncbe.sh");\r
+                       ps.println();\r
+                       ps\r
+                                       .println("# To run the DOL application, use the following command: ");\r
+                       ps.println("# ./pncbe.sh");\r
+                       ps.println();\r
+                       ps.println("# Folder in which the application is stored");\r
+                       ps.println("FOLDER=/opt/cell/sdk/src/tutorial/pn_test");\r
+                       ps.println();\r
+\r
+                       // Go through each process and copy its data to the Cell\r
+                       String subdirectory = "";\r
+                       String applicationName = "";\r
+                       Vector<String> pList = new Vector<String>();\r
+\r
+                       for (Process process : pn.getProcessList()) {\r
+                               String basename = process.getBasename();\r
+                               if (!pList.contains(basename) && process.getNumOfInports() > 0 && process.getNumOfOutports() > 0) {\r
+                                       subdirectory = "spu_" + basename;\r
+                                       applicationName = subdirectory + "/spu_"\r
+                                                       + basename + "_wrapper";\r
+\r
+                                       ps.println("# " + basename);\r
+                                       ps.println("if [ ! -d " + subdirectory + " ]; then");\r
+                                       ps.println("    mkdir " + subdirectory);\r
+                                       ps.println("fi;");\r
+                                       ps.println("callthru source $FOLDER/" + applicationName\r
+                                                       + " > " + applicationName);\r
+                                       ps.println("chmod +x " + applicationName);\r
+                                       ps.println();\r
+                                       pList.add(basename);\r
+                               }\r
+                       }\r
+\r
+                       // Load also the main application to the CBE\r
+                       ps.println("# Main program");\r
+                       ps.println("callthru source $FOLDER/ppu_main > ppu_main");\r
+                       ps.println("chmod +x ppu_main");\r
+                       ps.println();\r
+\r
+                       // Run the main program\r
+                       ps.println("# run the main program");\r
+                       ps.println("./ppu_main");\r
+               } catch (Exception e) {\r
+                       System.out.println("CbeMakefileVisitor: exception occured: "\r
+                                       + e.getMessage());\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       protected String _dir = null;\r
+\r
+}\r
diff --git a/dol/src/dol/visitor/cell/CellConstantVisitor.java b/dol/src/dol/visitor/cell/CellConstantVisitor.java
new file mode 100644 (file)
index 0000000..ce7e2a1
--- /dev/null
@@ -0,0 +1,128 @@
+package dol.visitor.cell;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+
+/**
+ * This class is a class for a constant file
+ *
+ * @author lschor, 2008-11-08
+ *
+ * Revision:
+ * 2008-11-08: Created
+ */
+public class CellConstantVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public CellConstantVisitor(String dir, CellMapping mapping) {
+        _dir = dir;
+        _mapping = mapping;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _ui = UserInterface.getInstance();
+            String filename = _dir + _delimiter + "lib" + _delimiter + "constant.h";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            int numSpes = 0;
+
+            for (Process p : x.getProcessList()) {
+                if (p.getNumOfInports() > 0 && p.getNumOfOutports() > 0)
+                    numSpes++;
+            }
+
+            //create header section
+            _mainPS.println("// ========================");
+            _mainPS.println("// constant.h file");
+            _mainPS.println("// ========================");
+
+            // Includes
+            _mainPS.println("#include <stdio.h>");
+
+            // Define the number of FIFO queues and the number of processes
+            _mainPS.println("#ifndef _CONSTANT_H_");
+            _mainPS.println("#define _CONSTANT_H_");
+            _mainPS.println("");
+            _mainPS.println("#define NUM_PROCS " + x.getProcessList().size()
+                + "           // total number of processes");
+            _mainPS.println("#define NUM_PROCS_SPU " + _mapping.getNrSPUProcess()
+                + "       // number of processes to map on the SPU");
+            _mainPS.println("#define NUM_PROCS_PPU " + _mapping.getNrPPUProcess()
+                + "       // number of processes to map to the PPU");
+            _mainPS.println("#define NUM_SPES " + _mapping.getNrSPE()
+                + "            // number of SPE's to be used (PS3 = 6)");
+            _mainPS.println("#define NUM_FIFO " + x.getChannelList().size()
+                + "           // number of FIFOs we use");
+            _mainPS.println("#define FIFO_SIZE_FACTOR 10  "
+                + " // factor to increase the IN-Channels of the PPE");
+            _mainPS.println("#define ALIGNMENT_FACTOR 7   "
+                + " // alignment factor for the DMA transfers (at least 4, "
+                + "7 for optimal performance)");
+            _mainPS.println("#define ALIGNMENT_FACTOR_POWER2 128");
+            _mainPS.println("#define BLOCKED_MAX_NR 5     "
+                + " // number of times a process should wait until "
+                + "resending a request");
+            _mainPS.println("#define STORE_REQUESTS       "
+                + " // defines if one would like to store requests which"
+                + "cannot be worked out currently (see also FastCommunication.cpp)");
+            _mainPS.println("");
+            _mainPS.print("static unsigned long int FIFO_SIZE[NUM_FIFO] = {");
+            for (int indx = 0; indx < x.getChannelList().size(); indx++) {
+                int size = x.getChannelList().elementAt(indx).getSize();
+                if (x.getChannelList().elementAt(indx).getTokenSize() != 0) {
+                    size *= x.getChannelList().elementAt(indx).getTokenSize();
+                }
+                if(indx == x.getChannelList().size() - 1) {
+                    _mainPS.print(size);
+                } else {
+                    _mainPS.print(size + ", ");
+                }
+            }
+
+            _mainPS.println("};  // Size of the FIFOs");
+            _mainPS.println("");
+            _mainPS.println("#endif // _CONSTANT_H_ ");
+        }
+        catch (Exception e) {
+            System.out.println("CellModuleVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param x process that needs to be processed
+     */
+    public void visitComponent(Process x) {
+    }
+
+    /**
+     *
+     * @param x channel that needs to be processed
+     */
+    public void visitComponent(Channel x) {
+    }
+
+    protected CellMapping _mapping;
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/cell/CellMakefileVisitor.java b/dol/src/dol/visitor/cell/CellMakefileVisitor.java
new file mode 100644 (file)
index 0000000..8c7e22e
--- /dev/null
@@ -0,0 +1,130 @@
+package dol.visitor.cell;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Configuration;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate a CBE package
+ * Makefile.
+ */
+public class CellMakefileVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir
+     *            path of the Makefile
+     */
+    public CellMakefileVisitor(String dir, CellMapping mapping) {
+        _dir = dir;
+        _mapping = mapping;
+    }
+
+    /**
+     * Create a Makefile for the given process network.
+     *
+     * @param pn
+     *            process network
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("####################");
+            ps.println("# Main Makefile for the DOL application on the CBE");
+            ps.println("####################");
+            ps.println();
+            ps.println("# Subdirectories");
+
+
+            // Subdirectories of baseprocesses on the SPU
+            String subdirectories = "";
+            Vector<String> pList = new Vector<String>();
+            for (Process process :  _mapping.getAllSpuBaseProcess()) {
+                String basename = process.getBasename();
+                subdirectories += "spu_" + basename + " ";
+            }
+
+            // Directory for the SPU OS'es (only if there are really processes on the SPE!
+            if (_mapping.getNrSPUProcess() > 0)
+                subdirectories += "spu";
+
+            String srcdirectories = "";
+
+            // Subdirectory of baseprocesses on the PPU
+            for (Process process :  _mapping.getAllPPUBaseProcess()) {
+                String basename = process.getBasename();
+                srcdirectories += " $(wildcard ppu_" + basename + "/*.cpp)";
+            }
+
+            // Directory for the PPU OS'es
+            srcdirectories += " $(wildcard ppu/*.cpp)";
+
+            String linkList = "";
+            String srcList = "";
+            for (Process process : _mapping.getAllPPUBaseProcess()) {
+                String basename = process.getBasename();
+                linkList += "ppu_" + basename + "/ppu_" + basename + ".o ";
+                srcList += "$(wildcard ppu_" + basename + "/*.cpp) ";
+            }
+            pList.clear();
+
+            ps.println("DIRS     := " + subdirectories);
+            ps.println("");
+
+            ps.println("# General definitions:");
+            ps.println("CC = ppu-g++");
+            ps.println("CCFLAGS = -ftree-vectorize -O3 -maltivec -funroll-loops -mabi=altivec -mcpu=cell");
+            ps.println("COMPILE = $(CC) $(CCFLAGS) -c");
+            ps.print("LINK = $(CC) -lspe2 -lpthread ");
+            for (Configuration conf : pn.getCfgList()) {
+                if (conf.getName().equals("DYNAMIC_LINK"))
+                    ps.print(conf.getValue() + " ");
+            }
+            ps.println("");
+
+            ps.println("CBE_INCLUDE = /opt/cell/sdk/usr/include");
+            ps.println("LIB_INC = -I lib -I lib/ppu -I lib/pt -I . -I $(CBE_INCLUDE)");
+            ps.println("RM = rm");
+            ps.println("ECHO = echo");
+            ps.println("EXE = sc_application");
+            ps.println("");
+            ps.println("src := $(wildcard lib/ppu/*.cpp) $(wildcard *.cpp)" + srcdirectories);
+            ps.println("srcAll := $(wildcard lib/ppu/*.cpp) $(wildcard *.cpp) " + srcList);
+            ps.println("srcspu := $(wildcard lib/spu/*.cpp) ");
+            ps.println("obj = $(src:.cpp=.o)");
+            ps.println("objspu = $(srcspu:.cpp=.o)");
+            ps.println("");
+            ps.println("$(EXE): $(obj) $(srcAll)");
+            ps.println("\tfor d in $(DIRS); do (cd $$d; $(MAKE) ); done");
+            ps.println("\t$(LINK) -o $(EXE) $(obj)");
+            ps.println("");
+            ps.println("%.o :");
+            ps.println("\t$(COMPILE) -o $(*D)/$(*F).o $(*D)/$(*F).cpp $(LIB_INC)");
+            ps.println("");
+            ps.println("clean:");
+            ps.println("\tfor d in $(DIRS); do (cd $$d; $(MAKE) clean ); done");
+            ps.println("\trm $(objspu)");
+            ps.println("\trm $(obj) ");
+            ps.println("\trm $(EXE)");
+            ps.println("");
+
+        } catch (Exception e) {
+            System.out.println("CbeMakefileVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected CellMapping _mapping;
+}
diff --git a/dol/src/dol/visitor/cell/CellMapping.java b/dol/src/dol/visitor/cell/CellMapping.java
new file mode 100644 (file)
index 0000000..d5421c5
--- /dev/null
@@ -0,0 +1,324 @@
+package dol.visitor.cell;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.mapping.ComputationBinding;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.main.UserInterface;
+import dol.parser.xml.archischema.ArchiXmlParser;
+import dol.parser.xml.mapschema.MapXmlParser;
+
+public class CellMapping {
+
+    /**
+     * Constructor
+     * @param pn
+     */
+    CellMapping(ProcessNetwork pn, String mapping, boolean ppu, int nrSPU) {
+        _pn = pn;
+
+        _maxSPU = nrSPU;
+
+        // Select the mapping
+
+        // Structural mapping
+        if (mapping.compareTo("structural") == 0) {
+            System.out.println("Cell: use structural mapping");
+            structuralMapping(pn, ppu);
+        }
+
+        // Random mapping
+        else if (mapping.compareTo("random") == 0) {
+            System.out.println("Cell: use random mapping");
+            randomMapping(pn, ppu);
+        }
+
+        // Predefined
+        else if (mapping.compareTo("predefined") == 0) {
+            System.out.println("Cell: Use predefined mapping.");
+            System.out.println("      All other parameters are ignored.");
+            predefinedMapping(pn);
+
+            _maxSPU = _SPUList.size();
+            ppu = this._PPU.size() == 0 ? false : true;
+        }
+
+        // All to PPU
+        else if (mapping.compareTo("ppu") == 0) {
+            System.out.println("Cell: Map all processes to the PPU");
+            allPPUMapping(pn);
+        }
+
+        // Default mapping
+        else {
+            System.out.println("WARNING: Cell: use default mapping");
+            structuralMapping(pn, ppu);
+        }
+
+        System.out.println("Cell: Nr of SPE is " + _maxSPU);
+
+        if (ppu) {
+            System.out.println("Cell: Mapped some processes to the PPE");
+        }
+    }
+
+    /**
+     * Returns a list which process is mapped to which spu
+     *
+     * @return the process list
+     */
+    public ArrayList<Vector<Process>> getSPUList() {
+        return _SPUList;
+    }
+
+    /**
+     * Returns list of all processes which are mapped to an spu
+     */
+    public Vector<Process> getAllSpuProcess() {
+        Vector<Process> processList = new Vector<Process>();
+
+        for (Vector<Process> spu : _SPUList) {
+            for (Process p : spu) {
+                processList.add(p);
+            }
+        }
+        return processList;
+    }
+
+    /**
+     * Returns a list of all base processes which occur on the spu's
+     */
+    public Vector<Process> getAllSpuBaseProcess() {
+        Vector<Process> pList = new Vector<Process>();
+        Vector<String> pListName = new Vector<String>();
+        for (Process process : getAllSpuProcess()) {
+            String basename = process.getBasename();
+            if (!pListName.contains(basename)) {
+                pList.add(process);
+                pListName.add(basename);
+            }
+        }
+        return pList;
+    }
+
+    /**
+     * Returns a list of all processes which are mapped to the ppu
+     */
+    public Vector<Process> getPPU() {
+        return _PPU;
+    }
+
+    /**
+     * Returns a list of all base processes which occur on the ppu
+     */
+    public Vector<Process> getAllPPUBaseProcess() {
+        Vector<Process> pList = new Vector<Process>();
+        Vector<String> pListName = new Vector<String>();
+        for (Process process : _PPU) {
+            String basename = process.getBasename();
+            if (!pListName.contains(basename)) {
+                pList.add(process);
+                pListName.add(basename);
+            }
+        }
+        return pList;
+    }
+
+    /**
+     * Return the number of processes which are mapped to the ppu
+     */
+    public int getNrPPUProcess() {
+        return _PPU.size();
+    }
+
+    /**
+     * Returns the number of processes which are mapped to the SPU
+     */
+    public int getNrSPUProcess() {
+        return getAllSpuProcess().size();
+    }
+
+    /**
+     * Returns the number of SPU which are used
+     */
+    public int getNrSPE() {
+        return _SPUList.size();
+    }
+
+    /**
+     * Performs a random mapping of the processes
+     *
+     * @param x
+     *            the process network
+     * @param ppu_choose
+     *            true if the sinks and sources should be mapped to the PPU
+     */
+    protected void randomMapping(ProcessNetwork x, boolean ppu_choose) {
+        ArrayList<Vector<Process>> spu = new ArrayList<Vector<Process>>();
+        Vector<Process> ppu = new Vector<Process>();
+
+        int addSPU = 0;
+        for (Process p : x.getProcessList()) {
+            // A process to map to the PPU
+            if ((p.getNumOfInports() == 0 || p.getNumOfOutports() == 0)
+                    && ppu_choose) {
+                ppu.add(p);
+            }
+
+            // A process to map to the SPU
+            else {
+                // As long as there is a free SPU, add the process to this SPU
+                if (addSPU < _maxSPU) {
+                    Vector<Process> pList = new Vector<Process>();
+                    pList.add(p);
+                    spu.add(pList);
+                }
+
+                // Have to add the process to an already used SPU
+                else {
+                    spu.get(addSPU % _maxSPU).add(p);
+                }
+
+                addSPU++;
+            }
+        }
+
+        _SPUList = spu;
+        _PPU = ppu;
+    }
+
+    /**
+     * Performs a structural mapping of the processes. That means that the
+     * function tries to keep the structural order of the process network. The
+     * order is given depending on the occurrence of the process in the
+     * structure file.
+     *
+     * @param x
+     *            the process network
+     * @param ppu_choose
+     *            true if the sinks and sources should be mapped to the PPU
+     */
+    protected void structuralMapping(ProcessNetwork x, boolean ppu_choose) {
+        ArrayList<Vector<Process>> spu = new ArrayList<Vector<Process>>();
+        Vector<Process> ppu = new Vector<Process>();
+
+        Vector<Process> spu_temp = new Vector<Process>();
+
+        // Each process is allocated to the PPE or the SPE (as general)
+        for (Process p : x.getProcessList()) {
+            // A process to map to the PPU
+            if ((p.getNumOfInports() == 0 || p.getNumOfOutports() == 0)
+                    && ppu_choose) {
+                ppu.add(p);
+            }
+
+            // A process to map to the SPU
+            else {
+                spu_temp.add(p);
+            }
+        }
+
+        System.out.println("Total processes: " + spu_temp.size());
+
+        // Do the structural mapping for all the SPE processes
+        int nrSPUProcess = spu_temp.size();
+        for (int i = 0; i < _maxSPU; i++) {
+
+            if (spu_temp.size() <= 0)
+                break;
+
+            Vector<Process> pList = new Vector<Process>();
+            for (int j = 0; j < Math.ceil(((double) (nrSPUProcess - i))
+                    / _maxSPU); j++) {
+                pList.add(spu_temp.remove(0));
+            }
+
+            spu.add(pList);
+        }
+
+        System.out.println("End Total processes: " + spu_temp.size());
+
+        _SPUList = spu;
+        _PPU = ppu;
+    }
+
+    /**
+     * Maps the processes depending on the architectural and mapping files
+     *
+     * @param x
+     */
+    protected void predefinedMapping(ProcessNetwork x) {
+        // The SPUs
+        ArrayList<Vector<Process>> spu = new ArrayList<Vector<Process>>();
+
+        // The PPU
+        Vector<Process> ppu = new Vector<Process>();
+
+        ArchiXmlParser archParser = new ArchiXmlParser();
+        //System.out.println(_ui.getPlatformFileName());
+        Architecture arch = archParser.doParse(_ui.getPlatformFileName());
+        MapXmlParser mappingParser = new MapXmlParser(x, arch);
+        Mapping mapping = mappingParser.doParse(_ui.getMappingFileName());
+
+        // Go through all process and check where to add
+        for (Process p : x.getProcessList()) {
+            for (ComputationBinding b : mapping.getCompBindList()) {
+                if (b.getProcess().getName().equals(p.getName())) {
+                    // Mapping to PPU
+                    if (b.getProcessor().getName().equals("ppu")) {
+                        System.out.println("Mapped process " + p.getName()
+                                + " to the PPU");
+                        ppu.add(p);
+                    }
+                    // Maps to one of the SPU, they are written in the format
+                    // spu_0, spu_1, ...
+                    else {
+                        int index = Integer.valueOf(b.getProcessor()
+                                .getName().replaceAll(".*_", ""));
+
+                        while (spu.size() <= index) {
+                            Vector<Process> spu_temp = new Vector<Process>();
+                            spu.add(spu_temp);
+                        }
+
+                        spu.get(index).add(p);
+                        System.out.println("Mapped process " + p.getName()
+                                + " to the SPU_" + index);
+                    }
+                }
+            }
+        }
+
+        _SPUList = spu;
+        _PPU = ppu;
+    }
+
+
+    /**
+     * Performs a mapping of all processes to the PPU.
+     *
+     * @param x the process network
+     */
+    protected void allPPUMapping(ProcessNetwork x) {
+        ArrayList<Vector<Process>> spu = new ArrayList<Vector<Process>>();
+        Vector<Process> ppu = new Vector<Process>();
+
+        // Each process is allocated to the PPE or the SPE (as general)
+        for (Process p : x.getProcessList()) {
+            ppu.add(p);
+        }
+
+        _SPUList = spu;
+        _PPU = ppu;
+    }
+
+    protected ArrayList<Vector<Process>> _SPUList = null;
+    protected Vector<Process> _PPU = null;
+    protected ProcessNetwork _pn;
+    protected int _maxSPU = 6;
+    protected UserInterface _ui = UserInterface.getInstance();
+}
diff --git a/dol/src/dol/visitor/cell/CellModuleVisitor.java b/dol/src/dol/visitor/cell/CellModuleVisitor.java
new file mode 100644 (file)
index 0000000..10c700b
--- /dev/null
@@ -0,0 +1,386 @@
+package dol.visitor.cell;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+
+/**
+ * This class is a class for a visitor that is used to generate the main
+ * program.
+ *
+ * @author lschor, 2008-10-30
+ *
+ *         Remarks: Based on a original file from khuang for rtems
+ *
+ *         Revision: 2008-10-30: Updated the file for the CBE 2008-11-08: Add
+ *         double buffering 2008-11-16: Add new fifo implementation and defines
+ *         for measurement 2008-11-21: Sink/Source do not run on the SPE, but on
+ *         the PPE (as Linux thread) 2009-03-17: Added Protothread Support
+ *         2009-04-07: Several modifications, so that one only writes if there
+ *         is enough memory, do not allocate all queues on PPU
+ */
+public class CellModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir
+     *            path of this file
+     */
+    public CellModuleVisitor(String dir, HashMap<Port, Integer> portMap,
+            CellMapping mapping) {
+        _dir = dir;
+        _portMap = portMap;
+        _mapping = mapping;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x
+     *            process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            // Create in a first step the different SPU OS Layers
+            ArrayList<Vector<Process>> spuList = _mapping.getSPUList();
+            Vector<Process> ppu = _mapping.getPPU();
+
+            // Create the main file for the PPU
+            _ui = UserInterface.getInstance();
+            String filename = _dir + _delimiter + "ppu_main.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            // create header section
+            _mainPS.println("// ========================");
+            _mainPS.println("// ppu_main.cpp file");
+            _mainPS.println("// ========================");
+            _mainPS.println("");
+
+            // Includes
+            _mainPS.println("#include \"ppu_main.h\"");
+            _mainPS.println("");
+
+            // Function to create and run one SPE thread
+            _mainPS.println("// create and run one SPE thread");
+            _mainPS.println("void *spu_pthread(void *arg) {");
+            _mainPS.println("    spu_data_t *datp = (spu_data_t *)arg;");
+            _mainPS.println("    uint32_t entry = SPE_DEFAULT_ENTRY;");
+            _mainPS.println("    printf(\")PPE: spe thread start run\\n\" );");
+            _mainPS.println("    if(spe_context_run(datp->spe_ctx,&entry,0,datp->argp,NULL,NULL)<0){");
+            _mainPS.println("        perror (\"Failed running context\"); exit (1);");
+            _mainPS.println("    }");
+            _mainPS.println("    printf(\")PPE: spe thread finish run\\n\");");
+            _mainPS.println("    pthread_exit(NULL);");
+            _mainPS.println("}");
+            _mainPS.println("");
+
+            // Declaration of the Header function for the PPE-Wrappers
+            /*
+             * for (Process p : ppu) { _mainPS.println("void *"+ p.getBasename()
+             * + "_wrapper( void *ptr );"); }
+             */
+            _mainPS.println("void *ppu( void *ptr );");
+            _mainPS.println();
+
+            // Create the port_id and the port_queue_id arrays to send over the
+            // DMA
+            for (Process process : _mapping.getAllSpuProcess()) {
+                String processName = process.getName();
+                _mainPS.println("volatile char " + processName
+                        + "_name[256] __attribute__ ((aligned(16)));");
+            }
+            _mainPS.println();
+
+            // Go through all SPEs
+            for (Vector<Process> spu : spuList) {
+                _mainPS.println("volatile uint64_t spu_"
+                        + spuList.indexOf(spu) + "[" + spu.size()
+                        + "] __attribute__ ((aligned(16)));");
+            }
+            _mainPS.println();
+            _mainPS.println("// The input queue of a process is always on the SPU of the receiver, negative means that the queue is on the PPE");
+            _mainPS.println("volatile int32_t queueOnSPU [NUM_FIFO] __attribute__ ((aligned(16)));");
+            _mainPS.println();
+            _mainPS.println(" // The queue comes from this SPU");
+            _mainPS.println("volatile int32_t queueFromSPU [NUM_FIFO] __attribute__ ((aligned(16)));");
+            _mainPS.println();
+            _mainPS.println(" volatile uint64_t ea_ls_base[NUM_SPES] __attribute__ ((aligned(16)));");
+            _mainPS.println("volatile uint64_t context_addr[NUM_SPES] __attribute__ ((aligned(16)));");
+            _mainPS.println("volatile spe_spu_control_area_t* mfc_ctl[NUM_SPES] __attribute__ ((aligned(16)));");
+            _mainPS.println("volatile uint64_t fifoTails[NUM_FIFO] __attribute__ ((aligned(16)));");
+            _mainPS.println();
+
+            // Create the main function
+            _mainPS.println("int main()");
+            _mainPS.println("{");
+
+            // List with all SPU to be open
+            _mainPS.println("    char spe_names[NUM_SPES][60] = {");
+            for (Vector<Process> spu : spuList) {
+                _mainPS.println("        \"spu/spu_os_" + spuList.indexOf(spu)
+                        + "\",");
+            }
+            _mainPS.println("    };");
+
+            _mainPS.println();
+
+            for (Channel c : x.getChannelList()) {
+                // Search for the origin spe
+                int origin = -1;
+
+                for (Vector<Process> spu : spuList) {
+
+                    if (spu.contains(c.getOrigin())) {
+                        origin = spuList.indexOf(spu);
+                        break;
+                    }
+                }
+
+                // Origin on the PPU
+                if (origin == -1) {
+                    origin = (-1) * (ppu.indexOf(c.getOrigin()) + 1);
+                }
+
+                _mainPS.println("    queueFromSPU["
+                        + x.getChannelList().indexOf(c) + "] = " + origin
+                        + ";");
+            }
+
+            _mainPS.println();
+
+            for (Channel c : x.getChannelList()) {
+                // Search for the origin spe
+                int origin = -1;
+
+                for (Vector<Process> spu : spuList) {
+                    if (spu.contains(c.getTarget())) {
+                        origin = spuList.indexOf(spu);
+                        break;
+                    }
+                }
+
+                // Origin on the PPU
+                if (origin == -1) {
+                    origin = (-1) * (ppu.indexOf(c.getTarget()) + 1);
+                }
+
+                _mainPS.println("    queueOnSPU["
+                        + x.getChannelList().indexOf(c) + "] = " + origin
+                        + ";");
+            }
+
+            _mainPS.println();
+
+            // connect ports to channels
+            HashMap<Channel, Integer> channel_map = new HashMap<Channel, Integer>();
+
+            int j = 0;
+            for (Channel c : x.getChannelList()) {
+                channel_map.put(c, j++);
+            }
+
+            // Add to each process the ports and the queues
+            _mainPS
+                    .println("     //Add to each process the ports and the queues");
+            j = 0;
+
+            // SPU Process
+            for (Process process : _mapping.getAllSpuProcess()) {
+                String processName = process.getName();
+                _mainPS.println("    ctx_proc[" + j + "]"
+                        + ".is_detached = 0;");
+                _mainPS.println("    strcpy((char *)" + processName
+                        + "_name, " + "\"" + processName + "\");");
+                _mainPS.println("    ctx_proc[" + j + "]"
+                        + ".processName = (uint64_t) " + processName
+                        + "_name;");
+                _mainPS.println("    ctx_proc[" + j + "]"
+                        + ".processNameLen = ((strlen((char *)"
+                        + processName + "_name) + 15) & ~15);");
+                _mainPS.println();
+                j++;
+            }
+
+            _mainPS.println("    // Mapping tasks -> What to map to which SPE?");
+            _mainPS.println("    // Example: Square 0-2 to SPE 0 AND Square 3-5 to SPE 1");
+            j = 0;
+            for (Process process : _mapping.getAllSpuProcess()) {
+                for (Vector<Process> spu : spuList) {
+                    if (spu.contains(process)) {
+                        _mainPS.println("    spu_" + spuList.indexOf(spu)
+                                        + "[" + spu.indexOf(process)
+                                        + "] = (uint64_t) &(ctx_proc[" + j
+                                        + "]);");
+                        j++;
+                        break;
+                    }
+                }
+            }
+
+            for (Vector<Process> spu : spuList) {
+                _mainPS.println("    ctx_spu[" + spuList.indexOf(spu)
+                        + "].procContents = (uint64_t) spu_"
+                        + spuList.indexOf(spu) + ";");
+                _mainPS.println("    ctx_spu[" + spuList.indexOf(spu)
+                        + "].procContentsLen = " + spu.size() + ";");
+            }
+
+            _mainPS.println();
+
+            // Init the SPE control structure
+            _mainPS.println("    //Initiate SPEs control structure");
+            _mainPS.println("    int num = 0; ");
+            _mainPS.println("    for( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("        data[num].argp = (void *)&(ctx_spu[num]);");
+            _mainPS.println("    }");
+            _mainPS.println();
+
+            _mainPS.println("    // Loop on all SPEs and for each perform three steps:");
+            _mainPS.println("    // - create SPE context");
+            _mainPS.println("    // - open images of SPE programs into main storage");
+            _mainPS.println("    //         <spe_names> variable store the executable name");
+            _mainPS.println("    // - Load SPEs objects into SPE context local store");
+            _mainPS.println("    for( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("        if ((data[num].spe_ctx = spe_context_create (SPE_MAP_PS, NULL)) == NULL) {");
+            _mainPS.println("            perror(\"Failed creating context\"); exit(1);");
+            _mainPS.println("        }");
+            _mainPS.println("        if (!(program[num] = spe_image_open(&spe_names[num][0]))) {");
+            _mainPS.println("             perror(\"Fail opening image\"); exit(1);");
+            _mainPS.println("        }");
+            _mainPS.println("        if (spe_program_load ( data[num].spe_ctx, program[num])) {");
+            _mainPS.println("            perror(\"Failed loading program\"); exit(1);");
+            _mainPS.println("        }      ");
+            _mainPS.println("    }");
+            _mainPS.println("");
+
+            _mainPS.println("    // update the parameters of each SPE");
+            _mainPS.println("    for( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("        if( (ea_ls_base[num] = (uint64_t)(spe_ls_area_get(data[num].spe_ctx))) == 0) {");
+            _mainPS.println("            perror(\"Failed map LS to main storage\"); exit(1);");
+            _mainPS.println("        }");
+            _mainPS.println("        ctx_spu[num].ea_base = ea_ls_base[num];");
+            _mainPS.println("        context_addr[num] = (uint64_t)data[num].spe_ctx;");
+            _mainPS.println("    }");
+
+            _mainPS.println("    for (num=0; num<NUM_SPES; num++) {");
+            _mainPS.println("        if ((mfc_ctl[num] = (spe_spu_control_area_t*) spe_ps_area_get(data[num].spe_ctx, SPE_CONTROL_AREA))==NULL){");
+            _mainPS.println("            perror(\"Failed mapping MFC control area\"); exit(1);");
+            _mainPS.println("        }");
+            _mainPS.println("    }");
+            _mainPS.println("    ");
+
+            _mainPS.println("    for (num=0; num<NUM_SPES; num++) {");
+            _mainPS.println("        ctx_spu[num].queueFromSPU = (uint64_t) queueFromSPU;");
+            _mainPS.println("        ctx_spu[num].queueOnSPU = (uint64_t) queueOnSPU;");
+            _mainPS.println("        ctx_spu[num].procContentsAll = (uint64_t) mfc_ctl;");
+            _mainPS.println("        ctx_spu[num].fifoTails = (uint64_t) fifoTails;");
+            _mainPS.println("    }");
+            _mainPS.println("");
+            _mainPS.println("// This is the PPU");
+            _mainPS.println("    ProcessData *ppu_Process_Wrapper = (ProcessData *)malloc(sizeof(ProcessData));");
+            _mainPS.println("    ppu_Process_Wrapper->procContentsAll = (uint64_t *) context_addr;");
+            _mainPS.println("    ppu_Process_Wrapper->queueFromSPU = (int32_t *)queueFromSPU;");
+            _mainPS.println("    ppu_Process_Wrapper->queueOnSPU = (int32_t *)queueOnSPU;");
+            _mainPS.println("    ppu_Process_Wrapper->ea_ls_base = (uint64_t *)ea_ls_base;");
+            _mainPS.println("    ppu_Process_Wrapper->fifoTails = (uint64_t *) fifoTails;");
+            _mainPS.println("    ");
+
+            _mainPS.println("    // create SPE pthreads");
+            _mainPS.println("    for( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("        if(pthread_create(&data[num].pthread,NULL,&spu_pthread, &data[num])){");
+            _mainPS.println("            perror(\"Failed creating thread\");  exit(1);");
+            _mainPS.println("        }");
+            _mainPS.println("    }");
+            _mainPS.println("    ");
+            _mainPS.println("    // create PPE pthreads");
+            _mainPS.println("    pthread_t thread_ppu;");
+            _mainPS.println("    pthread_create( &thread_ppu, NULL, ppu, ppu_Process_Wrapper);");
+            _mainPS.println("    ");
+
+            _mainPS.println();
+            _mainPS.println("    // Loop on all SPEs and for each perform two steps:");
+            _mainPS.println("    //   - wait for all the SPE pthread to complete");
+            _mainPS.println("    //   - destroy the SPE contexts");
+            _mainPS.println("    for( num=0; num<NUM_SPES; num++){");
+            _mainPS.println("        if(pthread_join (data[num].pthread, NULL)) {");
+            _mainPS.println("            perror(\"Failed joining thread\"); exit (1);");
+            _mainPS.println("        }");
+            _mainPS.println("        ");
+            _mainPS.println("        if (spe_context_destroy( data[num].spe_ctx   )) {");
+            _mainPS.println("            perror(\"Failed spe_context_destroy\"); exit(1);");
+            _mainPS.println("        }");
+            _mainPS.println("    }");
+            _mainPS.println("    ");
+            _mainPS.println("    // Join with PPU");
+            _mainPS.println("    if(pthread_join (thread_ppu, NULL)) {");
+            _mainPS.println("        perror(\"Failed joining thread\"); exit (1);");
+            _mainPS.println("    }");
+            _mainPS.println("    ");
+            _mainPS.println("    printf(\")PPE:) Complete running all super-fast SPEs and PPE\\n\");");
+            _mainPS.println("");
+
+            _mainPS.println("    return (0);");
+            _mainPS.println("}");
+        } catch (Exception e) {
+            System.out.println("CellModuleVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param x
+     *            process that needs to be processed
+     */
+    public void visitComponent(Process x) {
+    }
+
+    /**
+     *
+     * @param x
+     *            channel that needs to be processed
+     */
+    public void visitComponent(Channel x) {
+    }
+
+    /**
+     * Round the parameter to the next DMA-number up. Example: 23 gives 32.
+     *
+     * @param number
+     *            number to round up
+     * @return next DMA-number
+     */
+    protected int roundDMA(int number) {
+        if (number > 16)
+            return number + 16 - (number % 16);
+        else if (number > 8)
+            return 16;
+        else if (number > 4)
+            return 8;
+        else if (number > 2)
+            return 4;
+        else if (number > 1)
+            return 2;
+        else
+            return 1;
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected HashMap<Port, Integer> _portMap;
+    protected CellMapping _mapping;
+
+}
diff --git a/dol/src/dol/visitor/cell/CellPPEVisitor.java b/dol/src/dol/visitor/cell/CellPPEVisitor.java
new file mode 100644 (file)
index 0000000..e283fa6
--- /dev/null
@@ -0,0 +1,421 @@
+package dol.visitor.cell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+public class CellPPEVisitor extends PNVisitor {
+    /**
+     * Constructor.
+     *
+     * @param dir
+     *            path of this file
+     */
+    public CellPPEVisitor(String dir, CellMapping mapping) {
+        _dir = dir;
+        _mapping = mapping;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x
+     *            process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            // Create a directory for the OS Layer:
+            _ppuDir = _dir + _delimiter + "ppu";
+            File dir = new File(_ppuDir);
+            dir.mkdirs();
+
+            // Copy the header file to this directory
+            // Some library files must be copied to the main directory
+            (new File(_dir + _delimiter + "lib" + _delimiter + "ppu_os.h"))
+                    .renameTo(new File(dir.getPath() + _delimiter
+                            + "spu_os.h"));
+
+            createOSLayer(x, _mapping.getPPU());
+
+            createMakefilePPU();
+        } catch (Exception e) {
+            System.out.println("CellPPEVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Creates the OS layer for one SPU
+     *
+     * @param spu
+     *            List of all processes a SPU gets
+     * @param index
+     *            index of the SPU in the SPU list
+     */
+    protected void createOSLayer(ProcessNetwork x, Vector<Process> ppu) {
+        try {
+            // Create the filename for the new layer
+            String filename = _ppuDir + _delimiter + "ppu_os.cpp";
+
+            // PrintStream for writing to the file
+            OutputStream file = new FileOutputStream(filename);
+            CodePrintStream _code = new CodePrintStream(file);
+
+            _code = new CodePrintStream(file);
+
+            _code.printPrefixln("#include \"pt.h\"");
+            _code.printPrefixln("#include \"Fifo.h\"");
+            _code.printPrefixln("#include \"WindowedFifo.h\"");
+            _code.printPrefixln("#include \"FastCommunication.h\"");
+            _code.printPrefixln("#include \"common_ppu.h\"");
+            _code.printPrefixln("#include \"common.h\"");
+            for (Process p : ppu) {
+                _code.printPrefixln("#include \".." + _delimiter + "ppu_"
+                        + p.getBasename() + _delimiter + p.getBasename()
+                        + "Wrapper.h\"");
+            }
+
+            _code.println();
+            _code.printPrefixln("void *ppu( void *ptr )");
+            _code.printLeftBracket();
+
+            // instantiate channels
+            Vector<Channel> channelList = new Vector<Channel>();
+            int indx = 0;
+            for (Channel c : x.getChannelList()) {
+                if (ppu.contains(c.getOrigin())
+                        || ppu.contains(c.getTarget())) {
+                    channelList.add(c);
+
+                    if (c.getType().equals("fifo")) {
+                        // This is a IN-Channel --> Add an additional Factor to increase the speed
+                        if (ppu.contains(c.getTarget()) && !ppu.contains(c.getOrigin())) {
+                            _code.printPrefixln("Fifo " + c.getName()
+                                    + "(FIFO_SIZE[" + indx +"] * FIFO_SIZE_FACTOR);");
+                        // OUT-Channel --> Do not add any factor as we like to stall sometimes
+                        } else {
+                            _code.printPrefixln("Fifo " + c.getName()
+                                + "(FIFO_SIZE[" + indx + "]);");
+                        }
+                    } else if (c.getType().equals("wfifo")) {
+                        _code.printPrefixln("WindowedFifo " + c.getName()
+                                + "(FIFO_SIZE[" + indx + "]);");
+                    }
+                }
+               indx++;
+            }
+            _code.println();
+
+            // instantiate processes
+            for (Process p : ppu) {
+                _code.printPrefix("int " + p.getName() + "Indices[] = { ");
+                Vector<Integer> iteratorIndex = p.getIteratorIndices();
+                if (iteratorIndex.size() < 4) {
+                    while (iteratorIndex.size() < 4) {
+                        iteratorIndex.add(-1);
+                    }
+                } else if (iteratorIndex.size() > 4) {
+                    new RuntimeException("Error: Currently not more than "
+                            + "4 iterator dimensions are supported."
+                            + "Consider revising " + p.getBasename() + ".");
+                }
+                for (int i = 0; i < 4; i++) {
+                    if (i < 3) {
+                        _code.print(iteratorIndex.elementAt(i) + ", ");
+                    } else {
+                        _code.println(iteratorIndex.elementAt(i) + " };");
+                    }
+                }
+                _code.println();
+               _code.printPrefixln(p.getBasename() + "Wrapper *" + p.getName() + ";");
+                _code.printPrefixln("try { " 
+                        + p.getName() + " = new " + p.getBasename()
+                        + "Wrapper(\"" + p.getName() + "\", "
+                        + p.getName() + "Indices); }");
+               _code.println("    catch(std::bad_alloc &e) {");
+               _code.println("        fprintf(stderr, \"[" + p.getBasename() +"Wrapper] Memory allocation failure\\n\");");
+               _code.println("        exit(1);");
+               _code.println("    }");
+            }
+            _code.println();
+
+            // connect the network
+            for (Process p : ppu) {
+                for (Port port : p.getPortList()) {
+                    if (port.getName().equals(port.getBasename())) {
+                        _code.printPrefixln(p.getName() + "->_port"
+                                + port.getName() + "Fifo = &"
+                                + port.getPeerResource().getName() + ";");
+                    } else {
+                        _code.printPrefix(p.getName() + "->_port"
+                                + port.getBasename() + "Fifo");
+                        StringTokenizer tokenizer = new StringTokenizer(
+                                port.getName().replaceFirst(
+                                        port.getBasename(), ""), "_");
+                        while (tokenizer.hasMoreTokens()) {
+                            _code.print("[" + tokenizer.nextToken() + "]");
+                        }
+                        _code.println(" = &"
+                                + port.getPeerResource().getName() + ";");
+                    }
+                }
+            }
+            _code.println();
+
+            /**************************************************************************/
+            // This is the synchronisation code
+            _code.println("    for (int i = 0; i < NUM_FIFO; i++)");
+            _code.println("        ((ProcessData *)ptr)->fifoTails[i] = 0;");
+            _code.println("    ");
+
+            int outQueues = 0;
+
+            // Check all out queues on the SPU
+            for (Channel c : x.getChannelList()) {
+
+                // Check all SPUs
+                for (Vector<Process> spu : _mapping.getSPUList()) {
+                    if (spu.contains(c.getOrigin()) && !spu.contains(c.getTarget())) {
+                        outQueues++;
+                    }
+                }
+
+                // Check the PPU
+                if (ppu.contains(c.getOrigin()) && !ppu.contains(c.getTarget())) {
+                    outQueues++;
+                }
+            }
+
+            // On how much queues we have to wait
+            _code.println("    uint32_t nrOutQueues = NUM_FIFO;");
+            _code.println("    uint32_t countOutQueues = 0;");
+            _code.println("    uint32_t processNr = 0;");
+            _code.println("    uint32_t message;");
+            _code.println("");
+
+            // Add all out queues of the PPE
+
+            for (Channel c : channelList) {
+                if (ppu.contains(c.getOrigin()) && !ppu.contains(c.getTarget())) {
+                    _code.println("    ((ProcessData *)ptr)->fifoTails[" + x.getChannelList().indexOf(c) + "] = (uint64_t) " + c.getName() + ".getQueuePointer();");
+                    _code.println("    countOutQueues++;");
+                }
+            }
+
+            // Check to get all messages back
+            _code.println("    ");
+            _code.println("    // Get the offset of the queues");
+            _code.println("    while (countOutQueues < nrOutQueues) {");
+            _code.println("        for (processNr = 0; processNr < NUM_SPES; processNr++) {");
+            _code.println("            if (!spe_out_mbox_status((spe_context*)((ProcessData *)ptr)->procContentsAll[processNr])) continue;");
+            _code.println("            ");
+            _code.println("            spe_out_mbox_read((spe_context*)((ProcessData *)ptr)->procContentsAll[processNr], &message, 1);");
+            _code.println("            ");
+            _code.println("            uint32_t queue = ((message >> 24) & 0xFF);");
+            _code.println("            uint32_t offset = ((message >> 0) & 0xFFFFFF);");
+            _code.println("            ");
+            _code.println("            if (((ProcessData *)ptr)->queueOnSPU[queue] < 0)");
+            _code.println("                ((ProcessData *)ptr)->fifoTails[queue] = offset;  // Only the offset if the PPE needs to access the data");
+            _code.println("            else");
+            _code.println("                ((ProcessData *)ptr)->fifoTails[queue] = offset + ((ProcessData *)ptr)->ea_ls_base[processNr];");
+            _code.println("            countOutQueues++;");
+            _code.println("        }");
+            _code.println("    }");
+            _code.println("    ");
+
+            // Send a message that each SPE knows that he can access the list
+            _code.println("    // Send the Okay to all SPEs for that they can start reading the tail pointers of the fifos");
+            _code.println("    message = MSG_OK;");
+            _code.println("    for (processNr = 0; processNr < NUM_SPES; processNr++) {");
+            _code.println("        spe_in_mbox_write((spe_context*)((ProcessData *)ptr)->procContentsAll[processNr], (uint32_t*)&message, 1, SPE_MBOX_ANY_NONBLOCKING);");
+            _code.println("    }");
+
+            /**************************************************************************/
+
+            // initialize processes
+            for (Process p : ppu) {
+                _code.printPrefixln(p.getName() + "->init();");
+            }
+            _code.println();
+
+            // Count the effected channels
+            int countChannels = 0;
+            for (Channel c : channelList) {
+                if (ppu.contains(c.getOrigin())
+                        && ppu.contains(c.getTarget())) {
+                    continue;
+                } else if (ppu.contains(c.getOrigin()))
+                    countChannels++;
+                else if (ppu.contains(c.getTarget()))
+                    countChannels++;
+                else
+                    System.out.println("ERROR! Channel Mapping is wrong.");
+            }
+
+
+            _code.println("    FastCommunication * com;");
+            _code
+                    .println("    try { com = new FastCommunication("
+                            + countChannels
+                            + ", ((ProcessData *)ptr)->procContentsAll, ((ProcessData *)ptr)->ea_ls_base, ((ProcessData *)ptr)->queueFromSPU, ((ProcessData *)ptr)->queueOnSPU, ((ProcessData *)ptr)->fifoTails); }");
+           _code.println("    catch(std::bad_alloc &e) {");
+           _code.println("        fprintf(stderr, \"[FastCommunication] Memory allocation failure\\n\");");
+           _code.println("        exit(1);");
+           _code.println("    }");
+
+            String channelTyp = "";
+            int i = 0;
+            for (Channel c : channelList) {
+                if (ppu.contains(c.getOrigin())
+                        && ppu.contains(c.getTarget())) {
+                    // Local channels have no influence on external
+                    // communication (should be Windowed Fifos...)
+                    channelTyp = "local";
+                    continue;
+                } else if (ppu.contains(c.getOrigin())) {
+                    channelTyp = "out";
+                } else if (ppu.contains(c.getTarget())) {
+                    channelTyp = "in";
+                } else {
+                    System.out.println("ERROR! Channel Mapping is wrong.");
+                }
+
+                if (c.getType().equals("fifo")) {
+                    _code.println("    com->addFifo(" + (i) + ", &"
+                            + c.getName() + ", com->" + channelTyp + ", "
+                            + x.getChannelList().indexOf(c) + ");");
+                } else if (c.getType().equals("wfifo")) {
+                    _code.println("    com->addWFifo(" + (i) + ", &"
+                            + c.getName() + ", com->" + channelTyp + ", "
+                            + x.getChannelList().indexOf(c) + ");");
+                }
+                i++;
+            }
+
+            _code.printPrefixln("bool allBlocked = false;");
+            _code.printPrefixln("while(!allBlocked)");
+            _code.printLeftBracket();
+            _code.printPrefixln("allBlocked = true;");
+            for (Process p : ppu) {
+                _code.printPrefixln("if (!" + p.getName()
+                        + "->isDetached()) {");
+                _code.printPrefixln("    " + p.getName() + "->fire();");
+                _code.printPrefixln("    allBlocked = false;");
+                _code.printPrefixln("}");
+                _code.printPrefixln("");
+
+
+
+                // Communication only if this process needs some communication
+                for (Channel c : channelList) {
+                    // The channel may goes away
+                    if (!ppu.contains(c.getOrigin()) || !ppu.contains(c.getTarget())) {
+                        if (c.getOrigin().equals(p) || c.getTarget().equals(p)) {
+                            _code.printPrefixln("com->update();");
+                            _code.printPrefixln("");
+                            break;
+                        }
+                    }
+                }
+
+            }
+            _code.printRightBracket();
+            _code.println();
+
+            _code.println();
+            _code.println("    // Are there any open communication requests?");
+            _code.println("    while (!com->empty())");
+            _code.println("    {");
+            _code.println("        com->update();");
+            _code.println("    }");
+            _code.println("    ");
+            _code.println("    // Send all SPUs the complete message");
+            _code.println("    message = MSG_OK;");
+            _code.println("    for (processNr = 0; processNr < NUM_SPES; processNr++) {");
+            _code.println("        spe_in_mbox_write((spe_context*)((ProcessData *)ptr)->procContentsAll[processNr], (uint32_t*)&message, 1, SPE_MBOX_ANY_NONBLOCKING);");
+            _code.println("    }");
+            _code.println("");
+            for (Process p : ppu) {
+                _code.printPrefixln("delete " + p.getName() + ";");
+            }
+            _code.printPrefixln("delete com;");
+            _code.println();
+            _code.printPrefixln("pthread_exit(NULL);");
+            _code.printRightBracket();
+        } catch (Exception e) {
+            System.out.println("ProtothreadModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void createMakefilePPU() {
+        try {
+            // Directory of the process
+            String ppuDir = _dir + _delimiter + "ppu";
+
+            // Create the filename for the new wrapper
+            String filename = ppuDir + _delimiter + "Makefile";
+
+            OutputStream file = new FileOutputStream(filename);
+
+            PrintStream _makefilePS = new CodePrintStream(file);
+
+            _makefilePS.println("# Makefile for PPU OS");
+            _makefilePS.println("");
+            _makefilePS.println("src := $(wildcard ../lib/ppu/*.cpp)");
+            _makefilePS.println("obj = $(src:.cpp=.o)");
+            _makefilePS.println("");
+
+            // The Makefile must include all o-Files of the processes needed
+            String dependency = "";
+
+            // Go through all possible processes
+            for (Process p : _mapping.getAllPPUBaseProcess()) {
+                dependency += " .." + _delimiter + "ppu_"
+                        + p.getBasename() + _delimiter + p.getBasename()
+                        + "Wrapper.o";
+            }
+
+            _makefilePS.println("all: ${obj}");
+            _makefilePS
+                    .println("\tppu-g++ -c -I .. -I ../lib -I ../lib/pt -I ../lib/ppu -o ppu_os.o ppu_os.cpp -ftree-vectorize -lm -mtune=cell -O3 -fmodulo-sched -funroll-loops -ffast-math");
+
+            _makefilePS.println();
+            _makefilePS.println("clean: ");
+            _makefilePS.println("\trm ppu_os");
+
+            _makefilePS.println();
+            _makefilePS.println("%.o : ");
+            _makefilePS
+                    .println("\tppu-g++ -c -o $(*D)/$(*F).o $(*D)/$(*F).cpp -I .. -I ../lib -I ../lib/pt -I ../lib/ppu  -ftree-vectorize -lm -mtune=cell -O3 -fmodulo-sched -funroll-loops -ffast-math");
+            _makefilePS.println();
+
+        } catch (FileNotFoundException e) {
+            System.out.println("CbeProcessVisitor - Makefile: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _ppuDir = null;
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected CellMapping _mapping = null;
+
+}
diff --git a/dol/src/dol/visitor/cell/CellProcessVisitor.java b/dol/src/dol/visitor/cell/CellProcessVisitor.java
new file mode 100644 (file)
index 0000000..a0c70e4
--- /dev/null
@@ -0,0 +1,652 @@
+package dol.visitor.cell;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.visitor.PNVisitor;
+import dol.util.CodePrintStream;
+import dol.util.Copier;
+import dol.util.Sed;
+
+/**
+ * This class is a class for a visitor that is used to generate the main
+ * makefile for the application.
+ * 
+ * @author lschor, 2008-10-30
+ * 
+ *         Remarks: Based on a original file from wolferl for rtems
+ * 
+ *         Revision: 2008-10-30: Updated the file for the CBE 2008-11-08: Add
+ *         double buffering 2009-03-17: Add protothreads
+ */
+public class CellProcessVisitor extends PNVisitor {
+
+       /**
+        * Constructor.
+        * 
+        * @param dir
+        *            target directory
+        */
+       public CellProcessVisitor(String dir, HashMap<Port, Integer> portMap,
+                       CellMapping mapping) {
+               _dir = dir;
+               _portMap = portMap;
+               _mapping = mapping;
+       }
+
+       /**
+        * 
+        * @param x
+        *            process network that needs to be processed
+        */
+       public void visitComponent(ProcessNetwork x) {
+               try {
+                       // Create the Process staff for all processes on the SPU
+                       for (Process p : _mapping.getAllSpuBaseProcess()) {
+                               createSPEWrapper(p);
+                               createMakefileProcess(p);
+                               _adaptSources("spu_" + p.getBasename(), p);
+                       }
+
+                       // Create the Process staff for all processes on the SPU
+                       for (Process p : _mapping.getAllPPUBaseProcess()) {
+                               createPPEWrapper(p);
+                       }
+               } catch (Exception e) {
+                       System.out.println("CellProcessVisitor: exception "
+                                       + "occured: " + e.getMessage());
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Creates a Wrapper for an SPE process
+        * 
+        * @param p
+        *            process that needs to be processed
+        */
+       protected void createSPEWrapper(Process p) {
+               try {
+
+                       // Create of each process an own folder
+                       // Insert into this folder the source, the wrapper and a makefile
+                       String processDir = _dir + _delimiter + "spu_"
+                                       + p.getBasename();
+                       File dir = new File(processDir);
+                       dir.mkdirs();
+
+                       /***************** class File ******************************/
+
+                       // Create the filename for the new wrapper
+                       String filename = processDir + _delimiter + p.getBasename()
+                                       + "Wrapper.cpp";
+                       File process_file = new File(filename);
+                       File pattern_file = new File(_dir + _delimiter + _tempDirName
+                                       + _delimiter + "spu_process_wrapper_template.cpp");
+                       new Copier().copyFile(pattern_file, process_file);
+
+                       String includes = "";
+                       for (SourceCode code : p.getSrcList()) {
+                               includes += "#include \"" + code.getLocality() + "\""
+                                               + System.getProperty("line.separator");
+                       }
+
+                       Sed sed = new Sed();
+                       // Replace the include of the main c-file
+                       sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
+                       // Replace the process-name in the whole file
+                       sed.sed(filename, "@PROCESSNAME@", p.getBasename());
+                       sed.sed(filename, "@PROCESSNAME_UPPER@", p.getBasename()
+                                       .substring(0, 1).toUpperCase()
+                                       + p.getBasename().substring(1));
+
+                       /***************** header File ******************************/
+                       // Create the filename for the new wrapper
+                       filename = processDir + _delimiter + p.getBasename()
+                                       + "Wrapper.h";
+                       process_file = new File(filename);
+                       pattern_file = new File(_dir + _delimiter + _tempDirName
+                                       + _delimiter + "spu_process_wrapper_template.h");
+                       new Copier().copyFile(pattern_file, process_file);
+
+                       includes = "";
+                       for (SourceCode code : p.getSrcList()) {
+                               includes += "#include \"" + code.getLocality() + "\""
+                                               + System.getProperty("line.separator");
+                       }
+
+                       sed = new Sed();
+                       // Replace the include of the main c-file
+                       sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
+                       // Replace the process-name in the whole file
+                       sed.sed(filename, "@PROCESSNAME@", p.getBasename());
+
+                       // Create the correct Port and Fifo List
+                       String fifolist = "";
+                       Vector<String> basenames = new Vector<String>();
+                       for (Port port : p.getPortList()) {
+                               if (!basenames.contains(port.getBasename())) {
+                                       basenames.add(port.getBasename());
+                               } else {
+                                       continue;
+                               }
+
+                               Channel c = (Channel) port.getPeerResource();
+                               if (port.getName().equals(port.getBasename())) {
+                                       if (c.getType().equals("fifo")) {
+                                               fifolist += "Fifo* _port" + port.getName()
+                                                               + "Fifo;";
+                                       } else if (c.getType().equals("wfifo")) {
+                                               fifolist += "WindowedFifo* _port" + port.getName()
+                                                               + "Fifo;";
+                                       }
+                               } else {
+                                       if (c.getType().equals("fifo")) {
+                                               fifolist += "Fifo* _port" + port.getBasename()
+                                                               + "Fifo";
+                                       } else if (c.getType().equals("wfifo")) {
+                                               fifolist += "WindowedFifo* _port"
+                                                               + port.getBasename() + "Fifo";
+                                       }
+                                       StringTokenizer tokenizer = new StringTokenizer(port
+                                                       .getRange(), ";");
+                                       while (tokenizer.hasMoreTokens()) {
+                                               fifolist += "[" + tokenizer.nextToken() + "]";
+                                       }
+                                       fifolist += ";";
+                               }
+                       }
+
+                       // Set the correct Fifo's
+                       sed.sed(filename, "@FIFO@", fifolist);
+
+                       /***************** source File ******************************/
+
+                       // Go through all source files
+                       for (SourceCode sourceCode : p.getSrcList()) {
+                               // Copy the files to the new folder
+                               String oldFilename = _dir
+                                               + _delimiter
+                                               + sourceCode.getLocality().replaceAll(
+                                                               "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+                               filename = processDir
+                                               + _delimiter
+                                               + sourceCode.getLocality().replaceAll(
+                                                               "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                               if (new File(filename).exists()) {
+                                       new File(filename).delete();
+                               }
+
+                               new File(oldFilename).renameTo(new File(filename));
+
+                               // Copy also the c-files
+                               if ((oldFilename.substring(oldFilename.length() - 2))
+                                               .equals(".h")) {
+                                       String newFileNameC = filename.substring(0, filename
+                                                       .length() - 2)
+                                                       + ".c";
+                                       if (new File(newFileNameC).exists()) {
+                                               new File(newFileNameC).delete();
+                                       }
+                                       // new Copier().copyFile(new File(oldFilename.substring(0,
+                                       // oldFilename.length() - 2) + ".c"), new
+                                       // File(filename.substring(0, filename.length() - 2) +
+                                       // ".c"));
+                                       new File(oldFilename.substring(0,
+                                                       oldFilename.length() - 2)
+                                                       + ".c").renameTo(new File(newFileNameC));
+                               }
+
+                               // Update the files for the DOL project
+                               sed.sed(filename, "<dol.h>", "\"dol.h\"");
+
+                       }
+               } catch (Exception e) {
+                       System.out.println("CbeProcessVisitor: exception "
+                                       + "occured: " + e.getMessage());
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Creates a Wrapper for a PPE process
+        * 
+        * @param p
+        *            process that needs to be processed
+        */
+       protected void createPPEWrapper(Process p) {
+               try {
+                       // Create of each process an own folder
+                       // Insert into this folder the source, the wrapper and a makefile
+                       String processDir = _dir + _delimiter + "ppu_"
+                                       + p.getBasename();
+                       File dir = new File(processDir);
+                       dir.mkdirs();
+
+                       // Go through all source files
+                       for (SourceCode sourceCode : p.getSrcList()) {
+                               // Copy the files to the new folder
+                               String oldFilename = _dir
+                                               + _delimiter
+                                               + sourceCode.getLocality().replaceAll(
+                                                               "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+                               String filename = processDir
+                                               + _delimiter
+                                               + sourceCode.getLocality().replaceAll(
+                                                               "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                               if (new File(filename).exists()) {
+                                       new File(filename).delete();
+                               }
+
+                               new File(oldFilename).renameTo(new File(filename));
+
+                               // Copy also the c-files
+                               if ((oldFilename.substring(oldFilename.length() - 2))
+                                               .equals(".h")) {
+                                       String newFileNameC = filename.substring(0, filename
+                                                       .length() - 2)
+                                                       + ".c";
+                                       if (new File(newFileNameC).exists()) {
+                                               new File(newFileNameC).delete();
+                                       }
+                                       new File(oldFilename.substring(0,
+                                                       oldFilename.length() - 2)
+                                                       + ".c").renameTo(new File(newFileNameC));
+                               }
+                       }
+
+                       _createPPECppFile(dir, p);
+                       _createPPEHeaderFile(dir, p);
+                       _adaptSources("ppu_" + p.getBasename(), p);
+                       createMakeFilePPUProcess("ppu_" + p.getBasename(), p);
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+     *
+     */
+       private void _createPPECppFile(File dir, Process p) throws IOException {
+               String classname = p.getBasename() + "Wrapper";
+               String filename = dir + _delimiter + classname + ".cpp";
+               OutputStream file = new FileOutputStream(filename);
+               CodePrintStream ps = new CodePrintStream(file);
+
+               ps.printPrefixln("#include \"" + classname + ".h\"");
+               ps.printPrefixln("#include \"dolSupport.h\"");
+               ps.printPrefixln("#include <string.h>");
+               ps.println();
+               for (SourceCode sr : p.getSrcList()) {
+                       ps.printPrefixln("#include \"" + sr.getLocality() + "\"");
+               }
+               ps.println();
+               ps.printPrefixln(classname + "::" + classname
+                               + "(char* name, int iteratorIndex[4]) :");
+               ps.printPrefixln("        ProcessWrapper(name, iteratorIndex)");
+               ps.printLeftBracket();
+               ps.printPrefixln("_state = (LocalState)new "
+                               + p.getBasename().substring(0, 1).toUpperCase()
+                               + p.getBasename().substring(1) + "_State;");
+               ps.printPrefixln("_process.init = " + p.getBasename() + "_init;");
+               ps.printPrefixln("_process.fire = " + p.getBasename() + "_fire;");
+               ps.printPrefixln("_process.local = _state;");
+               ps.printPrefixln("_process.wptr = (void*)&_wrapper_data;");
+               ps.printPrefixln("_wrapper_data.wrapper = this;");
+               ps.printRightBracket();
+               ps.println();
+               ps.printPrefixln(classname + "::~" + classname + "()");
+               ps.printLeftBracket();
+               ps.printPrefixln("if (_state)");
+               ps.printPrefixln("    delete ("
+                               + p.getBasename().substring(0, 1).toUpperCase()
+                               + p.getBasename().substring(1) + "_State*)_state;");
+               // ps.printPrefixln("    delete _state;");
+               ps.printRightBracket();
+       }
+
+       /**
+     *
+     */
+       private void _createPPEHeaderFile(File dir, Process p)
+                       throws IOException {
+               String classname = p.getBasename() + "Wrapper";
+               String filename = dir + _delimiter + classname + ".h";
+               OutputStream file = new FileOutputStream(filename);
+               CodePrintStream ps = new CodePrintStream(file);
+
+               ps.printPrefixln("#ifndef " + classname.toUpperCase() + "_H");
+               ps.printPrefixln("#define " + classname.toUpperCase() + "_H");
+               ps.println();
+               ps.printPrefixln("#include \"ProcessWrapper.h\"");
+               ps.printPrefixln("#include \"Fifo.h\"");
+               ps.printPrefixln("#include \"WindowedFifo.h\"");
+               ps.println();
+               ps.printPrefixln("class " + classname + ";");
+               ps.println();
+               ps.printPrefixln("typedef struct _" + p.getBasename() + "_data {");
+               ps.printPrefixln("    int lc;");
+               ps.printPrefixln("    " + classname + " *wrapper;");
+               ps.printPrefixln("} " + p.getBasename() + "_data;");
+               ps.println();
+               ps
+                               .printPrefixln("class " + classname
+                                               + " : public ProcessWrapper");
+               ps.printLeftBracket();
+               ps.printPrefixln("public:");
+               ps.printPrefixln("    " + classname + "(char* name, "
+                               + "int iteratorIndex[4]);");
+               ps.printPrefixln("    virtual ~" + classname + "();");
+               ps.println();
+
+               Vector<String> basenames = new Vector<String>();
+               for (Port port : p.getPortList()) {
+                       if (!basenames.contains(port.getBasename())) {
+                               basenames.add(port.getBasename());
+                       } else {
+                               continue;
+                       }
+
+                       Channel c = (Channel) port.getPeerResource();
+                       if (port.getName().equals(port.getBasename())) {
+                               if (c.getType().equals("fifo")) {
+                                       ps.printPrefixln("    Fifo* _port" + port.getName()
+                                                       + "Fifo;");
+                               } else if (c.getType().equals("wfifo")) {
+                                       ps.printPrefixln("    WindowedFifo* _port"
+                                                       + port.getName() + "Fifo;");
+                               }
+                       } else {
+                               if (c.getType().equals("fifo")) {
+                                       ps.printPrefix("    Fifo* _port" + port.getBasename()
+                                                       + "Fifo");
+                               } else if (c.getType().equals("wfifo")) {
+                                       ps.printPrefix("    WindowedFifo* _port"
+                                                       + port.getBasename() + "Fifo");
+                               }
+                               StringTokenizer tokenizer = new StringTokenizer(port
+                                               .getRange(), ";");
+                               while (tokenizer.hasMoreTokens()) {
+                                       ps.print("[" + tokenizer.nextToken() + "]");
+                               }
+                               ps.println(";");
+                       }
+               }
+               ps.println("");
+               ps.printPrefixln("protected:");
+               ps.printPrefixln("    struct _local_states *_state;");
+               ps
+                               .printPrefixln("    " + p.getBasename()
+                                               + "_data _wrapper_data;");
+               ps.printRightBracket();
+
+               ps.printPrefixln(";");
+               ps.println();
+               ps.printPrefixln("#endif");
+       }
+
+       /**
+        * Create the makefile for a special process --> Each subprocess gets its
+        * own makefile
+        * 
+        * @param p
+        *            process for which the makefile should be created
+        */
+       protected void createMakefileProcess(Process p) {
+               try {
+                       // Directory of the process
+                       String processDir = _dir + _delimiter + "spu_"
+                                       + p.getBasename();
+
+                       // Create the filename for the new wrapper
+                       String filename = processDir + _delimiter + "Makefile";
+                       // File makefile = new File(filename);
+
+                       OutputStream file;
+
+                       file = new FileOutputStream(filename);
+
+                       PrintStream _makefilePS = new CodePrintStream(file);
+
+                       _makefilePS.println("# Makefile for process "
+                                       + p.getBasename());
+                       _makefilePS.println("");
+
+                       String dependency = "all: " + p.getBasename() + "Wrapper.cpp";
+
+                       for (SourceCode code : p.getSrcList()) {
+                               dependency += " " + code.getLocality();
+                       }
+
+                       _makefilePS.println(dependency);
+                       _makefilePS
+                                       .println("\tspu-g++ -c -I .. -I ../lib -o "
+                                                       + p.getBasename()
+                                                       + "Wrapper.o "
+                                                       + p.getBasename()
+                                                       + "Wrapper.cpp -ftree-vectorize -mtune=cell -O3 -fmodulo-sched -funroll-loops -ffast-math  -fno-rtti -ffunction-sections -fdata-sections" );
+                       _makefilePS.println("clean: ");
+                       _makefilePS.println("\trm " + p.getBasename() + "Wrapper.o");
+                       _makefilePS.println();
+
+               } catch (FileNotFoundException e) {
+                       System.out.println("CbeProcessVisitor - Makefile: exception "
+                                       + "occured: " + e.getMessage());
+                       e.printStackTrace();
+               }
+       }
+
+       private void createMakeFilePPUProcess(String subdir, Process p) {
+               try {
+                       // Directory of the process
+                       String processDir = _dir + _delimiter + subdir;
+
+                       // Create the filename for the new wrapper
+                       String filename = processDir + _delimiter + "Makefile";
+                       // File makefile = new File(filename);
+
+                       OutputStream file;
+
+                       file = new FileOutputStream(filename);
+
+                       PrintStream _makefilePS = new CodePrintStream(file);
+
+                       _makefilePS.println("# Makefile for process "
+                                       + p.getBasename());
+                       _makefilePS.println("");
+
+                       String dependency = "all: " + p.getBasename() + "Wrapper.cpp";
+
+                       for (SourceCode code : p.getSrcList()) {
+                               dependency += " " + code.getLocality();
+                       }
+                       _makefilePS.println("# General definitions:");
+                       _makefilePS.println("CC = ppu-g++");
+                       _makefilePS
+                                       .println("CCFLAGS = -ftree-vectorize -O3 -maltivec -funroll-loops -mabi=altivec -mcpu=cell");
+                       _makefilePS.println("COMPILE = $(CC) $(CCFLAGS) -c");
+
+                       _makefilePS.println(dependency);
+                       _makefilePS
+                                       .println("\t$(COMPILE) -o "
+                                                       + p.getBasename()
+                                                       + "Wrapper.o "
+                                                       + p.getBasename()
+                                                       + "Wrapper.cpp -I .. -I ../lib -I ../lib/ppu -I ../lib/pt;");
+                       _makefilePS.println("clean: ");
+                       _makefilePS.println("\trm " + p.getBasename() + "Wrapper.o");
+                       _makefilePS.println();
+
+               } catch (FileNotFoundException e) {
+                       System.out
+                                       .println("CbeProcessVisitor - Makefile PPU: exception "
+                                                       + "occured: " + e.getMessage());
+                       e.printStackTrace();
+               }
+       }
+
+       /**
+        * Make modifications to source files of a process. Port names need to be
+        * strings for the SystemC code generation. Therefore, in the header files
+        * integer port names are put into quotation marks.
+        * 
+        * @param p
+        *            process whose sources should be adapted
+        * @throws IOException
+        * @author haidw
+        */
+       protected void _adaptSources(String subdir, Process p)
+                       throws IOException {
+               Sed sed = new Sed();
+               // modify header file
+               for (Port port : p.getPortList()) {
+                       String processHeaderFile;
+
+                       for (SourceCode sr : p.getSrcList()) {
+                               processHeaderFile = _dir
+                                               + _delimiter
+                                               + subdir
+                                               + _delimiter
+                                               + sr.getLocality().replaceAll(
+                                                               "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                               sed.sed(processHeaderFile, "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                                               + port.getBasename() + "\"?", "$1 "
+                                               + "static_cast<" + p.getBasename()
+                                               + "Wrapper *>((static_cast<" + p.getBasename()
+                                               + "_data *>(p->wptr))->wrapper)->_port"
+                                               + port.getBasename() + "Fifo");
+                       }
+               }
+
+               // modify source file
+               for (SourceCode sr : p.getSrcList()) {
+                       String processSourceFile = _dir + _delimiter + subdir
+                                       + _delimiter + sr.getLocality();
+
+                       String line;
+                       StringBuffer buffer = new StringBuffer();
+                       FileInputStream fileInputStream = new FileInputStream(
+                                       processSourceFile);
+                       BufferedReader reader = new BufferedReader(
+                                       new InputStreamReader(fileInputStream));
+                       while ((line = reader.readLine()) != null) {
+                               buffer.append(line + "\n");
+                       }
+                       reader.close();
+
+                       String file = buffer.toString();
+                       // insert PT_BEGIN() at beginning of fire() function
+                       file = file.replaceAll("(int[ ]*" + p.getBasename()
+                                       + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
+                                       + "[\\s\\S&&[^\\{]]*)\\{", "$1"
+                                       + System.getProperty("line.separator") + "{"
+                                       + System.getProperty("line.separator")
+                                       + "    PT_BEGIN((pt*)(p->wptr));");
+
+                       // replace last return statement in fire function by PT_END()
+                       // find beginning of fire function
+                       Matcher matcher = Pattern.compile(
+                                       "(int[ ]*" + p.getBasename()
+                                                       + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
+                                                       + "[\\s\\S&&[^\\{]]*)\\{").matcher(file);
+                       matcher.find();
+                       int i = 0;
+                       try {
+                               i = matcher.start();
+                       } catch (Exception e) {
+                               System.out.println("Error: could not find "
+                                               + p.getBasename() + "_fire() function in "
+                                               + processSourceFile + ".");
+                               e.printStackTrace();
+                       }
+                       int openBraces = 0; // counter for open curly braces
+                       // position of last return statement
+                       int lastReturnStartPosition = 0;
+                       int lastReturnEndPosition = 0;
+                       while (i < file.length()) {
+                               // ignore single-line comments
+                               if (i < (file.length() - 1)
+                                               && file.substring(i, i + 2).equals("//")) {
+                                       while (!file.substring(i, i + 1).equals("\n")) {
+                                               i++;
+                                       }
+                               }
+                               // ignore multi-line comments
+                               else if (i < (file.length() - 1)
+                                               && file.substring(i, i + 2).equals("/*")) {
+                                       while (!file.substring(i, i + 2).equals("*/")) {
+                                               i++;
+                                       }
+                               }
+                               // ignore strings
+                               else if (file.substring(i, i + 1).equals("\"")) {
+                                       matcher = Pattern.compile("[\\s\\S&&[^\\\\]]\\\"")
+                                                       .matcher(file);
+                                       matcher.find(i + 1);
+                                       i = matcher.start() + 1;
+                               } else if (i < (file.length() - 5)
+                                               && file.substring(i, i + 6).equals("return")) {
+                                       lastReturnStartPosition = i;
+                                       while (!file.substring(i, i + 1).equals(";")) {
+                                               i++;
+                                       }
+                                       lastReturnEndPosition = i;
+                               } else if (file.substring(i, i + 1).equals("{")) {
+                                       openBraces++;
+                               } else if (file.substring(i, i + 1).equals("}")) {
+                                       openBraces--;
+                                       if (openBraces == 0) {
+                                               break;
+                                       }
+                               }
+                               i++;
+                       }
+
+                       file = file.substring(0, lastReturnStartPosition)
+                                       + "/* "
+                                       + file.substring(lastReturnStartPosition,
+                                                       lastReturnEndPosition + 1)
+                                       + " (commented out by DOL) */"
+                                       + System.getProperty("line.separator")
+                                       + "    PT_END((pt*)(p->wptr));"
+                                       + System.getProperty("line.separator")
+                                       + file.substring(lastReturnEndPosition + 2, file
+                                                       .length());
+
+                       BufferedWriter out = new BufferedWriter(new FileWriter(
+                                       processSourceFile));
+                       out.write(file);
+                       out.close();
+               }
+       }
+
+       protected CellMapping _mapping;
+       protected String _dir = null;
+       protected HashMap<Port, Integer> _portMap;
+
+       protected static String _libDirName = "lib";
+       protected static String _tempDirName = "template";
+
+}
diff --git a/dol/src/dol/visitor/cell/CellSPEVisitor.java b/dol/src/dol/visitor/cell/CellSPEVisitor.java
new file mode 100644 (file)
index 0000000..a8061ec
--- /dev/null
@@ -0,0 +1,416 @@
+package dol.visitor.cell;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+import dol.util.CodePrintStream;
+
+/**
+ * This class is a class for a visitor that is used to generate the the OS for
+ * the SPEs.
+ *
+ * @author lschor, 2009-03-24 * Revision: 2009-03-24: Created
+ */
+public class CellSPEVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir
+     *            path of this file
+     */
+    public CellSPEVisitor(String dir, CellMapping mapping) {
+        _dir = dir;
+        _mapping = mapping;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x
+     *            process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            // Create a directory where all SPU's are stored:
+            _spuDir = _dir + _delimiter + "spu";
+            File dir = new File(_spuDir);
+            dir.mkdirs();
+
+            // Copy the header file to this directory
+            // Some library files must be copied to the main directory
+            (new File(_dir + _delimiter + "lib" + _delimiter + "spu_os.h"))
+                    .renameTo(new File(dir.getPath() + _delimiter
+                            + "spu_os.h"));
+
+            ArrayList<Vector<Process>> spuList = _mapping.getSPUList();
+
+            int i = 0;
+            for (Vector<Process> spu : spuList) {
+                createOSLayer(x, spu, i++);
+            }
+
+            createMakefileSPU();
+
+        } catch (Exception e) {
+            System.out.println("CellSPEVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create the makefile for a SPU (so for the layer). Each SPU gets its own
+     * Makefile
+     *
+     * @param spu
+     *            SPU for which the Makefile should be used
+     */
+    protected void createMakefileSPU() {
+        try {
+            // Directory of the process
+            String spuDir = _dir + _delimiter + "spu";
+
+            // Create the filename for the new wrapper
+            String filename = spuDir + _delimiter + "Makefile";
+
+            OutputStream file = new FileOutputStream(filename);
+
+            PrintStream _makefilePS = new CodePrintStream(file);
+
+            _makefilePS.println("# Makefile for SPU OS");
+            _makefilePS.println("");
+            _makefilePS.println("src := $(wildcard ../lib/spu/*.cpp)");
+            _makefilePS.println("obj = $(src:.cpp=.o)");
+            _makefilePS.println("");
+
+            // The Makefile must include all o-Files of the processes needed
+            String dependency = "";
+
+            // Go through all possible processes
+            for (Process p : _mapping.getAllSpuBaseProcess()) {
+                dependency += " .." + _delimiter + "spu_"
+                        + p.getBasename() + _delimiter + p.getBasename()
+                        + "Wrapper.o";
+            }
+
+            _makefilePS.println("all: ${obj}" + dependency);
+            for (int i = 0; i < _mapping.getNrSPE(); i++) {
+                _makefilePS.println("\tspu-g++ -Wall -I .. -I ../lib -o "
+                        + "spu_os_" + i + " spu_os_" + i + ".cpp "
+                        + "../lib/spu/Fifo.o ../lib/spu/WindowedFifo.o "
+                        + "../lib/spu/dolSupport.o "
+                        + "../lib/spu/proc_wrapper.o ../lib/spu/common.o "
+                        + "../lib/spu/FastCommunication.o" + dependency
+                        + " -ftree-vectorize -lm -mtune=cell -O3"
+                        + " -fmodulo-sched -funroll-loops "
+                        + " -ffast-math -fno-rtti -ffunction-sections"
+                        + " -fdata-sections -Wl,--gc-sections");
+            }
+            _makefilePS.println();
+            _makefilePS.println("clean: ");
+            for (int i = 0; i < _mapping.getNrSPE(); i++) {
+                _makefilePS.println("\trm spu_os_" + i);
+            }
+            _makefilePS.println();
+            _makefilePS.println("%.o : ");
+            _makefilePS.println("\tspu-g++ -c -o $(*D)/$(*F).o "
+                    + "$(*D)/$(*F).cpp -I .. -I"
+                    + " ../lib -ftree-vectorize -mtune=cell -O3"
+                    + " -fmodulo-sched -funroll-loops -ffast-math"
+                    + " -fno-rtti -ffunction-sections -fdata-sections");
+            _makefilePS.println();
+        } catch (FileNotFoundException e) {
+            System.out.println("CbeProcessVisitor - Makefile: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Creates the OS layer for one SPU
+     *
+     * @param spu
+     *            List of all processes a SPU gets
+     * @param index
+     *            index of the SPU in the SPU list
+     */
+    protected void createOSLayer(ProcessNetwork x, Vector<Process> spu,
+            int index) {
+        try {
+            // Create the filename for the new layer
+            String filename = _spuDir + _delimiter + "spu_os_" + index
+                    + ".cpp";
+
+            // PrintStream for writing to the file
+            OutputStream file = new FileOutputStream(filename);
+            CodePrintStream _code = new CodePrintStream(file);
+
+            _code.println("/****************************************************************");
+            _code.println(" *   SPU OS file");
+            _code.println(" *   Description: OS for one SPU");
+            _code.println(" */");
+            _code.println();
+            _code.println("#include \"spu_os.h\"");
+
+            // Must include all possible wrappers
+            Vector<String> pList = new Vector<String>();
+            // Go through all possible processes
+            for (Process p : spu) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    _code.println("#include \".." + _delimiter + "spu_"
+                            + p.getBasename() + _delimiter
+                            + p.getBasename() + "Wrapper.h\"");
+                }
+            }
+
+            _code.println("");
+            _code.println("// Main application");
+            _code.println("int main(int speid , uint64_t argp)");
+            _code.println("{");
+            _code.println("    // reserve DMA tag ID");
+            _code.println("    uint32_t tag_id;");
+            _code.println("    if((tag_id=mfc_tag_reserve())==MFC_TAG_INVALID){");
+            _code.println("        printf(\"SPE: ERROR - can't reserve a tag ID\"); return 1;");
+            _code.println("    }");
+            _code.println("    ");
+            _code.println("    // Get the context information for the whole system");
+            _code.println("    mfc_get((void*) &ctx_spu, argp, sizeof(ctx_spu), tag_id, 0, 0);");
+            _code.println("    mfc_write_tag_mask(1<<tag_id);");
+            _code.println("    mfc_read_tag_status_all();");
+            _code.println("    ");
+            _code.println("    // This is the number of processes of this SPE");
+            _code.println("    uint64_t nr_proc = ctx_spu.procContentsLen;");
+            _code.println("    ");
+            _code.println("    // Get the addresses of the contexts for the Processes");
+            _code.println("    uint64_t context_addr[nr_proc];");
+            _code.println("    mfc_get((void*)context_addr, ctx_spu.procContents, sizeof(uint64_t) * roundDMA(nr_proc), tag_id,0,0);");
+            _code.println("    ");
+            _code.println("    mfc_write_tag_mask(1<<tag_id);");
+            _code.println("    mfc_read_tag_status_all();");
+            _code.println("    ");
+            _code.println("    int32_t queueFromSPU[roundDMA(NUM_FIFO)] __attribute__ ((aligned(16)));");
+            _code.println("    int32_t queueOnSPU[roundDMA(NUM_FIFO)]  __attribute__ ((aligned(16)));");
+            _code.println("    uint64_t tailAddresses[roundDMA(NUM_FIFO)] __attribute__ ((aligned(16)));");
+            _code.println("    ");
+            _code.println("    mfc_get((void*)queueFromSPU, ctx_spu.queueFromSPU, sizeof(int32_t) * roundDMA(NUM_FIFO), tag_id,0,0);");
+            _code.println("    mfc_write_tag_mask(1<<tag_id);");
+            _code.println("    mfc_read_tag_status_all();");
+            _code.println("    ");
+            _code.println("    mfc_get((void*)queueOnSPU, ctx_spu.queueOnSPU, sizeof(int32_t) * roundDMA(NUM_FIFO), tag_id,0,0);");
+            _code.println("    mfc_write_tag_mask(1<<tag_id);");
+            _code.println("    mfc_read_tag_status_all();");
+            _code.println("");
+            _code.println("    // Get the base addresses");
+            _code.println("    uint64_t procContentsAll[roundDMA(NUM_SPES)] __attribute__ ((aligned(16)));");
+            _code.println("    ");
+            _code.println("    mfc_get((void*)procContentsAll, ctx_spu.procContentsAll, sizeof(uint64_t) * roundDMA(NUM_SPES), tag_id,0,0);");
+            _code.println("    mfc_write_tag_mask(1<<tag_id);");
+            _code.println("    mfc_read_tag_status_all();");
+            _code.println("    ");
+            _code.println("    // Read the base address");
+            _code.println("    uint64_t ea_base = ctx_spu.ea_base;");
+            _code.println("    ");
+
+            Vector<Channel> channelList = new Vector<Channel>();
+            int indx = 0;
+            // instantiate channels
+            for (Channel c : x.getChannelList()) {
+                if (spu.contains(c.getOrigin())
+                        || spu.contains(c.getTarget())) {
+                    channelList.add(c);
+                    if (c.getType().equals("fifo")) {
+                        _code.printPrefixln("    Fifo " + c.getName() + "("
+                                + "FIFO_SIZE[" + indx + "]);");
+                    } else if (c.getType().equals("wfifo")) {
+                        _code.printPrefixln("    WindowedFifo "
+                                + c.getName() + "(" + "FIFO_SIZE[" + indx
+                                + "]);");
+                    }
+                }
+                indx++;
+            }
+
+            _code.println();
+
+            // Go through all processes
+            for (Process p : spu) {
+                // Create the process wrapper
+                _code.println("    " + p.getBasename() + "Wrapper *" + p.getName() +";");
+                _code.println("    try { "
+                        + p.getName() + " = new " + p.getBasename()
+                        + "Wrapper (context_addr[" + spu.indexOf(p)
+                        + "]); }");
+                _code.println("    catch(std::bad_alloc &e) {");
+                _code.println("        fprintf(stderr, \"[" + p.getBasename() +"Wrapper] Memory allocation failure\\n\");");
+                _code.println("        exit(1);");
+                _code.println("    }");
+
+                // Create the port-mapping
+                for (Port port : p.getPortList()) {
+                    if (port.getName().equals(port.getBasename())) {
+                        _code.printPrefixln("    " + p.getName() + "->_port"
+                                + port.getName() + "Fifo = &"
+                                + port.getPeerResource().getName() + ";");
+                    } else {
+                        _code.printPrefix("    " + p.getName() + "->_port"
+                                + port.getBasename() + "Fifo");
+                        StringTokenizer tokenizer = new StringTokenizer(
+                                port.getName().replaceFirst(
+                                        port.getBasename(), ""), "_");
+                        while (tokenizer.hasMoreTokens()) {
+                            _code.print("[" + tokenizer.nextToken() + "]");
+                        }
+                        _code.println(" = &"
+                                + port.getPeerResource().getName() + ";");
+                    }
+                }
+                _code.println();
+            }
+
+            // Count the effected channels
+            int countChannels = 0;
+            for (Channel c : channelList) {
+                if (spu.contains(c.getOrigin())
+                        && spu.contains(c.getTarget())) {
+                    continue;
+                } else if (spu.contains(c.getOrigin()))
+                    countChannels++;
+                else if (spu.contains(c.getTarget()))
+                    countChannels++;
+                else
+                    System.out.println("ERROR! Channel Mapping is wrong.");
+            }
+
+            _code.println("    // inited all queues, now one has to know:");
+            _code.println("    // sends out the start addresses to the SPU (of all out channels)");
+
+            // Check all out queues on the SPU
+            _code.println("    uint32_t queuemessage;");
+            for (Channel c : channelList) {
+                if (spu.contains(c.getOrigin()) && !spu.contains(c.getTarget())) {
+                    _code.println("    queuemessage = CREATEQUEUEMESSAGE(" + x.getChannelList().indexOf(c) + ", (uint32_t)" + c.getName() + ".getQueuePointer());");
+                    _code.println("    spu_write_out_mbox(queuemessage);");
+                }
+            }
+
+            _code.println("    ");
+            _code.println("    // Wait until we get the okey to read the tail pointers");
+            _code.println("    uint32_t messageIn = spu_read_in_mbox();");
+            _code.println("");
+            _code.println("    mfc_get((void*)tailAddresses, ctx_spu.fifoTails, sizeof(uint64_t) * roundDMA(NUM_FIFO), tag_id,0,0);");
+            _code.println("    mfc_write_tag_mask(1<<tag_id);");
+            _code.println("    mfc_read_tag_status_all();");
+            _code.println("    FastCommunication * com;");
+            _code.println("    try {  com = new FastCommunication("
+                    + countChannels + ", ea_base, procContentsAll, queueFromSPU, queueOnSPU, tailAddresses); }");
+            _code.println("    catch(std::bad_alloc &e) {");
+            _code.println("        fprintf(stderr, \"[FastCommunication] Memory allocation failure\\n\");");
+            _code.println("        exit(1);");
+            _code.println("    }");
+
+            String channelTyp = "";
+            int i = 0;
+            for (Channel c : channelList) {
+                if (spu.contains(c.getOrigin())
+                        && spu.contains(c.getTarget())) {
+                    // Local channels have no influence on external
+                    // communication (should be Windowed Fifos...)
+                    channelTyp = "local";
+                    continue;
+                } else if (spu.contains(c.getOrigin()))
+                    channelTyp = "out";
+                else if (spu.contains(c.getTarget()))
+                    channelTyp = "in";
+                else
+                    System.out.println("ERROR! Channel Mapping is wrong.");
+
+                if (c.getType().equals("fifo")) {
+                    _code.println("    com->addFifo(" + (i) + ", &"
+                        + c.getName() + ", com->" + channelTyp + ", "
+                        + x.getChannelList().indexOf(c) + ");");
+                }
+                else if (c.getType().equals("wfifo")) {
+                    _code.println("    com->addWFifo(" + (i) + ", &"
+                            + c.getName() + ", com->" + channelTyp + ", "
+                            + x.getChannelList().indexOf(c) + ");");
+                }
+                i++;
+            }
+
+            // The scheduler (yes, this could be optimized...)
+            _code.println("");
+            _code.println("    printf(\"SPU " + index + ": start to execute\\n\"); ");
+            _code.println("");
+            _code.println("    bool allBlocked = false;");
+            _code.println("    while (!allBlocked)");
+            _code.println("    {");
+            _code.println("        allBlocked = true;");
+            for (Process p : spu) {
+                _code.println("        if (!" + p.getName()
+                        + "->isDetached())");
+                _code.println("        {");
+                _code.println("            " + p.getName() + "->fire();");
+                _code.println("            allBlocked = false;");
+                _code.println("        }");
+
+                // communication only if this process needs some communication
+                for (Channel c : channelList) {
+                    // the channel may go away
+                    if (!spu.contains(c.getOrigin()) || !spu.contains(c.getTarget())) {
+                        if (c.getOrigin().equals(p) || c.getTarget().equals(p)) {
+                            _code.println("        com->update();");
+                            break;
+                        }
+                    }
+                }
+                _code.println();
+            }
+            _code.println("    }");
+            _code.println();
+
+            // End --> wait until all communications are finished
+            _code
+                    .println("    // Are there any open communication requests?");
+            _code.println("    while (!com->empty())");
+            _code.println("    {");
+            _code.println("        com->update();");
+            _code.println("    }");
+
+            for (Process p : spu) {
+                _code.println("    delete " + p.getName() + ";");
+            }
+
+            _code.println("    delete com;");
+            _code.println("    ");
+            _code.println("    // release tag ID before exiting");
+            _code.println("    mfc_tag_release(tag_id);");
+            _code.println("    ");
+            _code.println("    uint32_t message = CREATEFASTMESSAGE(SPE_COMPLETE, 0, 0);");
+            _code.println("    spu_write_out_mbox(message);");
+            _code.println("    ");
+            _code.println("    messageIn = spu_read_in_mbox();");
+            _code.println("}");
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+
+    protected String _spuDir = null;
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected CellMapping _mapping = null;
+}
diff --git a/dol/src/dol/visitor/cell/CellVisitor.java b/dol/src/dol/visitor/cell/CellVisitor.java
new file mode 100644 (file)
index 0000000..43c609d
--- /dev/null
@@ -0,0 +1,179 @@
+package dol.visitor.cell;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.main.UserInterface;
+import dol.visitor.PNVisitor;
+import dol.util.Copier;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a CELL package.
+ */
+public class CellVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param packageName name of the Cell directory
+     */
+    public CellVisitor(String packageName) {
+        _packageName = packageName;
+        _ui = UserInterface.getInstance();
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param pn process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            File dir = new File(_packageName);
+            dir.mkdirs();
+
+            // Create the library
+            File lib = new File(_packageName + _delimiter + "lib");
+            lib.mkdirs();
+
+            //copy library files
+            File source = new File(_ui.getMySystemCLib().
+                    replaceAll("systemC", "cell").replace("%20", " "));
+            new Copier().copy(source, lib);
+
+            // Create the template
+            File template = new File(_packageName + _delimiter + "template");
+            template.mkdirs();
+
+            //copy the templates
+            source = new File(_ui.getMySystemCLib().replaceAll("systemC", "cell").replace("lib", "template").replace("%20", " "));
+            new Copier().copy(source, template);
+
+            // Some library files must be copied to the main directory
+            (new File(lib.getPath() + _delimiter + "ppu_main.h")).renameTo(new File (dir.getPath() + _delimiter + "ppu_main.h"));
+
+            //copy process source code
+            source = new File(_srcDirName.replace("%20", " "));
+            new Copier().copy(source, dir);
+
+            createPortMap(pn);
+
+            // Create the mapping for this process network on the cell
+            CellMapping mapping = new CellMapping(pn, "predefined", true, MAX_SPUS);
+
+            pn.accept(new CellMakefileVisitor(_packageName, mapping));
+            pn.accept(new CellProcessVisitor(_packageName, _portMap, mapping));
+            pn.accept(new CellModuleVisitor(_packageName, _portMap, mapping));
+            pn.accept(new CellConstantVisitor(_packageName, mapping));
+            pn.accept(new CellSPEVisitor(_packageName, mapping));
+            pn.accept(new CellPPEVisitor(_packageName, mapping));
+        }
+        catch (Exception e) {
+            System.out.println("CellVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create a hashmap which maps each port of the given process network
+     * to an integer. For each process, ports are numbered with integers
+     * starting from 0.
+     *
+     * @param pn process network for which the map should be generated
+     */
+    protected void createPortMap(ProcessNetwork pn) {
+        _portMap = new HashMap<Port, Integer>();
+
+        for (Process process : pn.getProcessList()) {
+            int portCount = 0;
+            Vector<Port> portList = process.getPortList();
+            Vector<String> portNameList = new Vector<String>();
+            portNameList.clear();
+            HashMap<String, Integer> portMap =
+                new HashMap<String, Integer>();
+            portMap.clear();
+
+            for (int i = 0; i < portList.size(); i++) {
+                //treat single ports differently than iterated ports
+                String portName = portList.elementAt(i).getName();
+                String baseName = portList.elementAt(i).getBasename();
+
+                if (portName.equals(baseName)) {
+                    portNameList.add(portName);
+                    portMap.put(portName, portCount++);
+                } else {
+                    String range_indices = portList.elementAt(i).getRange();
+                    Vector<Integer> range_indices_values = getIndex(range_indices, ";");
+
+                    String port_indices = portName;
+                    port_indices.replaceAll(baseName, "");
+                    Vector<Integer> port_indices_values = getIndex(port_indices, "_");
+
+                    if (!portNameList.contains(baseName)) {
+                        portNameList.add(baseName);
+                        portMap.put(baseName, portCount);
+
+                        int size = 1;
+                        for (int j = 0; j < range_indices_values.size(); j++) {
+                            size *= range_indices_values.elementAt(j);
+                        }
+                        portCount += size;
+                    }
+
+                    int portId = portMap.get(baseName);
+                    for (int j = 0; j < port_indices_values.size(); j++) {
+                        int weight = 1;
+                        for (int k = j + 1; k < range_indices_values.size(); k++) {
+                            weight *= range_indices_values.elementAt(k);
+                        }
+                        portId += port_indices_values.elementAt(j) * weight;
+                    }
+                    portMap.put(portName, portId);
+                }
+            }
+
+            for (int i = 0; i < portList.size(); i++) {
+                _portMap.put(portList.elementAt(i),
+                        portMap.get(portList.elementAt(i).getName()));
+            }
+        }
+    }
+
+    /**
+     * Gets vector of indices of a string, where the index must be
+     * separated by the specified separator.
+     * examples:
+     * getIndex("name_1_2", "_", 0) will return 1.
+     * getIndex("name_1_2", "_", 1) will return 2.
+     *
+     * @param range string to parse
+     * @param separator delimiter of indices
+     * @return vector of indices
+     */
+    protected Vector<Integer> getIndex(String range, String separator) {
+        Vector<Integer> indices = new Vector<Integer>();
+        String[] subranges = range.split(separator);
+        for (int i = 0; i < subranges.length; i++) {
+            try {
+                int value = Integer.valueOf(subranges[i]);
+                indices.add(value);
+            } catch (Exception e) {
+                continue;
+            }
+        }
+        return indices;
+    }
+
+    public final static int MAX_SPUS = 6;
+    protected HashMap<Port, Integer> _portMap;
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+}
diff --git a/dol/src/dol/visitor/cell/lib/common.h b/dol/src/dol/visitor/cell/lib/common.h
new file mode 100644 (file)
index 0000000..b890fb9
--- /dev/null
@@ -0,0 +1,91 @@
+/****************************************************************
+ *     COMMON.H
+ *     Creator: lschor, 2008-10-30
+ *     Description: Specifies some structs and Constants for the CBE-DOL-Implementation
+ *
+ *     Revision:
+ *     - 2008-10-30: Created
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdint.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "dol.h"
+#include "constant.h"
+
+#define SPE_READ_DEMAND 0
+#define SPE_READ_COMPLETE 1
+#define SPE_COMPLETE 2
+
+// Context for one process --> 384 bit
+typedef struct{
+       uint64_t port_id;
+       uint64_t port_queue_id;
+
+       uint64_t processName;   // Address for the name of the process
+       uint64_t processNameLen;  // Len of the process Name
+
+       uint32_t number_of_ports;
+       uint32_t is_detached;
+       uint32_t padd[2]; // dummy - for alignment --> It always has to be a multiple of 128 bit!
+} process_context;
+
+// Context for one SPU --> This is send to him!
+typedef struct{
+       uint64_t procContents;
+       uint64_t procContentsLen;
+
+       uint64_t procContentsAll;
+       uint64_t queueFromSPU;
+       uint64_t queueOnSPU;
+
+       uint64_t fifoTails;
+
+       uint64_t ea_base; // Base address of the context
+       uint32_t padd[2]; // dummy - for alignment --> It always has to be a multiple of 128 bit!
+} spu_context;
+
+
+// Create a message to send the queue offset
+// 8 bit: queue number
+// 24 bit: offset of the LS
+#define CREATEQUEUEMESSAGE(_queue, _offset) \
+    ((_queue << 24) | (_offset))
+
+#define QUEUEMSGQUEUE(_message) \
+       ((_message >> 24) & 0xFF)
+
+#define QUEUEMSGOFFSET(_message) \
+       ((_message >> 0) & 0xFFFFFF)
+
+
+// Create the message we like to send, format:
+// 4 bit: code (total 16 possibilities)
+// 9 bit: queue (total 512 possibilities)
+// 19 bit: len
+#define CREATEFASTMESSAGE(_code, _queue, _len) \
+       ((_code << 28)  | (_queue << 19) | (_len))
+
+// Get the code from a message
+#define GETFASTCODE(_message) \
+       ((_message >> 28) & 0xF)
+
+// Get the queue from a message
+#define GETFASTQUEUE(_message) \
+       ((_message >> 19) & 0x1FF)
+
+// Get the len from a message
+#define GETFASTLEN(_message) \
+       ((_message >> 0) & 0x7FFFF)
+
+#define MSG_OK 19
+
+// Round a number ot the right DMA number --> Is used for DMA transfers
+uint32_t roundDMA(uint32_t number);
+
+#endif // _COMMON_H_
+
diff --git a/dol/src/dol/visitor/cell/lib/dol.h b/dol/src/dol/visitor/cell/lib/dol.h
new file mode 100644 (file)
index 0000000..297f8c5
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __DOL_H__
+#define __DOL_H__
+
+// structure for local memory of process
+typedef struct _local_states *LocalState;
+
+// structure for process
+struct _process;
+
+// standard functions
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr;
+} DOLProcess;
+
+void DOL_read(void *port, void *buf, int len, DOLProcess *process);
+void DOL_write(void *port, void *buf, int len, DOLProcess *process);
+
+unsigned DOL_reserve(void* port, void** destination, unsigned len, DOLProcess* process); 
+void DOL_release(void* port, DOLProcess* process); 
+unsigned DOL_capture(void* port, void** destination, unsigned len, DOLProcess* process);  
+void DOL_consume(void* port, DOLProcess* process); 
+void DOL_detach(DOLProcess *process);
+int getIndex(const char* string, char* tokens, int indexNumber); 
+int *createPort(int *port, int base, int number_of_indices, int index_range_pairs, ...); 
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/estimation.h b/dol/src/dol/visitor/cell/lib/estimation.h
new file mode 100644 (file)
index 0000000..eb1570a
--- /dev/null
@@ -0,0 +1,50 @@
+/**************************************************************** 
+ *     Estimation Defintions
+ *     Creator: lschor, 2008-11-15
+ *     Description: File with includes for time measurements
+ *  Principle: if 1 then this point will be measured, if 0 then this point will not be measured
+ *     
+ *     Revision: 
+ *     - 2008-11-15: Created
+ */
+
+// 
+#ifndef __ESTIMATION_H__
+#define __ESTIMATION_H__
+
+// What to measure?
+//#define              MEASURE                                                 0       // Measure activeted
+
+#ifdef MEASURE
+       //#define       MEASURE_DOL_READ                        0       // Measure DOL READ
+       //#define       MEASURE_DOL_READ_FINISH         0       // Measure FINISH DOL Read
+       //#define               MEASURE_DOL_READ_START_DMA      0       // Measure Time from start until the DMA process has started
+       //#define               MEASURE_DOL_READ_HANDSHAKE      0       // Measure Time of the whole handshake
+       //#define               MEASURE_DOL_READ_DMA            0       // Measure Time of DMA Setup
+       //#define               MEASURE_DOL_READ_LOCBUF         0       // Measure Time for LocBuf read
+       //#define               MEASURE_DOL_READ_DOUBLEBUF      0       // Measure Time for writing into the buffer
+
+       //#define       MEASURE_DOL_WRITE                       0       // Measure DOL WRITE
+       //#define       MEASURE_DOL_WRITE_FINISH        0       // Measure FINISH DOL Write
+       //#define               MEASURE_DOL_WRITE_START_DMA     0       // Measure Time from start until the DMA process has started
+       //#define               MEASURE_DOL_WRITE_HANDSHAKE     0       // Measure Time of the whole handshake
+       //#define               MEASURE_DOL_WRITE_DMA           0       // Measure Time of DMA Setup
+
+       //#define       MEASURE_DOL_FIRE                        0       // Measure DOL FIRE
+       //#define       MEASURE_DOL_INIT                        0       // Measure DOL INIT
+       //#define       MEASURE_SPE                                     0       // Measure whole SPE process
+
+       //#define       MEASURE_APPLICATION                     0       // Measure whole execution time
+       //#define       MEASURE_SET_UP_SPE_THREAD       0       // Measure time to set up the SPE-threads
+       //#define       MEASURE_SPE_WRITE_DEMAND        0       // Measure time of write demand
+       //#define       MEASURE_SPE_READ_DEMAND         0       // Measure time of read demand
+       //#define       MEASURE_SPE_WRITE_SUC           0       // Measure time of write successful
+       //#define       MEASURE_SPE_READ_SUC            0       // Measure time of read successful
+
+#endif
+
+// Some constants
+#define        MEASURE_START                                   0xFFFFFFFF      // Start decrementer at this value
+#define                MEASURE_CPU                                             79800000.0      // Timebase PS3 (in Hz)
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/free_align.h b/dol/src/dol/visitor/cell/lib/free_align.h
new file mode 100644 (file)
index 0000000..5924871
--- /dev/null
@@ -0,0 +1,65 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2006,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _FREE_ALIGN_H_
+#define _FREE_ALIGN_H_ 1
+
+#include <stdlib.h>
+
+/* Function
+ *
+ *     void free_align(void *ptr)
+ *
+ * Description
+ *     The free_align routine frees a memory buffer allocate by the
+ *     malloc_align routine. See malloc_align for complete details.
+ */
+
+static __inline void _free_align(void *ptr)
+{
+  void * real;
+
+  if (ptr) {
+    real = *((void **)(ptr)-1);
+    free(real);
+  }
+}
+
+#endif /* _FREE_ALIGN_H_ */
diff --git a/dol/src/dol/visitor/cell/lib/malloc_align.h b/dol/src/dol/visitor/cell/lib/malloc_align.h
new file mode 100644 (file)
index 0000000..0a19068
--- /dev/null
@@ -0,0 +1,105 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+
+#ifndef _MALLOC_ALIGN_H_
+#define _MALLOC_ALIGN_H_       1
+
+#include <stdlib.h>
+
+/* Function
+ *
+ *     void * malloc_align(size_t size, unsigned int log2_align)
+ *
+ * Description
+ *     The malloc_align routine allocates a memory buffer of <size>
+ *     bytes aligned to the power of 2 alignment specified by <log2_align>.
+ *     For example, malloc_align(4096, 7) will allocate a memory heap 
+ *     buffer of 4096 bytes aligned on a 128 byte boundary.
+ *
+ *     The aligned malloc routine allocates an enlarged buffer
+ *     from the standard memory heap. Space for the real allocated memory
+ *     pointer is reserved on the front of the memory buffer.
+ *
+ *           ----------------- <--- start of allocated memory
+ *          |    pad 0 to     |
+ *          |(1<<log2_align)-1|
+ *          |     bytes       |
+ *          |-----------------|
+ *          | allocation size |
+ *          |-----------------|
+ *          | real buffer ptr |
+ *          |-----------------|<---- returned aligned memory pointer
+ *          |                 |
+ *          |    requested    |
+ *          |     memory      |
+ *          |     buffer      |
+ *          |      size       |
+ *          |      bytes      |
+ *          |_________________|
+ *
+ *      Memory allocated by this routine must be freed using the free_align
+ *     routine.
+ *
+ *     The size of the allocation is saved for special cases where the 
+ *     data must be mored during a realloc_align.
+ */
+
+static __inline void * _malloc_align(size_t size, unsigned int log2_align)
+{
+  void *ret;
+  char *real;
+  unsigned long offset;
+  unsigned long align;
+  
+  align = 1 << log2_align;
+  real = (char *)malloc(size + 2*sizeof(void *) + (align-1));
+  if (real) {
+    offset = (align - (unsigned long)(real + 2*sizeof(void *))) & (align-1);
+    ret = (void *)((real + 2*sizeof(void *)) + offset);
+    *((size_t *)(ret)-2) = size;
+    *((void **)(ret)-1) = (void *)(real);
+  } else {
+    ret = (void *)(real);
+  }
+  return (ret);
+}
+
+#endif /* _MALLOC_ALIGN_H_ */
diff --git a/dol/src/dol/visitor/cell/lib/ppu/FastCommunication.cpp b/dol/src/dol/visitor/cell/lib/ppu/FastCommunication.cpp
new file mode 100644 (file)
index 0000000..70a3bbd
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ * FastCommunication.cpp / Version PPE
+ *
+ *  Created on: Mar 3, 2009
+ *      Author: lschor
+ *
+ * For remarks to this file, please refer to the SPE variant.
+ *
+ * Completion of the SPEs:
+ * Is coordinated by this process. Each SPE has to send a request to
+ * the PPE if it is allowed to finish.
+ * If all SPEs have requested to complete, the PPE sends to the SPEs a
+ * message that they can complete, thus return.
+ */
+
+#include "FastCommunication.h"
+
+/*
+ * Constructor
+ */
+FastCommunication::FastCommunication(int nrOfQueues,
+               uint64_t *context_all, uint64_t * ea_ls_base,
+               int32_t * queueFromSPEIn, int32_t * queueOnSPEIn,
+               uint64_t *fifoTails) {
+
+       _context_all = context_all;
+       queueFromSPE = queueFromSPEIn;
+       queueOnSPE = queueOnSPEIn;
+       _ea_ls_base = ea_ls_base;
+       _fifoTails = fifoTails;
+       _nrSpeComplete = 0;
+
+       _nrOfQueues = nrOfQueues;
+       try { _fifos = new fifoCollection[nrOfQueues]; }
+        catch(std::bad_alloc &e) {
+            fprintf(stderr, "[FastCommunication] Memory allocation failure\n");
+           exit(1);
+        }
+
+       for (int i = 0; i < MAXNOREQ; i++) {
+               _request[i].valid = false;
+       }
+}
+
+/*
+ * Deconstructor
+ */
+FastCommunication::~FastCommunication() {
+       delete _fifos;
+}
+
+/*
+ * Register an additional FIFO in the Communication
+ */
+bool FastCommunication::addFifo(int fifoNr, Fifo* fifo, int type,
+               int queue) {
+       _fifos[fifoNr].fifo = fifo;
+       _fifos[fifoNr].queue = queue;
+       _fifos[fifoNr].type = type;
+       _fifos[fifoNr].iswfifo = false;
+
+       // Per FIFO queue, we need two requests, but we can store at max MAXNOREQ of them
+       if (_nrOfRequest < MAXNOREQ) {
+               _nrOfRequest += 2;
+       }
+
+       return true;
+}
+
+/*
+ * Register an additional WindowedFIFO in the Communication
+ */
+bool FastCommunication::addWFifo(int fifoNr, WindowedFifo* wfifo,
+               int type, int queue) {
+       _fifos[fifoNr].wfifo = wfifo;
+       _fifos[fifoNr].queue = queue;
+       _fifos[fifoNr].type = type;
+       _fifos[fifoNr].iswfifo = true;
+
+       // Per FIFO queue, we need two requests, but we can store at max MAXNOREQ of them
+       if (_nrOfRequest < MAXNOREQ) {
+               _nrOfRequest += 2;
+       }
+
+       return true;
+}
+
+/*
+ * Communication: Main update procedure to update
+ */
+bool FastCommunication::update() {
+       // Check if you have received a new message
+       for (int processNr = 0; processNr < NUM_SPES; processNr++) {
+               if (!spe_out_mbox_status((spe_context*) _context_all[processNr]))
+                       continue;
+
+               uint32_t messageIn;
+               spe_out_mbox_read((spe_context*) _context_all[processNr],
+                               &messageIn, 1);
+
+               uint32_t code = GETFASTCODE(messageIn);
+               uint32_t queue = GETFASTQUEUE(messageIn);
+               uint32_t len = GETFASTLEN(messageIn);
+
+               /***************************************************************************************************************/
+               if (code == SPE_READ_DEMAND) // Have to send a write address (1) --> (2)
+               {
+                       // Find out for which fifo the request is
+                       fifoCollection *fifocol = NULL;
+                       int i;
+                       for (i = 0; i < _nrOfQueues; i++) {
+                               if (_fifos[i].queue == queue) {
+                                       fifocol = &_fifos[i];
+                                       break;
+                               }
+                       }
+
+                       // The queue was not found
+                       if (fifocol == NULL) {
+                               printf("PPU COM> ERROR, this queue does not exists!\n");
+                               return false;
+                       }
+
+                       // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                       // Windowed FIFO
+                       if (_fifos[i].iswfifo) {
+                               WindowedFifo* wfifo = NULL;
+                               wfifo = _fifos[i].wfifo;
+
+                               uint32_t inTail = wfifo->_inTail;
+
+                               // This is the len we like to read
+                               len = len > (wfifo->unused()) ? wfifo->unused() : len;
+
+                               // We can read something
+                               if (len > 0) {
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       uint64_t baseAddress = _fifoTails[queue] + inTail;
+                                       while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                               baseAddress--;
+
+                                       // Offset
+                                       uint32_t offset = _fifoTails[queue] + inTail
+                                                       - baseAddress;
+
+                                       // Store all data in the request buffer
+                                       request->data = (char *) _malloc_align(roundDMA(len
+                                                       + offset), ALIGNMENT_FACTOR);
+                                       request->len = len;
+                                       request->wfifo = wfifo;
+                                       request->iswfifo = true;
+                                       request->status = read_started;
+                                       request->queue = queue;
+                                       request->offset = offset;
+
+                                       int ret;
+                                       do {
+                                               ret = spe_mfcio_put(
+                                                               (spe_context*) _context_all[processNr],
+                                                               baseAddress, (void *) &(request->data[0]),
+                                                               roundDMA(len + offset), request->tag_id,
+                                                               0, 0);
+                                       } while (ret != 0);
+                               } else {
+#ifndef STORE_REQUESTS                // Send len = 0 back to the sender, this one should try it in a later phase
+                                       uint32_t message = CREATEFASTMESSAGE(
+                                                       SPE_READ_COMPLETE, queue, 0);
+                                       sendMessage(message, queueFromSPE[queue]);
+#else                                // I store the request and may try in a later time to start the transfer
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL)
+                                       {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       request->len = len;
+                                       request->wfifo = wfifo;
+                                       request->iswfifo = true;
+                                       request->status = read_pending;
+                                       request->queue = queue;
+#endif
+                               }
+
+                       }
+
+                       // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                       // Classic FIFO
+                       else {
+                               Fifo* fifo = NULL;
+                               fifo = _fifos[i].fifo;
+
+                               uint32_t inTail = fifo->_inTail;
+
+                               // This is the len we like to read
+                               len = len > (fifo->unused()) ? fifo->unused() : len;
+
+                               // We can read something
+                               if (len > 0) {
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       uint64_t baseAddress = _fifoTails[queue] + inTail;
+                                       while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                               baseAddress--;
+
+                                       // Offset
+                                       uint32_t offset = _fifoTails[queue] + inTail
+                                                       - baseAddress;
+
+                                       // Store all data in the request buffer
+                                       request->data = (char *) _malloc_align(roundDMA(len
+                                                       + offset), ALIGNMENT_FACTOR);
+                                       request->len = len;
+                                       request->fifo = fifo;
+                                       request->iswfifo = false;
+                                       request->status = read_started;
+                                       request->queue = queue;
+                                       request->offset = offset;
+
+                                       int ret;
+                                       do {
+                                               ret = spe_mfcio_put(
+                                                               (spe_context*) _context_all[processNr],
+                                                               baseAddress, (void *) &(request->data[0]),
+                                                               roundDMA(len + offset), request->tag_id,
+                                                               0, 0);
+                                       } while (ret != 0);
+                               }
+
+                               // Len == 0
+                               else {
+#ifndef STORE_REQUESTS                // Send len = 0 back to the sender, this one should try it in a later phase
+                                       uint32_t message = CREATEFASTMESSAGE(
+                                                       SPE_READ_COMPLETE, queue, 0);
+                                       sendMessage(message, queueFromSPE[queue]);
+#else                                // I store the request and may try in a later time to start the transfer
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       request->len = len;
+                                       request->fifo = fifo;
+                                       request->iswfifo = false;
+                                       request->status = read_pending;
+                                       request->queue = queue;
+#endif
+                               }
+                       }
+               }
+
+               /***************************************************************************************************************/
+               else if (code == SPE_READ_COMPLETE) // Can finish a write request (4) --> (5)
+               {
+                       // Get the stored request
+                       comRequest* request = getRequest(read_request_sent, queue);
+
+                       if (request == NULL) {
+                               printf("PPU Communicate> Couldn't find the request\n");
+                               return 0;
+                       }
+
+                       // Inform my FIFO that the request is completed
+                       if (request->iswfifo)
+                               request->wfifo->dmaRead(len);
+                       else
+                               request->fifo->dmaRead(len);
+
+                       // Request free
+                       deleteRequest(request);
+               }
+
+               /***************************************************************************************************************/
+               else if (code == SPE_COMPLETE) // One SPE has finished
+               {
+                       _nrSpeComplete++;
+               }
+       }
+
+       /***************************************************************************************************************/
+       // Check if some active write processes have finished (4)
+       uint8_t req = _currentRequest;
+
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (_request[req].valid) {
+                       if (_request[req].status == read_started) {
+                               if (!(testMessage(queueFromSPE[_request[req].queue]) > 0))
+                                       continue;
+
+                               uint32_t tag_id = _request[req].tag_id;
+                               uint32_t ret;
+                               uint32_t
+                                               test =
+                                                               spe_mfcio_tag_status_read(
+                                                                               (spe_context*) _context_all[queueFromSPE[_request[req].queue]],
+                                                                               0, SPE_TAG_IMMEDIATE, &ret);
+
+                               if (((ret & (1 << tag_id)) == 0)) {
+                                       // Have to write the data into the fifo
+                                       if (_request[req].iswfifo) { // WFIFO
+
+                                               _request[req].wfifo->dmaWrite(
+                                                               (char *) _request[req].data
+                                                                               + _request[req].offset,
+                                                               _request[req].len);
+                                               _free_align(_request[req].data);
+
+                                               // Increase the inTail value (used to know where the last request was started)
+
+                                               _request[req].wfifo->_inTail
+                                                               = (_request[req].wfifo->_inTail
+                                                                               + _request[req].len) % (FIFO_SIZE[_request[req].queue]);
+                                       } else { // FIFO
+                                               _request[req].fifo->write(
+                                                               (char *) _request[req].data
+                                                                               + _request[req].offset,
+                                                               _request[req].len);
+                                               _free_align(_request[req].data);
+
+                                               _request[req].fifo->_inTail
+                                                               = (_request[req].fifo->_inTail
+                                                                               + _request[req].len) % (FIFO_SIZE[_request[req].queue]);
+
+                                       }
+
+                                       uint32_t message = CREATEFASTMESSAGE(
+                                                       SPE_READ_COMPLETE, _request[req].queue,
+                                                       _request[req].len);
+                                       sendMessage(message, queueFromSPE[_request[req].queue]);
+
+                                       deleteRequest(&_request[req]);
+                                       _currentRequest = (req + 1) % _nrOfRequest;
+
+                                       break;
+                               }
+                       } else if (_request[req].status == read_pending) { // Has an open request for sending
+
+                               // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                               // Windowed FIFO
+                               if (_request[req].iswfifo) {
+
+                                       if (_request[req].wfifo->unused() > 0) {
+                                               comRequest *request = &_request[req];
+
+                                               // This is the len we like to read
+                                               uint32_t len = request->len > (request->wfifo->unused()) ? request->wfifo->unused()
+                                                               : request->len;
+
+                                               uint32_t inTail = request->wfifo->_inTail;
+                                               uint64_t baseAddress = _fifoTails[request->queue]
+                                                               + inTail;
+
+                                               while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                                       baseAddress--;
+
+                                               // Offset --> How much we had to align
+                                               uint32_t offset = _fifoTails[request->queue]
+                                                               + inTail - baseAddress;
+
+                                               request->data = (char *) _malloc_align(roundDMA(
+                                                               len + offset), ALIGNMENT_FACTOR);
+                                               request->len = len;
+                                               request->status = read_started;
+                                               request->offset = offset;
+
+                                               // Set up the request in the MFC
+                                               int ret;
+                                               do {
+                                                       ret = spe_mfcio_put(
+                                                                       (spe_context*) _context_all[queueFromSPE[_request[req].queue]],
+                                                                       baseAddress,
+                                                                       (void *) &(request->data[0]),
+                                                                       roundDMA(len + offset),
+                                                                       request->tag_id, 0, 0);
+                                               } while (ret != 0);
+                                       }
+                               }
+
+                               // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                               // Classic FIFO
+                               else {
+
+                                       if (_request[req].fifo->unused() > 0) {
+                                               comRequest *request = &_request[req];
+
+                                               // This is the len we like to read
+                                               uint32_t len =  request->len > (request->fifo->unused()) ? request->fifo->unused() : request->len;
+
+                                               uint32_t inTail = request->fifo->_inTail;
+                                               uint64_t baseAddress = _fifoTails[request->queue]
+                                                               + inTail;
+
+                                               while (baseAddress % 16 != 0)
+                                                       baseAddress--;
+
+                                               // Offset
+                                               uint32_t offset = _fifoTails[request->queue]
+                                                               + inTail - baseAddress;
+
+                                               // Store all data in the request buffer
+                                               request->data = (char *) _malloc_align(roundDMA(
+                                                               len + offset), ALIGNMENT_FACTOR);
+                                               request->len = len;
+                                               request->status = read_started;
+                                               request->offset = offset;
+
+                                               // Start the DMA transfer
+                                               int ret;
+                                               do {
+                                                       ret
+                                                                       = spe_mfcio_put(
+                                                                                       (spe_context*) _context_all[queueFromSPE[_request[req].queue]],
+                                                                                       baseAddress,
+                                                                                       (void *) &(request->data[0]),
+                                                                                       roundDMA(len + offset),
+                                                                                       request->tag_id, 0, 0);
+                                               } while (ret != 0);
+                                       }
+                               }
+                       }
+               }
+               req = (req + 1) % _nrOfRequest;
+       }
+
+       /***************************************************************************************************************/
+       // Have some out - queue some data to send
+       for (int i = 0; i < _nrOfQueues; i++) {
+               if (_fifos[i].type == this->out) {
+                       if (_fifos[i].iswfifo) { // WFIFO
+                               // Start only a write process if there is really enough place in the outbound mailbox
+                               if (_fifos[i].wfifo->dmaAllowed()
+                                               && _fifos[i].wfifo->used() > 0) {
+                                       uint32_t queue = _fifos[i].queue;
+
+                                       // Can we send a message to this processor or is it blocked?
+                                       if (testMessage(queueOnSPE[queue]) <= 0) {
+                                               continue;
+                                       }
+
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                       } else {
+                                               uint32_t len = _fifos[i].wfifo->dmaStart();
+                                               // Create a write-demand message
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_DEMAND, queue, len);
+
+                                               request->len = len;
+                                               request->queue = queue;
+                                               request->status = read_request_sent;
+                                               request->wfifo = _fifos[i].wfifo;
+                                               request->iswfifo = true;
+
+                                               sendMessage(message, queueOnSPE[queue]);
+                                       }
+                                       break;
+                               }
+                       } else { // FIFO
+                               // Start only a write process if there is really enough place in the outbound mailbox
+                               if (_fifos[i].fifo->dmaAllowed() && _fifos[i].fifo->used()
+                                               > 0) {
+                                       uint32_t queue = _fifos[i].queue;
+
+                                       if (testMessage(queueOnSPE[queue]) <= 0)
+                                               continue;
+
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                       } else {
+                                               uint32_t len = _fifos[i].fifo->dmaStart();
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_DEMAND, queue, len);
+                                               request->len = len;
+                                               request->queue = queue;
+                                               request->status = read_request_sent;
+                                               request->fifo = _fifos[i].fifo;
+                                               request->iswfifo = false;
+
+                                               sendMessage(message, queueOnSPE[queue]);
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       }
+       return true;
+}
+
+/*
+ * Create a new request to store in the cache
+ *
+ */
+comRequest* FastCommunication::newRequest() {
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (!_request[i].valid) {
+                       _request[i].tag_id = i + 3;
+                       _request[i].valid = true;
+                       return &(_request[i]);
+               }
+       }
+
+       return NULL;
+}
+
+/*
+ * Delete the request
+ *
+ */
+void FastCommunication::deleteRequest(comRequest* request) {
+       request->valid = false;
+       request->tag_id = 0;
+}
+
+/*
+ * Returns the request one like to get
+ */
+comRequest* FastCommunication::getRequest(uint8_t status, uint32_t queue) {
+       uint8_t req = _currentRequest;
+
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (_request[req].valid && _request[req].status == status
+                               && _request[req].queue == queue) {
+                       _currentRequest = (req + 1) % _nrOfRequest;
+                       return &(_request[req]);
+               }
+               req = (req + 1) % _nrOfRequest;
+       }
+
+       return NULL;
+}
+
+/**
+ * True if no communication is necessary, false if there is active communication
+ */
+bool FastCommunication::empty() { /////////////////////////////////////////////////////////////////
+       // check if one fifo would like to send something to another SPE
+       for (int i = 0; i < _nrOfQueues; i++) {
+               if (_fifos[i].type == this->out) {
+                       if (_fifos[i].iswfifo) { // WFIFO
+                               if (_fifos[i].wfifo->used() > 0) 
+                               {
+                                       return false;
+                               }
+                       } else {
+                               if (_fifos[i].fifo->used() > 0) 
+                               {
+                                       return false;
+                               }               
+                       }
+               }
+       }
+
+       // are open sendings?
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (_request[i].valid) {
+                       return false;
+               }
+       }
+
+       if (_nrSpeComplete < NUM_SPES) {
+               return false;
+       }
+
+       return true;
+}
+
+/**
+ * Send a message to a SPE
+ */
+void FastCommunication::sendMessage(uint32_t message, int32_t process) {
+       spe_in_mbox_write((spe_context*) _context_all[process],
+                       (uint32_t*) &message, 1, SPE_MBOX_ANY_NONBLOCKING);
+}
+
+/**
+ * Test if we can send a message to an SPE without stalling
+ */
+int FastCommunication::testMessage(int32_t process) {
+       return spe_in_mbox_status((spe_context*) _context_all[process]);
+}
+
diff --git a/dol/src/dol/visitor/cell/lib/ppu/FastCommunication.h b/dol/src/dol/visitor/cell/lib/ppu/FastCommunication.h
new file mode 100644 (file)
index 0000000..8ba7731
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Communication.h
+ *
+ *  Created on: Mar 3, 2009
+ *      Author: lschor
+ */
+
+#ifndef FASTCOMMUNICATION_H_
+#define FASTCOMMUNICATION_H_
+
+// System includes
+#include "cbe_mfc.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <new>
+#include <sys/time.h>
+#include <stddef.h>
+#include <libspe2.h>
+#include <pthread.h>
+
+// Local includes
+#include "lib/ppu/common_ppu.h"
+#include "Fifo.h"
+#include "WindowedFifo.h"
+#include "../common.h"
+
+
+// Include to allocate/free using for DMA transfers
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+//Cell Macros
+#define waittag(tag_id) mfc_write_tag_mask(1<<tag_id);    mfc_read_tag_status_all();
+
+#define MAXNOREQ 24
+
+// A request
+typedef struct _comRequest {
+    bool valid;           // If the request is valid
+    uint32_t status;      // Status of the request (write_request_sen, ...)
+
+    uint32_t tag_id;      // Tag ID
+    uint32_t queue;       // The queue which is used by the request
+
+    bool iswfifo;         // True if it is a WFIFO
+    Fifo* fifo;           // Pointer to the used FIFO
+    WindowedFifo* wfifo;  // Pointer to the WFIFO
+
+    uint32_t len;         // The len of the data
+    char* data;           // Point to the data which are stored
+    uint32_t offset;
+} comRequest;
+
+typedef struct _fifoCollection {
+    int type;               // local, in or out
+    int queue;            // Corresponding queue number
+
+    bool iswfifo;         // True if it is a WFIFO
+    WindowedFifo* wfifo;  // Pointer to the WFIFO
+    Fifo* fifo;           // Pointer to the FIFO
+} fifoCollection;
+
+/**
+ * The Communication Class
+ */
+class FastCommunication {
+public:
+    FastCommunication(int nrOfQueues, uint64_t *context_all, uint64_t *ea_base_all, int32_t * queueFromSPE, int32_t * queueOnSPE, uint64_t *);
+    virtual ~FastCommunication();
+
+    bool addFifo(int fifoNr, Fifo* fifo, int type, int queue);
+    bool addWFifo(int fifoNr, WindowedFifo* fifo, int type, int queue);
+
+    bool update();
+    bool empty();
+
+    static int const local = 0;
+    static int const in = 1;
+    static int const out = 2;
+
+    static int const comIn = 0;
+    static int const comOut = 1;
+
+    static int const read_request_sent = 0;
+    static int const read_started = 1;
+    static int const read_pending = 2;
+
+protected:
+    void sendMessage(uint32_t message, int32_t process);
+    int testMessage(int32_t process);
+
+    comRequest* newRequest();
+    void deleteRequest(comRequest* request);
+    comRequest* getRequest(uint8_t status, uint32_t queue);
+
+    int _nrOfRequest;
+    comRequest _request[MAXNOREQ];
+    uint8_t _currentRequest;
+
+    int _nrOfQueues;
+    fifoCollection * _fifos;
+
+    uint64_t _ea_base;
+    uint64_t * _context_all;
+    int32_t * queueFromSPE;
+    int32_t * queueOnSPE;
+    uint64_t * _ea_ls_base;
+    uint64_t * _fifoTails;
+
+    // This is used to check the completion of the SPEs (See remarks in FifoCommunication.cpp)
+    uint8_t _nrSpeComplete;
+
+};
+
+#endif /* FASTCOMMUNICATION_H_ */
diff --git a/dol/src/dol/visitor/cell/lib/ppu/Fifo.cpp b/dol/src/dol/visitor/cell/lib/ppu/Fifo.cpp
new file mode 100644 (file)
index 0000000..6198d3c
--- /dev/null
@@ -0,0 +1,142 @@
+#include "Fifo.h"
+
+/**
+ *
+ */
+Fifo::Fifo(unsigned size = 18) {
+       //except at the beginning, _head and _tail must never overlap,
+       //otherwise one does not know whether the buffer is full or
+       //empty. To have nevertheless a buffer with the given capacity,
+       //a buffer with one more element is allocated.
+       _size = size;
+       _buffer = (char *) _malloc_align(_size, ALIGNMENT_FACTOR);
+        if(!_buffer) {
+           fprintf(stderr,"[FIFO] Memory allocation failure\n");
+           exit(-1);
+       }
+        
+       _tail = 0;
+       _pos = 0;
+       _blocked = 0;
+
+       _inTail = 0;
+       _activeDMA = false;
+}
+
+/**
+ *
+ */
+Fifo::~Fifo() {
+       if (_buffer) {
+               _free_align(_buffer);
+       }
+       _buffer = 0;
+       _tail = 0;
+       _pos = 0;
+}
+
+/**
+ *
+ */
+unsigned Fifo::read(void *destination, unsigned len) {
+       char* buffer = (char*) destination;
+       unsigned read = (len <= used() ? len : used());
+
+       if (_tail + read < _size) {
+               memcpy(buffer, _buffer + _tail, read);
+       } else {
+               memcpy(buffer, _buffer + _tail, _size - _tail);
+               memcpy(buffer + _size - _tail, _buffer, read - _size + _tail);
+       }
+
+       _tail = ((unsigned) (_tail + read) % _size);
+       _pos -= read;
+       return read;
+}
+
+/**
+ *
+ */
+unsigned Fifo::write(const void *source, unsigned len) {
+
+       char* buffer = (char*) source;
+       unsigned write = (len <= unused() ? len : unused());
+       unsigned head = (_tail + _pos) % _size;
+
+       if (head + write < _size) {
+               memcpy(_buffer + head, buffer, write);
+       } else {
+               memcpy(_buffer + head, buffer, _size - head);
+               memcpy(_buffer, buffer + _size - head, write - _size + head);
+       }
+
+       _pos += write;
+       return write;
+}
+
+/**
+ * Size of this fifo
+ */
+unsigned Fifo::size() const {
+       return (_size);
+}
+
+/**
+ * How many bytes are currently free in the buffer
+ */
+unsigned Fifo::unused() const {
+       return (_size) - used();
+}
+
+/**
+ * How many data are currently stored in the fifo
+ */
+unsigned Fifo::used() const {
+       return _pos;
+}
+
+/*
+ * Get the pointer to the start of the queue
+ */
+char *Fifo::getQueuePointer() {
+       return _buffer;
+}
+
+/*
+ * Has completed a dma read process, i.e. has read out of the queue
+ */
+void Fifo::dmaRead(unsigned len) {
+       _activeDMA = false;
+
+       if (len == 0) {
+               _blocked = BLOCKED_MAX_NR;
+       } else {
+               _tail = ((unsigned) (_tail + len) % _size);
+               _pos -= len;
+       }
+}
+
+/*
+ * Start a DMA request, returns the current space one have
+ */
+unsigned Fifo::dmaStart() {
+       _activeDMA = true;
+
+       if (_tail + _pos > _size) {
+               return _size - _tail;
+       } else {
+               return _pos;
+       }
+}
+
+/*
+ * Is allowed to start a dma request
+ */
+bool Fifo::dmaAllowed() {
+       if (_blocked > 0) {
+               _blocked--;
+               return false;
+       } else {
+               return !_activeDMA;
+       }
+}
diff --git a/dol/src/dol/visitor/cell/lib/ppu/Fifo.h b/dol/src/dol/visitor/cell/lib/ppu/Fifo.h
new file mode 100644 (file)
index 0000000..8a06087
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _FIFO_H_
+#define _FIFO_H_
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../constant.h"
+
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+/** 
+ * FIFO Class: For remarks see SPE
+ */
+class Fifo {
+    public:
+        Fifo(unsigned size);
+        virtual ~Fifo();
+
+        virtual unsigned read(void *destination, unsigned len);
+        virtual unsigned write(const void *source, unsigned len);
+        
+               virtual unsigned used() const;
+        virtual unsigned unused() const;
+        virtual unsigned size() const;
+        
+        virtual char *getQueuePointer();
+        virtual void dmaRead(unsigned len);
+        virtual unsigned dmaStart();
+        virtual bool dmaAllowed();
+
+        unsigned _inTail;
+
+    protected:
+        char *_buffer;
+        
+               unsigned _tail;
+        unsigned _pos; 
+        unsigned _size;
+        
+        unsigned _blocked; 
+        bool _activeDMA;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/ppu/ProcessWrapper.cpp b/dol/src/dol/visitor/cell/lib/ppu/ProcessWrapper.cpp
new file mode 100644 (file)
index 0000000..fcd5f0e
--- /dev/null
@@ -0,0 +1,66 @@
+#include "ProcessWrapper.h"
+
+/**
+ *
+ */
+ProcessWrapper::ProcessWrapper(char* name, int iteratorIndex[4]) {
+       //copy name, deliberately avoid using strlen and strcpy for code size
+       //minimization
+       int nameLength = 0;
+       while (name[nameLength] != 0) {
+               nameLength++;
+       }
+       _name = new char[nameLength + 1];
+       for (int i = 0; i < nameLength; i++) {
+               _name[i] = name[i];
+       }
+
+       _isDetached = false;
+       for (int i = 0; i < 4; i++) {
+               _iteratorIndex[i] = iteratorIndex[i];
+       }
+
+       readPos = 0;
+       writePos = 0;
+}
+
+/**
+ *
+ */
+ProcessWrapper::~ProcessWrapper() {
+       if (_name) {
+               delete _name;
+       }
+}
+
+/**
+ *
+ */
+void ProcessWrapper::init() {
+       _process.init(&_process);
+}
+
+/**
+ *
+ */
+int ProcessWrapper::fire() {
+       return _process.fire(&_process);
+}
+
+/**
+ *
+ */
+void ProcessWrapper::detach() {
+       _isDetached = true;
+}
+
+/**
+ * Get the index of this process.
+ * @param indexNumber position of index (starting at 0)
+ */
+int ProcessWrapper::getIndex(unsigned indexNumber) const {
+       if (indexNumber < 4) {
+               return _iteratorIndex[indexNumber];
+       }
+       return -1;
+}
diff --git a/dol/src/dol/visitor/cell/lib/ppu/ProcessWrapper.h b/dol/src/dol/visitor/cell/lib/ppu/ProcessWrapper.h
new file mode 100644 (file)
index 0000000..0754af4
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _PROCESSWRAPPER_H_
+#define _PROCESSWRAPPER_H_
+
+#include <dol.h>
+
+/**
+ * Process Wrapper Class
+ */
+class ProcessWrapper
+{
+    public:
+        ProcessWrapper(char* name, int iteratorIndex[4]);
+        virtual ~ProcessWrapper();
+
+        virtual void init();
+        virtual int fire();
+        virtual bool isDetached() { return _isDetached; }
+        virtual void detach();
+        virtual int getIndex(unsigned indexNumber) const;
+        
+               // Positions for read and write operations which are blocked by Protothread
+        unsigned int readPos; 
+        unsigned int writePos; 
+
+    protected:
+        char* _name;;
+        DOLProcess _process;
+        bool _isDetached;
+        int _iteratorIndex[4];
+};
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/ppu/WindowedFifo.cpp b/dol/src/dol/visitor/cell/lib/ppu/WindowedFifo.cpp
new file mode 100644 (file)
index 0000000..16e09ba
--- /dev/null
@@ -0,0 +1,223 @@
+#include "WindowedFifo.h"
+
+/**
+ *
+ */
+WindowedFifo::WindowedFifo(unsigned size = 20) {
+       //std::cout << "Create WindowedFifo." << std::endl;
+       _size = size;
+       _buffer = (char *) _malloc_align(_size, ALIGNMENT_FACTOR);
+        if(!_buffer) {
+           fprintf(stderr,"[WFIFO] Memory allocation failure\n");
+           exit(-1);
+       }
+
+       _head = 0;
+       _tail = 0;
+
+       _headRoom = 0;
+       _tailRoom = 0;
+       _use = 0;
+       _blocked = 0;
+
+       _isHeadReserved = false;
+       _isTailReserved = false;
+       _activeDMA = false;
+}
+
+/**
+ *
+ */
+WindowedFifo::~WindowedFifo() {
+       if (_buffer) {
+               _free_align(_buffer);
+       }
+       _buffer = 0;
+       _head = 0;
+       _tail = 0;
+       _use = 0;
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::reserve(void** dest, unsigned len) {
+       char** destination = (char**) dest;
+       //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;
+
+       //can only reserve one piece at a time
+       if (_isHeadReserved) {
+               *destination = 0;
+               return 0;
+       }
+
+       //reserve at most as much memory as still available in the buffer
+       unsigned write = (len <= _size - _use ? len : _size - _use);
+
+       if (write > 0) {
+               //if wrap-around in buffer: return only buffer for the
+               //contiguous buffer space
+               if (_head + write > _size) {
+                       write = _size - _head;
+               }
+
+               _headRoom = (_head + write) == _size ? 0 : _head + write;
+               *destination = &(_buffer[_head]);
+               _isHeadReserved = true;
+       }
+
+       //std::cout << "Reserved " << write << " bytes." << std::endl;
+       _writeReserve = write;
+       return write;
+}
+
+/**
+ *
+ */
+void WindowedFifo::release() {
+       if (_isHeadReserved) {
+               //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;
+               _head = _headRoom;
+               _use += _writeReserve;
+               _isHeadReserved = false;
+       }
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::capture(void **dest, unsigned len) {
+       char** destination = (char**) dest;
+       //std::cout << "Attempt to capture " << len << " bytes." << std::endl;
+
+       if (_isTailReserved) {
+               //std::cout << "Only one attempt to capture allowed." << std::endl;
+               *destination = 0;
+               return 0;
+       }
+
+       //capture at most as much data as available in the buffer
+       unsigned read = (len <= _use ? len : _use);
+
+       if (read > 0) {
+               //if wrap-around in buffer: return only buffer for the
+               //conntiguous buffer space
+               if (_tail + read > _size) {
+                       read = _size - _tail;
+               }
+
+               _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;
+               *destination = &(_buffer[_tail]);
+               _isTailReserved = true;
+       }
+
+       //std::cout << "Captured " << read << " bytes." << std::endl;
+       _readReserve = read;
+       return read;
+}
+
+/**
+ *
+ */
+void WindowedFifo::consume() {
+       if (_isTailReserved) {
+               //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;
+               _tail = _tailRoom;
+               _use -= _readReserve;
+               _isTailReserved = false;
+       }
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::size() const {
+       return _size;
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::unused() const {
+       return _size - _use;
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::used() const {
+       return _use;
+}
+
+/*
+ * Get the pointer to the start of the queue
+ */
+char *WindowedFifo::getQueuePointer() {
+       return _buffer;
+}
+
+/*
+ * Has completed a dma read process, i.e. has read out of the queue
+ */
+void WindowedFifo::dmaRead(unsigned len) {
+       _activeDMA = false;
+
+       if (len == 0) {
+               _blocked = BLOCKED_MAX_NR;
+       } else {
+               _tail = ((unsigned) (_tail + len) % _size);
+               _use -= len;
+       }
+}
+
+/*
+ * Start a DMA request, returns the current space one have
+ */
+unsigned WindowedFifo::dmaStart() {
+       _activeDMA = true;
+
+       // If we go over the end, we only take as much as is on one side!
+       //return used();
+
+       if (_tail + _use > _size) {
+               return _size - _tail;
+       } else {
+               return _use;
+       }
+}
+
+/*
+ * Is allowed to start a dma request
+ */
+bool WindowedFifo::dmaAllowed() {
+#ifndef STORE_REQUESTS
+       if (_blocked > 0) {
+               _blocked--;
+               return false;
+       } else {
+               return !_activeDMA;
+       }
+#else
+       return !_activeDMA;
+#endif
+}
+
+/**
+ * Is needed for DMA transfers
+ */
+unsigned WindowedFifo::dmaWrite(const void *source, unsigned len) {
+
+       char* buffer = (char*) source;
+
+       if (_head + len < _size) {
+               memcpy(_buffer + _head, buffer, len);
+       } else {
+               // We should never be here!
+               memcpy(_buffer + _head, buffer, _size - _head);
+               memcpy(_buffer, buffer + _size - _head, len - _size + _head);
+       }
+       _use += len;
+       _head = (_head + len) >= _size ? _head + len - _size : _head + len;
+
+       return len;
+}
diff --git a/dol/src/dol/visitor/cell/lib/ppu/WindowedFifo.h b/dol/src/dol/visitor/cell/lib/ppu/WindowedFifo.h
new file mode 100644 (file)
index 0000000..2e94c46
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef _WINDOWEDFIFO_H_
+#define _WINDOWEDFIFO_H_
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../constant.h"
+
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+class WindowedFifo {
+    public:
+        WindowedFifo(unsigned size);
+        virtual ~WindowedFifo();
+
+        // Write
+               virtual unsigned reserve(void** destination, unsigned len);
+        virtual void release();
+
+        // Read
+               virtual unsigned capture(void** destination, unsigned len);
+        virtual void consume();
+
+               // General FIFO functions
+        virtual unsigned used() const;
+        virtual unsigned unused() const;
+        virtual unsigned size() const;
+
+               // DMA functions
+        virtual char *getQueuePointer();
+        virtual void dmaRead(unsigned len);
+        virtual unsigned dmaStart();
+        virtual bool dmaAllowed();
+               virtual unsigned dmaWrite(const void *source, unsigned len);
+
+               // Global variables
+               unsigned _inTail;
+    protected:
+        char *_buffer;
+        
+               unsigned _head;
+        unsigned _tail;
+        unsigned _headRoom;
+        unsigned _tailRoom;
+        
+               unsigned _size;
+        unsigned _use; 
+               
+               unsigned _writeReserve;  
+        unsigned _readReserve; 
+        
+               bool _isHeadReserved;
+        bool _isTailReserved;
+
+               unsigned _blocked;      // Blocked number the request has to wait
+        bool _activeDMA;        // Is there an active DMA on this buffer
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/ppu/common.cpp b/dol/src/dol/visitor/cell/lib/ppu/common.cpp
new file mode 100644 (file)
index 0000000..bdaf7c8
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * common.cpp
+ *
+ *  Created on: Feb 27, 2009
+ *      Author: lschor
+ */
+
+#include "../common.h"
+
+/**
+ * Aligend a number to to the data bus
+ */
+uint32_t roundDMA(uint32_t number)
+{
+       if (number > 16)
+               if (number % 16 == 0) return number;
+               else return number + 16 - (number % 16);
+       else if (number > 8)
+               return 16;
+       else if (number > 4)
+               return 8;
+       else if (number > 2)
+               return 4;
+       else if (number > 1)
+               return 2;
+       else
+               return 1;
+}
diff --git a/dol/src/dol/visitor/cell/lib/ppu/common_ppu.h b/dol/src/dol/visitor/cell/lib/ppu/common_ppu.h
new file mode 100644 (file)
index 0000000..09a8d78
--- /dev/null
@@ -0,0 +1,32 @@
+/****************************************************************
+ *     Common structs for the PPU
+ *     Creator: lschor, 2008-11-21
+ *     Description: Common structs for the PPU
+ *
+ *     Revision:
+ *     - 2008-11-21: Created
+ */
+
+#ifndef __COMMON_PPU_H__
+#define __COMMON_PPU_H__
+
+#include <libspe2.h>
+
+// data structure for running SPE thread
+typedef struct spu_data {
+       spe_context_ptr_t spe_ctx;
+       pthread_t pthread;
+       void *argp;
+} spu_data_t;
+
+// Struct for a process
+typedef struct _process_data {
+       uint64_t *procContentsAll;
+       int32_t *queueFromSPU;
+       int32_t *queueOnSPU;
+       uint64_t *ea_ls_base;
+       uint64_t *fifoTails;
+} ProcessData;
+
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/ppu/dolSupport.cpp b/dol/src/dol/visitor/cell/lib/ppu/dolSupport.cpp
new file mode 100644 (file)
index 0000000..3c6d36d
--- /dev/null
@@ -0,0 +1,98 @@
+#include "dolSupport.h"\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p) {\r
+       unsigned int\r
+                       pos =\r
+                                       static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->readPos;\r
+       pos += ((Fifo*) fifo)->read((char *) buf + pos, len - pos);\r
+\r
+       if (pos == len)\r
+               static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->readPos\r
+                               = 0;\r
+       else\r
+               static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->readPos\r
+                               = pos;\r
+       return pos;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p) {\r
+       unsigned int\r
+                       pos =\r
+                                       static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->writePos;\r
+       pos += ((Fifo*) fifo)->write((char *) buf + pos, len - pos);\r
+\r
+       if (pos == len)\r
+               static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->writePos\r
+                               = 0;\r
+       else\r
+               static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->writePos\r
+                               = pos;\r
+       return pos;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned reserve(void* fifo, void** destination, unsigned len,\r
+               DOLProcess* p) {\r
+       return ((WindowedFifo*) fifo)->reserve(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void release(void* fifo, DOLProcess* p) {\r
+       ((WindowedFifo*) fifo)->release();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned capture(void* fifo, void** destination, unsigned len,\r
+               DOLProcess* p) {\r
+       return ((WindowedFifo*) fifo)->capture(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void consume(void* fifo, DOLProcess* p) {\r
+       ((WindowedFifo*) fifo)->consume();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void DOL_detach(DOLProcess* p) {\r
+       static_cast<ProcessWrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->detach();\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0) {\r
+       *port = (void**) ((void**) base)[index0];\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0, int index1, int range1) {\r
+       *port = (void**) ((void**) base)[index0 * range1 + index1];\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0, int index1, int range1, int index2,\r
+               int range2) {\r
+       *port = (void**) ((void**) base)[index0 * range1 * range2 + index1\r
+                       * range2 + index2];\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0, int index1, int range1, int index2,\r
+               int range2, int index3, int range3) {\r
+       *port = (void**) ((void**) base)[index0 * range1 * range2 * range3\r
+                       + index1 * range2 * range3 + index2 * range3 + index3];\r
+}\r
diff --git a/dol/src/dol/visitor/cell/lib/ppu/dolSupport.h b/dol/src/dol/visitor/cell/lib/ppu/dolSupport.h
new file mode 100644 (file)
index 0000000..14a1c55
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef DOLSUPPORT_H\r
+#define DOLSUPPORT_H\r
+\r
+#include "dol.h"\r
+#include "pt.h"\r
+\r
+#include "ProcessWrapper.h"\r
+\r
+#include "Fifo.h"\r
+#include "WindowedFifo.h"\r
+\r
+typedef struct _process_data {\r
+    int lc;\r
+    ProcessWrapper *wrapper;\r
+} process_data;\r
+\r
+\r
+#define DOL_read(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), read(port, buf, size, process) == size);\r
+\r
+#define DOL_write(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), write(port, buf, size, process) == size);\r
+\r
+#define DOL_reserve(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), reserve(port, (void**)buf, size, process) == size);\r
+\r
+#define DOL_release(port, process) \\r
+    release(port, process);\r
+\r
+#define DOL_capture(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), capture(port, (void**)buf, size, process) == size);\r
+\r
+#define DOL_consume(port, process) \\r
+    consume(port, process);\r
+\r
+void DOL_detach(DOLProcess* p);\r
+\r
+//macros to deal with iterated ports\r
+/**\r
+ * macro to create a variable to store a port name\r
+ *\r
+ * @param name name of the variable\r
+ */\r
+#define CREATEPORTVAR(name) static Fifo *name\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+  createPort((void**)(&port), base, number_of_indices, index_range_pairs)\r
+\r
+#define GETINDEX(dimension) \\r
+  static_cast<ProcessWrapper *>((static_cast<process_data *>(p->wptr))->wrapper)->getIndex(dimension)\r
+\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1, int index2, int range2);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1, int index2, int range2, int index3, int range3);\r
+\r
+//fifo access functions\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+\r
+//windowed fifo access functions\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void release(void* fifo, DOLProcess* p);\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void consume(void* fifo, DOLProcess* p);\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cell/lib/ppu_main.h b/dol/src/dol/visitor/cell/lib/ppu_main.h
new file mode 100644 (file)
index 0000000..3b80e8a
--- /dev/null
@@ -0,0 +1,43 @@
+/**************************************************************** 
+ *     Header for the main function
+ *     Creator: lschor, 2008-11-21
+ *     Description: Header file for the main function of the PPU
+ *     
+ *     Revision: 
+ *     - 2008-11-21: Created
+ */
+
+#ifndef __PPU_MAIN_H__
+#define __PPU_MAIN_H__
+
+// System includes
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <libspe2.h>
+#include <pthread.h>
+
+// Local includes
+#include "lib/malloc_align.h"
+#include "lib/free_align.h"
+#include "lib/common.h"
+#include "lib/estimation.h"
+#include "lib/ppu/common_ppu.h"
+#include "cbe_mfc.h"
+
+// Program context for the Processes
+volatile process_context ctx_proc[NUM_PROCS_SPU] __attribute__ ((aligned(16)));
+
+// Program context for the SPEs
+volatile spu_context ctx_spu[NUM_SPES] __attribute__ ((aligned(16)));
+
+// The SPE-program-handler
+spe_program_handle_t *program[NUM_SPES];
+
+// Data for the SPEs
+spu_data_t data[NUM_SPES]; 
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/pt/lc-addrlabels.h b/dol/src/dol/visitor/cell/lib/pt/lc-addrlabels.h
new file mode 100644 (file)
index 0000000..b75f4e7
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+#define LC_RESUME(s)                           \
+  do {                                         \
+    if(s != NULL) {                            \
+      goto *s;                                 \
+    }                                          \
+  } while(0)
+
+#define LC_CONCAT2(s1, s2) s1##s2
+#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
+
+#define LC_SET(s)                              \
+  do {                                         \
+    LC_CONCAT(LC_LABEL, __LINE__):             \
+    (s) = &&LC_CONCAT(LC_LABEL, __LINE__);     \
+  } while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+/** @} */
diff --git a/dol/src/dol/visitor/cell/lib/pt/lc-switch.h b/dol/src/dol/visitor/cell/lib/pt/lc-switch.h
new file mode 100644 (file)
index 0000000..e47085c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWITCH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+   LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
diff --git a/dol/src/dol/visitor/cell/lib/pt/lc.h b/dol/src/dol/visitor/cell/lib/pt/lc.h
new file mode 100644 (file)
index 0000000..9ef2f0f
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the protothreads library.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer 
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+
+#ifdef LC_INCLUDE
+#include LC_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
diff --git a/dol/src/dol/visitor/cell/lib/pt/pt-sem.h b/dol/src/dol/visitor/cell/lib/pt/pt-sem.h
new file mode 100644 (file)
index 0000000..a6e1428
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the protothreads library.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt-sem.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup ptsem Protothread semaphores
+ * @{
+ *
+ * This module implements counting semaphores on top of
+ * protothreads. Semaphores are a synchronization primitive that
+ * provide two operations: "wait" and "signal". The "wait" operation
+ * checks the semaphore counter and blocks the thread if the counter
+ * is zero. The "signal" operation increases the semaphore counter but
+ * does not block. If another thread has blocked waiting for the
+ * semaphore that is signalled, the blocked thread will become
+ * runnable again.
+ *
+ * Semaphores can be used to implement other, more structured,
+ * synchronization primitives such as monitors and message
+ * queues/bounded buffers (see below).
+ *
+ * The following example shows how the producer-consumer problem, also
+ * known as the bounded buffer problem, can be solved using
+ * protothreads and semaphores. Notes on the program follow after the
+ * example.
+ *
+ \code
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static struct pt_sem mutex, full, empty;
+
+PT_THREAD(producer(struct pt *pt))
+{
+  static int produced;
+  
+  PT_BEGIN(pt);
+  
+  for(produced = 0; produced < NUM_ITEMS; ++produced) {
+  
+    PT_SEM_WAIT(pt, &full);
+    
+    PT_SEM_WAIT(pt, &mutex);
+    add_to_buffer(produce_item());    
+    PT_SEM_SIGNAL(pt, &mutex);
+    
+    PT_SEM_SIGNAL(pt, &empty);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(consumer(struct pt *pt))
+{
+  static int consumed;
+  
+  PT_BEGIN(pt);
+
+  for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+    
+    PT_SEM_WAIT(pt, &empty);
+    
+    PT_SEM_WAIT(pt, &mutex);    
+    consume_item(get_from_buffer());    
+    PT_SEM_SIGNAL(pt, &mutex);
+    
+    PT_SEM_SIGNAL(pt, &full);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(driver_thread(struct pt *pt))
+{
+  static struct pt pt_producer, pt_consumer;
+
+  PT_BEGIN(pt);
+  
+  PT_SEM_INIT(&empty, 0);
+  PT_SEM_INIT(&full, BUFSIZE);
+  PT_SEM_INIT(&mutex, 1);
+
+  PT_INIT(&pt_producer);
+  PT_INIT(&pt_consumer);
+
+  PT_WAIT_THREAD(pt, producer(&pt_producer) &
+                    consumer(&pt_consumer));
+
+  PT_END(pt);
+}
+ \endcode
+ *
+ * The program uses three protothreads: one protothread that
+ * implements the consumer, one thread that implements the producer,
+ * and one protothread that drives the two other protothreads. The
+ * program uses three semaphores: "full", "empty" and "mutex". The
+ * "mutex" semaphore is used to provide mutual exclusion for the
+ * buffer, the "empty" semaphore is used to block the consumer is the
+ * buffer is empty, and the "full" semaphore is used to block the
+ * producer is the buffer is full.
+ *
+ * The "driver_thread" holds two protothread state variables,
+ * "pt_producer" and "pt_consumer". It is important to note that both
+ * these variables are declared as <i>static</i>. If the static
+ * keyword is not used, both variables are stored on the stack. Since
+ * protothreads do not store the stack, these variables may be
+ * overwritten during a protothread wait operation. Similarly, both
+ * the "consumer" and "producer" protothreads declare their local
+ * variables as static, to avoid them being stored on the stack.
+ * 
+ *
+ */
+   
+/**
+ * \file
+ * Couting semaphores implemented on protothreads
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_SEM_H__
+#define __PT_SEM_H__
+
+#include "pt.h"
+
+struct pt_sem {
+  unsigned int count;
+};
+
+/**
+ * Initialize a semaphore
+ *
+ * This macro initializes a semaphore with a value for the
+ * counter. Internally, the semaphores use an "unsigned int" to
+ * represent the counter, and therefore the "count" argument should be
+ * within range of an unsigned int.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \param c (unsigned int) The initial count of the semaphore.
+ * \hideinitializer
+ */
+#define PT_SEM_INIT(s, c) (s)->count = c
+
+/**
+ * Wait for a semaphore
+ *
+ * This macro carries out the "wait" operation on the semaphore. The
+ * wait operation causes the protothread to block while the counter is
+ * zero. When the counter reaches a value larger than zero, the
+ * protothread will continue.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_WAIT(pt, s)     \
+  do {                                         \
+    PT_WAIT_UNTIL(pt, (s)->count > 0);         \
+    --(s)->count;                              \
+  } while(0)
+
+/**
+ * Signal a semaphore
+ *
+ * This macro carries out the "signal" operation on the semaphore. The
+ * signal operation increments the counter inside the semaphore, which
+ * eventually will cause waiting protothreads to continue executing.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_SIGNAL(pt, s) ++(s)->count
+
+#endif /* __PT_SEM_H__ */
+
+/** @} */
+/** @} */
+   
diff --git a/dol/src/dol/visitor/cell/lib/pt/pt.h b/dol/src/dol/visitor/cell/lib/pt/pt.h
new file mode 100644 (file)
index 0000000..a834a13
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+typedef struct _pt {
+  lc_t lc;
+} pt;
+
+#define PT_WAITING 0
+#define PT_YIELDED 1
+#define PT_EXITED  2
+#define PT_ENDED   3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt)   LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+                   PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)           \
+  do {/*printf("Test1: %d, %s\n",__LINE__,__FILE__);*/                                         \
+    LC_SET((pt)->lc); /*printf("Test2: %d\n",(pt)->lc);*/                              \
+    if(!(condition)) {                         \
+      return PT_WAITING;                       \
+    }                                          \
+  } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)            \
+  do {                                         \
+    PT_INIT((child));                          \
+    PT_WAIT_THREAD((pt), (thread));            \
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)                         \
+  do {                                         \
+    PT_INIT(pt);                               \
+    return PT_WAITING;                 \
+  } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)                            \
+  do {                                         \
+    PT_INIT(pt);                               \
+    return PT_EXITED;                  \
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)                           \
+  do {                                         \
+    PT_YIELD_FLAG = 0;                         \
+    LC_SET((pt)->lc);                          \
+    if(PT_YIELD_FLAG == 0) {                   \
+      return PT_YIELDED;                       \
+    }                                          \
+  } while(0)
+
+/**
+ * \brief      Yield from the protothread until a condition occurs.
+ * \param pt   A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ *             This function will yield the protothread, until the
+ *             specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond)               \
+  do {                                         \
+    PT_YIELD_FLAG = 0;                         \
+    LC_SET((pt)->lc);                          \
+    if((PT_YIELD_FLAG == 0) || !(cond)) {      \
+      return PT_YIELDED;                       \
+    }                                          \
+  } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */
diff --git a/dol/src/dol/visitor/cell/lib/spu/FastCommunication.cpp b/dol/src/dol/visitor/cell/lib/spu/FastCommunication.cpp
new file mode 100644 (file)
index 0000000..2f2c3de
--- /dev/null
@@ -0,0 +1,707 @@
+/*
+ * FastCommunication.cpp
+ *
+ *  Created on: Mar 3, 2009
+ *      Author: lschor
+ *
+ * Provides the communication between various processors.
+ *
+ *
+ *
+ * Description:
+ *
+ * Sender: The processor now has some data that need to be forwarded
+ * to another processor.
+ * Receiver: The processor that needs to get the data.
+ *
+ * Sender ----                                                      *
+ *            -----> Have some data                                 *
+ *                   (Len, queue)                                   *
+ *                                 ----------->        Receiver     *
+ *                                                                  *
+ *                                                  Check its len   *
+ *                                                                  *
+ *                                                  Sets up a DMA   *
+ *                                                  transfer to     *
+ *                                                  read from the   *
+ *                                 <--------------  queue to a      *
+ *                  MFC performs the                local buffer    *
+ *                  transfer                        (Alignment)     *
+ *       <---------                                                 *
+ *                                                                  *
+ *                                                                  *
+ *                                                  (Pools if the   *
+ *                                                   transfer is    *
+ *                                                   completed)     *
+ *                                                                  *
+ *                                                                  *
+ *                                                  Copy the data   *
+ *                                                  from its temp.  *
+ *                                                  buffer to the   *
+ *                                                  queue und       *
+ *                    Have completed <------------  informs the     *
+ *       <---------- (queue, len)                 sender            *
+ * Can increase the                                                 *
+ * pointers in the FIFO
+ *
+ *
+ * Has two ways to handling request, which are not possible
+ * to work out currently:
+ *  1) Send back "len = 0"
+ *     --> Needs to send more messages, but may bigger lens
+ *  2) Store them until you have enough space to read
+ *     --> Smaller lens and less messages
+ */
+
+#include "FastCommunication.h"
+
+/*
+ * Constructor
+ */
+FastCommunication::FastCommunication(int nrOfQueues, uint64_t ea_base,
+               uint64_t *ea_base_all, int32_t * queueFromSPEIn,
+               int32_t * queueOnSPEIn, uint64_t *fifoTails) {
+
+       // Set the base address
+       _ea_base = ea_base;
+
+       _ea_base_all = ea_base_all;
+       queueFromSPE = queueFromSPEIn;
+       queueOnSPE = queueOnSPEIn;
+       _fifoTails = fifoTails;
+
+       _nrOfQueues = nrOfQueues;
+       try { _fifos = new fifoCollection[nrOfQueues]; }
+        catch(std::bad_alloc &e) {
+            fprintf(stderr, "[FastCommunication] Memory allocation failure\n");
+           exit(1);
+        }
+       _nrOfRequest = 0;
+
+       for (int i = 0; i < MAXNOREQ; i++) {
+               _request[i].valid = false;
+       }
+}
+
+/*
+ * Deconstructor
+ */
+FastCommunication::~FastCommunication() {
+       delete _fifos;
+}
+
+/*
+ * Register an additional FIFO in the Communication
+ */
+bool FastCommunication::addFifo(int fifoNr, Fifo* fifo, int type,
+               int queue) {
+       _fifos[fifoNr].fifo = fifo;
+       _fifos[fifoNr].queue = queue;
+       _fifos[fifoNr].type = type;
+       _fifos[fifoNr].iswfifo = false;
+
+       // Per FIFO queue, we need two requests, but we store at max MAXNOREQ of them
+       if (_nrOfRequest < MAXNOREQ) {
+               _nrOfRequest += 2;
+       }
+
+       return true;
+}
+
+/*
+ * Register an additional WindowedFIFO in the Communication
+ */
+bool FastCommunication::addWFifo(int fifoNr, WindowedFifo* wfifo,
+               int type, int queue) {
+       _fifos[fifoNr].wfifo = wfifo;
+       _fifos[fifoNr].queue = queue;
+       _fifos[fifoNr].type = type;
+       _fifos[fifoNr].iswfifo = true;
+
+       // Per FIFO queue, we need two requests, but we store at max MAXNOREQ of them
+       if (_nrOfRequest < MAXNOREQ) {
+               _nrOfRequest += 2;
+       }
+
+       return true;
+}
+
+/*
+ * Communication: Main update procedure to update
+ */
+bool FastCommunication::update() {
+       // Check if you have received a new message
+       while (spu_stat_in_mbox() > 0) {
+               uint32_t messageIn = spu_read_in_mbox();
+
+               uint32_t code = GETFASTCODE(messageIn);
+               uint32_t queue = GETFASTQUEUE(messageIn);
+               uint32_t len = GETFASTLEN(messageIn);
+
+               /***************************************************************************************************************/
+               if (code == SPE_READ_DEMAND) // One should start a read process
+               {
+                       // Find out for which fifo the request is
+                       fifoCollection *fifocol = NULL;
+                       int i = 0;
+                       for (i = 0; i < _nrOfQueues; i++) {
+                               if (_fifos[i].queue == queue) {
+                                       fifocol = &_fifos[i];
+                                       break;
+                               }
+                       }
+
+                       // The queue was not found
+                       if (fifocol == NULL) {
+                               printf("SPU COM> ERROR, this queue does not exists!\n");
+                               return false;
+                       }
+
+                       // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                       // Windowed FIFO
+                       if (_fifos[i].iswfifo) {
+
+                               WindowedFifo* wfifo = NULL;
+                               wfifo = _fifos[i].wfifo;
+
+                               // Find the current tail of the queue from where to read
+                               uint32_t inTail = wfifo->_inTail;
+
+                               // This is the len we like to read
+                               len = len > (wfifo->unused()) ? wfifo->unused() : len;
+
+                               // We can read something
+                               if (len > 0) {
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       // reserve DMA tag ID
+                                       uint32_t tag_id;
+                                       if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID) {
+                                               printf("SPE: ERROR - can't reserve a tag ID\n");
+                                               return false;
+                                       }
+
+                                       // Generate the base address of the input FIFO
+                                       uint64_t baseAddress = _fifoTails[queue] + inTail;
+
+                                       // Align the address to the correct factor (in general 128 or 32)
+                                       while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                               baseAddress--;
+
+                                       // Offset --> How much we had to align
+                                       uint32_t offset = _fifoTails[queue] + inTail
+                                                       - baseAddress;
+
+                                       request->data = (char *) _malloc_align(roundDMA(len
+                                                       + offset), ALIGNMENT_FACTOR);
+
+                                       // Store all data in the request buffer
+                                       request->len = len;
+
+                                       request->wfifo = wfifo;
+                                       request->iswfifo = true;
+
+                                       request->status = read_started;
+                                       request->queue = queue;
+                                       request->offset = offset;
+                                       request->tag_id = tag_id;
+
+                                       // Set up the request in the MFC
+                                       mfc_get((void *) &(request->data[0]), baseAddress,
+                                                       roundDMA(len + offset), tag_id, 0, 0);
+                               }
+
+                               else {
+#ifndef STORE_REQUESTS                // Send len = 0 back to the sender, this one should try it in a later phase
+                                       uint32_t message = CREATEFASTMESSAGE(
+                                                       SPE_READ_COMPLETE, queue, 0);
+                                       sendMessage(message, queueFromSPE[queue]);
+#else                                // I store the request and may try in a later time to start the transfer
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL)
+                                       {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       request->len = len;
+                                       request->wfifo = wfifo;
+                                       request->iswfifo = true;
+                                       request->status = read_pending;
+                                       request->queue = queue;
+#endif
+                               }
+                       }
+
+                       // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                       // Classic FIFO
+                       else {
+                               Fifo* fifo = NULL;
+                               fifo = _fifos[i].fifo;
+
+                               uint32_t inTail = fifo->_inTail;
+
+                               // This is the len we like to read
+                               len = len > (fifo->unused()) ? fifo->unused() : len;
+
+                               // We can read something
+                               if (len > 0) {
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       uint32_t tag_id;
+
+                                       // reserve DMA tag ID
+                                       if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID) {
+                                               printf("SPE: ERROR - can't reserve a tag ID\n");
+                                               return false;
+                                       }
+
+                                       uint64_t baseAddress = _fifoTails[queue] + inTail;
+
+                                       while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                               baseAddress--;
+
+                                       // Offset
+                                       uint32_t offset = _fifoTails[queue] + inTail
+                                                       - baseAddress;
+
+                                       // Store all data in the request buffer
+                                       request->data = (char *) _malloc_align(roundDMA(len
+                                                       + offset), ALIGNMENT_FACTOR);
+                                       request->len = len;
+                                       request->fifo = fifo;
+                                       request->iswfifo = false;
+                                       request->status = read_started;
+                                       request->queue = queue;
+                                       request->offset = offset;
+                                       request->tag_id = tag_id;
+
+                                       // Tell the fifo that one has reserved some data
+
+                                       mfc_get((void *) &(request->data[0]), baseAddress,
+                                                       roundDMA(len + offset), tag_id, 0, 0);
+                               }
+
+                               // len == 0
+                               else {
+#ifndef STORE_REQUESTS                // Send len = 0 back to the sender, this one should try it in a later phase
+                                       uint32_t message = CREATEFASTMESSAGE(
+                                                       SPE_READ_COMPLETE, queue, 0);
+                                       sendMessage(message, queueFromSPE[queue]);
+#else                                // I store the request and may try in a later time to start the transfer
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL)
+                                       {
+                                               // not possible to start a request for this SPE --> Send len = 0
+                                               uint32_t message = CREATEFASTMESSAGE(SPE_READ_COMPLETE, queue, 0);
+                                               sendMessage(message, queueFromSPE[queue]);
+                                               return false;
+                                       }
+
+                                       request->len = len;
+                                       request->fifo = fifo;
+                                       request->iswfifo = false;
+                                       request->status = read_pending;
+                                       request->queue = queue;
+#endif
+                               }
+                       }
+               }
+
+               /***************************************************************************************************************/
+               else if (code == SPE_READ_COMPLETE) // A read has finished
+               {
+                       // Get the stored request
+                       comRequest* request = getRequest(read_request_sent, queue);
+                       if (request == NULL) {
+                               printf(
+                                               ">>>>>>>>>>>>>>>>> Communicate SPU> Couldn't find the request\n");
+                               return 0;
+                       }
+
+                       // Inform my FIFO that the request is completed
+                       if (request->iswfifo)
+                               request->wfifo->dmaRead(len);
+                       else
+                               request->fifo->dmaRead(len);
+
+                       // Request free
+                       deleteRequest(request);
+               }
+       }
+
+       /***************************************************************************************************************/
+       // Check if some active write processes have finished
+       uint8_t req = _currentRequest;
+
+       for (int i = 0; i < _nrOfRequest; i++) // Check all possible requests
+       {
+               if (_request[req].valid) // Only to check if the request is valid
+               {
+                       if (_request[req].status == read_started) { // We have setup the request, now check if it is complete
+
+                               // If I cannot send a message to the corresponding processor --> Do not have to check it
+                               if (!(testMessage(queueOnSPE[_request[req].queue]) > 0))
+                                       continue;
+
+                               // Check if the specific Tag-ID has completed
+                               uint32_t tag_id = _request[req].tag_id;
+                               mfc_write_tag_mask(1 << tag_id);
+                               mfc_write_tag_update(MFC_TAG_UPDATE_IMMEDIATE);
+                               uint32_t ret = mfc_read_tag_status();
+
+                               if (!((ret & (1 << tag_id)) == 0)) {
+
+                                       // This update is finished
+                                       mfc_tag_release(tag_id);
+
+                                       // Have to write the data into the fifo
+                                       if (_request[req].iswfifo) { // WFIFO
+
+                                               _request[req].wfifo->dmaWrite(
+                                                               (char *) _request[req].data
+                                                                               + _request[req].offset,
+                                                               _request[req].len);
+                                               _free_align(_request[req].data);
+
+                                               // Increase the inTail value (used to know where the last request was started)
+                                               _request[req].wfifo->_inTail
+                                                               = (_request[req].wfifo->_inTail
+                                                                               + _request[req].len) % (FIFO_SIZE[_request[req].queue]);
+                                       } else { // FIFO
+                                               _request[req].fifo->write(
+                                                               (char *) _request[req].data
+                                                                               + _request[req].offset,
+                                                               _request[req].len);
+                                               _free_align(_request[req].data);
+
+                                               _request[req].fifo->_inTail
+                                                               = (_request[req].fifo->_inTail
+                                                                               + _request[req].len) % (FIFO_SIZE[_request[req].queue]);
+
+                                       }
+
+                                       // Inform the sender about the event
+                                       uint32_t message = CREATEFASTMESSAGE(
+                                                       SPE_READ_COMPLETE, _request[req].queue,
+                                                       _request[req].len);
+                                       sendMessage(message, queueFromSPE[_request[req].queue]);
+
+                                       // Delete the request
+                                       deleteRequest(&_request[req]);
+                                       _currentRequest = (req + 1) % _nrOfRequest;
+
+                                       break; // continue is also working
+                               }
+                       } else if (_request[req].status == read_pending) { // Has an open request for sending
+
+                               // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                               // Windowed FIFO
+                               if (_request[req].iswfifo) {
+
+                                       if (_request[req].wfifo->unused() > 0) {
+                                               comRequest *request = &_request[req];
+
+                                               // This is the len we like to read
+                                               uint32_t len =  request->len > (request->wfifo->unused()) ? request->wfifo->unused()
+                                                                       : request->len;
+
+                                               // reserve DMA tag ID
+                                               uint32_t tag_id;
+                                               if ((tag_id = mfc_tag_reserve())
+                                                               == MFC_TAG_INVALID) {
+                                                       printf("SPE: ERROR - can't reserve a tag ID\n");
+                                                       return false;
+                                               }
+
+                                               uint32_t inTail = request->wfifo->_inTail;
+                                               uint64_t baseAddress = _fifoTails[request->queue]
+                                                               + inTail;
+
+                                               while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                                       baseAddress--;
+
+                                               // Offset --> How much we had to align
+                                               uint32_t offset = _fifoTails[request->queue]
+                                                               + inTail - baseAddress;
+
+                                               request->data = (char *) _malloc_align(roundDMA(
+                                                               len + offset), ALIGNMENT_FACTOR);
+                                               request->len = len;
+                                               request->status = read_started;
+                                               request->offset = offset;
+                                               request->tag_id = tag_id;
+
+                                               // Set up the request in the MFC
+                                               mfc_get((void *) &(request->data[0]), baseAddress,
+                                                               roundDMA(len + offset), tag_id, 0, 0);
+                                       }
+                               }
+
+                               // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+                               // Classic FIFO
+                               else {
+
+                                       if (_request[req].fifo->unused() > 0) {
+                                               comRequest *request = &_request[req];
+
+                                               // This is the len we like to read
+                                               uint32_t len = request->len > (request->fifo->unused()) ? request->fifo->unused()
+                                                                       : request->len;
+
+                                               uint32_t tag_id;
+                                               // reserve DMA tag ID
+                                               if ((tag_id = mfc_tag_reserve())
+                                                               == MFC_TAG_INVALID) {
+                                                       printf("SPE: ERROR - can't reserve a tag ID\n");
+                                                       return false;
+                                               }
+
+                                               uint32_t inTail = request->fifo->_inTail;
+                                               uint64_t baseAddress = _fifoTails[request->queue] + inTail;
+
+                                               while (baseAddress % ALIGNMENT_FACTOR_POWER2 != 0)
+                                                       baseAddress--;
+
+                                               // Offset
+                                               uint32_t offset = _fifoTails[request->queue]
+                                                               + inTail - baseAddress;
+
+                                               // Store all data in the request buffer
+                                               request->data = (char *) _malloc_align(roundDMA(
+                                                               len + offset), ALIGNMENT_FACTOR);
+                                               request->len = len;
+                                               request->status = read_started;
+                                               request->offset = offset;
+                                               request->tag_id = tag_id;
+
+                                               // Start the DMA transfer
+                                               mfc_get((void *) &(request->data[0]), baseAddress,
+                                                               roundDMA(len + offset), tag_id, 0, 0);
+                                       }
+                               }
+                       }
+               }
+               // Go to the next Request
+               req = (req + 1) % _nrOfRequest;
+       }
+
+       /***************************************************************************************************************/
+       // Start a new request to the receiver of a FIFO
+       for (int i = 0; i < _nrOfQueues; i++) {
+               if (_fifos[i].type == this->out) // Only out-FIFO have to be quecked
+               {
+                       if (_fifos[i].iswfifo) { // WFIFO
+
+                               // Start only a write process if there is really enough place in the outbound mailbox
+                               if (_fifos[i].wfifo->dmaAllowed() && _fifos[i].wfifo->used() > 0) {
+                                       uint32_t queue = _fifos[i].queue;
+
+                                       // Can we send a message to this processor or is it blocked?
+                                       if (testMessage(queueOnSPE[queue]) <= 0) {
+                                               continue;
+                                       }
+
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                       } else {
+                                               uint32_t len = _fifos[i].wfifo->dmaStart();
+                                               // Create a write-demand message
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_DEMAND, queue, len);
+
+                                               request->len = len;
+                                               request->queue = queue;
+                                               request->status = read_request_sent;
+                                               request->wfifo = _fifos[i].wfifo;
+                                               request->iswfifo = true;
+
+                                               sendMessage(message, queueOnSPE[queue]);
+                                       }
+                                       break;
+                               }
+                       } else { // FIFO
+
+                               // Start only a write process if there is really enough place in the outbound mailbox
+                               if (_fifos[i].fifo->dmaAllowed() && _fifos[i].fifo->used() > 0) {
+                                       uint32_t queue = _fifos[i].queue;
+
+                                       // Check if we can send a message to the processor
+                                       if (testMessage(queueOnSPE[queue]) <= 0) {
+                                               continue;
+                                       }
+
+                                       // Write all information we used to the request-memory
+                                       comRequest* request = newRequest();
+
+                                       // Has no memory to store a new request
+                                       if (request == NULL) {
+                                       } else {
+                                               uint32_t len = _fifos[i].fifo->dmaStart();
+                                               // Create a write-demand message
+                                               uint32_t message = CREATEFASTMESSAGE(
+                                                               SPE_READ_DEMAND, queue, len);
+
+                                               request->len = len;
+                                               request->queue = queue;
+                                               request->status = read_request_sent;
+                                               request->fifo = _fifos[i].fifo;
+                                               request->iswfifo = false;
+
+                                               sendMessage(message, queueOnSPE[queue]);
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       }
+       return true;
+}
+
+/*
+ * Create a new request to store in the cache
+ *
+ */
+comRequest* FastCommunication::newRequest() {
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (!_request[i].valid) {
+                       _request[i].valid = true;
+                       return &(_request[i]);
+               }
+       }
+
+       return NULL;
+}
+
+/*
+ * Delete the request
+ *
+ */
+void FastCommunication::deleteRequest(comRequest* request) {
+       request->valid = false;
+}
+
+/*
+ * Returns the request one like to get
+ */
+comRequest* FastCommunication::getRequest(uint8_t status, uint32_t queue) {
+       uint8_t req = _currentRequest;
+
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (_request[req].valid && _request[req].status == status
+                               && _request[req].queue == queue) {
+                       _currentRequest = (req + 1) % _nrOfRequest;
+                       return &(_request[req]);
+               }
+               req = (req + 1) % _nrOfRequest;
+       }
+
+       return NULL;
+}
+
+/**
+ * True if no communication is necessary, false if there is active communication
+ */
+bool FastCommunication::empty() {
+       // check if one fifo would like to send something to another SPE
+       for (int i = 0; i < _nrOfQueues; i++) {
+               if (_fifos[i].type == this->out) {
+                       if (_fifos[i].iswfifo) {
+                               if (_fifos[i].wfifo->used() > 0) 
+                               {
+                                       return false;
+                               }
+                       } else {
+                               if (_fifos[i].fifo->used() > 0)
+                               {
+                                       return false;
+                               }
+                       }
+               }
+       }
+
+       // are open sendings?
+       for (int i = 0; i < _nrOfRequest; i++) {
+               if (_request[i].valid) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+void FastCommunication::sendMessage(uint32_t message, int32_t process) {
+       // Simple forward the message to the PPE
+       if (process <= -1) {
+               spu_write_out_mbox(message);
+       }
+
+       // Forward message to the corresponding SPE
+       else {
+               uint32_t tag_id;
+
+               // reserve DMA tag ID
+               if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID) {
+                       printf("SPE: ERROR - can't reserve a tag ID\n");
+                       return;
+               }
+
+               //printf("SPE > OUT Message to process = %d, addr = %llx\n", process, _ea_base_all[process]);
+               write_in_mbox(message, _ea_base_all[process], tag_id);
+               mfc_tag_release(tag_id);
+       }
+}
+
+int FastCommunication::testMessage(int32_t process) {
+       //int32_t process = queueOnSPE[queue];
+
+       // Simple forward the message to the PPE
+       if (process <= -1) {
+               return spu_stat_out_mbox();
+       }
+
+       // Forward message to the corresponding SPE
+       else {
+               uint32_t tag_id;
+
+               // reserve DMA tag ID
+               if ((tag_id = mfc_tag_reserve()) == MFC_TAG_INVALID) {
+                       printf("SPE: ERROR - can't reserve a tag ID\n");
+                       return 0;
+               }
+
+               // IMPORTANT: THIS IS NOT RACE CONDITION FREE!!!!
+               int test = status_in_mbox(_ea_base_all[process], tag_id);
+               mfc_tag_release(tag_id);
+               return test;
+       }
+}
diff --git a/dol/src/dol/visitor/cell/lib/spu/FastCommunication.h b/dol/src/dol/visitor/cell/lib/spu/FastCommunication.h
new file mode 100644 (file)
index 0000000..a787556
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * FastCommunication.h
+ *
+ *  Created on: Mar 3, 2009
+ *      Author: lschor
+ */
+
+#ifndef FASTCOMMUNICATION_H_
+#define FASTCOMMUNICATION_H_
+
+// CBE includes
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+// C++ includes
+#include <stdint.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <new>
+
+// Local includes
+#include "Fifo.h"
+#include "WindowedFifo.h"
+#include "../common.h"
+
+// For external Mailbox Communication
+#include "../spu_mfcio_ext.h"
+
+// Include to allocate/free using for DMA transfers
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+//Cell Macros
+#define waittag(tag_id) mfc_write_tag_mask(1<<tag_id);    mfc_read_tag_status_all();
+
+#define MAXNOREQ 256
+
+// This is a full Request
+typedef struct _comRequest {
+    bool valid;              // If the request is valid
+    uint32_t status;      // Status of the request (read_..., ...)
+    
+    uint32_t tag_id;      // Tag ID
+    uint32_t queue;       // The queue which is used by the request
+    
+    bool iswfifo;         // True if it is a WFIFO
+    Fifo* fifo;           // Pointer to the used FIFO
+    WindowedFifo* wfifo;  // Pointer to the WFIFO
+
+    uint32_t len;           // The len of the data
+    char* data;           // Point to the data which are stored    
+    uint32_t offset;      // Offset generated by alignment
+} comRequest;
+
+// Struct to store a FIFO
+typedef struct _fifoCollection {
+    int type;               // local, in or out
+    int queue;            // Corresponding queue number
+
+    bool iswfifo;         // True if it is a WFIFO
+    WindowedFifo* wfifo;  // Pointer to the WFIFO
+    Fifo* fifo;           // Pointer to the FIFO   
+} fifoCollection;
+
+/**
+ * The Communication Class
+ */
+class FastCommunication {
+public:
+    FastCommunication(int nrOfQueues, uint64_t ea_base, uint64_t *ea_base_all, int32_t * queueFromSPE, int32_t * queueOnSPE, uint64_t * fifoTails);
+    virtual ~FastCommunication();
+
+    bool addFifo(int fifoNr, Fifo* fifo, int type, int queue);
+    bool addWFifo(int fifoNr, WindowedFifo* fifo, int type, int queue);
+    
+    bool update();
+    bool empty();
+
+    static int const local = 0;
+    static int const in = 1;
+    static int const out = 2;
+
+    static int const comIn = 0;
+    static int const comOut = 1;
+
+    static int const read_request_sent = 0;
+    static int const read_started = 1;
+    static int const read_pending = 2;
+
+protected:
+    // To send messages
+    void sendMessage(uint32_t message, int32_t process);
+    int testMessage(int32_t process);
+
+    // Requests
+    comRequest* newRequest();
+    void deleteRequest(comRequest* request);
+    comRequest* getRequest(uint8_t status, uint32_t queue);
+
+    // Queues
+    int _nrOfQueues;
+    fifoCollection * _fifos;
+
+    // Request
+    int _nrOfRequest;           // Need only 2 requests per queue (others are blocked...)
+    comRequest _request[MAXNOREQ];    // Stores at maximum 12 requests
+    uint8_t _currentRequest;    // The current request (so that we can start in the next iteration by the next one)
+    
+    // Pointers for communication
+    uint64_t _ea_base;          // This is my base address
+    uint64_t * _ea_base_all;    // All base addresses of the control blocks of the other SPEs (for sending message to)
+    int32_t * queueFromSPE;     // Array which tells us from which processor a queue comes
+    int32_t * queueOnSPE;       // Array which tells us to which processor a queue goes
+    uint64_t * _fifoTails;      // Pointers to the tail of the other queues
+};
+
+#endif /* FASTCOMMUNICATION_H_ */
diff --git a/dol/src/dol/visitor/cell/lib/spu/Fifo.cpp b/dol/src/dol/visitor/cell/lib/spu/Fifo.cpp
new file mode 100644 (file)
index 0000000..959b70f
--- /dev/null
@@ -0,0 +1,182 @@
+#include "Fifo.h"
+
+/**
+ *
+ */
+Fifo::Fifo(unsigned size = 18) {
+       //except at the beginning, _head and _tail must never overlap,
+       //otherwise one does not know whether the buffer is full or
+       //empty. to have nevertheless a buffer with the given capacity,
+       //a buffer with one more element is allocated.
+
+       _size = size;
+       _buffer = (char *) _malloc_align(_size, ALIGNMENT_FACTOR);
+  if(!_buffer) {
+    fprintf(stderr,"[FIFO] Memory allocation failure\n");
+    exit(-1);
+  }
+       _pos = 0;
+       _tail = 0;
+       _blocked = 0;
+
+       _inTail = 0;
+       _activeDMA = false;
+}
+
+/**
+ *
+ */
+Fifo::~Fifo() {
+       if (_buffer) {
+               _free_align(_buffer);
+       }
+       _buffer = 0;
+       _pos = 0;
+       _tail = 0;
+}
+
+/**
+ *
+ */
+unsigned Fifo::read(void *destination, unsigned len) {
+
+       char* buffer = (char*) destination;
+       unsigned read = (len <= used() ? len : used());
+
+       if (_tail + read < _size) {
+               memcpy(buffer, _buffer + _tail, read);
+       } else {
+               memcpy(buffer, _buffer + _tail, _size - _tail);
+               memcpy(buffer + _size - _tail, _buffer, read - _size + _tail);
+       }
+
+       _tail = ((unsigned) (_tail + read) % _size);
+       _pos -= read;
+       return read;
+}
+
+/**
+ *
+ */
+unsigned Fifo::write(const void *source, unsigned len) {
+
+       char* buffer = (char*) source;
+       unsigned write = (len <= unused() ? len : unused());
+       unsigned head = (_tail + _pos) % _size;
+
+       if (head + write < _size) {
+               memcpy(_buffer + head, buffer, write);
+       } else {
+               memcpy(_buffer + head, buffer, _size - head);
+               memcpy(_buffer, buffer + _size - head, write - _size + head);
+       }
+
+       _pos += write;
+       return write;
+}
+
+/**
+ * Size of this fifo
+ */
+unsigned Fifo::size() const {
+       return (_size);
+}
+
+/**
+ * How many bytes is currently free in the buffer
+ */
+unsigned Fifo::unused() const {
+       return (_size) - used();
+}
+
+/**
+ * How many data are currently stored in the fifo
+ */
+unsigned Fifo::used() const {
+       return _pos;
+}
+
+/*
+ * Get the pointer to the start of the queue
+ */
+char *Fifo::getQueuePointer() {
+       return _buffer;
+}
+
+/*
+ * Has completed a dma read process, i.e. has read out of the queue
+ */
+void Fifo::dmaRead(unsigned len) {
+       _activeDMA = false;
+
+       if (len == 0) {
+               _blocked = BLOCKED_MAX_NR;
+       } else {
+               _tail = ((unsigned) (_tail + len) % _size);
+               _pos -= len;
+       }
+}
+
+/*
+ * Start a DMA request, returns the current space one have
+ */
+unsigned Fifo::dmaStart() {
+       _activeDMA = true;
+
+       if (_tail + _pos > _size) {
+               return _size - _tail;
+       } else {
+               return _pos;
+       }
+}
+
+/*
+ * Is allowed to start a dma request
+ */
+bool Fifo::dmaAllowed() {
+       if (_blocked > 0) {
+               _blocked--;
+               return false;
+       } else {
+               return !_activeDMA;
+       }
+}
+
+/**
+ * Test the implementation
+ */
+/*
+ int main() {
+ std::cout.width(5);
+ Fifo *myFifo = new Fifo();
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 6; i++) {
+ std::cout << "write " << i << " to Fifo.    ";
+ int write = myFifo->write(&i, sizeof(int));
+ printf(" %d ", write);
+ if (write == sizeof(int)) {
+ std::cout << "used: " << std::setw(2) << myFifo->used()
+ << ", unused: " << std::setw(2) << myFifo->unused()
+ << ", size: "  << std::setw(2) << myFifo->size()
+ << std::endl;
+ } else {
+ std::cout << std::endl;
+ }
+ }
+ for (int i = 0; i < 6; i++) {
+ int value;
+ int read = myFifo->read(&value, sizeof(int));
+ printf(" %d ", read);
+ if (read == sizeof(int)) {
+ std::cout << "read " << value << "  from Fifo   ";
+ std::cout << "used: " << std::setw(2) << myFifo->used()
+ << ", unused: " << std::setw(2) << myFifo->unused()
+ << ", size: "  << std::setw(2) << myFifo->size()
+ << std::endl;
+ }
+ }
+ }
+ delete myFifo;
+ return 0;
+ }
+ */
diff --git a/dol/src/dol/visitor/cell/lib/spu/Fifo.h b/dol/src/dol/visitor/cell/lib/spu/Fifo.h
new file mode 100644 (file)
index 0000000..798e7dd
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _FIFO_H_
+#define _FIFO_H_
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../constant.h"
+
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+class Fifo {
+    public:
+        Fifo(unsigned size);
+        virtual ~Fifo();
+
+               // Read / Write
+        virtual unsigned read(void *destination, unsigned len);
+        virtual unsigned write(const void *source, unsigned len);
+        
+               // Buffer functions
+               virtual unsigned used() const;
+        virtual unsigned unused() const;
+        virtual unsigned size() const;
+        
+               // DMA functions
+        virtual char *getQueuePointer();
+        virtual void dmaRead(unsigned len);
+        virtual unsigned dmaStart();
+        virtual bool dmaAllowed();
+                               
+           // Global Variables
+        unsigned _inTail;
+
+    protected:
+        char *_buffer;         // Buffer pointer
+
+        unsigned _tail;        // Pointer to the tail
+        
+               unsigned _pos;         // Amount used
+        unsigned _size;        // Size of the buffer
+        
+               unsigned _blocked;     // Number of blocking necessary
+        bool _activeDMA;       // Active DMA?
+};
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/spu/WindowedFifo.cpp b/dol/src/dol/visitor/cell/lib/spu/WindowedFifo.cpp
new file mode 100644 (file)
index 0000000..9b03f6a
--- /dev/null
@@ -0,0 +1,277 @@
+#include "WindowedFifo.h"
+
+/**
+ *
+ */
+WindowedFifo::WindowedFifo(unsigned size = 20) {
+       //std::cout << "Create WindowedFifo." << std::endl;
+
+       _size = size;
+       _buffer = (char *) _malloc_align(_size, ALIGNMENT_FACTOR);
+  if(!_buffer) {
+    fprintf(stderr,"[WFIFO] Memory allocation failure\n");
+    exit(-1);
+  }
+       _head = 0;
+       _tail = 0;
+       _headRoom = 0;
+       _tailRoom = 0;
+       _use = 0;
+
+       _isHeadReserved = false;
+       _isTailReserved = false;
+
+       // For DMA transfers
+       _blocked = 0;
+       _activeDMA = false;
+}
+
+/**
+ *
+ */
+WindowedFifo::~WindowedFifo() {
+       //std::cout << "Delete WindowedFifo." << std::endl;
+       if (_buffer) {
+               _free_align(_buffer);
+       }
+       _buffer = 0;
+       _head = 0;
+       _tail = 0;
+       _use = 0;
+       //std::cout << "Deleted WindowedFifo." << std::endl;
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::reserve(char** destination, unsigned len) {
+
+       //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;
+
+       //can only reserve once piece at a time
+       if (_isHeadReserved) {
+               *destination = 0;
+               return 0;
+       }
+
+       //reserve at most as much memory as still available in the buffer
+       unsigned write = (len <= _size - _use ? len : 0);
+
+       if (write > 0) {
+               //if wrap-around in buffer: return only buffer for the
+               //contiguous buffer space
+               if (_head + write > _size) {
+                       write = _size - _head;
+               }
+
+               _headRoom = (_head + write) == _size ? 0 : _head + write;
+               *destination = &(_buffer[_head]);
+               _isHeadReserved = true;
+       }
+
+       //std::cout << "Reserved " << write << " bytes." << std::endl;
+       _writeReserve = write;
+       return write;
+}
+
+/**
+ *
+ */
+void WindowedFifo::release() {
+       if (_isHeadReserved) {
+               //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;
+               _head = _headRoom;
+               _use += _writeReserve;
+               _isHeadReserved = false;
+       }
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::capture(char **destination, unsigned len) {
+
+       //std::cout << "Attempt to capture " << len << " bytes." << std::endl;
+
+       if (_isTailReserved) {
+               //std::cout << "Only one attempt to capture allowed." << std::endl;
+               *destination = 0;
+               return 0;
+       }
+
+       //capture at most as much data as available in the buffer
+       unsigned read = (len <= _use ? len : 0);
+
+       if (read > 0) {
+               //if wrap-around in buffer: return only buffer for the
+               //conntiguous buffer space
+               if (_tail + read > _size) {
+                       read = _size - _tail;
+               }
+
+               _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;
+               *destination = &(_buffer[_tail]);
+               _isTailReserved = true;
+       }
+
+       _readReserve = read;
+       //std::cout << "Captured " << read << " bytes." << std::endl;
+
+       return read;
+}
+
+/**
+ *
+ */
+void WindowedFifo::consume() {
+       if (_isTailReserved) {
+               //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;
+               _tail = _tailRoom;
+               _use -= _readReserve;
+               _isTailReserved = false;
+       }
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::size() const {
+       return _size;
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::unused() const {
+       return _size - _use;
+}
+
+/**
+ *
+ */
+unsigned WindowedFifo::used() const {
+       return _use;
+}
+
+/*
+ * Get the pointer to the start of the queue
+ */
+char *WindowedFifo::getQueuePointer() {
+       return _buffer;
+}
+
+/*
+ * Has completed a dma read process, i.e. has read out of the queue
+ */
+void WindowedFifo::dmaRead(unsigned len) {
+       if (len == 0) {
+               _blocked = BLOCKED_MAX_NR;
+       } else {
+               _tail = ((unsigned) (_tail + len) % _size);
+               _use -= len;
+       }
+
+       _activeDMA = false;
+}
+
+/*
+ * Start a DMA request, returns the current space one have
+ */
+unsigned WindowedFifo::dmaStart() {
+       _activeDMA = true;
+
+       if (_tail + _use > _size) {
+               return _size - _tail;
+       } else {
+               return _use;
+       }
+}
+
+/*
+ * Is allowed to start a dma request
+ */
+bool WindowedFifo::dmaAllowed() {
+#ifndef STORE_REQUESTS
+       if (_blocked > 0) {
+               _blocked--;
+               return false;
+       } else {
+               return !_activeDMA;
+       }
+#else
+       return !_activeDMA;
+#endif
+}
+
+/**
+ * Is needed for DMA transfers
+ */
+unsigned WindowedFifo::dmaWrite(const void *source, unsigned len) {
+
+       char* buffer = (char*) source;
+
+       if (_head + len < _size) {
+               memcpy(_buffer + _head, buffer, len);
+       } else {
+               // We should never be here!
+               memcpy(_buffer + _head, buffer, _size - _head);
+               memcpy(_buffer, buffer + _size - _head, len - _size + _head);
+       }
+       _use += len;
+       _head = (_head + len) >= _size ? _head + len - _size : _head + len;
+
+       return len;
+}
+
+/**
+ * Test the implementation
+ */
+/*
+ int main() {
+ WindowedFifo *myFifo = new WindowedFifo(16);
+
+ int* buf1;
+ int* buf2;
+ int x = myFifo->reserve((char**)&buf1, 8);
+ *buf1 = 10;
+ *(buf1 + 1) = 20;
+ myFifo->release();
+ int y = myFifo->capture((char**)&buf2, 8);
+ std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl;
+ myFifo->consume();
+
+ for (int j = 0; j < 3; j++) {
+ for (int i = 0; i < 6; i++) {
+ std::cout << "write " << i << " to Fifo.    ";
+ int write = myFifo->reserve((char**)&buf1, sizeof(int));
+ if (write == sizeof(int)) {
+ *buf1 = i;
+ myFifo->release();
+ std::cout << "used: " << std::setw(2) << myFifo->used()
+ << ", unused: " << std::setw(2) << myFifo->unused()
+ << ", size: "  << std::setw(2) << myFifo->size()
+ << std::endl;
+ } else {
+ std::cout << std::endl;
+ }
+ }
+ for (int i = 0; i < 16; i++) {
+ char* buf3;
+ int read = myFifo->capture((char**)&buf3, sizeof(char));
+ if (read == sizeof(char)) {
+ std::cout << "read " << (unsigned)*buf3 << "  from Fifo   ";
+ std::cout << "used: " << std::setw(2) << myFifo->used()
+ << ", unused: " << std::setw(2) << myFifo->unused()
+ << ", size: "  << std::setw(2) << myFifo->size()
+ << std::endl;
+ myFifo->consume();
+ } else {
+ std::cout << "read nothing from Fifo." << std::endl;
+ }
+
+ }
+ }
+ delete myFifo;
+ return 0;
+ }
+ */
diff --git a/dol/src/dol/visitor/cell/lib/spu/WindowedFifo.h b/dol/src/dol/visitor/cell/lib/spu/WindowedFifo.h
new file mode 100644 (file)
index 0000000..5ef97d9
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _WINDOWEDFIFO_H_
+#define _WINDOWEDFIFO_H_
+
+#include <stdio.h>
+#include <string.h>
+
+#include "../constant.h"
+
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+class WindowedFifo {
+    public:
+        WindowedFifo(unsigned size);
+        virtual ~WindowedFifo();
+
+        // Write
+               virtual unsigned reserve(char** destination, unsigned len);
+        virtual void release();
+
+               // Read
+        virtual unsigned capture(char** destination, unsigned len);
+        virtual void consume();
+
+               // General functions
+        virtual unsigned used() const;
+        virtual unsigned unused() const;
+        virtual unsigned size() const;
+
+               // DMA functions
+        virtual char *getQueuePointer();
+        virtual void dmaRead(unsigned len);
+        virtual unsigned dmaStart();
+        virtual bool dmaAllowed();
+               virtual unsigned dmaWrite(const void *source, unsigned len);
+
+               // Global variables
+               unsigned _inTail;
+
+    protected:
+        char *_buffer;          // Pointer to the buffer
+        
+               unsigned _head;         // Current position of the head
+        unsigned _tail;         // Current position of the tail
+        unsigned _headRoom;     // HeadRoom pointer 
+        unsigned _tailRoom;     // Tailroom pointer
+        
+               unsigned _size;         // Total space of the buffer
+        unsigned _use;          // How many data are used in the buffer
+        unsigned _writeReserve; // Number of tokens one is writing
+        unsigned _readReserve;  // Number of tokens one is reading
+        
+               bool _isHeadReserved;   // Head reserved?
+        bool _isTailReserved;   // Tail reserved?
+
+               unsigned _blocked;      // Blocked number the request has to wait
+        bool _activeDMA;        // Is there an active DMA on this buffer
+};
+
+#endif
diff --git a/dol/src/dol/visitor/cell/lib/spu/common.cpp b/dol/src/dol/visitor/cell/lib/spu/common.cpp
new file mode 100644 (file)
index 0000000..df56fc8
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * common.cpp
+ *
+ *  Created on: Feb 27, 2009
+ *      Author: lschor
+ */
+
+#include "../common.h"
+
+/**
+ Round a number to the alignment of the Cell
+ */
+uint32_t roundDMA(uint32_t number) {
+       if (number > 16)
+               if (number % 16 == 0)
+                       return number;
+               else
+                       return number + 16 - (number % 16);
+       else if (number > 8)
+               return 16;
+       else if (number > 4)
+               return 8;
+       else if (number > 2)
+               return 4;
+       else if (number > 1)
+               return 2;
+       else
+               return 1;
+}
diff --git a/dol/src/dol/visitor/cell/lib/spu/dolSupport.cpp b/dol/src/dol/visitor/cell/lib/spu/dolSupport.cpp
new file mode 100644 (file)
index 0000000..4bf2b6e
--- /dev/null
@@ -0,0 +1,98 @@
+#include "dolSupport.h"\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p) {\r
+       unsigned int\r
+                       pos =\r
+                                       static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->readPos;\r
+       pos += ((Fifo*) fifo)->read((char *) buf + pos, len - pos);\r
+\r
+       if (pos == len)\r
+               static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->readPos\r
+                               = 0;\r
+       else\r
+               static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->readPos\r
+                               = pos;\r
+       return pos;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p) {\r
+       unsigned int\r
+                       pos =\r
+                                       static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->writePos;\r
+       pos += ((Fifo*) fifo)->write((char *) buf + pos, len - pos);\r
+\r
+       if (pos == len)\r
+               static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->writePos\r
+                               = 0;\r
+       else\r
+               static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->writePos\r
+                               = pos;\r
+       return pos;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void DOL_detach(DOLProcess* p) {\r
+       static_cast<proc_wrapper *> ((static_cast<process_data *> (p->wptr))->wrapper)->detach();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned reserve(void* fifo, void** destination, unsigned len,\r
+               DOLProcess* p) {\r
+       return ((WindowedFifo*) fifo)->reserve((char **) destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void release(void* fifo, DOLProcess* p) {\r
+       ((WindowedFifo*) fifo)->release();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned capture(void* fifo, void** destination, unsigned len,\r
+               DOLProcess* p) {\r
+       return ((WindowedFifo*) fifo)->capture((char **) destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void consume(void* fifo, DOLProcess* p) {\r
+       ((WindowedFifo*) fifo)->consume();\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0) {\r
+       *port = (void**) ((void**) base)[index0];\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0, int index1, int range1) {\r
+       *port = (void**) ((void**) base)[index0 * range1 + index1];\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0, int index1, int range1, int index2,\r
+               int range2) {\r
+       *port = (void**) ((void**) base)[index0 * range1 * range2 + index1\r
+                       * range2 + index2];\r
+}\r
+\r
+void createPort(void** port, void* base, int number_of_indices,\r
+               int index0, int range0, int index1, int range1, int index2,\r
+               int range2, int index3, int range3) {\r
+       *port = (void**) ((void**) base)[index0 * range1 * range2 * range3\r
+                       + index1 * range2 * range3 + index2 * range3 + index3];\r
+}\r
diff --git a/dol/src/dol/visitor/cell/lib/spu/dolSupport.h b/dol/src/dol/visitor/cell/lib/spu/dolSupport.h
new file mode 100644 (file)
index 0000000..63f1f74
--- /dev/null
@@ -0,0 +1,88 @@
+#ifndef DOLSUPPORT_H\r
+#define DOLSUPPORT_H\r
+\r
+#include <stdio.h>\r
+\r
+#include "dol.h"\r
+#include "../pt/pt.h"\r
+#include "proc_wrapper.h"\r
+\r
+#include "Fifo.h"\r
+#include "WindowedFifo.h"\r
+\r
+\r
+typedef struct _process_data {\r
+    int lc;\r
+    proc_wrapper *wrapper;\r
+} process_data;\r
+\r
+\r
+#define DOL_read(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), read(port, buf, size, process) == size);\r
+\r
+#define DOL_write(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), write(port, buf, size, process) == size);\r
+\r
+#define DOL_reserve(port, buf, size, process) \\r
+       PT_WAIT_UNTIL((pt*)(p->wptr), reserve(port, (void**)buf, size, process) == size);\r
+\r
+       //should stall only if the return size is 0!!! (but how, one has to give a return value...)\r
+\r
+#define DOL_release(port, process) \\r
+       release(port, process);\r
+\r
+#define DOL_capture(port, buf, size, process) \\r
+       PT_WAIT_UNTIL((pt*)(p->wptr), capture(port, (void**)buf, size, process) == size);\r
+\r
+       //should stall only if the return size is 0!!! (but how, one has to give a return value...)\r
+\r
+#define DOL_consume(port, process) \\r
+       consume(port, process);\r
+\r
+\r
+void DOL_detach(DOLProcess* p);\r
+\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+\r
+void release(void* fifo, DOLProcess* p);\r
+\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+\r
+void consume(void* fifo, DOLProcess* p);\r
+\r
+\r
+//macros to deal with iterated ports\r
+/**\r
+ * macro to create a variable to store a port name\r
+ *\r
+ * @param name name of the variable\r
+ */\r
+#define CREATEPORTVAR(name) static Fifo *name\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+  createPort((void**)(&port), base, number_of_indices, index_range_pairs)\r
+\r
+#define GETINDEX(dimension) \\r
+  static_cast<proc_wrapper *>((static_cast<process_data *>(p->wptr))->wrapper)->getIndex(dimension)\r
+\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1, int index2, int range2);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1, int index2, int range2, int index3, int range3);\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/cell/lib/spu/proc_wrapper.cpp b/dol/src/dol/visitor/cell/lib/spu/proc_wrapper.cpp
new file mode 100644 (file)
index 0000000..41e2705
--- /dev/null
@@ -0,0 +1,92 @@
+/**
+ * proc_wrapper.cpp
+ *
+ *  Created on: Feb 24, 2009
+ *      Author: lschor
+ */
+
+#include "proc_wrapper.h"
+
+proc_wrapper::proc_wrapper() {
+  _isDetached = false;
+  readPos = 0;
+  writePos = 0;
+}
+
+proc_wrapper::~proc_wrapper() {
+}
+
+/**
+ *
+ */
+void proc_wrapper::init() {
+  _process.init(&_process);
+}
+
+/**
+ *
+ */
+int proc_wrapper::fire() {
+  return _process.fire(&_process);
+}
+
+/**
+ *
+ */
+void proc_wrapper::detach() {
+  _isDetached = true;
+}
+
+/**
+ * Gets an index of a string, where the index must be separated by
+ * a character specified in tokens.
+ * Returns -1, when an error occurs.
+ *
+ * Example:
+ * getIndex("name_1_2", "_", 0) will return 1.
+ * getIndex("name_1_2", "_", 1) will return 2.
+ *
+ * @param string string to parse
+ * @param tokens delimiter of indices
+ * @param indexNumber position of index (starting at 0)
+ */
+int proc_wrapper::getIndex(const char* string, char* tokens,
+    int indexNumber) {
+  char* string_copy;
+  char* token_pointer;
+  int index = 0;
+
+  string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));
+  if (!string_copy) {
+    fprintf(stderr, "getIndex(): could not allocate memory.\n");
+    return -1;
+  }
+
+  strcpy(string_copy, string);
+
+  token_pointer = strtok(string_copy, tokens);
+  do {
+    token_pointer = strtok(NULL, tokens);
+    index++;
+  } while (index <= indexNumber && token_pointer != 0);
+
+  if (token_pointer) {
+    index = atoi(token_pointer);
+    free(string_copy);
+    return index;
+  }
+
+  free(string_copy);
+  return -1;
+}
+
+/**
+ * Get the index of this process.
+ * @param indexNumber position of index (starting at 0)
+ */
+int proc_wrapper::getIndex(unsigned indexNumber) const {
+    if (indexNumber < 4) {
+        return _iteratorIndex[indexNumber];
+    }
+    return -1;
+}
diff --git a/dol/src/dol/visitor/cell/lib/spu/proc_wrapper.h b/dol/src/dol/visitor/cell/lib/spu/proc_wrapper.h
new file mode 100644 (file)
index 0000000..656fcdb
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * proc_wrapper.h
+ *
+ *  Created on: Feb 24, 2009
+ *      Author: lschor
+ */
+
+#ifndef PROC_WRAPPER_H_
+#define PROC_WRAPPER_H_
+
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+//CBE Macros
+#define waittag(tag_id) mfc_write_tag_mask(1<<tag_id); \
+        mfc_read_tag_status_all();
+
+#include "../dol.h"
+
+/**
+ * Wrapper for a SPE Process
+ */
+class proc_wrapper {
+public:
+    proc_wrapper();
+    virtual ~proc_wrapper();
+
+    virtual void init();
+    virtual int fire();
+    virtual bool isDetached() { return _isDetached; }
+    virtual void detach();
+    virtual int getIndex(unsigned indexNumber) const;
+
+    //for FIFO access --> current position you are while blocking
+    unsigned int readPos;
+    unsigned int writePos;
+
+protected:
+    char* name;
+    DOLProcess _process;
+    bool _isDetached;
+    int _iteratorIndex[4];
+
+    uint32_t* port_id;
+    uint32_t* port_queue_id;
+    uint32_t number_of_ports;
+    virtual int getIndex(const char* string, char* tokens,
+            int indexNumber);
+};
+
+#endif /* PROC_WRAPPER_H_ */
diff --git a/dol/src/dol/visitor/cell/lib/spu_mfcio_ext.h b/dol/src/dol/visitor/cell/lib/spu_mfcio_ext.h
new file mode 100644 (file)
index 0000000..d85f1e8
--- /dev/null
@@ -0,0 +1,173 @@
+// -------------------------------------------------------------- \r
+// (C)Copyright 2007,                                         \r
+// International Business Machines Corporation, \r
+// All Rights Reserved.\r
+// -------------------------------------------------------------- \r
\r
+#ifndef _spu_mfcio_ext_h_\r
+#define _spu_mfcio_ext_h_\r
+\r
+#include <stdint.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+\r
+#include <spu_intrinsics.h>\r
+#include <spu_mfcio.h>\r
+\r
+static uint32_t msg[4]__attribute__ ((aligned (16)));\r
+\r
+// ==========================================================================\r
+// Definitions\r
+// ==========================================================================\r
+#define SPU_IN_MBOX_OFFSET                     0x0C // offset of mailbox status register from control area base\r
+#define SPU_IN_MBOX_OFFSET_SLOT        0x3  // 16B alignment of mailbox status register = (SPU_MBOX_STAT_OFFSET&0xF)>>2\r
+#define SPU_MBOX_STAT_OFFSET           0x14 // offset of mailbox status register from control area base\r
+#define SPU_MBOX_STAT_OFFSET_SLOT      0x1  // 16B alignment of mailbox status register = (SPU_MBOX_STAT_OFFSET&0xF)>>2\r
+\r
+#define SPU_SIG_NOTIFY_OFFSET          0x0C // offset of signal notify 1 or 2 registera from signal notify 1 or 2 areas base\r
+#define SPU_SIG_NOTIFY_OFFSET_SLOT     0x3  // 16B alignment of signal notify 1 or 2 register = (SPU_SIG_NOTIFY_OFFSET&0xF)>>2\r
+\r
+// ==========================================================================\r
+// Functions definitions\r
+// ==========================================================================\r
+\r
+inline int status_mbox(uint64_t ea_mfc, uint32_t tag_id);\r
+inline int status_in_mbox(uint64_t ea_mfc, uint32_t tag_id);\r
+inline int status_out_mbox(uint64_t ea_mfc, uint32_t tag_id);\r
+inline int status_outintr_mbox(uint64_t ea_mfc, uint32_t tag_id);\r
+\r
+int write_in_mbox(uint32_t data, uint64_t ea_mfc, uint32_t tag_id);\r
+int write_signal1(uint32_t data, uint64_t ea_mfc, uint32_t tag_id);\r
+int write_signal2(uint32_t data, uint64_t ea_mfc, uint32_t tag_id);\r
+\r
+// returns the value of mailbox status register of remote SPE\r
+inline int status_mbox(uint64_t ea_mfc, uint32_t tag_id)\r
+{\r
+       uint32_t status[4], idx;        \r
+       uint64_t ea_stat_mbox = ea_mfc + SPU_MBOX_STAT_OFFSET;\r
+\r
+       //printf("<SPE: ea_mfc=0x%llx, ea_stat_mbox=0x%llx\n", ea_mfc, ea_stat_mbox );\r
+       \r
+       idx = SPU_MBOX_STAT_OFFSET_SLOT;\r
+       \r
+       mfc_get((void *)&status[idx], ea_stat_mbox, sizeof(uint32_t), tag_id, 0, 0);\r
+       mfc_write_tag_mask(1<<tag_id);\r
+       mfc_read_tag_status_any();\r
+\r
+    //printf("<SPE: Status=0x%x: OutIntrCnt=0x%x, InCnt=0x%x, OutCnt=0x%x\n", status[idx], \r
+       //              (status[idx]&0xffff0000)>>16, (status[idx]&0x0000ff00)>>8, (status[idx]&0x000000ff) );\r
+       //printf("<SPE: status_mbox=%d\n", status[idx] );\r
+       \r
+       return status[idx];\r
+}\r
+\r
+// returns the status (counter) of inbound_mailbox of remote SPE\r
+inline int status_in_mbox(uint64_t ea_mfc, uint32_t tag_id)\r
+{\r
+       int status = status_mbox( ea_mfc, tag_id);\r
+       \r
+       status = (status&0x0000ff00)>>8;\r
+                       \r
+       //printf("<SPE: status_in_mbox=%d\n", status );\r
+       \r
+       return status;\r
+}\r
+\r
+// returns the status (counter) of outbound_mailbox of remote SPE\r
+inline int status_out_mbox(uint64_t ea_mfc, uint32_t tag_id)\r
+{\r
+       int status = status_mbox( ea_mfc, tag_id);\r
+\r
+       status = (status&0x000000ff);\r
+                       \r
+       //printf("<SPE: status_out_mbox=%d\n", status[idx] );\r
+       \r
+       return status;\r
+}\r
+\r
+// returns the status (counter) of inbound_interrupt_mailbox of remote SPE\r
+inline int status_outintr_mbox(uint64_t ea_mfc, uint32_t tag_id)\r
+{\r
+       int status = status_mbox( ea_mfc, tag_id);\r
+\r
+       status = (status&0xffff0000)>>16;\r
+                       \r
+       //printf("<SPE: status_outintr_mbox=%d\n", status[idx] );\r
+       \r
+       return status;\r
+}\r
+\r
+// writing to a remote SPE�s inbound mailbox\r
+inline int write_in_mbox(uint32_t data, uint64_t ea_mfc, uint32_t tag_id){\r
+\r
+       int status;\r
+       uint64_t ea_in_mbox = ea_mfc + SPU_IN_MBOX_OFFSET;      \r
+       uint32_t mbx[4], idx;\r
+\r
+       idx = SPU_IN_MBOX_OFFSET_SLOT;\r
+       mbx[idx] = data;\r
+       \r
+       while( (status= status_in_mbox(ea_mfc, tag_id))<1);\r
+       \r
+       mfc_put((void *)&mbx[idx], ea_in_mbox, sizeof(uint32_t), tag_id, 0, 0);\r
+       mfc_write_tag_mask(1<<tag_id);\r
+       mfc_read_tag_status_any();\r
+\r
+       //printf("<SPE: write_in_mbox: complete\n" );   \r
+       \r
+       return 1; // number of mailbox being written\r
+}\r
+\r
+// signal a remote SPE�s signal1 register\r
+inline int write_signal1(uint32_t data, uint64_t ea_sig1, uint32_t tag_id)\r
+{\r
+       uint64_t ea_sig1_notify = ea_sig1 + SPU_SIG_NOTIFY_OFFSET;      \r
+       uint32_t idx;\r
+\r
+       //printf("<SPE: write_signal1: starts\n" );\r
+       \r
+       //printf("<SPE: write_signal1:  ea_mfc=0x%llx, ea_in_mbox=0x%llx\n", ea_sig1, ea_sig1_notify );\r
+       \r
+       idx = SPU_SIG_NOTIFY_OFFSET_SLOT;\r
+       msg[idx] = data;\r
+       \r
+       mfc_sndsig( &msg[idx], ea_sig1_notify, tag_id, 0,0)     ;\r
+       mfc_write_tag_mask(1<<tag_id);\r
+       mfc_read_tag_status_any();\r
+\r
+       //printf("<SPE: write_in_mbox: complete\n" );   \r
+       \r
+       return 1; // number of mailbox being written\r
+}\r
+\r
+// signal a remote SPE�s signal1 register\r
+inline int write_signal2(uint32_t data, uint64_t ea_sig2, uint32_t tag_id)\r
+{\r
+       uint64_t ea_sig2_notify = ea_sig2 + SPU_SIG_NOTIFY_OFFSET;      \r
+       uint32_t idx;\r
+\r
+       //printf("<SPE: write_signal2: starts\n" );\r
+       \r
+       //printf("<SPE: write_signal2:  ea_mfc=0x%llx, ea_in_mbox=0x%llx\n", ea_sig2, ea_sig2_notify );\r
+       \r
+       idx = SPU_SIG_NOTIFY_OFFSET_SLOT;\r
+       msg[idx] = data;\r
+       \r
+       mfc_sndsig( &msg[idx], ea_sig2_notify, tag_id, 0,0)     ;\r
+       mfc_write_tag_mask(1<<tag_id);\r
+       mfc_read_tag_status_any();\r
+\r
+       //printf("<SPE: write_in_mbox: complete\n" );   \r
+       \r
+       return 1; // number of mailbox being written\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
diff --git a/dol/src/dol/visitor/cell/lib/spu_os.h b/dol/src/dol/visitor/cell/lib/spu_os.h
new file mode 100644 (file)
index 0000000..d4caf85
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * spu_os.h
+ *
+ *  Created on: Mar 17, 2009
+ *      Author: lschor
+ */
+
+#ifndef SPU_OS_H_
+#define SPU_OS_H_
+
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <new>
+
+// Include to allocate/free using for DMA transfers
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+
+// Local includes
+#include "../lib/spu/Fifo.h"
+#include "../lib/common.h"
+//#include "../lib/spu/Communication.h"
+#include "../lib/spu/FastCommunication.h"
+
+// Protothread includes
+#include "../lib/pt/pt.h"
+
+// Context file
+static spu_context ctx_spu __attribute__ ((aligned (128)));
+
+#endif /* SPU_OS_H_ */
diff --git a/dol/src/dol/visitor/cell/template/spu_process_wrapper_template.cpp b/dol/src/dol/visitor/cell/template/spu_process_wrapper_template.cpp
new file mode 100644 (file)
index 0000000..ebb1f4c
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Square_wrapper.cpp
+ *
+ *  Created on: Feb 27, 2009
+ *      Author: lschor
+ */
+
+
+#include "@PROCESSNAME@Wrapper.h"
+#include "../lib/spu/dolSupport.h"
+
+#include "@PROCESSNAME@.c"
+
+@PROCESSNAME@Wrapper::@PROCESSNAME@Wrapper(uint64_t argp) {
+       // reserve DMA tag ID
+       uint32_t tag_id;
+       if((tag_id=mfc_tag_reserve())==MFC_TAG_INVALID){
+               printf("SPE: ERROR - can't reserve a tag ID\n"); return;
+       }
+
+       // Get the context information for the whole system
+       mfc_get((void*) &ctx_proc, argp, sizeof(ctx_proc), tag_id, 0, 0);
+       mfc_write_tag_mask(1<<tag_id);
+       mfc_read_tag_status_all();
+
+       this->name = (char *)_malloc_align((uint32_t)ctx_proc.processNameLen, 4);
+        if(!this->name) {
+           fprintf(stderr,"[SPUProcessWrapper] Memory allocation failure\n");
+           exit(-1);
+       }
+       mfc_get((void *)this->name, ctx_proc.processName, ctx_proc.processNameLen, tag_id, 0, 0);
+       waittag(tag_id);
+
+
+       //initialize the index array
+       for (int i = 0; i < 4; i++)     {
+               this->_iteratorIndex[i] = getIndex(this->name, "_", i);
+       }
+
+    try { _state = (LocalState) new @PROCESSNAME_UPPER@_State; }
+    catch(std::bad_alloc &e) {
+        fprintf(stderr, "[SPUProcessWrapper] Memory allocation failure\n");
+       exit(-1);
+    }
+    _process.local = _state;
+    _process.init = @PROCESSNAME@_init;
+    _process.fire = @PROCESSNAME@_fire;
+    _process.wptr = (void*)&_wrapper_data;
+
+    _wrapper_data.wrapper = this;
+
+       // Init the process
+       _process.init(&_process);
+
+       // release tag ID before exiting
+       mfc_tag_release(tag_id);
+}
+
+@PROCESSNAME@Wrapper::~@PROCESSNAME@Wrapper() {
+       // Free the state
+    if (_state)
+        delete (@PROCESSNAME_UPPER@_State*) _state;
+
+       // Free the name of the wrapper
+       _free_align(this->name);
+}
diff --git a/dol/src/dol/visitor/cell/template/spu_process_wrapper_template.h b/dol/src/dol/visitor/cell/template/spu_process_wrapper_template.h
new file mode 100644 (file)
index 0000000..a0f9800
--- /dev/null
@@ -0,0 +1,56 @@
+/****************************************************************
+ *     Process Wrapper file
+ *     Creator: lschor, 2009-02-24
+ *     Description: Wrapper for a specific SPE process
+ *
+ *     Revision:
+ *     - 2009-02-24: Created
+ */
+
+#ifndef @PROCESSNAME@_WRAPPER_H_
+#define @PROCESSNAME@_WRAPPER_H_
+
+// General includes
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <new>
+
+// Include to allocate/free using for DMA transfers
+#include "../lib/malloc_align.h"
+#include "../lib/free_align.h"
+#include "../lib/spu/Fifo.h"
+#include "../lib/spu/WindowedFifo.h"
+
+// Local includes
+#include "../lib/common.h"
+//#include "../lib/estimation.h"
+
+#include "../lib/spu/proc_wrapper.h"
+
+class @PROCESSNAME@Wrapper; 
+
+typedef struct _@PROCESSNAME@_data {
+    int lc;
+    @PROCESSNAME@Wrapper *wrapper;
+} @PROCESSNAME@_data;
+
+class @PROCESSNAME@Wrapper  : public proc_wrapper {
+       
+// Context file
+public:
+       @PROCESSNAME@Wrapper(uint64_t argp);
+       virtual ~@PROCESSNAME@Wrapper();
+       
+       @FIFO@
+
+protected:
+       LocalState _state;
+       process_context ctx_proc __attribute__ ((aligned (128)));
+       @PROCESSNAME@_data _wrapper_data;
+
+};
+
+#endif /* @PROCESSNAME@_WRAPPER_H_ */
diff --git a/dol/src/dol/visitor/dot/ArchDotVisitor.java b/dol/src/dol/visitor/dot/ArchDotVisitor.java
new file mode 100644 (file)
index 0000000..5f71ee8
--- /dev/null
@@ -0,0 +1,250 @@
+/* $Id: ArchDotVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.dot;
+
+import java.util.Iterator;
+
+import dol.datamodel.architecture.ArchiConnection;
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.HWChannel;
+import dol.datamodel.architecture.Memory;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.architecture.ReadPath;
+import dol.datamodel.architecture.WritePath;
+import dol.datamodel.pn.Process;
+import dol.util.CodePrintStream;
+import dol.visitor.ArchiVisitor;
+
+/**
+ * Helps to generate DOTTY information for architecture resources.
+ */
+public class ArchDotVisitor extends ArchiVisitor
+{
+    /**
+     * Constructor.
+     *
+     * @param printStream print stream to which the contents is written
+     */
+    public ArchDotVisitor(CodePrintStream printStream) {
+        _printStream = printStream;
+        _pnVisitor = new PNDotVisitor(printStream);
+    }
+
+    /**
+     * Print a .dot file in the correct format for DOTTY.
+     *
+     * @param arch architecture that needs to be rendered
+     */
+    public void visitComponent(Architecture arch) {
+        _printStream.printPrefixln("digraph architecture {");
+        _printStream.println();
+        _printStream.prefixInc();
+        _printStream.printPrefixln("ratio = auto;");
+        _printStream.printPrefixln("rankdir = LR;");
+        _printStream.printPrefixln("ranksep = 2;");
+        _printStream.printPrefixln("nodesep = 0.2;");
+        _printStream.printPrefixln("center = true;");
+        _printStream.printPrefixln("");
+        _printStream.printPrefixln("node [ fontsize=12, height=0.4, "
+                + "width=0.4, style=filled, color=\"0.65 0.20 1.00\" ]");
+        _printStream.println();
+
+        //visit all processors
+        Processor processor;
+        Iterator<Processor> processorIter = arch.getProcessorList().iterator();
+        while( processorIter.hasNext() ) {
+            processor = processorIter.next();
+            processor.accept(this);
+        }
+
+        //visit all hw_channels
+        HWChannel chan;
+        Iterator<HWChannel> chanIter = arch.getHWChannelList().iterator();
+        while(chanIter.hasNext()) {
+            chan = chanIter.next();
+            chan.accept(this);
+        }
+
+        //visit all memories
+        Memory mem;
+        Iterator<Memory> memIter = arch.getMemoryList().iterator();
+        while(memIter.hasNext()) {
+            mem = memIter.next();
+            mem.accept(this);
+        }
+        
+        //visit all connections
+        ArchiConnection cn;
+        Iterator<ArchiConnection> cnIter = arch.getConnectionList().iterator();
+        while(cnIter.hasNext()) {
+            cn = cnIter.next();
+            cn.accept(this);
+        }
+
+        ReadPath rPath;
+        Iterator<ReadPath> rpIter = arch.getReadPathList().iterator();
+        while(rpIter.hasNext()) {
+            rPath = rpIter.next();
+            rPath.accept(this);
+        }
+
+        WritePath wPath;
+        Iterator<WritePath> wpIter = arch.getWritePathList().iterator();
+        while(wpIter.hasNext()) {
+            wPath = wpIter.next();
+            wPath.accept(this);
+        }
+
+        _printStream.prefixDec();
+        _printStream.println();
+        _printStream.printPrefixln("}");
+    }
+
+    public void visitComponent(HWChannel  chan)
+    {
+        _printStream.printPrefixln("subgraph cluster_"
+                + chan.getName().replaceAll("\\.", "") + " {");
+        _printStream.prefixInc();
+        _printStream.printPrefixln("label = \"" + chan.getName() + "\"");
+
+        if (!chan.getPathList().isEmpty()) {
+            Iterator<String> pIter = chan.getPathList().iterator();
+            String path;
+            while (pIter.hasNext()) {
+                path = (String) pIter.next();
+                _printStream.printPrefixln("\"" + path + "_" + chan.getName()
+                                           + "\" [label=\"  " +
+                                           "\" shape=circle style=solid]");
+            }
+        }
+
+        _printStream.prefixDec();
+        _printStream.printPrefixln("}");
+        _printStream.println();
+    }
+
+    public void visitComponent(Memory mem)
+    {
+       _printStream.printPrefixln("subgraph cluster_"
+               + mem.getName().replaceAll("\\.", "") + " {");
+       _printStream.prefixInc();
+       _printStream.printPrefixln("label = \"" + mem.getName() + "\"");
+
+       if (!mem.getRXBufList().isEmpty()) {
+           Iterator<String> rIter = mem.getRXBufList().iterator();
+           String rxBuf;
+           while (rIter.hasNext()) {
+               rxBuf = (String) rIter.next();
+               _printStream.printPrefixln("\"" + rxBuf.replaceAll("\\.", "")
+                       + "_RX\" [label=\"RX"
+                       + "\" shape=circle style=dotted]");
+           }
+       }
+
+       if (!mem.getTXBufList().isEmpty()) {
+           Iterator<String> rIter = mem.getTXBufList().iterator();
+           String txBuf;
+           while (rIter.hasNext()) {
+               txBuf = (String) rIter.next();
+               _printStream.printPrefixln("\"" + txBuf.replaceAll("\\.", "")
+                       + "_TX\" [label=\"TX"
+                       + "\" shape=circle style=dashed]");
+           }
+       }
+
+       if (!mem.getCHBufList().isEmpty()) {
+           Iterator<String> rIter = mem.getCHBufList().iterator();
+           String chBuf;
+           while (rIter.hasNext()) {
+               chBuf = (String) rIter.next();
+               _printStream.printPrefixln("\"" + chBuf.replaceAll("\\.", "")
+                       + "_CH\" [label=\"CH"
+                       + "\" shape=circle style=bold]");
+           }
+       }
+
+       _printStream.prefixDec();
+       _printStream.printPrefixln("}");
+       _printStream.println();
+    }
+
+
+    public void visitComponent(ArchiConnection cn)
+    {
+        _printStream.printPrefix();
+        _printStream.print("\""
+                + cn.getOrigin().getName().replaceAll("\\.", "") + "\" -> \""
+                + cn.getTarget().getName().replaceAll("\\.", "")
+                + "\" [ color=" + _color + " ];");
+        _printStream.println();
+    }
+
+    public void visitComponent(ReadPath rp)
+    {
+        String rName = rp.getName().replaceAll("\\.", "");
+
+        _printStream.printPrefix();
+        _printStream.print(rName + "_RPath_CH->" );
+
+        Iterator<HWChannel> cIter = rp.getHWChannelList().iterator();
+        while (cIter.hasNext()) {
+            HWChannel channel = cIter.next();
+            _printStream.print(rName + "_RPath_"
+                    + channel.getName().replaceAll("\\.", "")
+                    + "->");
+        }
+        _printStream.println(rName + "_RX");
+    }
+
+    public void visitComponent(WritePath rp)
+    {
+        String rName = rp.getName().replaceAll("\\.", "");
+
+        _printStream.printPrefix();
+        _printStream.print(rName + "_TX->" );
+
+        Iterator<HWChannel> cIter = rp.getHWChannelList().iterator();
+        while (cIter.hasNext()) {
+            HWChannel channel = cIter.next();
+            _printStream.print(rName + "_WPath_"
+                    + channel.getName().replaceAll("\\.", "")
+                    + "->");
+        }
+        _printStream.println(rName + "_WPath_CH");
+    }
+
+    /**
+     * Clusters all processes of this processor.
+     */
+    public void visitComponent(Processor processor)
+    {
+        /*
+       _printStream.printPrefix();
+       _printStream.print("\"" + processor.getName() + "\" [ label=\""
+                          + processor.getName() + "\", color=" + _color
+                          + ", shape=box];");
+       _printStream.println();
+        */
+
+       _printStream.printPrefixln("subgraph cluster_"
+               + processor.getName().replaceAll("\\.", "") + " {");
+       _printStream.prefixInc();
+       _printStream.printPrefixln("label = \"" + processor.getName() + "\"");
+
+       // labeleling clusters with dot2.8 & graphviz2.8 seems buggy
+       //_printStream.printPrefixln("label = \"" + processor.getName()+"\";");
+       if (!processor.getProcessList().isEmpty()) {
+           Iterator<Process> pIter = processor.getProcessList().iterator();
+           while (pIter.hasNext()) {
+               pIter.next().accept(_pnVisitor);
+           }
+       }
+       _printStream.prefixDec();
+       _printStream.printPrefixln("}");
+       _printStream.println();
+    }
+    
+    /** DOT Visitor to visit process network resources */
+    protected PNDotVisitor _pnVisitor = null;
+
+    protected String _color = "dimgray";
+}
diff --git a/dol/src/dol/visitor/dot/MapDotVisitor.java b/dol/src/dol/visitor/dot/MapDotVisitor.java
new file mode 100644 (file)
index 0000000..581c615
--- /dev/null
@@ -0,0 +1,80 @@
+/* $Id: MapDotVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.dot;
+
+import java.util.Iterator;
+
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Channel;
+import dol.util.CodePrintStream;
+import dol.visitor.MapVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * ".dot" output in order to visualize a mapping using the DOTTY tool.
+ */
+public class MapDotVisitor extends MapVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param printStream print stream to which the contents is written
+     */
+    public MapDotVisitor(CodePrintStream printStream) {
+        _printStream = printStream;
+        _pnVisitor = new PNDotVisitor(printStream);
+        _archiVisitor = new ArchDotVisitor(printStream);
+    }
+
+    /**
+     * Print a .dot file in the correct format for DOTTY.
+     *
+     * @param map process network that needs to be rendered
+     */
+    public void visitComponent(Mapping map) {
+        _printStream.printPrefixln("digraph mapping {");
+        _printStream.println();
+        _printStream.prefixInc();
+        _printStream.printPrefixln("ratio = auto;");
+        _printStream.printPrefixln("rankdir = LR;");
+        _printStream.printPrefixln("ranksep = 0.3;");
+        _printStream.printPrefixln("nodesep = 0.2;");
+        _printStream.printPrefixln("center = true;");
+        _printStream.printPrefixln("");
+        _printStream.printPrefixln("node [ fontsize=12, height=0.4, "
+                + "width=0.4, style=filled, color=\"0.65 0.20 1.00\" ];");
+        _printStream.printPrefixln("edge [ fontsize=10, arrowhead=normal, "
+                + "arrowsize=0.8, style=\"setlinewidth(2)\" ];");
+        _printStream.println();
+
+        //visit all processors
+        Processor processor;
+        Iterator<Processor> processorIter = map.getProcessorList().iterator();
+        while( processorIter.hasNext() )
+        {
+            processor = processorIter.next();
+            processor.accept(_archiVisitor);
+        }
+        
+        //visit all channels (from PN)
+        _pnVisitor.setMapping(map);
+        Channel chan;
+        Iterator<Channel> chanIter = map.getPN().getChannelList().iterator();
+        while (chanIter.hasNext() )
+        {
+            chan = chanIter.next();
+            chan.accept(_pnVisitor);
+        }
+
+        _printStream.prefixDec();
+        _printStream.println();
+        _printStream.printPrefixln("}");
+    }
+
+
+    /** DOT Visitor to visit process network resources */
+    protected PNDotVisitor _pnVisitor = null;
+
+    /** DOT Visitor to visit architecture resources */
+    protected ArchDotVisitor _archiVisitor = null;
+}
diff --git a/dol/src/dol/visitor/dot/PNDotVisitor.java b/dol/src/dol/visitor/dot/PNDotVisitor.java
new file mode 100644 (file)
index 0000000..3a0205a
--- /dev/null
@@ -0,0 +1,163 @@
+/* $Id: PNDotVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.dot;
+
+import java.util.Iterator;
+
+import dol.datamodel.mapping.ComputationBinding;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * ".dot" output in order to visualize a PN using the DOTTY tool.
+ */
+public class PNDotVisitor extends PNVisitor {
+
+    Mapping _mapping = null;
+    
+    /**
+     * Constructor.
+     *
+     * @param printStream print stream to which the contents is written
+     */
+    public PNDotVisitor(CodePrintStream printStream) {
+        _printStream = printStream;
+    }
+
+    /**
+     * Print a .dot file in the correct format for DOTTY.
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        _printStream.printPrefixln("digraph pn {");
+        _printStream.println();
+        _printStream.prefixInc();
+        _printStream.printPrefixln("ratio = auto;");
+        _printStream.printPrefixln("rankdir = LR;");
+        _printStream.printPrefixln("ranksep = 0.3;");
+        _printStream.printPrefixln("nodesep = 0.2;");
+        _printStream.printPrefixln("center = true;");
+        _printStream.printPrefixln("");
+        _printStream.printPrefixln("node [ fontsize=12, height=0.4, "
+                + "width=0.4, style=filled, color=\"0.65 0.20 1.00\" ];");
+        _printStream.printPrefixln("edge [ fontsize=10, arrowhead=normal, "
+                + "arrowsize=0.8, style=\"setlinewidth(2)\" ];");
+        _printStream.println();
+        
+        //visit all processes
+        Iterator<Process> pIter;
+        Process p;
+        pIter = x.getProcessList().iterator();
+        while (pIter.hasNext())
+        {
+            p = pIter.next();
+            p.accept(this);
+        }
+        _printStream.println();
+        
+        //visit all channels
+        Iterator<Channel> cIter;
+        Channel c;
+        cIter = x.getChannelList().iterator();
+        while( cIter.hasNext() ) {
+            c = cIter.next();
+            c.accept(this);
+        }
+
+        _printStream.prefixDec();
+        _printStream.println();
+        _printStream.printPrefixln("}");
+    }
+    
+    /**
+     * Print a line for the process in the correct format for DOTTY.
+     *
+     * @param x process that needs to be rendered
+     */
+    public void visitComponent(Process x) {
+        //other colors: beige, lightgoldenrod, orange, tan, khaki3,
+        //aliceblue, lightskyblue, lightseagreen, mintcream,
+        //burlywood3, lightblue1, linen, papayawhip, azure1,2,3
+        String color = "lightskyblue";
+
+        _printStream.printPrefix();
+        _printStream.print("\"" + x.getName() + "\" [ label=\""
+                                   + x.getName() + "\", color=" +
+                                   color);
+        if (!x.hasInPorts() || !x.hasOutPorts())
+            _printStream.print(", shape=diamond");
+        else
+            _printStream.print(", shape=ellipse");
+        _printStream.print(" ];");
+        _printStream.println();
+    }
+
+    /**
+     * Print a line for the channel in the correct format for DOTTY.
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        String color = "lightblue3";
+
+        //change the color of the channel to indicate whether connection
+        //is on-tile or off-tile 
+        if (_mapping != null) {
+            String process1 = _mapping.getPN().getProcess(x.getOrigin().
+                    getName()).getName();
+            String process2 = _mapping.getPN().getProcess(x.getTarget().
+                    getName()).getName();
+            String processor1 = "";
+            String processor2 = "";
+            
+            for (ComputationBinding binding :
+                _mapping.getCompBindList()) {
+                if (binding.getProcess().getName().
+                        equals(process1)) {
+                    processor1 = binding.getProcessor().getName();
+                } else if (binding.getProcess().getName().
+                        equals(process2)) {
+                    processor2 = binding.getProcessor().getName();
+                }
+            }
+            if (processor1.equals(processor2)) {
+            } else if (processor1.length() >= 6 && processor2.length() >=6
+                    && processor1.substring(0, 6).equals(
+                    processor2.substring(0, 6))) {
+                color = "orange";
+            } else {
+                color = "red";
+            }
+        }
+        
+
+        Iterator<Port> i;
+        Port port, portNext;
+        i = x.getPortList().iterator();
+
+        port = (Port) i.next();
+
+        portNext = (Port) i.next();
+        _printStream.printPrefix();
+
+        _printStream.print("\"" + port.getPeerResource().getName()
+                + "\" -> " + "\"" + portNext.getPeerResource().getName()
+                + "\" [" );
+        _printStream.print(" label=\"" + x.getName() + "\""
+                + ", color=" + color + " ];");
+        _printStream.println();
+    }
+
+    /**
+     * 
+     */
+    public void setMapping(Mapping mapping) {
+        _mapping = mapping;
+    }
+}
diff --git a/dol/src/dol/visitor/dot/package.html b/dol/src/dol/visitor/dot/package.html
new file mode 100644 (file)
index 0000000..f219d05
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Dotty graphical representation generation.
+This package will generate a dotty representation for a given example.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/visitor/hds/HdsMakefileVisitor.java b/dol/src/dol/visitor/hds/HdsMakefileVisitor.java
new file mode 100644 (file)
index 0000000..9256b2a
--- /dev/null
@@ -0,0 +1,93 @@
+/* $Id: HdsMakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.hds;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Configuration;
+import dol.visitor.PNVisitor;
+
+/**
+ *  This class is a class for a visitor that is used to generate
+ *  a HdS package Makefile.
+ */
+public class HdsMakefileVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of the Makefile
+     */
+    public HdsMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * Create a Makefile for the given process network.
+     *
+     * @param x process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("CXX = g++");
+            ps.println("CC = g++");
+            ps.println();
+            ps.println("PREPROC_MACROS = -D__DOL_ETHZ_GEN__ "
+                + " -DINCLUDE_PROFILER #-DINCLUDE_PERFORMANCE"
+                + " #-DINCLUDE_TRACE");
+            ps.println();
+            ps.println("SYSTEMC_INC = -I" + _ui.getSystemCINC());
+            ps.println("SYSTEMC_LIB = " + _ui.getSystemCLIB());
+            ps.println("MY_LIB_INC = -Ilib -Isc_wrappers -Iprocesses");
+            ps.println("VPATH = lib:sc_wrappers:processes");
+            ps.println();
+            ps.println("CXXFLAGS = -g -O0 -Wall $(PREPROC_MACROS) "
+                + "$(SYSTEMC_INC) $(MY_LIB_INC)");
+            ps.println("CFLAGS = $(CXXFLAGS)");
+            ps.println();
+
+            ps.print("PROCESS_OBJS = dolSupport.o ProcessWrapper.o "
+                + "Fifo.o WindowedFifo.o ");
+
+            for (String basename : x.getProcessBasenames()) {
+                ps.print(basename + "_wrapper.o ");
+            }
+
+            for (Configuration conf : x.getCfgList()) {
+                if (conf.getName().equals("EXTERNAL_SRC")) {
+                    ps.print(conf.getValue() + " ");
+                }
+            }
+
+            ps.println("#xmlParser.o Performance_Extraction.o "
+                + "functional_trace.o");
+            ps.println();
+            ps.println("all:" + _name);
+            ps.println();
+            ps.println(_name + ": " + _name + ".o $(PROCESS_OBJS)");
+            ps.print("\t$(CXX) $(CXXFLAGS) -o $@ $^ $(SYSTEMC_LIB) ");
+            for (Configuration conf : x.getCfgList()) {
+                if (conf.getName().equals("DYNAMIC_LINK"))
+                    ps.print(conf.getValue() + " ");
+            }
+            ps.println("# -lpthread -lX11 -lrt");
+            ps.println("clean:");
+            ps.println("\t-rm -f *.o core core.* *.core *.tga "
+                + "static_characterization.xml " + _name);
+
+        } catch (Exception e) {
+            System.out.println("HdsMakefileVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected String _name = "sc_application";
+}
diff --git a/dol/src/dol/visitor/hds/HdsModuleVisitor.java b/dol/src/dol/visitor/hds/HdsModuleVisitor.java
new file mode 100644 (file)
index 0000000..f00bbe3
--- /dev/null
@@ -0,0 +1,347 @@
+/* $Id: HdsModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.hds;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Resource;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class HdsModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public HdsModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "sc_application.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            _mainPS.printPrefixln("#include <systemc>");
+            _mainPS.printPrefixln("#include <list>");
+
+            /* begin of profiling: standard i/o file handling routines */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("#include <stdio.h>");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("#include \"dol_sched_if.h\"");
+            _mainPS.println();
+
+            for (String basename : x.getProcessBasenames()) {
+                _mainPS.printPrefixln("#include \"" + basename
+                        + "_wrapper.h\"");
+            }
+            _mainPS.println();
+            _mainPS.printPrefixln("using namespace std;");
+
+            /* begin of profiling: global variables */
+            _mainPS.println();
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("#define PROFILER_OUTPUT_FILENAME \"profile.txt\"");
+            _mainPS.printPrefixln("FILE *profiler_output_file;");
+            _mainPS.printPrefixln("unsigned int profiler_event_counter;");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.println();
+            _mainPS.printPrefixln("class sc_application : public sc_module ");
+            _mainPS.printLeftBracket();
+
+            _mainPS.printPrefixln("public:");
+            _mainPS.printPrefixln("SC_HAS_PROCESS(sc_application);");
+
+            //declare processes
+            _mainPS.println();
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln(p.getBasename() + "_wrapper "
+                        + p.getName() + "_ins"+ ";");
+                _mainPS.printPrefixln("sc_event " + p.getName()
+                        + "_event;");
+            }
+            _mainPS.println();
+
+            //define the scheduler
+            _mainPS.printPrefixln("sc_event sched_event;");
+            _mainPS.printPrefixln("list<sc_event* > eventList;");
+            _mainPS.printPrefixln("list<sc_event* >::iterator iter;");
+            _mainPS.println();
+
+            //declare channels
+            _mainPS.println();
+            for (Channel p : x.getChannelList()) {
+                if (p.getType().equals("fifo")) { 
+                    _mainPS.printPrefixln("Fifo " + p.getName() + "_ins;");
+                } else if (p.getType().equals("wfifo")) {
+                    _mainPS.printPrefixln("WindowedFifo " + p.getName() + "_ins;");
+                }
+            }
+            _mainPS.println();
+
+            //model constructor
+            _mainPS.printPrefixln("sc_application(sc_module_name name)");
+
+            //parameter of constructor
+            _mainPS.printPrefix(":       sc_module(name)");
+            for (Process p : x.getProcessList()) {
+                _mainPS.println(",");
+                _mainPS.printPrefix(p.getName() + "_ins(\""
+                        + p.getName() +"\")");
+            }
+
+            if (x.getChannelList().size() > 0) {
+                for (Channel c : x.getChannelList()) {
+                    _mainPS.println(",");
+                    _mainPS.printPrefix(c.getName() + "_ins("
+                                        + "\"" + c.getName() + "\", "
+                                        + c.getSize() * c.getTokenSize()
+                                        + ")");
+                }
+            }
+            _mainPS.println("");
+            _mainPS.printLeftBracket();
+
+            //construtor content
+            //build the network
+            for (Channel ch : x.getChannelList()) {
+                ch.accept(this);
+            }
+            _mainPS.println("");
+
+            _mainPS.println("");
+
+            _mainPS.printPrefixln("SC_THREAD(thread_init);");
+            //init thread
+            _mainPS.printPrefixln("SC_THREAD(thread_sched);");
+
+            //declare concurrent non-terminating threads
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln("SC_THREAD(thread_" +
+                                      p.getName() + ");");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define scheduler thread
+            _mainPS.printPrefixln("void thread_init()");
+            _mainPS.printLeftBracket();
+            //init
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln(p.getName() + "_ins.initialize();");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+
+            //different scheduling algorithm can be put here
+            _mainPS.printPrefixln("void thread_sched()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("while (1)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("for (iter=eventList.begin(); iter != "
+                    + "eventList.end(); ++iter)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_event* e = (*iter);");
+            _mainPS.printPrefixln("e->notify();");
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("eventList.clear();");
+            _mainPS.printPrefixln("wait(sched_event);");
+            _mainPS.printRightBracket();
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define threads
+            for (Process p : x.getProcessList()) {
+                p.accept(this);
+            }
+
+            /* begin of profiling: initialization function. */
+            /* - opens file */
+            /* - writes a list of all channels with the connected ports to the file. */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("void initialize_profiler()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("if ((profiler_output_file = fopen(PROFILER_OUTPUT_FILENAME,\"w\"))==NULL)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("printf(\"Unable to open profiler output file. No profiling output is written.\\n\");");
+            _mainPS.printPrefixln("return;");
+            _mainPS.printRightBracket();
+            //_mainPS.printPrefixln("printf(\"Profiling data is written to %s.\\n\", PROFILER_OUTPUT_FILENAME);");
+            _mainPS.println();
+
+            for (Channel ch : x.getChannelList()) {
+                String outputString = "fprintf(profiler_output_file, \"c " + ch.getName() + " " + ch.getSize();
+                String outputStringAppendix = "";
+                for (Port p : ch.getPortList()) {
+                    Port peerPort = (Port)(p.getPeerPort());
+                    Resource peerResource = p.getPeerResource();
+
+                    if (p.isOutPort()) {
+                        // channel.out == process.in
+                        outputString += " i " + peerResource.getName() + " %pI";
+                        outputStringAppendix += ",(" + peerResource.getName()
+                            + "_ins.INPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), "") + ")";
+                    } else {
+                        outputString += " o " + peerResource.getName() + " %pO";
+                        outputStringAppendix += ",(" + peerResource.getName()
+                            + "_ins.OUTPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), "") + ")";
+                    }
+                }
+                outputString += "\\n\"" + outputStringAppendix + ");";
+                _mainPS.printPrefixln(outputString);
+            }
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("#endif");
+            _mainPS.println();
+            /* end of profiling */
+
+            _mainPS.printRightBracket(); // end of class
+            _mainPS.println(";");
+
+            //create and run the simulator
+            _mainPS.printPrefixln("int sc_main (int argc, char *argv[])");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_report_handler::set_actions(\""
+                    + "/IEEE_Std_1666/deprecated\", SC_DO_NOTHING);");
+            _mainPS.printPrefixln("sc_report::register_id("
+                    + "5000, "
+                    + "\"parameter problem\" );");
+
+            //create an instance of the application model
+            //remove potential whitespaces before using the process
+            //network name as a systemc identifier
+            _mainPS.printPrefixln("sc_application my_app_mdl(\""
+                    + x.getName().replaceAll(" ", "")  + "\");");
+
+            /* begin of profiling: initialize the profiler */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("my_app_mdl.initialize_profiler();");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("sc_start(-1,SC_NS);");
+            /* begin of profiling: close the output file */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("if (profiler_output_file != NULL) fclose(profiler_output_file);");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("return 0;");
+
+            _mainPS.printRightBracket();
+
+        }
+        catch (Exception e) {
+            System.out.println("HdsModuleVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Print a line for the process in the correct format for DOTTY.
+     *
+     * @param x process that needs to be rendered
+     */
+    public void visitComponent(Process x) {
+        _mainPS.printPrefixln("void thread_" + x.getName() + "()");
+        _mainPS.printLeftBracket();
+        _mainPS.printPrefixln("while (!" + x.getName()
+                + "_ins.isDetached())");
+        _mainPS.printLeftBracket();
+
+        /* begin of profiling: start event */
+        _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+        _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " started.\\n\", profiler_event_counter++);");
+        _mainPS.printPrefixln("#endif");
+        /* end of profiling */
+
+        _mainPS.printPrefixln(x.getName() + "_ins.fire();");
+
+        /* begin of profiling: stop event */
+        _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+        _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " stopped.\\n\", profiler_event_counter++);");
+        _mainPS.printPrefixln("#endif");
+        /* end of profiling */
+
+        _mainPS.printPrefixln("eventList.push_back(&" + x.getName()
+                              + "_event);");
+        _mainPS.printPrefixln("sched_event.notify();");
+        _mainPS.printPrefixln("wait(" + x.getName() + "_event);");
+
+        _mainPS.printRightBracket();
+        _mainPS.printRightBracket();
+    }
+
+    /**
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        for (Port p : x.getPortList()) {
+            Port peerPort = (Port)(p.getPeerPort());
+            Resource peerResource = p.getPeerResource();
+            if (peerPort.getRange() != null) {
+                if (p.isOutPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.INPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), ""));
+                }
+                else if (p.isInPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.OUTPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replaceAll(
+                            "_([0-9]+)", "[$1]").replaceFirst(
+                            peerPort.getBasename(), ""));
+                }
+            }
+            else {
+                if (p.isOutPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.INPORT_" + peerPort.getName());
+                }
+                else if (p.isInPort()) {
+                    _mainPS.printPrefix(peerResource.getName()
+                            + "_ins.OUTPORT_" + peerPort.getName());
+                }
+            }
+            _mainPS.println(" = &" + x.getName() + "_ins;");
+        }
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/hds/HdsProcessVisitor.java b/dol/src/dol/visitor/hds/HdsProcessVisitor.java
new file mode 100644 (file)
index 0000000..3912408
--- /dev/null
@@ -0,0 +1,232 @@
+/* $Id: HdsProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $$ */
+package dol.visitor.hds;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a wrapper class for a process: process_wrapper.[h/cpp].
+ */
+public class HdsProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public HdsProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> pList = new Vector<String>();
+
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    p.accept(this);
+                }
+            }
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param p process that needs to be rendered
+     */
+    public void visitComponent(Process p) {
+        try {
+            _createCppFile(p);
+            _createHeaderFile(p);
+            _adaptSources(p);
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _adaptSources(Process p) throws IOException {
+        Sed sed = new Sed();
+        for (Port port : p.getPortList()) {
+            String processHeaderFile;
+
+            for (SourceCode sr : p.getSrcList()) {
+                processHeaderFile = _dir + _delimiter + ".."
+                        + _delimiter + "processes" + _delimiter
+                        + sr.getLocality().
+                        replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                if (port.isOutPort()) {
+                    sed.sed(processHeaderFile,
+                            "(#define[ ]+PORT_\\w*[ ]+)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + "((static_cast<" + p.getBasename()
+                            + "_wrapper *>(p->wptr))->OUTPORT_"
+                            + port.getBasename() + ")");
+
+                }
+                else if (port.isInPort()) {
+                    sed.sed(processHeaderFile,
+                            "(#define[ ]+PORT_\\w*[ ]+)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + "((static_cast<" + p.getBasename()
+                            + "_wrapper *>(p->wptr))->INPORT_"
+                            + port.getBasename() + ")");
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _createCppFile(Process p) throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.cpp";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        String newline = System.getProperty("line.separator");
+        String code = "#include \"" + p.getBasename() + "_wrapper.h\""
+                + newline;
+        for (SourceCode sr : p.getSrcList()) {
+            code += "#include \"" + sr.getLocality() + "\"" + newline;
+        }
+        /*
+        for (SourceCode sr : p.getSrcList()) {
+            code += "#include \"" + sr.getLocality().substring(0,
+                    sr.getLocality().lastIndexOf(".") + 1) + "h\""
+                    + newline;
+        }
+        */
+        
+        code += newline;
+
+        code += p.getBasename() + "_wrapper::"
+                + p.getBasename() + "_wrapper(char* name)"
+                + newline;
+        code += "        : ProcessWrapper(name) {" + newline;
+        code += "    _state = (LocalState)new "
+                + p.getBasename().substring(0, 1).toUpperCase()
+                + p.getBasename().substring(1) + "_State;"
+                + newline;
+        code += "    _process.local = _state;"  + newline; 
+        code += "    _process.init = " + p.getBasename() + "_init;"
+                + newline;
+        code += "    _process.fire = " + p.getBasename() + "_fire;"
+        + newline;
+        code += "    _process.wptr = this;" + newline;
+        code += "}" + newline + newline;
+
+        code += p.getBasename() + "_wrapper::~" + p.getBasename()
+                + "_wrapper() {" + newline;
+        code += "    if (_state)" + newline;
+        code += "        delete ("
+                + p.getBasename().substring(0, 1).toUpperCase()
+                + p.getBasename().substring(1) + "_State*)_state;"
+                + newline;
+        code += "}" + newline;
+        ps.printPrefixln(code);
+    }
+
+    protected void _createHeaderFile(Process p)
+        throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        String newline = System.getProperty("line.separator");
+        String code = "#ifndef " + p.getBasename() + "_WRAPPER_H"
+                + newline;
+        code += "#define " + p.getBasename() + "_WRAPPER_H" + newline
+                + newline;
+        code += "#include \"ProcessWrapper.h\"" + newline; 
+        code += "#include \"dolSupport.h\"" + newline;
+        code += newline;
+
+        code += "class " + p.getBasename() + "_wrapper : "
+                + "public ProcessWrapper {" + newline;
+        code += "    public:" + newline;
+        code += "        " + p.getBasename()
+                + "_wrapper(char* name);" + newline;
+        code += "        virtual ~" + p.getBasename() + "_wrapper();"
+                + newline;
+
+        Vector<String> portList = new Vector<String>();
+        for (Port port : p.getPortList()) {
+            String basename = port.getBasename();
+
+            if (!portList.contains(basename)) {
+                portList.add(basename);
+
+                if (((Channel)port.getPeerResource()).getType().
+                        equals("wfifo")) {
+                    code += "        WindowedFifo *";      
+                } else {
+                    code += "        Fifo *";
+                }
+                if (!port.getRange().equals("")) {
+                    if (port.isOutPort()) {
+                        code += "OUTPORT_"
+                                + port.getBasename() + "["
+                                + port.getRange().replaceAll(
+                                ";", "\\]\\[") + "];" + newline;
+                    }
+                    else if (port.isInPort()) {
+                        code += "INPORT_"
+                                + port.getBasename() + "["
+                                + port.getRange().replaceAll(
+                                ";", "\\]\\[") + "];" + newline;
+                    }
+                }
+                else {
+                    if (port.isOutPort()) {
+                        code += "OUTPORT_"
+                                + port.getName() + ";" + newline;
+                    }
+                    else if (port.isInPort()) {
+                        code += "INPORT_"
+                                + port.getName() + ";" + newline;
+                    }
+                }
+            }
+        }
+
+        code += "    protected:" + newline;
+        code += "        LocalState _state;" + newline;
+        code += "};" + newline + newline;
+        code += "#endif";
+        ps.printPrefixln(code);
+    }
+
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/hds/HdsVisitor.java b/dol/src/dol/visitor/hds/HdsVisitor.java
new file mode 100644 (file)
index 0000000..bb8d47a
--- /dev/null
@@ -0,0 +1,100 @@
+/* $Id: HdsVisitor.java 1 2010-02-24 13:03:05Z haidw $$ */
+package dol.visitor.hds;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a HdS package.
+ */
+public class HdsVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param packageName name of the HdS directory
+     */
+    public HdsVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _generateDirHierarchy();
+
+            x.accept(new HdsMakefileVisitor(_srcDir));
+            x.accept(new HdsModuleVisitor(_srcDir));
+            x.accept(new HdsProcessVisitor(_wrapperDir));
+        }
+        catch (Exception e) {
+            System.out.println("HdSVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _generateDirHierarchy()
+        throws IOException, FileNotFoundException {
+        File dir = new File(_packageName);
+        dir.mkdirs();
+
+        _srcDir = _packageName + _delimiter + _srcDirName;
+        dir = new File(_srcDir);
+        dir.mkdirs();
+
+        _libDir = _srcDir + _delimiter + _libDirName;
+        dir = new File(_libDir);
+        dir.mkdirs();
+
+        _processDir = _srcDir + _delimiter + _processDirName;
+        dir = new File(_processDir);
+        dir.mkdirs();
+
+        _wrapperDir = _srcDir + _delimiter + _wrapperDirName;
+        dir = new File(_wrapperDir);
+        dir.mkdirs();
+
+        //copy library files
+        File source = new File(_ui.getMySystemCLib().
+                replaceAll("systemC", "hds"));
+        File destination = new File(_libDir);
+        new Copier().copy(source, destination);
+
+        //copy process source code
+        source = new File(_srcDirName);
+        destination = new File(_processDir);
+        new Copier().copy(source, destination);
+    }
+
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+
+    protected String _libDir = "";
+    protected static String _libDirName = "lib";
+
+    protected String _processDir = "";
+    protected static String _processDirName = "processes";
+
+    protected String _wrapperDir = "";
+    protected static String _wrapperDirName = "sc_wrappers";
+
+    protected String _threadPostfix = "_thread";
+
+    protected CodePrintStream _mainPS = null;
+}
diff --git a/dol/src/dol/visitor/hds/lib/Fifo.cpp b/dol/src/dol/visitor/hds/lib/Fifo.cpp
new file mode 100644 (file)
index 0000000..4c66c4c
--- /dev/null
@@ -0,0 +1,254 @@
+#include "Fifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::Fifo(char* name, unsigned size = 18) {\r
+    //std::cout << "Create Fifo." << std::endl;\r
+    //except at the beginning, _head and _tail must never overlap,\r
+    //otherwise one does not know whether the buffer is full or\r
+    //empty. to have nevertheless a buffer with the given capacity,\r
+    //a buffer with one more element is allocated.\r
+    _size = size;\r
+    _buffer = new char[_size];\r
+    //_head = 0;\r
+       _use = 0;\r
+    _tail = 0;\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::~Fifo() {\r
+    //std::cout << "Delete Fifo." << std::endl;\r
+    if (_buffer) {\r
+        delete _buffer;\r
+    }\r
+    if (_name) {\r
+        delete _name;\r
+    }\r
+    _buffer = 0;\r
+    //_head = 0;\r
+       _use = 0;\r
+    _tail = 0;\r
+    _name = 0;\r
+    //std::cout << "Deleted Fifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::read(void *destination, unsigned len) {\r
+    char* buffer = (char*)destination;\r
+    unsigned read = 0;\r
+    //std::cout << "Try to read " << len << " bytes from Fifo " << _name << "." << std::endl;\r
+\r
+\r
+    while (read < len) {\r
+           while( _use < len)\r
+                   wait(_writeEvent);\r
+           unsigned tocopy = (len - read <= _use ? len - read : _use);\r
+\r
+           if ((unsigned)_tail + tocopy < _size) {\r
+                   memcpy(buffer, _buffer + (unsigned)_tail, tocopy);\r
+           }\r
+           else {\r
+                   memcpy(buffer, _buffer + (unsigned)_tail, _size - (unsigned)_tail);\r
+                   memcpy(buffer + _size - (unsigned)_tail, _buffer, tocopy - _size + (unsigned)_tail);\r
+           }\r
+\r
+           read += tocopy;\r
+           buffer += tocopy;\r
+           _tail = (_tail + tocopy) % _size;\r
+           _use -= read;\r
+           _readEvent.notify();\r
+    }\r
+\r
+    /*while (read < len) {\r
+         if (used() == 0) {\r
+               wait(_writeEvent);\r
+         } else if ((len - read) < used()) {\r
+               while (read < len) {\r
+                 unsigned tocopy = (len - read + _tail >= _size) ? _size - _tail : len - read;\r
+                 memcpy(buffer, _buffer + _tail, tocopy);\r
+                 _tail = (_tail + tocopy) % _size;\r
+                 read += tocopy;\r
+                 buffer += tocopy;\r
+               }\r
+               _readEvent.notify();\r
+         } else {\r
+               *buffer++ = *(_buffer + _tail % _size);\r
+               _tail = (_tail + 1) % _size;\r
+               read++;\r
+               _readEvent.notify();\r
+         }\r
+       }*/\r
+\r
+    //std::cout << "Read " << read << " bytes from Fifo " << _name << "." << std::endl;\r
+    return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::write(const void *source, unsigned len) {\r
+    char* buffer = (char*)source;\r
+    unsigned write = 0;\r
+       unsigned head = (_tail + _use) % _size;\r
+    //std::cout << "Try to write " << len << " bytes to Fifo " << _name << std::endl;\r
+\r
+    while (write < len) {\r
+           while (unused() < len) \r
+                   wait(_readEvent);\r
+           unsigned tocopy = (len - write <= unused() ? len - write : unused());\r
+\r
+           if (head + tocopy < _size) {\r
+                   memcpy(_buffer + head, buffer, tocopy);\r
+           }\r
+           else {\r
+                   memcpy(_buffer + head, buffer, _size - head);\r
+                   memcpy(_buffer, buffer + _size - head, tocopy - _size + head);\r
+           }\r
+\r
+           write += tocopy;\r
+           buffer += tocopy;\r
+           head = (head + tocopy) % _size;\r
+           _use += write;\r
+           _writeEvent.notify();\r
+    }\r
+\r
+    /* while (write < len) {\r
+      if (unused() == 0) {\r
+        wait(_readEvent);\r
+      } else if ((len - write) < unused()) {\r
+        while (write < len) {\r
+          unsigned tocopy = (len - write + _head >= _size) ? _size - _head : len - write;\r
+          memcpy(_buffer + _head, buffer, tocopy);\r
+          _head = (_head + tocopy) % _size;\r
+          write += tocopy;\r
+          buffer += tocopy;\r
+        }\r
+        _writeEvent.notify();\r
+      } else {\r
+        *(_buffer + (unsigned)(_head) % _size) = *buffer++;\r
+        _head = (_head + 1) % _size;\r
+        write++;\r
+        _writeEvent.notify();\r
+      }\r
+    }*/\r
+\r
+    //std::cout << "Wrote " << write << " bytes to Fifo " << _name << "." << std::endl;\r
+    return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::size() const {\r
+    return (_size);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::unused() const {\r
+    return (_size) - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::used() const {\r
+    return _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+char* Fifo::getName() const {\r
+    return _name;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+class producer : public sc_module\r
+{\r
+   public:\r
+     Fifo *fifo;\r
+\r
+     SC_HAS_PROCESS(producer);\r
+\r
+     producer(sc_module_name name) : sc_module(name)\r
+     {\r
+       SC_THREAD(main);\r
+     }\r
+\r
+     void main()\r
+     {\r
+       const char *str =\r
+         "Visit www.systemc.org and see what SystemC can do for you today!\n";\r
+\r
+       while (*str) {\r
+         fifo->write((void*)str++, 4);\r
+       }\r
+     }\r
+};\r
+\r
+class consumer : public sc_module\r
+{\r
+   public:\r
+     Fifo *fifo;\r
+\r
+     SC_HAS_PROCESS(consumer);\r
+\r
+     consumer(sc_module_name name) : sc_module(name)\r
+     {\r
+       SC_THREAD(main);\r
+     }\r
+\r
+     void main()\r
+     {\r
+       char c;\r
+       cout << endl << endl;\r
+\r
+       while (true) {\r
+         fifo->read(&c, 4);\r
+         cout << c << flush;\r
+\r
+         if (fifo->used() == 1)\r
+             cout << "<1>" << flush;\r
+         if (fifo->used() == 9)\r
+             cout << "<9>" << flush;\r
+       }\r
+     }\r
+};\r
+\r
+class top : public sc_module\r
+{\r
+   public:\r
+     Fifo *fifo_inst;\r
+     producer *prod_inst;\r
+     consumer *cons_inst;\r
+\r
+     top(sc_module_name name) : sc_module(name)\r
+     {\r
+       fifo_inst = new Fifo("myfifo", 10);\r
+\r
+       prod_inst = new producer("producer");\r
+       prod_inst->fifo = fifo_inst;\r
+\r
+       cons_inst = new consumer("consumer");\r
+       cons_inst->fifo = fifo_inst;\r
+     }\r
+};\r
+\r
+int sc_main (int argc , char *argv[]) {\r
+   top top1("top");\r
+   sc_start();\r
+   return 0;\r
+}\r
+*/\r
diff --git a/dol/src/dol/visitor/hds/lib/Fifo.h b/dol/src/dol/visitor/hds/lib/Fifo.h
new file mode 100644 (file)
index 0000000..e694612
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _FIFO_H_\r
+#define _FIFO_H_\r
+\r
+#include "systemc.h"\r
+\r
+class Fifo {\r
+    public:\r
+        Fifo(char* name, unsigned size);\r
+        virtual ~Fifo();\r
+\r
+        virtual unsigned read(void *destination, unsigned len);\r
+        virtual unsigned write(const void *source, unsigned len);\r
+        virtual unsigned used() const;\r
+        virtual unsigned unused() const;\r
+        virtual unsigned size() const;\r
+        virtual char* getName() const;\r
+\r
+    protected:\r
+        char *_buffer;\r
+        //unsigned _head;\r
+        unsigned _tail;\r
+        unsigned _size;\r
+               unsigned _use; \r
+        char *_name;\r
+        sc_event _readEvent;\r
+        sc_event _writeEvent;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/Performance_Extraction.cpp b/dol/src/dol/visitor/hds/lib/Performance_Extraction.cpp
new file mode 100644 (file)
index 0000000..9322648
--- /dev/null
@@ -0,0 +1,447 @@
+#include "Performance_Extraction.h"
+#include <string>
+#include <fstream>
+
+
+Performance_Extraction performance_extraction("static_characterization.xml");
+
+/**
+ *
+ */
+int get_current_time(CURRENT_TIME *current_time_ptr)
+{
+    return clock_gettime(CLOCK_REALTIME, &(current_time_ptr->ts));
+}
+
+
+/**
+ *
+ */
+double sub_time(CURRENT_TIME *start_time_ptr, CURRENT_TIME *end_time_ptr)
+{
+    CURRENT_TIME diff_time;
+    double time_ns;
+
+    diff_time.ts.tv_sec = end_time_ptr->ts.tv_sec - start_time_ptr->ts.tv_sec;
+    diff_time.ts.tv_nsec = end_time_ptr->ts.tv_nsec - start_time_ptr->ts.tv_nsec;
+    time_ns = diff_time.ts.tv_sec * 1E+9 + diff_time.ts.tv_nsec;
+
+    return time_ns;
+}
+
+
+/**
+ *
+ */
+Process_Performance::Process_Performance(const char *name)
+{
+    strcpy(_process_name, name);
+    _head = NULL;
+    _tail = NULL;
+}
+
+
+/**
+ *
+ */
+Process_Performance::~Process_Performance()
+{
+    COMP_ENTRY *temp;
+    DBGPRINT;
+    while (_head != NULL) {
+        temp = _head;
+        _head = _head->next;
+        delete temp;
+    }
+}
+
+
+/**
+ *
+ */
+const char *Process_Performance::get_name()
+{
+    return _process_name;
+}
+
+
+/**
+ *
+ */
+COMP_ENTRY *Process_Performance::get_head_entry()
+{
+    return _head;
+}
+
+
+/**
+ *
+ */
+COMP_ENTRY *Process_Performance::get_entry(int start_line, int end_line)
+{
+    COMP_ENTRY *temp = NULL;
+    temp = _head;
+    while (temp != NULL) {
+        if ((temp->start_line == start_line) && (temp->end_line == end_line)) {
+            break;
+        }
+        temp = temp->next;
+    }
+
+    return temp;
+}
+
+
+/**
+ *
+ */
+COMP_ENTRY *Process_Performance::add_entry(int start_line, int end_line)
+{
+    COMP_ENTRY *temp = NULL;
+    temp = get_entry(start_line, end_line);
+    if (temp == NULL) {
+        temp = new COMP_ENTRY;
+
+        if (_head == NULL) {
+            _head = temp;
+            _tail = temp;
+            temp->next = NULL;
+        } else {
+            _tail->next = temp;
+            _tail = temp;
+            temp->next = NULL;
+        }
+        temp->start_line = start_line;
+        temp->end_line = end_line;
+        temp->total_computation_time = 0;
+        temp->called_times = 0;
+    }
+
+    return temp;
+}
+
+
+/**
+ *
+ */
+int Process_Performance::set_entry(int start_line, int end_line,
+                                   CURRENT_TIME *start_time_ptr,
+                                   CURRENT_TIME *end_time_ptr)
+{
+    int ret = 0;
+    COMP_ENTRY *temp;
+    double computation_time;
+    computation_time = sub_time(start_time_ptr, end_time_ptr);
+    temp = get_entry(start_line, end_line);
+    if (temp == NULL) {
+        temp = add_entry(start_line, end_line);
+    }
+
+    temp->total_computation_time += computation_time;
+    temp->called_times++;
+
+    return ret;
+}
+
+
+/**
+ *
+ */
+Performance_Extraction::Performance_Extraction(const char *chr_file_name)
+{
+    strcpy(_chr_file_name, chr_file_name);
+}
+
+
+/**
+ *
+ */
+Performance_Extraction::~Performance_Extraction()
+{
+    Process_Performance *process_performance_ptr;
+
+#ifdef INCLUDE_PERFORMANCE
+    //strcpy(_processor_type, "DSP");
+    //add_to_xml_file(_chr_file_name);
+    //strcpy(_processor_type, "RISC");
+    //add_to_xml_file(_chr_file_name);
+
+    write_to_xml_file(_chr_file_name);
+#endif
+
+    for (_iter_process_performance = _list_process_performance.begin();
+         _iter_process_performance != _list_process_performance.end();
+         _iter_process_performance++)
+    {
+        process_performance_ptr = *_iter_process_performance;
+        delete process_performance_ptr;
+    }
+    _list_process_performance.clear();
+
+}
+
+
+/**
+ *
+ */
+int Performance_Extraction::add_computation_performance(
+    const char *process_name, int start_line, int end_line,
+    CURRENT_TIME *start_time_ptr, CURRENT_TIME *end_time_ptr)
+{
+    int ret = 0;
+    Process_Performance *process_performance_ptr;
+
+    process_performance_ptr = get_process_performance(process_name);
+    if (process_performance_ptr == NULL) {
+        process_performance_ptr = new Process_Performance(process_name);
+        _list_process_performance.push_back(process_performance_ptr);
+    }
+
+    process_performance_ptr->set_entry(start_line, end_line,
+                                       start_time_ptr, end_time_ptr);
+
+    return ret;
+}
+
+
+/**
+ *
+ */
+Process_Performance *Performance_Extraction::get_process_performance(
+    const char *process_name)
+{
+    Process_Performance *process_performance_ptr = NULL;
+
+    for (_iter_process_performance = _list_process_performance.begin();
+         _iter_process_performance != _list_process_performance.end();
+         _iter_process_performance++) {
+        process_performance_ptr = *_iter_process_performance;
+        if (strcmp(process_performance_ptr->get_name(), process_name) == 0) {
+            break;
+        }
+    }
+
+    if (_iter_process_performance == _list_process_performance.end()) {
+        process_performance_ptr = NULL;
+    }
+
+    return process_performance_ptr;
+}
+
+
+/**
+ * write performance data into XML file. (identical to add_to_xml_file()
+ * if file does not exist).
+ */
+int Performance_Extraction::write_to_xml_file(const char *chr_file_name)
+{
+    char start_line_str[NAME_LENGTH];
+    char end_line_str[NAME_LENGTH];
+    char computation_time_str[NAME_LENGTH];
+    double computation_time;
+    Process_Performance *process_performance_ptr;
+    COMP_ENTRY *comp_entry;
+
+    //create xml
+    string text = "<?xml version=\"1.0\"?>\n<characterization>\n";
+    for (_iter_process_performance = _list_process_performance.begin();
+         _iter_process_performance != _list_process_performance.end();
+         _iter_process_performance++) {
+        process_performance_ptr = *_iter_process_performance;
+
+        text += "  <process name=\"";
+        text += process_performance_ptr->get_name();
+        text += "\">\n";
+
+        for (comp_entry = process_performance_ptr->get_head_entry();
+             comp_entry != NULL;
+             comp_entry = comp_entry->next) {
+            sprintf(start_line_str, "%d", comp_entry->start_line);
+            sprintf(end_line_str, "%d", comp_entry->end_line);
+
+            //hack to eliminate the overhead of system call clock_gettime.
+            //computation_time is nano sec. To get cycles, need to mutiply
+            //by the frequency of cpu. result is in cycles.
+            computation_time = (comp_entry->total_computation_time
+                                / comp_entry->called_times - SYS_OVERHEAD)
+                                * HOST_FREQUENCY;
+            if (computation_time < 0) {
+                computation_time = 0;
+            }
+            sprintf(computation_time_str, "%.0f", computation_time);
+
+            text += "    <computation start=\"";
+            text += start_line_str;
+            text += "\" end=\"";
+            text += end_line_str;
+            text += "\">\n";
+            text += "      <processor type=\"DSP\" time=\"";
+            text += computation_time_str;
+            text += "\"/>\n";
+            text += "      <processor type=\"RISC\" time=\"";
+            text += computation_time_str;
+            text += "\"/>\n";
+            text += "    </computation>\n";
+        }
+        text += "  </process>\n";
+    }
+    text += "  <communication name=\"read\">\n";
+    text += "    <processor type=\"DSP\" time=\"2\"/>\n";
+    text += "    <processor type=\"RISC\" time=\"2\"/>\n";
+    text += "  </communication>\n";
+    text += "  <communication name=\"write\">\n";
+    text += "    <processor type=\"DSP\" time=\"2\"/>\n";
+    text += "    <processor type=\"RISC\" time=\"2\"/>\n";
+    text += "  </communication>\n";
+    text += "</characterization>\n";
+
+    //write xml to file
+    std::ofstream out(chr_file_name, ios::out);
+    if (!out) {
+      printf("Cannot open file %s. Return.\n", chr_file_name);
+      return -1;
+    }
+    out.write(text.c_str(), text.size());
+    out.close();
+    return 0;
+}
+
+
+/**
+ * add performance data to existing XML file (or create new one if file
+ * does not exist).
+ */
+int Performance_Extraction::add_to_xml_file(const char *chr_file_name)
+{
+    int ret = 0;
+    XMLNode file_node;
+    XMLNode root_node;
+    XMLNode process_node;
+    XMLNode comp_node;
+    int computation_index = 0;
+    XMLNode processor_node;
+    XMLNode read_node;
+    XMLNode write_node;
+
+    Process_Performance *process_performance_ptr;
+    COMP_ENTRY *comp_entry;
+
+    char start_line_str[NAME_LENGTH];
+    char end_line_str[NAME_LENGTH];
+    char computation_time_str[NAME_LENGTH];
+    double computation_time;
+
+    file_node = XMLNode::parseFile(chr_file_name);
+    if (file_node.isEmpty()) {
+        file_node = XMLNode::createXMLTopNode("xml", TRUE);
+        file_node.addAttribute("version", "1.0");
+        root_node = file_node.addChild("characterization");
+    }
+
+    root_node = file_node.getChildNode();
+    if (root_node.isEmpty()) {
+        ret = -1;
+        printf("Open characterization file error\n");
+        return ret;
+    }
+
+    for (_iter_process_performance = _list_process_performance.begin();
+         _iter_process_performance != _list_process_performance.end();
+         _iter_process_performance++) {
+        process_performance_ptr = *_iter_process_performance;
+
+        printf("%s\n", process_performance_ptr->get_name());
+
+        process_node = root_node.getChildNodeWithAttribute(
+            "process", "name", process_performance_ptr->get_name());
+        if (process_node.isEmpty())
+        {
+            process_node = root_node.addChild("process");
+            process_node.addAttribute(
+                "name",process_performance_ptr->get_name());
+        }
+
+        for (comp_entry = process_performance_ptr->get_head_entry();
+             comp_entry != NULL;
+             comp_entry = comp_entry->next) {
+            sprintf(start_line_str, "%d", comp_entry->start_line);
+            sprintf(end_line_str, "%d", comp_entry->end_line);
+
+            printf("%d %d\n", comp_entry->start_line, comp_entry->end_line);
+
+            /* Hack to eliminate the overhead of system call clock_gettime.
+               computation_time is nano sec. To get cycles, need to mutiply
+               by the frequency of cpu.
+               result is cycles */
+            computation_time = (comp_entry->total_computation_time
+                                / comp_entry->called_times - SYS_OVERHEAD)
+                                * HOST_FREQUENCY;
+
+            if (computation_time < 0) {
+                computation_time = 0;
+            }
+
+            sprintf(computation_time_str, "%.0f", computation_time);
+            computation_index = 0;
+            comp_node = process_node.getChildNode("computation",
+                                                  computation_index++);
+            while (!comp_node.isEmpty()) {
+                if (strcmp(comp_node.getAttribute("start"),start_line_str)==0
+                    && strcmp(comp_node.getAttribute("end"),end_line_str)==0) {
+                    break;
+                }
+
+                comp_node = process_node.getChildNode("computation",
+                                                      computation_index++);
+            }
+
+            if (comp_node.isEmpty()) {
+                comp_node = process_node.addChild("computation");
+                comp_node.addAttribute("start", start_line_str);
+                comp_node.addAttribute("end", end_line_str);
+            }
+
+            processor_node = comp_node.getChildNodeWithAttribute("processor", "type", _processor_type);
+            if (processor_node.isEmpty()) {
+                processor_node = comp_node.addChild("processor");
+                processor_node.addAttribute("type", _processor_type);
+                processor_node.addAttribute("time", computation_time_str);
+            }
+        }
+    }
+
+    read_node = root_node.getChildNodeWithAttribute("communication",
+                                                    "name", "read");
+    if (read_node.isEmpty()) {
+        read_node = root_node.addChild("communication");
+        read_node.addAttribute("name", "read");
+    }
+
+    processor_node = read_node.getChildNodeWithAttribute("processor",
+                                                         "type",
+                                                         _processor_type);
+    if (processor_node.isEmpty()) {
+        processor_node = read_node.addChild("processor");
+        processor_node.addAttribute("type", _processor_type);
+        processor_node.addAttribute("time", "2");
+    }
+
+    write_node = root_node.getChildNodeWithAttribute("communication",
+                                                     "name", "write");
+    if (write_node.isEmpty()) {
+        write_node = root_node.addChild("communication");
+        write_node.addAttribute("name", "write");
+    }
+
+    processor_node = write_node.getChildNodeWithAttribute("processor",
+                                                          "type",
+                                                          _processor_type);
+    if (processor_node.isEmpty()) {
+        processor_node = write_node.addChild("processor");
+        processor_node.addAttribute("type", _processor_type);
+        processor_node.addAttribute("time", "2");
+    }
+
+    file_node.writeToFile(chr_file_name);
+    return 0;
+}
diff --git a/dol/src/dol/visitor/hds/lib/Performance_Extraction.h b/dol/src/dol/visitor/hds/lib/Performance_Extraction.h
new file mode 100644 (file)
index 0000000..f122696
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef _PERFORMANCE_EXTRACTION_H
+#define _PERFORMANCE_EXTRACTION_H
+
+#include <sys/time.h>
+#include <time.h>
+#include "trace.h"
+
+#define SYS_OVERHEAD 1400 //what should be exact vale
+#define HOST_FREQUENCY 3 //Ghz
+
+typedef struct COMP_ENTRY {
+    int start_line;
+    int end_line;
+    double total_computation_time;
+    int called_times;
+    COMP_ENTRY *next;
+} COMP_ENTRY;
+
+typedef struct CURRENT_TIME {
+    struct timespec ts;
+}CURRENT_TIME;
+
+extern  int get_current_time(CURRENT_TIME *current_time_ptr);
+extern double sub_time(CURRENT_TIME *start_time_ptr, CURRENT_TIME *end_time_ptr);
+
+class Process_Performance
+{
+private:
+    char _process_name[NAME_LENGTH];
+    COMP_ENTRY *_head;
+    COMP_ENTRY *_tail;
+
+public:
+    Process_Performance(const char *process_name);
+    ~Process_Performance();
+
+    const char *get_name();
+    COMP_ENTRY * add_entry(int start_line, int end_line);
+    int set_entry(int start_line, int end_line, CURRENT_TIME *start_time_ptr,
+                  CURRENT_TIME *end_time_ptr);
+    COMP_ENTRY *get_entry(int start_line, int end_line);
+    COMP_ENTRY *get_head_entry();
+};
+
+class Performance_Extraction
+{
+private:
+    char _processor_type[NAME_LENGTH];
+    char _chr_file_name[NAME_LENGTH];
+    list<Process_Performance *> _list_process_performance;
+    list<Process_Performance *>::iterator _iter_process_performance;
+
+public:
+    Performance_Extraction(const char *chr_file_name);
+    ~Performance_Extraction();
+
+    int add_computation_performance(const char *process_name, int start_line,
+                                    int end_line, CURRENT_TIME *start_time_ptr,
+                                    CURRENT_TIME *end_time_ptr);
+    Process_Performance *get_process_performance(const char *process_name);
+    int write_to_xml_file(const char *chr_file_name);
+    int add_to_xml_file(const char *chr_file_name);
+};
+
+extern Performance_Extraction performance_extraction;
+
+#endif
diff --git a/dol/src/dol/visitor/hds/lib/ProcessWrapper.cpp b/dol/src/dol/visitor/hds/lib/ProcessWrapper.cpp
new file mode 100644 (file)
index 0000000..89f413a
--- /dev/null
@@ -0,0 +1,157 @@
+#include "ProcessWrapper.h"\r
+#include "dolSupport.h"\r
+\r
+/**\r
+ *\r
+ */\r
+ProcessWrapper::ProcessWrapper(\r
+        sc_module_name name = sc_gen_unique_name("process"))\r
+        : sc_module(name) {\r
+\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+\r
+    _isDetached = false;\r
+    for (int i = 0; i < 4; i++) {\r
+        _iteratorIndex[i] = getIndex(_name, "_", i);\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+ProcessWrapper::~ProcessWrapper() {\r
+    if (_name) {\r
+        delete _name;\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void ProcessWrapper::initialize() {\r
+    _process.init(&_process);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+int ProcessWrapper::fire()\r
+{\r
+    int returnValue;\r
+\r
+    #ifdef INCLUDE_TRACE\r
+    start_line = -1;\r
+    #endif\r
+\r
+    #ifdef INCLUDE_PERFORMANCE\r
+    start_line = -1;\r
+    get_current_time(&start_time);\r
+    #endif\r
+\r
+    returnValue = _process.fire(&_process);\r
+\r
+    #ifdef INCLUDE_TRACE\r
+    end_line = -1;\r
+    dol_functional_trace.create_computation_event(basename(),\r
+            start_line, end_line);\r
+    #endif\r
+\r
+    #ifdef INCLUDE_PERFORMANCE\r
+    get_current_time(&end_time);\r
+    end_line = -1;\r
+    performance_extraction.add_computation_performance(basename(),\r
+            start_line, end_line, &start_time, &end_time);\r
+    #endif\r
+\r
+    return returnValue;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void ProcessWrapper::detach() {\r
+    _isDetached = true;\r
+}\r
+\r
+\r
+/**\r
+ * Gets an index of a string, where the index must be separated by\r
+ * a character specified in tokens.\r
+ * Returns -1, when an error occurs.\r
+ *\r
+ * Example:\r
+ * getIndex("name_1_2", "_", 0) will return 1.\r
+ * getIndex("name_1_2", "_", 1) will return 2.\r
+ *\r
+ * @param string string to parse\r
+ * @param tokens delimiter of indices\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int ProcessWrapper::getIndex(const char* string, char* tokens,\r
+        int indexNumber) const {\r
+    char* string_copy;\r
+    char* token_pointer;\r
+    int index = 0;\r
+\r
+    string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));\r
+    if (!string_copy) {\r
+        fprintf(stderr, "getIndex(): could not allocate memory.\n");\r
+        return -1;\r
+    }\r
+\r
+    strcpy(string_copy, string);\r
+\r
+    token_pointer = strtok(string_copy, tokens);\r
+    do {\r
+        token_pointer = strtok(NULL, tokens);\r
+        index++;\r
+    } while (index <= indexNumber && token_pointer != 0);\r
+\r
+    if (token_pointer) {\r
+        index = atoi(token_pointer);\r
+        free(string_copy);\r
+        return index;\r
+    }\r
+\r
+    return -1;\r
+}\r
+\r
+\r
+/**\r
+ * Get the index of this process.\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int ProcessWrapper::getIndex(unsigned indexNumber) const {\r
+    if (indexNumber < 4) {\r
+        return _iteratorIndex[indexNumber];\r
+    }\r
+    return -1;\r
+}\r
+\r
+\r
+/**\r
+ * Get the name of this process.\r
+ */\r
+char* ProcessWrapper::getName() const {\r
+    return _name;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+#ifdef INCLUDE_PROFILER\r
+void ProcessWrapper::addToProfile(const char *event, void *port,\r
+    int length) {\r
+    if (profiler_output_file != NULL) {\r
+        fprintf(profiler_output_file, "%u %s %s %p%s %d\n",\r
+                profiler_event_counter++, _name, event, port, (event[0] == 'r') ? "I" : "O",\r
+                length);\r
+\r
+    } else {\r
+        printf("profiler_output_file does not exist");\r
+    }\r
+}\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/ProcessWrapper.h b/dol/src/dol/visitor/hds/lib/ProcessWrapper.h
new file mode 100644 (file)
index 0000000..76ab3b3
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _PROCESSWRAPPER_H_\r
+#define _PROCESSWRAPPER_H_\r
+\r
+#include "systemc.h"\r
+#include "dol.h"\r
+#include "dol_sched_if.h"\r
+#include "Fifo.h"\r
+#include "WindowedFifo.h"\r
+#include "functional_trace.h"\r
+#include "Performance_Extraction.h"\r
+\r
+\r
+#ifdef INCLUDE_PROFILER\r
+extern FILE *profiler_output_file;\r
+extern unsigned int profiler_event_counter;\r
+#endif\r
+\r
+class ProcessWrapper : virtual public dol_sched_if, public sc_module\r
+{\r
+    public:\r
+        ProcessWrapper(sc_module_name name);\r
+        virtual ~ProcessWrapper();\r
+        virtual void initialize();\r
+        virtual int fire();\r
+        virtual bool isDetached() { return _isDetached; }\r
+        virtual void detach();\r
+        virtual int getIndex(unsigned indexNumber) const;\r
+        virtual char* getName() const;\r
+\r
+#ifdef INCLUDE_PROFILER\r
+        virtual void addToProfile(const char *event, void *port,\r
+                int length);\r
+#endif\r
+\r
+#ifdef INCLUDE_TRACE\r
+        int start_line;\r
+        int end_line;\r
+        char channel_name[NAME_LENGTH];\r
+#endif\r
+\r
+#ifdef INCLUDE_PERFORMANCE\r
+        int start_line;\r
+        int end_line;\r
+        CURRENT_TIME start_time;\r
+        CURRENT_TIME end_time;\r
+#endif\r
+\r
+    protected:\r
+        char* _name;\r
+        DOLProcess _process;\r
+        bool _isDetached;\r
+        int _iteratorIndex[4];\r
+        virtual int getIndex(const char* string, char* tokens,\r
+                int indexNumber) const;\r
+};\r
+\r
+#endif\r
+\r
diff --git a/dol/src/dol/visitor/hds/lib/WindowedFifo.cpp b/dol/src/dol/visitor/hds/lib/WindowedFifo.cpp
new file mode 100644 (file)
index 0000000..50e960a
--- /dev/null
@@ -0,0 +1,288 @@
+#include "WindowedFifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::WindowedFifo(char* name, unsigned size = 20) {\r
+    //std::cout << "Create WindowedFifo." << std::endl;\r
+    _size = size;\r
+    _buffer = new char[_size];\r
+    _head = 0;\r
+    _tail = 0;\r
+    _headRoom = 0;\r
+    _tailRoom = 0;\r
+    _use = 0;\r
+    //indicates whether Fifo is empty or full if _head == _tail\r
+    //_isFull = false;\r
+    _isHeadReserved = false;\r
+    _isTailReserved = false;\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::~WindowedFifo() {\r
+    //std::cout << "Delete WindowedFifo." << std::endl;\r
+    if (_buffer) {\r
+        delete _buffer;\r
+    }\r
+    if (_name) {\r
+        delete _name;\r
+    }\r
+    _buffer = 0;\r
+    _head = 0;\r
+    _tail = 0;\r
+    _name = 0;\r
+    _use = 0;\r
+    //std::cout << "Deleted WindowedFifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::reserve(void** dest, unsigned len) {\r
+    char** destination = (char**)dest;\r
+    //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;\r
+\r
+    //can only reserve once piece at a time\r
+    if (_isHeadReserved) {\r
+        *destination = 0;\r
+        return 0;\r
+    }\r
+\r
+    while (unused() == 0) {\r
+      wait(_readEvent);\r
+    }\r
+\r
+    //reserve at most as much memory as still available in the buffer\r
+    unsigned write = (len <= _size - _use ? len : _size - _use);\r
+\r
+    if (write > 0) {\r
+        //if wrap-around in buffer: return only buffer for the\r
+        //contiguous buffer space\r
+        if (_head + write > _size) {\r
+            write = _size - _head;\r
+        }\r
+\r
+        _headRoom = (_head + write) == _size? 0 : _head + write;\r
+        *destination = &(_buffer[_head]);\r
+        _isHeadReserved = true;\r
+\r
+        //the following comparison is unsafe in a multi-threaded\r
+        //environment and potentially leads to race-conditions\r
+        /*if (_headRoom == _tail) {\r
+            _isFull = true;\r
+        } else {\r
+            _isFull = false;\r
+        }*/\r
+    }\r
+\r
+    //std::cout << "Reserved " << write << " bytes." << std::endl;\r
+    _writeReserve = write; \r
+    return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::release() {\r
+    if (_isHeadReserved) {\r
+        //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;\r
+        _head = _headRoom;\r
+        _use += _writeReserve;\r
+        _isHeadReserved = false;\r
+        _writeEvent.notify();\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::capture(void **dest, unsigned len) {\r
+    char** destination = (char**)dest;\r
+    //std::cout << "Attempt to capture " << len << " bytes." << std::endl;\r
+\r
+    if (_isTailReserved) {\r
+        //std::cout << "Only one attempt to capture allowed." << std::endl;\r
+        *destination = 0;\r
+        return 0;\r
+    }\r
+\r
+    while (used() == 0) {\r
+      wait(_writeEvent);\r
+    }\r
+\r
+    //capture at most as much data as available in the buffer\r
+    unsigned read = (len <= _use ? len : _use);\r
+\r
+    if ( read > 0 ) {\r
+        //if wrap-around in buffer: return only buffer for the\r
+        //contiguous buffer space\r
+        if (_tail + read> _size) {\r
+            read = _size - _tail;\r
+        }\r
+\r
+        _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;\r
+        *destination = &(_buffer[_tail]);\r
+        _isTailReserved = true;\r
+    }\r
+\r
+    //std::cout << "Captured " << read << " bytes." << std::endl;\r
+\r
+    _readReserve = read; \r
+    return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::consume() {\r
+    if (_isTailReserved) {\r
+        //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;\r
+        _tail = _tailRoom;\r
+        _use -= _readReserve;\r
+        _isTailReserved = false;\r
+        //_isFull = false;\r
+        _readEvent.notify();\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::size() const {\r
+    return _size;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::unused() const {\r
+    return _size - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::used() const {\r
+       return _use;\r
+    /*if (_headRoom > _tail) {\r
+        return _headRoom - _tail;\r
+    } else if (_headRoom == _tail) {\r
+        if (_isFull == true) {\r
+            return _size;\r
+        } else {\r
+            return 0;\r
+        }\r
+    }\r
+    return _headRoom + _size - _tail;*/\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+char* WindowedFifo::getName() const {\r
+    return _name;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+#include <iostream>\r
+#include <iomanip>\r
+#define LENGTH 10\r
+\r
+class producer : public sc_module\r
+{\r
+    public:\r
+    WindowedFifo *wfifo;\r
+\r
+    SC_HAS_PROCESS(producer);\r
+\r
+    producer(sc_module_name name) : sc_module(name)\r
+    {\r
+      SC_THREAD(main);\r
+    }\r
+\r
+    void main()\r
+    {\r
+        for (int j = 0; j < LENGTH; j++) {\r
+            //std::cout << "write " << i << " to Fifo.    ";\r
+            int *buf1;\r
+            int write = wfifo->reserve((void**)&buf1, sizeof(int));\r
+\r
+            if (write == sizeof(int)) {\r
+                *buf1 = j;\r
+                wfifo->release();\r
+                //std::cout << "used: " << std::setw(2) << wfifo->used()\r
+                //        << ", unused: " << std::setw(2) << wfifo->unused()\r
+                //        << ", size: "  << std::setw(2) << wfifo->size()\r
+                //        << std::endl;\r
+            } else {\r
+                std::cout << "Not successful: " << write << std::endl;\r
+            }\r
+        }\r
+        printf("producer returns.\n");\r
+    }\r
+};\r
+\r
+class consumer : public sc_module\r
+{\r
+    public:\r
+    WindowedFifo *wfifo;\r
+\r
+    SC_HAS_PROCESS(consumer);\r
+\r
+    consumer(sc_module_name name) : sc_module(name)\r
+    {\r
+        SC_THREAD(main);\r
+    }\r
+\r
+    void main()\r
+    {\r
+        for (int j = 0; j < LENGTH; j++) {\r
+            int* buf3;\r
+            int read = wfifo->capture((void**)&buf3, sizeof(int));\r
+            if (read == sizeof(int)) {\r
+                std::cout << "read " << (unsigned)*buf3 << "  from WindowedFifo   ";\r
+                std::cout << "used: " << std::setw(2) << wfifo->used()\r
+                        << ", unused: " << std::setw(2) << wfifo->unused()\r
+                        << ", size: "  << std::setw(2) << wfifo->size()\r
+                        << std::endl;\r
+                wfifo->consume();\r
+            } else {\r
+                std::cout << "Read nothing from WindowedFifo." << std::endl;\r
+            }\r
+        }\r
+        printf("consumer returns.\n");\r
+    }\r
+};\r
+\r
+class top : public sc_module\r
+{\r
+    public:\r
+    WindowedFifo *wfifo_inst;\r
+    producer *prod_inst;\r
+    consumer *cons_inst;\r
+\r
+    top(sc_module_name name) : sc_module(name)\r
+    {\r
+        wfifo_inst = new WindowedFifo("myfifo", 4);\r
+\r
+        prod_inst = new producer("producer");\r
+        prod_inst->wfifo = wfifo_inst;\r
+\r
+        cons_inst = new consumer("consumer");\r
+        cons_inst->wfifo = wfifo_inst;\r
+     }\r
+};\r
+\r
+int sc_main (int argc , char *argv[]) {\r
+    top top1("top");\r
+    sc_start();\r
+    return 0;\r
+}\r
+*/\r
diff --git a/dol/src/dol/visitor/hds/lib/WindowedFifo.h b/dol/src/dol/visitor/hds/lib/WindowedFifo.h
new file mode 100644 (file)
index 0000000..a223c95
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _WINDOWEDFIFO_H_\r
+#define _WINDOWEDFIFO_H_\r
+\r
+#include "systemc.h"\r
+\r
+class WindowedFifo {\r
+    public:\r
+        WindowedFifo(char* name, unsigned size);\r
+        virtual ~WindowedFifo();\r
+\r
+        virtual unsigned reserve(void** destination, unsigned len);\r
+        virtual void release();\r
+\r
+        virtual unsigned capture(void** destination, unsigned len);\r
+        virtual void consume();\r
+\r
+        virtual unsigned used() const;\r
+        virtual unsigned unused() const;\r
+        virtual unsigned size() const;\r
+        virtual char* getName() const;\r
+\r
+    protected:\r
+        char *_buffer;\r
+        unsigned _head;\r
+        unsigned _tail;\r
+        unsigned _headRoom;\r
+        unsigned _tailRoom;\r
+        unsigned _size;\r
+        unsigned _use;\r
+        unsigned _writeReserve;  
+        unsigned _readReserve; 
+        //bool _isFull;\r
+        bool _isHeadReserved;\r
+        bool _isTailReserved;\r
+        char *_name;\r
+        sc_event _readEvent;\r
+        sc_event _writeEvent;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/dol.h b/dol/src/dol/visitor/hds/lib/dol.h
new file mode 100644 (file)
index 0000000..8fbefe4
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef DOL_H
+#define DOL_H
+
+/************************************************************************
+ * do not add code to this header
+ ************************************************************************/
+
+/**
+ *  Define the DOL process handler scheme.
+ *  - Local variables are defined in structure LocalState. Local
+ *    variables may vary from different processes.
+ *  - The ProcessInit function pointer points to a function which
+ *    initializes a process.
+ *  - The ProcessFire function pointer points to a function which
+ *    performs the actual computation. The communication between
+ *    processes is inside the ProcessFire function.
+ *  - The WPTR is a placeholder for callback. One can just
+ *    leave it blank.
+ */
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//additional behavioral functions could be declared here
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+//process handler
+struct _process;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr; //placeholder for wrapper instance
+} DOLProcess;
+
+#endif
diff --git a/dol/src/dol/visitor/hds/lib/dolSupport.cpp b/dol/src/dol/visitor/hds/lib/dolSupport.cpp
new file mode 100644 (file)
index 0000000..1db732a
--- /dev/null
@@ -0,0 +1,149 @@
+#include "dolSupport.h"\r
+#include "ProcessWrapper.h"\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned write(void *port, void *buf, unsigned len, DOLProcess *process)\r
+{\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    char *str = static_cast<char*>(buf);\r
+    #ifdef INCLUDE_PROFILER\r
+    (static_cast<ProcessWrapper *>(process->wptr))->addToProfile(\r
+            "w", port, len);\r
+    #endif\r
+    fifo->write((void*)str, len);\r
+    #ifdef INCLUDE_TRACE\r
+    strcpy((static_cast<ProcessWrapper *>(process->wptr))->channel_name,\r
+            fifo->getName());\r
+    #endif\r
+    return len;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned read(void *port, void *buf, unsigned len, DOLProcess *process) {\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    char *str = static_cast<char*>(buf);\r
+    #ifdef INCLUDE_PROFILER\r
+    (static_cast<ProcessWrapper *>(process->wptr))->addToProfile(\r
+            "r", port, len);\r
+    #endif\r
+    fifo->read((void*)str, len);\r
+    #ifdef INCLUDE_TRACE\r
+    strcpy((static_cast<ProcessWrapper *>(process->wptr))->channel_name,\r
+            fifo->getName());\r
+    #endif\r
+    return len;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+int wtest(void *port, unsigned len, DOLProcess *process) {\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    return (fifo->unused() >= len) ? 1 : 0;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+int rtest(void *port, unsigned len, DOLProcess *process) {\r
+    Fifo *fifo = static_cast<Fifo *>(port);\r
+    return (fifo->used() >= len) ? 1 : 0;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p) {\r
+    return ((WindowedFifo*)fifo)->reserve(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void release(void* fifo, DOLProcess* p) {\r
+    ((WindowedFifo*)fifo)->release();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p) {\r
+    return ((WindowedFifo*)fifo)->capture(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void consume(void* fifo, DOLProcess* p) {\r
+    ((WindowedFifo*)fifo)->consume();\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void DOL_detach(DOLProcess* p) {\r
+    static_cast<ProcessWrapper *>(p->wptr)->detach();\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0) {\r
+    *port = (void**)((void**)base)[index0];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1) {\r
+    *port = (void**)((void**)base)[index0 * range1 + index1];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2\r
+                       + index1 * range2 + index2];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2 * range3\r
+                       + index1 * range2 * range3\r
+                       + index2 * range3\r
+                       + index3];\r
+}\r
diff --git a/dol/src/dol/visitor/hds/lib/dolSupport.h b/dol/src/dol/visitor/hds/lib/dolSupport.h
new file mode 100644 (file)
index 0000000..5f0505c
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef DOLSUPPORT_H\r
+#define DOLSUPPORT_H\r
+\r
+#include "dol.h"\r
+#include "Fifo.h"\r
+#include "functional_trace.h"\r
+#include "Performance_Extraction.h"\r
+\r
+#ifdef INCLUDE_PERFORMANCE\r
+#define DOL_write(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    end_time));\\r
+    performance_extraction.add_computation_performance(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line,\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->start_time),\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->end_time));\\r
+    write(port, buf, len, process);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    start_time)); }\r
+#define DOL_read(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    end_time));\\r
+    performance_extraction.add_computation_performance(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line,\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->start_time),\\r
+    &((static_cast<ProcessWrapper *>(p->wptr))->end_time));\\r
+    read(port, buf, len, process);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__;\\r
+    get_current_time(&((static_cast<ProcessWrapper *>(p->wptr))->\\r
+    start_time)); }\r
+#elif INCLUDE_TRACE\r
+#define DOL_write(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    dol_functional_trace.create_computation_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line);\\r
+    write(port, buf, len, process);\\r
+    dol_functional_trace.create_write_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(), len,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->channel_name);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__; }\r
+#define DOL_read(port, buf, len, process) {\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line = __LINE__;\\r
+    dol_functional_trace.create_computation_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(),\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->end_line);\\r
+    read(port, buf, len, process);\\r
+    dol_functional_trace.create_read_event(\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->basename(), len,\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->channel_name);\\r
+    (static_cast<ProcessWrapper *>(p->wptr))->start_line = __LINE__; }\r
+#else\r
+    #define DOL_write(port, buf, len, process) \\r
+    write(port, buf, len, process)\r
+    #define DOL_read(port, buf, len, process) \\r
+    read(port, buf, len, process)\r
+#endif\r
+\r
+#define DOL_reserve(port, buf, size, process) \\r
+    reserve(port, (void**)buf, size, process);\r
+\r
+#define DOL_release(port, process) \\r
+    release(port, process);\r
+\r
+#define DOL_capture(port, buf, size, process) \\r
+    capture(port, (void**)buf, size, process);\r
+\r
+#define DOL_consume(port, process) \\r
+    consume(port, process);\r
+\r
+#define DOL_wtest(port, len, process) wtest(port, len, process)\r
+\r
+#define DOL_rtest(port, len, process) rtest(port, len, process)\r
+\r
+void DOL_detach(DOLProcess* p);\r
+\r
+//fifo access functions\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+int wtest(void *port, unsigned len, DOLProcess *process);\r
+int rtest(void *port, unsigned len, DOLProcess *process);\r
+\r
+//windowed fifo access functions\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void release(void* fifo, DOLProcess* p);\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void consume(void* fifo, DOLProcess* p);\r
+\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3);\r
+\r
+#define GETINDEX(dimension) \\r
+  static_cast<ProcessWrapper *>(p->wptr)->getIndex(dimension)\r
+\r
+/**\r
+ * macro to create a variable to store a port name\r
+ *\r
+ * @param name name of the variable\r
+ */\r
+#define CREATEPORTVAR(name) Fifo *name\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+  createPort((void**)(&port), base, number_of_indices, index_range_pairs)\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/dol_sched_if.h b/dol/src/dol/visitor/hds/lib/dol_sched_if.h
new file mode 100644 (file)
index 0000000..d861b1e
--- /dev/null
@@ -0,0 +1,43 @@
+/**************************************************************************\r
+       dol_sched_if.h\r
\r
+       Scheduler interface for a DOL process    \r
+\r
+       (c) 2006 by Alexander Maxiaguine <maxiagui@tik.ee.ethz.ch>\r
+\r
+       Computer Engineering and Networks Laboratory, TIK\r
+       Swiss Federal Institute of Technology, ETHZ Zurich \r
+       Switzerland\r
+\r
+**************************************************************************/\r
+\r
+/**************************************************************************\r
+       Change Log:\r
+\r
+       14.03.06 -- creation\r
+\r
+**************************************************************************/\r
+\r
+#ifndef DOL_SCHED_IF_H\r
+#define DOL_SCHED_IF_H\r
+\r
+class dol_sched_if \r
+{\r
+\r
+public:\r
+       virtual void initialize() = 0;\r
+       virtual int fire() = 0;\r
+\r
+\r
+protected:\r
+       dol_sched_if()  {}\r
+\r
+\r
+private:\r
+\r
+    // disabled\r
+    dol_sched_if( const dol_sched_if& );\r
+    dol_sched_if& operator = ( const dol_sched_if& );\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/functional_trace.cpp b/dol/src/dol/visitor/hds/lib/functional_trace.cpp
new file mode 100644 (file)
index 0000000..efca06c
--- /dev/null
@@ -0,0 +1,295 @@
+#include "functional_trace.h"\r
+\r
+functional_trace dol_functional_trace;\r
+\r
+functional_trace::functional_trace()\r
+{\r
+    //DBGPRINT;\r
+    strcpy(trace_file_name, "trace1.txt");\r
+    event_num = 0;\r
+    file_index = 1;\r
+}\r
+\r
+functional_trace::~functional_trace()\r
+{\r
+    //DBGPRINT;\r
+    char temp[NAME_LENGTH];\r
+#ifdef INCLUDE_TRACE\r
+    strcpy(trace_file_name, "trace");\r
+    sprintf(temp, "%d", file_index);\r
+    strcat(trace_file_name, temp);\r
+    strcat(trace_file_name, ".txt");\r
+    write_to_file(trace_file_name);\r
+    free_traces();\r
+    //printf("The traces in the memory have been freed\n");\r
+#endif\r
+    //DBGPRINT;\r
+}\r
+\r
+void functional_trace::add_event_node(TRACE_EVENT &trace_event)\r
+{\r
+    Process_Trace *process_trace_ptr;\r
+    char temp[NAME_LENGTH];\r
+\r
+    process_trace_ptr = get_process_trace(trace_event.process_name);\r
+    if (process_trace_ptr == NULL)\r
+    {\r
+        process_trace_ptr = new Process_Trace(trace_event.process_name);\r
+        _list_process_trace.push_back(process_trace_ptr);\r
+    }\r
+\r
+    process_trace_ptr->add_entry(&trace_event);\r
+\r
+    event_num++;\r
+    if (event_num > 8000000)\r
+    {\r
+        strcpy(trace_file_name, "trace");\r
+        sprintf(temp, "%d", file_index);\r
+        strcat(trace_file_name, temp);\r
+        strcat(trace_file_name, ".txt");\r
+        write_to_file(trace_file_name);\r
+        free_traces();\r
+        file_index++;\r
+        event_num = 0;\r
+    }\r
+\r
+}\r
+\r
+/*\r
+void functional_trace::add_event_node(TRACE_EVENT &trace_event)\r
+{\r
+    XMLNode process_node;\r
+    char temp[NAME_LENGTH];\r
+    process_node = xml_main_node.getChildNode(trace_event.process_name);\r
+\r
+    if(process_node.isEmpty())\r
+    {\r
+        process_node = xml_main_node.addChild(trace_event.process_name);\r
+    }\r
+\r
+    XMLNode event_node = process_node.addChild("event");\r
+\r
+    event_node.addAttribute("type", trace_event_type_string[trace_event.event_type]);\r
+\r
+    if(trace_event.event_type == COMPUTATION_EVENT)\r
+    {\r
+\r
+        sprintf(temp, "%d", trace_event.computation_start_line);\r
+        event_node.addAttribute("start", temp);\r
+        sprintf(temp, "%d", trace_event.computation_end_line);\r
+        event_node.addAttribute("end", temp);\r
+    }\r
+    else if((trace_event.event_type == READ_EVENT) || (trace_event.event_type == WRITE_EVENT))\r
+    {\r
+        sprintf(temp, "%d", trace_event.data_num);\r
+        event_node.addAttribute("data_num", temp);\r
+        event_node.addAttribute("channel_name", trace_event.channel_name);\r
+    }\r
+}\r
+*/\r
+\r
+void functional_trace::create_computation_event(const char *process_name, int start_line, int end_line)\r
+{\r
+    TRACE_EVENT trace_event;\r
+\r
+    trace_event.event_type = COMPUTATION_EVENT;\r
+    strcpy(trace_event.process_name, process_name);\r
+    trace_event.computation_start_line = start_line;\r
+    trace_event.computation_end_line = end_line;\r
+    strcpy(trace_event.channel_name, "");\r
+    trace_event.data_num = 0;\r
+\r
+    add_event_node(trace_event);\r
+}\r
+\r
+void functional_trace::create_read_event(const char *process_name, int data_num, const char *channel_name)\r
+{\r
+    //DBGPRINT;\r
+    TRACE_EVENT trace_event;\r
+    trace_event.event_type = READ_EVENT;\r
+    strcpy(trace_event.process_name, process_name);\r
+    trace_event.data_num = data_num;\r
+    strcpy(trace_event.channel_name, channel_name);\r
+\r
+    trace_event.computation_start_line = 0;\r
+    trace_event.computation_end_line = 0;\r
+\r
+    add_event_node(trace_event);\r
+}\r
+\r
+void functional_trace::create_write_event(const char *process_name, int data_num, const char *channel_name)\r
+{\r
+    //DBGPRINT;\r
+    TRACE_EVENT trace_event;\r
+    trace_event.event_type = WRITE_EVENT;\r
+    strcpy(trace_event.process_name, process_name);\r
+    trace_event.data_num = data_num;\r
+    strcpy(trace_event.channel_name, channel_name);\r
+\r
+    trace_event.computation_start_line = 0;\r
+    trace_event.computation_end_line = 0;\r
+\r
+    add_event_node(trace_event);\r
+}\r
+\r
+\r
+Process_Trace *functional_trace::get_process_trace(const char *process_name)\r
+{\r
+    Process_Trace *process_trace_ptr;\r
+\r
+    for (_iter_process_trace = _list_process_trace.begin();\r
+         _iter_process_trace != _list_process_trace.end();\r
+         _iter_process_trace++)\r
+    {\r
+        process_trace_ptr = *_iter_process_trace;\r
+\r
+        if (strcmp(process_trace_ptr->get_name(), process_name) == 0)\r
+        {\r
+            break;\r
+        }\r
+    }\r
+\r
+    if (_iter_process_trace == _list_process_trace.end())\r
+    {\r
+        process_trace_ptr = NULL;\r
+    }\r
+\r
+    return process_trace_ptr;\r
+}\r
+\r
+void functional_trace::free_traces()\r
+{\r
+    Process_Trace *process_trace_ptr;\r
+\r
+    for (_iter_process_trace = _list_process_trace.begin();\r
+         _iter_process_trace != _list_process_trace.end();\r
+         _iter_process_trace++)\r
+    {\r
+        process_trace_ptr = *_iter_process_trace;\r
+        delete process_trace_ptr;\r
+    }\r
+    _list_process_trace.clear();\r
+}\r
+\r
+int functional_trace::write_to_file(const char *trace_file_name) {\r
+    int ret = -1;\r
+    Process_Trace *process_trace_ptr;\r
+    FILE *trace_file_handle;\r
+    EVENT_ENTRY *event_entry_ptr;\r
+\r
+    if ((trace_file_handle = fopen(trace_file_name, "w")) == NULL) {\r
+        ret = -1;\r
+        printf("Can not create file: %s\n", trace_file_name);\r
+        goto end1;\r
+    }\r
+\r
+    for (_iter_process_trace = _list_process_trace.begin();\r
+         _iter_process_trace != _list_process_trace.end();\r
+         _iter_process_trace++) {\r
+        process_trace_ptr = *_iter_process_trace;\r
+        fprintf(trace_file_handle, "$ %s\n", process_trace_ptr->get_name());\r
+\r
+        event_entry_ptr = process_trace_ptr->get_head_entry();\r
+        while (event_entry_ptr != NULL) {\r
+            if (event_entry_ptr->event_type == COMPUTATION_EVENT) {\r
+                if (event_entry_ptr->end_line!=(event_entry_ptr->start_line+1))\r
+                fprintf(trace_file_handle, "c %d %d\n",\r
+                        event_entry_ptr->start_line,\r
+                        event_entry_ptr->end_line);\r
+            }\r
+            else if (event_entry_ptr->event_type == WRITE_EVENT) {\r
+                fprintf(trace_file_handle, "w %d %s\n",\r
+                        event_entry_ptr->data_num,\r
+                        event_entry_ptr->channel_name);\r
+            }\r
+            else if (event_entry_ptr->event_type == READ_EVENT) {\r
+                fprintf(trace_file_handle, "r %d %s\n",\r
+                        event_entry_ptr->data_num,\r
+                        event_entry_ptr->channel_name);\r
+            }\r
+\r
+            event_entry_ptr = event_entry_ptr->next;\r
+        }\r
+    }\r
+\r
+    fflush(trace_file_handle);\r
+    fseek(trace_file_handle, 0, SEEK_SET);\r
+    fclose(trace_file_handle);\r
+\r
+end1:\r
+    return ret;\r
+}\r
+\r
+Process_Trace::Process_Trace(const char *process_name)\r
+{\r
+    strcpy(_process_name, process_name);\r
+    _head = NULL;\r
+    _tail = NULL;\r
+}\r
+\r
+Process_Trace::~Process_Trace()\r
+{\r
+    EVENT_ENTRY *temp;\r
+\r
+    while (_head != NULL)\r
+    {\r
+        temp = _head;\r
+        _head = _head->next;\r
+        if (temp->channel_name != NULL)\r
+            delete [] temp->channel_name;\r
+        delete temp;\r
+    }\r
+}\r
+\r
+const char *Process_Trace::get_name()\r
+{\r
+    return _process_name;\r
+}\r
+\r
+EVENT_ENTRY *Process_Trace::get_head_entry()\r
+{\r
+    return _head;\r
+}\r
+\r
+int Process_Trace::add_entry(TRACE_EVENT *trace_event_ptr)\r
+{\r
+    int ret = 0;\r
+    EVENT_ENTRY *temp;\r
+    int channel_name_length;\r
+\r
+    temp = new EVENT_ENTRY;\r
+    memset(temp, 0, sizeof(EVENT_ENTRY));\r
+\r
+    temp->event_type = trace_event_ptr->event_type;\r
+    temp->start_line = trace_event_ptr->computation_start_line;\r
+    temp->end_line = trace_event_ptr->computation_end_line;\r
+    temp->data_num = trace_event_ptr->data_num;\r
+\r
+    channel_name_length = strlen(trace_event_ptr->channel_name);\r
+    if (channel_name_length != 0)\r
+    {\r
+        temp->channel_name = new char[channel_name_length + 1];\r
+        strcpy(temp->channel_name, trace_event_ptr->channel_name);\r
+    }\r
+    else\r
+    {\r
+        temp->channel_name = NULL;\r
+    }\r
+\r
+    if (_head == NULL)\r
+    {\r
+        _head = temp;\r
+        _tail = temp;\r
+        temp->next = NULL;\r
+    }\r
+    else\r
+    {\r
+        _tail->next = temp;\r
+        _tail = temp;\r
+        temp->next = NULL;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+\r
diff --git a/dol/src/dol/visitor/hds/lib/functional_trace.h b/dol/src/dol/visitor/hds/lib/functional_trace.h
new file mode 100644 (file)
index 0000000..f3f0a8b
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _FUNCTIONAL_H\r
+#define _FUNCTIONAL_H\r
+\r
+#include "trace.h"\r
+\r
+typedef struct EVENT_ENTRY\r
+{\r
+    char event_type;\r
+    int start_line;\r
+    int end_line;\r
+    int data_num;\r
+    char *channel_name;\r
+\r
+    EVENT_ENTRY *next;\r
+}EVENT_ENTRY;\r
+\r
+class Process_Trace\r
+{\r
+private:\r
+    char _process_name[NAME_LENGTH];\r
+    EVENT_ENTRY *_head;\r
+    EVENT_ENTRY *_tail;\r
+\r
+public:\r
+    Process_Trace(const char *process_name);\r
+    ~Process_Trace();\r
+\r
+    const char *get_name();\r
+    int add_entry(TRACE_EVENT *trace_event_ptr);\r
+    EVENT_ENTRY *get_head_entry();\r
+};\r
+\r
+class functional_trace\r
+{\r
+public:\r
+    char trace_file_name[NAME_LENGTH];\r
+    unsigned long event_num;\r
+    int file_index;\r
+\r
+    list<Process_Trace *> _list_process_trace;\r
+    list<Process_Trace *>::iterator _iter_process_trace;\r
+\r
+    functional_trace();\r
+    ~functional_trace();\r
+\r
+    void add_event_node(TRACE_EVENT &trace_event);\r
+    void create_computation_event(const char *process_name, int start_line, int end_line);\r
+    void create_read_event(const char *process_name, int data_num, const char *channel_name);\r
+    void create_write_event(const char *process_name, int data_num, const char *channel_name);\r
+    int write_to_file(const char *trace_file_name);\r
+    Process_Trace *get_process_trace(const char *process_name);\r
+    void free_traces();\r
+};\r
+\r
+extern functional_trace dol_functional_trace;\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/trace.h b/dol/src/dol/visitor/hds/lib/trace.h
new file mode 100644 (file)
index 0000000..3d92e67
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _TRACE_H\r
+#define _TRACE_H\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "xmlParser.h"\r
+#include <list>\r
+\r
+using namespace std;\r
+\r
+#define NAME_LENGTH 256\r
+#ifdef DBG\r
+#define DBGPRINT printf("file: %s--line: %d\n", __FILE__, __LINE__)\r
+#else\r
+#define DBGPRINT\r
+#endif\r
+\r
+typedef enum TRACE_EVENT_TYPE\r
+{\r
+    COMPUTATION_EVENT,\r
+    READ_EVENT,\r
+    WRITE_EVENT,\r
+    UNKOWN\r
+}TRACE_EVENT_TYPE;\r
+\r
+#define MAX_EVENT_TYPE 3\r
+\r
+typedef struct TRACE_EVENT\r
+{\r
+    char process_name[NAME_LENGTH];\r
+    char event_type;\r
+    int computation_start_line;\r
+    int computation_end_line;\r
+    int data_num;\r
+    char channel_name[NAME_LENGTH];\r
+}TRACE_EVENT;\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hds/lib/xmlParser.cpp b/dol/src/dol/visitor/hds/lib/xmlParser.cpp
new file mode 100644 (file)
index 0000000..9868566
--- /dev/null
@@ -0,0 +1,2594 @@
+/**
+ ****************************************************************************
+ * <P> XML.c - implementation file for basic XML parser written in ANSI C++
+ * for portability. It works by using recursion and a node tree for breaking
+ * down the elements of an XML document.  </P>
+ *
+ * @version     V2.23
+ * @author      Frank Vanden Berghen
+ *
+ * NOTE:
+ *
+ *   If you add "#define STRICT_PARSING", on the first line of this file
+ *   the parser will see the following XML-stream:
+ *      <a><b>some text</b><b>other text    </a>
+ *   as an error. Otherwise, this tring will be equivalent to:
+ *      <a><b>some text</b><b>other text</b></a>
+ *
+ * NOTE:
+ *
+ *   If you add "#define APPROXIMATE_PARSING" on the first line of this file
+ *   the parser will see the following XML-stream:
+ *     <data name="n1">
+ *     <data name="n2">
+ *     <data name="n3" />
+ *   as equivalent to the following XML-stream:
+ *     <data name="n1" />
+ *     <data name="n2" />
+ *     <data name="n3" />
+ *   This can be useful for badly-formed XML-streams but prevent the use
+ *   of the following XML-stream (problem is: tags at contiguous levels
+ *   have the same names):
+ *     <data name="n1">
+ *        <data name="n2">
+ *            <data name="n3" />
+ *        </data>
+ *     </data>
+ *
+ * NOTE:
+ *
+ *   If you add "#define _XMLPARSER_NO_MESSAGEBOX_" on the first line of this file
+ *   the "openFileHelper" function will always display error messages inside the
+ *   console instead of inside a message-box-window. Message-box-windows are
+ *   available on windows 9x/NT/2000/XP/Vista only.
+ *
+ * BSD license:
+ * Copyright (c) 2002, Frank Vanden Berghen
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Frank Vanden Berghen nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************
+ */
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#include "xmlParser.h"
+#ifdef _XMLWINDOWS
+//#ifdef _DEBUG
+//#define _CRTDBG_MAP_ALLOC
+//#include <crtdbg.h>
+//#endif
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h> // to have IsTextUnicode, MultiByteToWideChar, WideCharToMultiByte to handle unicode files
+                     // to have "MessageBoxA" to display error messages for openFilHelper
+#endif
+
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+XMLCSTR XMLNode::getVersion() { return _T("v2.23"); }
+void free_XMLDLL(void *t){free(t);}
+
+static char strictUTF8Parsing=1, guessUnicodeChars=1, dropWhiteSpace=1;
+
+inline int mmin( const int t1, const int t2 ) { return t1 < t2 ? t1 : t2; }
+
+// You can modify the initialization of the variable "XMLClearTags" below
+// to change the clearTags that are currently recognized by the library.
+// The number on the second columns is the length of the string inside the
+// first column. The "<!DOCTYPE" declaration must be the second in the list.
+static ALLXMLClearTag XMLClearTags[] =
+{
+    {    _T("<![CDATA["),9,  _T("]]>")      },
+    {    _T("<!DOCTYPE"),9,  _T(">")        },
+    {    _T("<PRE>")    ,5,  _T("</PRE>")   },
+    {    _T("<Script>") ,8,  _T("</Script>")},
+    {    _T("<!--")     ,4,  _T("-->")      },
+    {    NULL           ,0,  NULL           }
+};
+ALLXMLClearTag* XMLNode::getClearTagTable() { return XMLClearTags; }
+
+// You can modify the initialization of the variable "XMLEntities" below
+// to change the character entities that are currently recognized by the library.
+// The number on the second columns is the length of the string inside the
+// first column. Additionally, the syntaxes "&#xA0;" and "&#160;" are recognized.
+typedef struct { XMLCSTR s; int l; XMLCHAR c;} XMLCharacterEntity;
+static XMLCharacterEntity XMLEntities[] =
+{
+    { _T("&amp;" ), 5, _T('&' )},
+    { _T("&lt;"  ), 4, _T('<' )},
+    { _T("&gt;"  ), 4, _T('>' )},
+    { _T("&quot;"), 6, _T('\"')},
+    { _T("&apos;"), 6, _T('\'')},
+    { NULL        , 0, '\0'    }
+};
+
+// When rendering the XMLNode to a string (using the "createXMLString" function),
+// you can ask for a beautiful formatting. This formatting is using the
+// following indentation character:
+#define INDENTCHAR _T('\t')
+
+// The following function parses the XML errors into a user friendly string.
+// You can edit this to change the output language of the library to something else.
+XMLCSTR XMLNode::getError(XMLError xerror)
+{
+    switch (xerror)
+    {
+    case eXMLErrorNone:                  return _T("No error");
+    case eXMLErrorMissingEndTag:         return _T("Warning: Unmatched end tag");
+    case eXMLErrorEmpty:                 return _T("Error: No XML data");
+    case eXMLErrorFirstNotStartTag:      return _T("Error: First token not start tag");
+    case eXMLErrorMissingTagName:        return _T("Error: Missing start tag name");
+    case eXMLErrorMissingEndTagName:     return _T("Error: Missing end tag name");
+    case eXMLErrorNoMatchingQuote:       return _T("Error: Unmatched quote");
+    case eXMLErrorUnmatchedEndTag:       return _T("Error: Unmatched end tag");
+    case eXMLErrorUnmatchedEndClearTag:  return _T("Error: Unmatched clear tag end");
+    case eXMLErrorUnexpectedToken:       return _T("Error: Unexpected token found");
+    case eXMLErrorInvalidTag:            return _T("Error: Invalid tag found");
+    case eXMLErrorNoElements:            return _T("Error: No elements found");
+    case eXMLErrorFileNotFound:          return _T("Error: File not found");
+    case eXMLErrorFirstTagNotFound:      return _T("Error: First Tag not found");
+    case eXMLErrorUnknownCharacterEntity:return _T("Error: Unknown character entity");
+    case eXMLErrorCharConversionError:   return _T("Error: unable to convert between UNICODE and MultiByte chars");
+    case eXMLErrorCannotOpenWriteFile:   return _T("Error: unable to open file for writing");
+    case eXMLErrorCannotWriteFile:       return _T("Error: cannot write into file");
+
+    case eXMLErrorBase64DataSizeIsNotMultipleOf4: return _T("Warning: Base64-string length is not a multiple of 4");
+    case eXMLErrorBase64DecodeTruncatedData:      return _T("Warning: Base64-string is truncated");
+    case eXMLErrorBase64DecodeIllegalCharacter:   return _T("Error: Base64-string contains an illegal character");
+    case eXMLErrorBase64DecodeBufferTooSmall:     return _T("Error: Base64 decode output buffer is too small");
+    };
+    return _T("Unknown");
+}
+
+// Here is an abstraction layer to access some common string manipulation functions.
+// The abstraction layer is currently working for gcc, Microsoft Visual Studio 6.0,
+// Microsoft Visual Studio .NET, CC (sun compiler) and Borland C++.
+// If you plan to "port" the library to a new system/compiler, all you have to do is
+// to edit the following lines.
+#ifdef XML_NO_WIDE_CHAR
+char myIsTextUnicode(const void *b, int len) { return FALSE; }
+#else
+    #if defined (UNDER_CE) || !defined(WIN32)
+    char myIsTextUnicode(const void *b, int len) // inspired by the Wine API: RtlIsTextUnicode
+    {
+#ifdef sun
+        // for SPARC processors: wchar_t* buffers must always be alligned, otherwise it's a char* buffer.
+        if ((((unsigned long)b)%sizeof(wchar_t))!=0) return FALSE;
+#endif
+        const wchar_t *s=(const wchar_t*)b;
+
+        // buffer too small:
+        if (len<(int)sizeof(wchar_t)) return FALSE;
+
+        // odd length test
+        if (len&1) return FALSE;
+
+        /* only checks the first 256 characters */
+        len=mmin(256,len/sizeof(wchar_t));
+
+        // Check for the special byte order:
+        if (*s == 0xFFFE) return FALSE;     // IS_TEXT_UNICODE_REVERSE_SIGNATURE;
+        if (*s == 0xFEFF) return TRUE;      // IS_TEXT_UNICODE_SIGNATURE
+
+        // checks for ASCII characters in the UNICODE stream
+        int i,stats=0;
+        for (i=0; i<len; i++) if (s[i]<=(unsigned short)255) stats++;
+        if (stats>len/2) return TRUE;
+
+        // Check for UNICODE NULL chars
+        for (i=0; i<len; i++) if (!s[i]) return TRUE;
+
+        return FALSE;
+    }
+    #else
+    char myIsTextUnicode(const void *b,int l) { return (char)IsTextUnicode((CONST LPVOID)b,l,NULL); };
+    #endif
+#endif
+
+#ifdef _XMLWINDOWS
+// for Microsoft Visual Studio 6.0 and Microsoft Visual Studio .NET,
+    #ifdef _XMLUNICODE
+        wchar_t *myMultiByteToWideChar(const char *s,int l)
+        {
+            int i;
+            if (strictUTF8Parsing)  i=(int)MultiByteToWideChar(CP_UTF8,0             ,s,l,NULL,0);
+            else                    i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,l,NULL,0);
+            if (i<0) return NULL;
+            wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(XMLCHAR));
+            if (strictUTF8Parsing)  i=(int)MultiByteToWideChar(CP_UTF8,0             ,s,l,d,i);
+            else                    i=(int)MultiByteToWideChar(CP_ACP ,MB_PRECOMPOSED,s,l,d,i);
+            d[i]=0;
+            return d;
+        }
+    #else
+        char *myWideCharToMultiByte(const wchar_t *s,int l)
+        {
+            UINT codePage=CP_ACP; if (strictUTF8Parsing) codePage=CP_UTF8;
+            int i=(int)WideCharToMultiByte(codePage,  // code page
+                0,                       // performance and mapping flags
+                s,                       // wide-character string
+                l,                       // number of chars in string
+                NULL,                       // buffer for new string
+                0,                       // size of buffer
+                NULL,                    // default for unmappable chars
+                NULL                     // set when default char used
+                );
+            if (i<0) return NULL;
+            char *d=(char*)malloc(i+1);
+            WideCharToMultiByte(codePage,  // code page
+                0,                       // performance and mapping flags
+                s,                       // wide-character string
+                l,                       // number of chars in string
+                d,                       // buffer for new string
+                i,                       // size of buffer
+                NULL,                    // default for unmappable chars
+                NULL                     // set when default char used
+                );
+            d[i]=0;
+            return d;
+        }
+    #endif
+    #ifdef __BORLANDC__
+    int _strnicmp(char *c1, char *c2, int l){ return strnicmp(c1,c2,l);}
+    #endif
+#else
+// for gcc and CC
+    #ifdef XML_NO_WIDE_CHAR
+        char *myWideCharToMultiByte(const wchar_t *s, int l) { return NULL; }
+    #else
+        char *myWideCharToMultiByte(const wchar_t *s, int l)
+        {
+            const wchar_t *ss=s;
+            int i=(int)wcsrtombs(NULL,&ss,0,NULL);
+            if (i<0) return NULL;
+            char *d=(char *)malloc(i+1);
+            wcsrtombs(d,&s,i,NULL);
+            d[i]=0;
+            return d;
+        }
+    #endif
+    #ifdef _XMLUNICODE
+        wchar_t *myMultiByteToWideChar(const char *s, int l)
+        {
+            const char *ss=s;
+            int i=(int)mbsrtowcs(NULL,&ss,0,NULL);
+            if (i<0) return NULL;
+            wchar_t *d=(wchar_t *)malloc((i+1)*sizeof(wchar_t));
+            mbsrtowcs(d,&s,l,NULL);
+            d[i]=0;
+            return d;
+        }
+        int _tcslen(XMLCSTR c)   { return wcslen(c); }
+        #ifdef sun
+        // for CC
+           #include <widec.h>
+           int _tcsnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wsncasecmp(c1,c2,l);}
+           int _tcsicmp(XMLCSTR c1, XMLCSTR c2) { return wscasecmp(c1,c2); }
+        #else
+        // for gcc
+           int _tcsnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return wcsncasecmp(c1,c2,l);}
+           int _tcsicmp(XMLCSTR c1, XMLCSTR c2) { return wcscasecmp(c1,c2); }
+        #endif
+        XMLSTR _tcsstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)wcsstr(c1,c2); }
+        XMLSTR _tcscpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)wcscpy(c1,c2); }
+        FILE *_tfopen(XMLCSTR filename,XMLCSTR mode)
+        {
+            char *filenameAscii=myWideCharToMultiByte(filename,0);
+            FILE *f;
+            if (mode[0]==_T('r')) f=fopen(filenameAscii,"rb");
+            else                  f=fopen(filenameAscii,"wb");
+            free(filenameAscii);
+            return f;
+        }
+    #else
+        FILE *_tfopen(XMLCSTR filename,XMLCSTR mode) { return fopen(filename,mode); }
+        int _tcslen(XMLCSTR c)   { return strlen(c); }
+        int _tcsnicmp(XMLCSTR c1, XMLCSTR c2, int l) { return strncasecmp(c1,c2,l);}
+        int _tcsicmp(XMLCSTR c1, XMLCSTR c2) { return strcasecmp(c1,c2); }
+        XMLSTR _tcsstr(XMLCSTR c1, XMLCSTR c2) { return (XMLSTR)strstr(c1,c2); }
+        XMLSTR _tcscpy(XMLSTR c1, XMLCSTR c2) { return (XMLSTR)strcpy(c1,c2); }
+    #endif
+    int _strnicmp(const char *c1,const char *c2, int l) { return strncasecmp(c1,c2,l);}
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+//      Here start the core implementation of the XMLParser library    //
+/////////////////////////////////////////////////////////////////////////
+
+// You should normally not change anything below this point.
+// For your own information, I suggest that you read the openFileHelper below:
+XMLNode XMLNode::openFileHelper(XMLCSTR filename, XMLCSTR tag)
+{
+    // guess the value of the global parameter "strictUTF8Parsing"
+    // (the guess is based on the first 200 bytes of the file).
+    FILE *f=_tfopen(filename,_T("rb"));
+    if (f)
+    {
+        char bb[205];
+        int l=(int)fread(bb,1,200,f);
+        setGlobalOptions(guessUnicodeChars,guessUTF8ParsingParameterValue(bb,l),dropWhiteSpace);
+        fclose(f);
+    }
+
+    // parse the file
+    XMLResults pResults;
+    XMLNode xnode=XMLNode::parseFile(filename,tag,&pResults);
+
+    // display error message (if any)
+    if (pResults.error != eXMLErrorNone)
+    {
+        // create message
+        char message[2000],*s1=(char*)"",*s3=(char*)""; XMLCSTR s2=_T("");
+        if (pResults.error==eXMLErrorFirstTagNotFound) { s1=(char*)"First Tag should be '"; s2=tag; s3=(char*)"'.\n"; }
+        sprintf(message,
+#ifdef _XMLUNICODE
+            "XML Parsing error inside file '%S'.\n%S\nAt line %i, column %i.\n%s%S%s"
+#else
+            "XML Parsing error inside file '%s'.\n%s\nAt line %i, column %i.\n%s%s%s"
+#endif
+            ,filename,XMLNode::getError(pResults.error),pResults.nLine,pResults.nColumn,s1,s2,s3);
+
+        // display message
+#if defined(WIN32) && !defined(UNDER_CE) && !defined(_XMLPARSER_NO_MESSAGEBOX_)
+        MessageBoxA(NULL,message,"XML Parsing error",MB_OK|MB_ICONERROR|MB_TOPMOST);
+#else
+        printf("%s",message);
+#endif
+        exit(255);
+    }
+    return xnode;
+}
+
+#ifndef _XMLUNICODE
+// If "strictUTF8Parsing=0" then we assume that all characters have the same length of 1 byte.
+// If "strictUTF8Parsing=1" then the characters have different lengths (from 1 byte to 4 bytes).
+// This table is used as lookup-table to know the length of a character (in byte) based on the
+// content of the first byte of the character.
+// (note: if you modify this, you must always have XML_utf8ByteTable[0]=0 ).
+static const char XML_utf8ByteTable[256] =
+{
+    //  0 1 2 3 4 5 6 7 8 9 a b c d e f
+    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x00
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x10
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x20
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x30
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x40
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x50
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x60
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x70End of ASCII range
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x80 0x80 to 0xc1 invalid
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0x90
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xa0
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,// 0xb0
+    1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xc0 0xc2 to 0xdf 2 byte
+    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,// 0xd0
+    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,// 0xe0 0xe0 to 0xef 3 byte
+    4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1 // 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+static const char XML_asciiByteTable[256] =
+{
+    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
+};
+static const char *XML_ByteTable=(const char *)XML_utf8ByteTable; // the default is "strictUTF8Parsing=1"
+#endif
+
+XMLError XMLNode::writeToFile(XMLCSTR filename, const char *encoding, char nFormat) const
+{
+    int i;
+    XMLSTR t=createXMLString(nFormat,&i);
+    FILE *f=_tfopen(filename,_T("wb"));
+    if (!f) return eXMLErrorCannotOpenWriteFile;
+#ifdef _XMLUNICODE
+    unsigned char h[2]={ 0xFF, 0xFE };
+    if (!fwrite(h,2,1,f)) return eXMLErrorCannotWriteFile;
+    if (!isDeclaration())
+    {
+        if (!fwrite(_T("<?xml version=\"1.0\" encoding=\"utf-16\"?>\n"),sizeof(wchar_t)*40,1,f))
+            return eXMLErrorCannotWriteFile;
+    }
+#else
+    if (!isDeclaration())
+    {
+        if ((!encoding)||(XML_ByteTable==XML_utf8ByteTable))
+        {
+            // header so that windows recognize the file as UTF-8:
+//            unsigned char h[3]={0xEF,0xBB,0xBF};
+//            if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile;
+            if (!fwrite("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",39,1,f)) return eXMLErrorCannotWriteFile;
+        }
+        else
+            if (fprintf(f,"<?xml version=\"1.0\" encoding=\"%s\"?>\n",encoding)<0) return eXMLErrorCannotWriteFile;
+    } else
+    {
+        if (XML_ByteTable==XML_utf8ByteTable) // test if strictUTF8Parsing==1"
+        {
+//            unsigned char h[3]={0xEF,0xBB,0xBF}; if (!fwrite(h,3,1,f)) return eXMLErrorCannotWriteFile;
+        }
+    }
+#endif
+    if (!fwrite(t,sizeof(XMLCHAR)*i,1,f)) return eXMLErrorCannotWriteFile;
+    if (fclose(f)!=0) return eXMLErrorCannotWriteFile;
+    free(t);
+    return eXMLErrorNone;
+}
+
+// Duplicate a given string.
+XMLSTR stringDup(XMLCSTR lpszData, int cbData)
+{
+    if (lpszData==NULL) return NULL;
+
+    XMLSTR lpszNew;
+    if (cbData==0) cbData=(int)_tcslen(lpszData);
+    lpszNew = (XMLSTR)malloc((cbData+1) * sizeof(XMLCHAR));
+    if (lpszNew)
+    {
+        memcpy(lpszNew, lpszData, (cbData) * sizeof(XMLCHAR));
+        lpszNew[cbData] = (XMLCHAR)NULL;
+    }
+    return lpszNew;
+}
+
+XMLNode XMLNode::emptyXMLNode;
+XMLClear XMLNode::emptyXMLClear={ NULL, NULL, NULL};
+XMLAttribute XMLNode::emptyXMLAttribute={ NULL, NULL};
+
+// Enumeration used to decipher what type a token is
+typedef enum XMLTokenTypeTag
+{
+    eTokenText = 0,
+    eTokenQuotedText,
+    eTokenTagStart,         /* "<"            */
+    eTokenTagEnd,           /* "</"           */
+    eTokenCloseTag,         /* ">"            */
+    eTokenEquals,           /* "="            */
+    eTokenDeclaration,      /* "<?"           */
+    eTokenShortHandClose,   /* "/>"           */
+    eTokenClear,
+    eTokenError
+} XMLTokenType;
+
+// Main structure used for parsing XML
+typedef struct XML
+{
+    XMLCSTR                lpXML;
+    XMLCSTR                lpszText;
+    int                    nIndex,nIndexMissigEndTag;
+    enum XMLError          error;
+    XMLCSTR                lpEndTag;
+    int                    cbEndTag;
+    XMLCSTR                lpNewElement;
+    int                    cbNewElement;
+    int                    nFirst;
+} XML;
+
+typedef struct
+{
+    ALLXMLClearTag *pClr;
+    XMLCSTR     pStr;
+} NextToken;
+
+// Enumeration used when parsing attributes
+typedef enum Attrib
+{
+    eAttribName = 0,
+    eAttribEquals,
+    eAttribValue
+} Attrib;
+
+// Enumeration used when parsing elements to dictate whether we are currently
+// inside a tag
+typedef enum Status
+{
+    eInsideTag = 0,
+    eOutsideTag
+} Status;
+
+// private (used while rendering):
+XMLSTR toXMLString(XMLSTR dest,XMLCSTR source)
+{
+    XMLSTR dd=dest;
+    XMLCHAR ch;
+    XMLCharacterEntity *entity;
+    while ((ch=*source))
+    {
+        entity=XMLEntities;
+        do
+        {
+            if (ch==entity->c) {_tcscpy(dest,entity->s); dest+=entity->l; source++; goto out_of_loop1; }
+            entity++;
+        } while(entity->s);
+#ifdef _XMLUNICODE
+        *(dest++)=*(source++);
+#else
+        switch(XML_ByteTable[(unsigned char)ch])
+        {
+        case 4: *(dest++)=*(source++);
+        case 3: *(dest++)=*(source++);
+        case 2: *(dest++)=*(source++);
+        case 1: *(dest++)=*(source++);
+        }
+#endif
+out_of_loop1:
+        ;
+    }
+    *dest=0;
+    return dd;
+}
+
+// private (used while rendering):
+int lengthXMLString(XMLCSTR source)
+{
+    int r=0;
+    XMLCharacterEntity *entity;
+    XMLCHAR ch;
+    while ((ch=*source))
+    {
+        entity=XMLEntities;
+        do
+        {
+            if (ch==entity->c) { r+=entity->l; source++; goto out_of_loop1; }
+            entity++;
+        } while(entity->s);
+#ifdef _XMLUNICODE
+        r++; source++;
+#else
+        ch=XML_ByteTable[(unsigned char)ch]; r+=ch; source+=ch;
+#endif
+out_of_loop1:
+        ;
+    }
+    return r;
+}
+
+XMLSTR toXMLString(XMLCSTR source)
+{
+    XMLSTR dest=(XMLSTR)malloc((lengthXMLString(source)+1)*sizeof(XMLCHAR));
+    return toXMLString(dest,source);
+}
+
+XMLSTR toXMLStringFast(XMLSTR *dest,int *destSz, XMLCSTR source)
+{
+    int l=lengthXMLString(source)+1;
+    if (l>*destSz) { *destSz=l; *dest=(XMLSTR)realloc(*dest,l*sizeof(XMLCHAR)); }
+    return toXMLString(*dest,source);
+}
+
+// private:
+XMLSTR fromXMLString(XMLCSTR s, int lo, XML *pXML)
+{
+    // This function is the opposite of the function "toXMLString". It decodes the escape
+    // sequences &amp;, &quot;, &apos;, &lt;, &gt; and replace them by the characters
+    // &,",',<,>. This function is used internally by the XML Parser. All the calls to
+    // the XML library will always gives you back "decoded" strings.
+    //
+    // in: string (s) and length (lo) of string
+    // out:  new allocated string converted from xml
+    if (!s) return NULL;
+
+    int ll=0,j;
+    XMLSTR d;
+    XMLCSTR ss=s;
+    XMLCharacterEntity *entity;
+    while ((lo>0)&&(*s))
+    {
+        if (*s==_T('&'))
+        {
+            if ((lo>2)&&(s[1]==_T('#')))
+            {
+                s+=2; lo-=2;
+                if ((*s==_T('X'))||(*s==_T('x'))) { s++; lo--; }
+                while ((*s)&&(*s!=_T(';'))&&((lo--)>0)) s++;
+                if (*s!=_T(';'))
+                {
+                    pXML->error=eXMLErrorUnknownCharacterEntity;
+                    return NULL;
+                }
+                s++; lo--;
+            } else
+            {
+                entity=XMLEntities;
+                do
+                {
+                    if ((lo>=entity->l)&&(_tcsnicmp(s,entity->s,entity->l)==0)) { s+=entity->l; lo-=entity->l; break; }
+                    entity++;
+                } while(entity->s);
+                if (!entity->s)
+                {
+                    pXML->error=eXMLErrorUnknownCharacterEntity;
+                    return NULL;
+                }
+            }
+        } else
+        {
+#ifdef _XMLUNICODE
+            s++; lo--;
+#else
+            j=XML_ByteTable[(unsigned char)*s]; s+=j; lo-=j; ll+=j-1;
+#endif
+        }
+        ll++;
+    }
+
+    d=(XMLSTR)malloc((ll+1)*sizeof(XMLCHAR));
+    s=d;
+    while (ll-->0)
+    {
+        if (*ss==_T('&'))
+        {
+            if (ss[1]==_T('#'))
+            {
+                ss+=2; j=0;
+                if ((*ss==_T('X'))||(*ss==_T('x')))
+                {
+                    ss++;
+                    while (*ss!=_T(';'))
+                    {
+                        if ((*ss>=_T('0'))&&(*ss<=_T('9'))) j=(j<<4)+*ss-_T('0');
+                        else if ((*ss>=_T('A'))&&(*ss<=_T('F'))) j=(j<<4)+*ss-_T('A')+10;
+                        else if ((*ss>=_T('a'))&&(*ss<=_T('f'))) j=(j<<4)+*ss-_T('a')+10;
+                        else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;}
+                        ss++;
+                    }
+                } else
+                {
+                    while (*ss!=_T(';'))
+                    {
+                        if ((*ss>=_T('0'))&&(*ss<=_T('9'))) j=(j*10)+*ss-_T('0');
+                        else { free((void*)s); pXML->error=eXMLErrorUnknownCharacterEntity;return NULL;}
+                        ss++;
+                    }
+                }
+                (*d++)=(XMLCHAR)j; ss++;
+            } else
+            {
+                entity=XMLEntities;
+                do
+                {
+                    if (_tcsnicmp(ss,entity->s,entity->l)==0) { *(d++)=entity->c; ss+=entity->l; break; }
+                    entity++;
+                } while(entity->s);
+            }
+        } else
+        {
+#ifdef _XMLUNICODE
+            *(d++)=*(ss++);
+#else
+            switch(XML_ByteTable[(unsigned char)*ss])
+            {
+            case 4: *(d++)=*(ss++); ll--;
+            case 3: *(d++)=*(ss++); ll--;
+            case 2: *(d++)=*(ss++); ll--;
+            case 1: *(d++)=*(ss++);
+            }
+#endif
+        }
+    }
+    *d=0;
+    return (XMLSTR)s;
+}
+
+#define XML_isSPACECHAR(ch) ((ch==_T('\n'))||(ch==_T(' '))||(ch== _T('\t'))||(ch==_T('\r')))
+
+// private:
+char myTagCompare(XMLCSTR cclose, XMLCSTR copen)
+// !!!! WARNING strange convention&:
+// return 0 if equals
+// return 1 if different
+{
+    if (!cclose) return 1;
+    int l=(int)_tcslen(cclose);
+    if (_tcsnicmp(cclose, copen, l)!=0) return 1;
+    const XMLCHAR c=copen[l];
+    if (XML_isSPACECHAR(c)||
+        (c==_T('/' ))||
+        (c==_T('<' ))||
+        (c==_T('>' ))||
+        (c==_T('=' ))) return 0;
+    return 1;
+}
+
+// Obtain the next character from the string.
+static inline XMLCHAR getNextChar(XML *pXML)
+{
+    XMLCHAR ch = pXML->lpXML[pXML->nIndex];
+#ifdef _XMLUNICODE
+    if (ch!=0) pXML->nIndex++;
+#else
+    pXML->nIndex+=XML_ByteTable[(unsigned char)ch];
+#endif
+    return ch;
+}
+
+// Find the next token in a string.
+// pcbToken contains the number of characters that have been read.
+static NextToken GetNextToken(XML *pXML, int *pcbToken, enum XMLTokenTypeTag *pType)
+{
+    NextToken        result;
+    XMLCHAR            ch;
+    XMLCHAR            chTemp;
+    int              indexStart,nFoundMatch,nIsText=FALSE;
+    result.pClr=NULL; // prevent warning
+
+    // Find next non-white space character
+    do { indexStart=pXML->nIndex; ch=getNextChar(pXML); } while XML_isSPACECHAR(ch);
+
+    if (ch)
+    {
+        // Cache the current string pointer
+        result.pStr = &pXML->lpXML[indexStart];
+
+        // First check whether the token is in the clear tag list (meaning it
+        // does not need formatting).
+        ALLXMLClearTag *ctag=XMLClearTags;
+        do
+        {
+            if (_tcsnicmp(ctag->lpszOpen, result.pStr, ctag->openTagLen)==0)
+            {
+                result.pClr=ctag;
+                pXML->nIndex+=ctag->openTagLen-1;
+                *pType=eTokenClear;
+                return result;
+            }
+            ctag++;
+        } while(ctag->lpszOpen);
+
+        // If we didn't find a clear tag then check for standard tokens
+        switch(ch)
+        {
+        // Check for quotes
+        case _T('\''):
+        case _T('\"'):
+            // Type of token
+            *pType = eTokenQuotedText;
+            chTemp = ch;
+
+            // Set the size
+            nFoundMatch = FALSE;
+
+            // Search through the string to find a matching quote
+            while((ch = getNextChar(pXML)))
+            {
+                if (ch==chTemp) { nFoundMatch = TRUE; break; }
+                if (ch==_T('<')) break;
+            }
+
+            // If we failed to find a matching quote
+            if (nFoundMatch == FALSE)
+            {
+                pXML->nIndex=indexStart+1;
+                nIsText=TRUE;
+                break;
+            }
+
+//  4.02.2002
+//            if (FindNonWhiteSpace(pXML)) pXML->nIndex--;
+
+            break;
+
+        // Equals (used with attribute values)
+        case _T('='):
+            *pType = eTokenEquals;
+            break;
+
+        // Close tag
+        case _T('>'):
+            *pType = eTokenCloseTag;
+            break;
+
+        // Check for tag start and tag end
+        case _T('<'):
+
+            // Peek at the next character to see if we have an end tag '</',
+            // or an xml declaration '<?'
+            chTemp = pXML->lpXML[pXML->nIndex];
+
+            // If we have a tag end...
+            if (chTemp == _T('/'))
+            {
+                // Set the type and ensure we point at the next character
+                getNextChar(pXML);
+                *pType = eTokenTagEnd;
+            }
+
+            // If we have an XML declaration tag
+            else if (chTemp == _T('?'))
+            {
+
+                // Set the type and ensure we point at the next character
+                getNextChar(pXML);
+                *pType = eTokenDeclaration;
+            }
+
+            // Otherwise we must have a start tag
+            else
+            {
+                *pType = eTokenTagStart;
+            }
+            break;
+
+        // Check to see if we have a short hand type end tag ('/>').
+        case _T('/'):
+
+            // Peek at the next character to see if we have a short end tag '/>'
+            chTemp = pXML->lpXML[pXML->nIndex];
+
+            // If we have a short hand end tag...
+            if (chTemp == _T('>'))
+            {
+                // Set the type and ensure we point at the next character
+                getNextChar(pXML);
+                *pType = eTokenShortHandClose;
+                break;
+            }
+
+            // If we haven't found a short hand closing tag then drop into the
+            // text process
+
+        // Other characters
+        default:
+            nIsText = TRUE;
+        }
+
+        // If this is a TEXT node
+        if (nIsText)
+        {
+            // Indicate we are dealing with text
+            *pType = eTokenText;
+            while((ch = getNextChar(pXML)))
+            {
+                if XML_isSPACECHAR(ch)
+                {
+                    indexStart++; break;
+
+                } else if (ch==_T('/'))
+                {
+                    // If we find a slash then this maybe text or a short hand end tag
+                    // Peek at the next character to see it we have short hand end tag
+                    ch=pXML->lpXML[pXML->nIndex];
+                    // If we found a short hand end tag then we need to exit the loop
+                    if (ch==_T('>')) { pXML->nIndex--; break; }
+
+                } else if ((ch==_T('<'))||(ch==_T('>'))||(ch==_T('=')))
+                {
+                    pXML->nIndex--; break;
+                }
+            }
+        }
+        *pcbToken = pXML->nIndex-indexStart;
+    } else
+    {
+        // If we failed to obtain a valid character
+        *pcbToken = 0;
+        *pType = eTokenError;
+        result.pStr=NULL;
+    }
+
+    return result;
+}
+
+XMLCSTR XMLNode::updateName_WOSD(XMLCSTR lpszName)
+{
+    if (d->lpszName&&(lpszName!=d->lpszName)) free((void*)d->lpszName);
+    d->lpszName=lpszName;
+    return lpszName;
+}
+
+// private:
+XMLNode::XMLNode(struct XMLNodeDataTag *p){ d=p; (p->ref_count)++; }
+XMLNode::XMLNode(XMLNodeData *pParent, XMLCSTR lpszName, char isDeclaration)
+{
+    d=(XMLNodeData*)malloc(sizeof(XMLNodeData));
+    d->ref_count=1;
+
+    d->lpszName=NULL;
+    d->nChild= 0;
+    d->nText = 0;
+    d->nClear = 0;
+    d->nAttribute = 0;
+
+    d->isDeclaration = isDeclaration;
+
+    d->pParent = pParent;
+    d->pChild= NULL;
+    d->pText= NULL;
+    d->pClear= NULL;
+    d->pAttribute= NULL;
+    d->pOrder= NULL;
+
+    updateName_WOSD(lpszName);
+}
+
+XMLNode XMLNode::createXMLTopNode_WOSD(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,lpszName,isDeclaration); }
+XMLNode XMLNode::createXMLTopNode(XMLCSTR lpszName, char isDeclaration) { return XMLNode(NULL,stringDup(lpszName),isDeclaration); }
+
+#define MEMORYINCREASE 50
+
+static inline void *myRealloc(void *p, int newsize, int memInc, int sizeofElem)
+{
+    if (p==NULL) { if (memInc) return malloc(memInc*sizeofElem); return malloc(sizeofElem); }
+    if ((memInc==0)||((newsize%memInc)==0)) p=realloc(p,(newsize+memInc)*sizeofElem);
+//    if (!p)
+//    {
+//        printf("XMLParser Error: Not enough memory! Aborting...\n"); exit(220);
+//    }
+    return p;
+}
+
+// private:
+int XMLNode::findPosition(XMLNodeData *d, int index, XMLElementType xtype)
+{
+    if (index<0) return -1;
+    int i=0,j=(int)((index<<2)+xtype),*o=d->pOrder; while (o[i]!=j) i++; return i;
+}
+
+// private:
+// update "order" information when deleting a content of a XMLNode
+int XMLNode::removeOrderElement(XMLNodeData *d, XMLElementType t, int index)
+{
+    int n=d->nChild+d->nText+d->nClear, *o=d->pOrder,i=findPosition(d,index,t);
+    memmove(o+i, o+i+1, (n-i)*sizeof(int));
+    for (;i<n;i++)
+        if ((o[i]&3)==(int)t) o[i]-=4;
+    // We should normally do:
+    // d->pOrder=(int)realloc(d->pOrder,n*sizeof(int));
+    // but we skip reallocation because it's too time consuming.
+    // Anyway, at the end, it will be free'd completely at once.
+    return i;
+}
+
+void *XMLNode::addToOrder(int memoryIncrease,int *_pos, int nc, void *p, int size, XMLElementType xtype)
+{
+    //  in: *_pos is the position inside d->pOrder ("-1" means "EndOf")
+    // out: *_pos is the index inside p
+    p=myRealloc(p,(nc+1),memoryIncrease,size);
+    int n=d->nChild+d->nText+d->nClear;
+    d->pOrder=(int*)myRealloc(d->pOrder,n+1,memoryIncrease*3,sizeof(int));
+    int pos=*_pos,*o=d->pOrder;
+
+    if ((pos<0)||(pos>=n)) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; }
+
+    int i=pos;
+    memmove(o+i+1, o+i, (n-i)*sizeof(int));
+
+    while ((pos<n)&&((o[pos]&3)!=(int)xtype)) pos++;
+    if (pos==n) { *_pos=nc; o[n]=(int)((nc<<2)+xtype); return p; }
+
+    o[i]=o[pos];
+    for (i=pos+1;i<=n;i++) if ((o[i]&3)==(int)xtype) o[i]+=4;
+
+    *_pos=pos=o[pos]>>2;
+    memmove(((char*)p)+(pos+1)*size,((char*)p)+pos*size,(nc-pos)*size);
+
+    return p;
+}
+
+// Add a child node to the given element.
+XMLNode XMLNode::addChild_priv(int memoryIncrease, XMLCSTR lpszName, char isDeclaration, int pos)
+{
+    if (!lpszName) return emptyXMLNode;
+    d->pChild=(XMLNode*)addToOrder(memoryIncrease,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild);
+    d->pChild[pos].d=NULL;
+    d->pChild[pos]=XMLNode(d,lpszName,isDeclaration);
+    d->nChild++;
+    return d->pChild[pos];
+}
+
+// Add an attribute to an element.
+XMLAttribute *XMLNode::addAttribute_priv(int memoryIncrease,XMLCSTR lpszName, XMLCSTR lpszValuev)
+{
+    if (!lpszName) return &emptyXMLAttribute;
+    int nc=d->nAttribute;
+    d->pAttribute=(XMLAttribute*)myRealloc(d->pAttribute,(nc+1),memoryIncrease,sizeof(XMLAttribute));
+    XMLAttribute *pAttr=d->pAttribute+nc;
+    pAttr->lpszName = lpszName;
+    pAttr->lpszValue = lpszValuev;
+    d->nAttribute++;
+    return pAttr;
+}
+
+// Add text to the element.
+XMLCSTR XMLNode::addText_priv(int memoryIncrease, XMLCSTR lpszValue, int pos)
+{
+    if (!lpszValue) return NULL;
+    d->pText=(XMLCSTR*)addToOrder(memoryIncrease,&pos,d->nText,d->pText,sizeof(XMLSTR),eNodeText);
+    d->pText[pos]=lpszValue;
+    d->nText++;
+    return lpszValue;
+}
+
+// Add clear (unformatted) text to the element.
+XMLClear *XMLNode::addClear_priv(int memoryIncrease, XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
+{
+    if (!lpszValue) return &emptyXMLClear;
+    d->pClear=(XMLClear *)addToOrder(memoryIncrease,&pos,d->nClear,d->pClear,sizeof(XMLClear),eNodeClear);
+    XMLClear *pNewClear=d->pClear+pos;
+    pNewClear->lpszValue = lpszValue;
+    if (!lpszOpen) lpszOpen=getClearTagTable()->lpszOpen;
+    if (!lpszClose) lpszOpen=getClearTagTable()->lpszClose;
+    pNewClear->lpszOpenTag = lpszOpen;
+    pNewClear->lpszCloseTag = lpszClose;
+    d->nClear++;
+    return pNewClear;
+}
+
+// private:
+// Parse a clear (unformatted) type node.
+char XMLNode::parseClearTag(void *px, ALLXMLClearTag *pClear)
+{
+    XML *pXML=(XML *)px;
+    int cbTemp=0;
+    XMLCSTR lpszTemp=NULL;
+    XMLCSTR lpXML=&pXML->lpXML[pXML->nIndex];
+    static XMLCSTR docTypeEnd=_T("]>");
+
+    // Find the closing tag
+    // Seems the <!DOCTYPE need a better treatment so lets handle it
+    if (pClear->lpszOpen==XMLClearTags[1].lpszOpen)
+    {
+        XMLCSTR pCh=lpXML;
+        while (*pCh)
+        {
+            if (*pCh==_T('<')) { pClear->lpszClose=docTypeEnd; lpszTemp=_tcsstr(lpXML,docTypeEnd); break; }
+            else if (*pCh==_T('>')) { lpszTemp=pCh; break; }
+#ifdef _XMLUNICODE
+            pCh++;
+#else
+            pCh+=XML_ByteTable[(unsigned char)(*pCh)];
+#endif
+        }
+    } else lpszTemp=_tcsstr(lpXML, pClear->lpszClose);
+
+    if (lpszTemp)
+    {
+        // Cache the size and increment the index
+        cbTemp = (int)(lpszTemp - lpXML);
+
+        pXML->nIndex += cbTemp+(int)_tcslen(pClear->lpszClose);
+
+        // Add the clear node to the current element
+        addClear_priv(MEMORYINCREASE,stringDup(lpXML,cbTemp), pClear->lpszOpen, pClear->lpszClose,-1);
+        return 0;
+    }
+
+    // If we failed to find the end tag
+    pXML->error = eXMLErrorUnmatchedEndClearTag;
+    return 1;
+}
+
+void XMLNode::exactMemory(XMLNodeData *d)
+{
+    if (d->pOrder)     d->pOrder=(int*)realloc(d->pOrder,(d->nChild+d->nText+d->nClear)*sizeof(int));
+    if (d->pChild)     d->pChild=(XMLNode*)realloc(d->pChild,d->nChild*sizeof(XMLNode));
+    if (d->pAttribute) d->pAttribute=(XMLAttribute*)realloc(d->pAttribute,d->nAttribute*sizeof(XMLAttribute));
+    if (d->pText)      d->pText=(XMLCSTR*)realloc(d->pText,d->nText*sizeof(XMLSTR));
+    if (d->pClear)     d->pClear=(XMLClear *)realloc(d->pClear,d->nClear*sizeof(XMLClear));
+}
+
+char XMLNode::maybeAddTxT(void *pa, XMLCSTR tokenPStr)
+{
+    XML *pXML=(XML *)pa;
+    XMLCSTR lpszText=pXML->lpszText;
+    if (!lpszText) return 0;
+    if (dropWhiteSpace) while (XML_isSPACECHAR(*lpszText)&&(lpszText!=tokenPStr)) lpszText++;
+    int cbText = (int)(tokenPStr - lpszText);
+    if (!cbText) { pXML->lpszText=NULL; return 0; }
+    if (dropWhiteSpace) { cbText--; while ((cbText)&&XML_isSPACECHAR(lpszText[cbText])) cbText--; cbText++; }
+    if (!cbText) { pXML->lpszText=NULL; return 0; }
+    lpszText=fromXMLString(lpszText,cbText,pXML);
+    if (!lpszText) return 1;
+    addText_priv(MEMORYINCREASE,lpszText,-1);
+    pXML->lpszText=NULL;
+    return 0;
+}
+// private:
+// Recursively parse an XML element.
+int XMLNode::ParseXMLElement(void *pa)
+{
+    XML *pXML=(XML *)pa;
+    int cbToken;
+    enum XMLTokenTypeTag type;
+    NextToken token;
+    XMLCSTR lpszTemp=NULL;
+    int cbTemp=0;
+    char nDeclaration;
+    XMLNode pNew;
+    enum Status status; // inside or outside a tag
+    enum Attrib attrib = eAttribName;
+
+    assert(pXML);
+
+    // If this is the first call to the function
+    if (pXML->nFirst)
+    {
+        // Assume we are outside of a tag definition
+        pXML->nFirst = FALSE;
+        status = eOutsideTag;
+    } else
+    {
+        // If this is not the first call then we should only be called when inside a tag.
+        status = eInsideTag;
+    }
+
+    // Iterate through the tokens in the document
+    for(;;)
+    {
+        // Obtain the next token
+        token = GetNextToken(pXML, &cbToken, &type);
+
+        if (type != eTokenError)
+        {
+            // Check the current status
+            switch(status)
+            {
+
+            // If we are outside of a tag definition
+            case eOutsideTag:
+
+                // Check what type of token we obtained
+                switch(type)
+                {
+                // If we have found text or quoted text
+                case eTokenText:
+                case eTokenCloseTag:          /* '>'         */
+                case eTokenShortHandClose:    /* '/>'        */
+                case eTokenQuotedText:
+                case eTokenEquals:
+                    break;
+
+                // If we found a start tag '<' and declarations '<?'
+                case eTokenTagStart:
+                case eTokenDeclaration:
+
+                    // Cache whether this new element is a declaration or not
+                    nDeclaration = (type == eTokenDeclaration);
+
+                    // If we have node text then add this to the element
+                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
+
+                    // Find the name of the tag
+                    token = GetNextToken(pXML, &cbToken, &type);
+
+                    // Return an error if we couldn't obtain the next token or
+                    // it wasnt text
+                    if (type != eTokenText)
+                    {
+                        pXML->error = eXMLErrorMissingTagName;
+                        return FALSE;
+                    }
+
+                    // If we found a new element which is the same as this
+                    // element then we need to pass this back to the caller..
+
+#ifdef APPROXIMATE_PARSING
+                    if (d->lpszName &&
+                        myTagCompare(d->lpszName, token.pStr) == 0)
+                    {
+                        // Indicate to the caller that it needs to create a
+                        // new element.
+                        pXML->lpNewElement = token.pStr;
+                        pXML->cbNewElement = cbToken;
+                        return TRUE;
+                    } else
+#endif
+                    {
+                        // If the name of the new element differs from the name of
+                        // the current element we need to add the new element to
+                        // the current one and recurse
+                        pNew = addChild_priv(MEMORYINCREASE,stringDup(token.pStr,cbToken), nDeclaration,-1);
+
+                        while (!pNew.isEmpty())
+                        {
+                            // Callself to process the new node.  If we return
+                            // FALSE this means we dont have any more
+                            // processing to do...
+
+                            if (!pNew.ParseXMLElement(pXML)) return FALSE;
+                            else
+                            {
+                                // If the call to recurse this function
+                                // evented in a end tag specified in XML then
+                                // we need to unwind the calls to this
+                                // function until we find the appropriate node
+                                // (the element name and end tag name must
+                                // match)
+                                if (pXML->cbEndTag)
+                                {
+                                    // If we are back at the root node then we
+                                    // have an unmatched end tag
+                                    if (!d->lpszName)
+                                    {
+                                        pXML->error=eXMLErrorUnmatchedEndTag;
+                                        return FALSE;
+                                    }
+
+                                    // If the end tag matches the name of this
+                                    // element then we only need to unwind
+                                    // once more...
+
+                                    if (myTagCompare(d->lpszName, pXML->lpEndTag)==0)
+                                    {
+                                        pXML->cbEndTag = 0;
+                                    }
+
+                                    return TRUE;
+                                } else
+                                    if (pXML->cbNewElement)
+                                    {
+                                        // If the call indicated a new element is to
+                                        // be created on THIS element.
+
+                                        // If the name of this element matches the
+                                        // name of the element we need to create
+                                        // then we need to return to the caller
+                                        // and let it process the element.
+
+                                        if (myTagCompare(d->lpszName, pXML->lpNewElement)==0)
+                                        {
+                                            return TRUE;
+                                        }
+
+                                        // Add the new element and recurse
+                                        pNew = addChild_priv(MEMORYINCREASE,stringDup(pXML->lpNewElement,pXML->cbNewElement),0,-1);
+                                        pXML->cbNewElement = 0;
+                                    }
+                                    else
+                                    {
+                                        // If we didn't have a new element to create
+                                        pNew = emptyXMLNode;
+
+                                    }
+                            }
+                        }
+                    }
+                    break;
+
+                // If we found an end tag
+                case eTokenTagEnd:
+
+                    // If we have node text then add this to the element
+                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
+
+                    // Find the name of the end tag
+                    token = GetNextToken(pXML, &cbTemp, &type);
+
+                    // The end tag should be text
+                    if (type != eTokenText)
+                    {
+                        pXML->error = eXMLErrorMissingEndTagName;
+                        return FALSE;
+                    }
+                    lpszTemp = token.pStr;
+
+                    // After the end tag we should find a closing tag
+                    token = GetNextToken(pXML, &cbToken, &type);
+                    if (type != eTokenCloseTag)
+                    {
+                        pXML->error = eXMLErrorMissingEndTagName;
+                        return FALSE;
+                    }
+                    pXML->lpszText=pXML->lpXML+pXML->nIndex;
+
+                    // We need to return to the previous caller.  If the name
+                    // of the tag cannot be found we need to keep returning to
+                    // caller until we find a match
+                    if (myTagCompare(d->lpszName, lpszTemp) != 0)
+#ifdef STRICT_PARSING
+                    {
+                        pXML->error=eXMLErrorUnmatchedEndTag;
+                        pXML->nIndexMissigEndTag=pXML->nIndex;
+                        return FALSE;
+                    }
+#else
+                    {
+                        pXML->error=eXMLErrorMissingEndTag;
+                        pXML->nIndexMissigEndTag=pXML->nIndex;
+                        pXML->lpEndTag = lpszTemp;
+                        pXML->cbEndTag = cbTemp;
+                    }
+#endif
+
+                    // Return to the caller
+                    exactMemory(d);
+                    return TRUE;
+
+                // If we found a clear (unformatted) token
+                case eTokenClear:
+                    // If we have node text then add this to the element
+                    if (maybeAddTxT(pXML,token.pStr)) return FALSE;
+                    if (parseClearTag(pXML, token.pClr)) return FALSE;
+                    pXML->lpszText=pXML->lpXML+pXML->nIndex;
+                    break;
+
+                default:
+                    break;
+                }
+                break;
+
+            // If we are inside a tag definition we need to search for attributes
+            case eInsideTag:
+
+                // Check what part of the attribute (name, equals, value) we
+                // are looking for.
+                switch(attrib)
+                {
+                // If we are looking for a new attribute
+                case eAttribName:
+
+                    // Check what the current token type is
+                    switch(type)
+                    {
+                    // If the current type is text...
+                    // Eg.  'attribute'
+                    case eTokenText:
+                        // Cache the token then indicate that we are next to
+                        // look for the equals
+                        lpszTemp = token.pStr;
+                        cbTemp = cbToken;
+                        attrib = eAttribEquals;
+                        break;
+
+                    // If we found a closing tag...
+                    // Eg.  '>'
+                    case eTokenCloseTag:
+                        // We are now outside the tag
+                        status = eOutsideTag;
+                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
+                        break;
+
+                    // If we found a short hand '/>' closing tag then we can
+                    // return to the caller
+                    case eTokenShortHandClose:
+                        exactMemory(d);
+                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
+                        return TRUE;
+
+                    // Errors...
+                    case eTokenQuotedText:    /* '"SomeText"'   */
+                    case eTokenTagStart:      /* '<'            */
+                    case eTokenTagEnd:        /* '</'           */
+                    case eTokenEquals:        /* '='            */
+                    case eTokenDeclaration:   /* '<?'           */
+                    case eTokenClear:
+                        pXML->error = eXMLErrorUnexpectedToken;
+                        return FALSE;
+                    default: break;
+                    }
+                    break;
+
+                // If we are looking for an equals
+                case eAttribEquals:
+                    // Check what the current token type is
+                    switch(type)
+                    {
+                    // If the current type is text...
+                    // Eg.  'Attribute AnotherAttribute'
+                    case eTokenText:
+                        // Add the unvalued attribute to the list
+                        addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
+                        // Cache the token then indicate.  We are next to
+                        // look for the equals attribute
+                        lpszTemp = token.pStr;
+                        cbTemp = cbToken;
+                        break;
+
+                    // If we found a closing tag 'Attribute >' or a short hand
+                    // closing tag 'Attribute />'
+                    case eTokenShortHandClose:
+                    case eTokenCloseTag:
+                        // If we are a declaration element '<?' then we need
+                        // to remove extra closing '?' if it exists
+                        pXML->lpszText=pXML->lpXML+pXML->nIndex;
+
+                        if (d->isDeclaration &&
+                            (lpszTemp[cbTemp-1]) == _T('?'))
+                        {
+                            cbTemp--;
+                        }
+
+                        if (cbTemp)
+                        {
+                            // Add the unvalued attribute to the list
+                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp), NULL);
+                        }
+
+                        // If this is the end of the tag then return to the caller
+                        if (type == eTokenShortHandClose)
+                        {
+                            exactMemory(d);
+                            return TRUE;
+                        }
+
+                        // We are now outside the tag
+                        status = eOutsideTag;
+                        break;
+
+                    // If we found the equals token...
+                    // Eg.  'Attribute ='
+                    case eTokenEquals:
+                        // Indicate that we next need to search for the value
+                        // for the attribute
+                        attrib = eAttribValue;
+                        break;
+
+                    // Errors...
+                    case eTokenQuotedText:    /* 'Attribute "InvalidAttr"'*/
+                    case eTokenTagStart:      /* 'Attribute <'            */
+                    case eTokenTagEnd:        /* 'Attribute </'           */
+                    case eTokenDeclaration:   /* 'Attribute <?'           */
+                    case eTokenClear:
+                        pXML->error = eXMLErrorUnexpectedToken;
+                        return FALSE;
+                    default: break;
+                    }
+                    break;
+
+                // If we are looking for an attribute value
+                case eAttribValue:
+                    // Check what the current token type is
+                    switch(type)
+                    {
+                    // If the current type is text or quoted text...
+                    // Eg.  'Attribute = "Value"' or 'Attribute = Value' or
+                    // 'Attribute = 'Value''.
+                    case eTokenText:
+                    case eTokenQuotedText:
+                        // If we are a declaration element '<?' then we need
+                        // to remove extra closing '?' if it exists
+                        if (d->isDeclaration &&
+                            (token.pStr[cbToken-1]) == _T('?'))
+                        {
+                            cbToken--;
+                        }
+
+                        if (cbTemp)
+                        {
+                            // Add the valued attribute to the list
+                            if (type==eTokenQuotedText) { token.pStr++; cbToken-=2; }
+                            XMLCSTR attrVal=token.pStr;
+                            if (attrVal)
+                            {
+                                attrVal=fromXMLString(attrVal,cbToken,pXML);
+                                if (!attrVal) return FALSE;
+                            }
+                            addAttribute_priv(MEMORYINCREASE,stringDup(lpszTemp,cbTemp),attrVal);
+                        }
+
+                        // Indicate we are searching for a new attribute
+                        attrib = eAttribName;
+                        break;
+
+                    // Errors...
+                    case eTokenTagStart:        /* 'Attr = <'          */
+                    case eTokenTagEnd:          /* 'Attr = </'         */
+                    case eTokenCloseTag:        /* 'Attr = >'          */
+                    case eTokenShortHandClose:  /* "Attr = />"         */
+                    case eTokenEquals:          /* 'Attr = ='          */
+                    case eTokenDeclaration:     /* 'Attr = <?'         */
+                    case eTokenClear:
+                        pXML->error = eXMLErrorUnexpectedToken;
+                        return FALSE;
+                        break;
+                    default: break;
+                    }
+                }
+            }
+        }
+        // If we failed to obtain the next token
+        else
+        {
+            if ((!d->isDeclaration)&&(d->pParent))
+            {
+#ifdef STRICT_PARSING
+                pXML->error=eXMLErrorUnmatchedEndTag;
+#else
+                pXML->error=eXMLErrorMissingEndTag;
+#endif
+                pXML->nIndexMissigEndTag=pXML->nIndex;
+            }
+            return FALSE;
+        }
+    }
+}
+
+// Count the number of lines and columns in an XML string.
+static void CountLinesAndColumns(XMLCSTR lpXML, int nUpto, XMLResults *pResults)
+{
+    XMLCHAR ch;
+    assert(lpXML);
+    assert(pResults);
+
+    struct XML xml={ lpXML,lpXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
+
+    pResults->nLine = 1;
+    pResults->nColumn = 1;
+    while (xml.nIndex<nUpto)
+    {
+        ch = getNextChar(&xml);
+        if (ch != _T('\n')) pResults->nColumn++;
+        else
+        {
+            pResults->nLine++;
+            pResults->nColumn=1;
+        }
+    }
+}
+
+// Parse XML and return the root element.
+XMLNode XMLNode::parseString(XMLCSTR lpszXML, XMLCSTR tag, XMLResults *pResults)
+{
+    if (!lpszXML)
+    {
+        if (pResults)
+        {
+            pResults->error=eXMLErrorNoElements;
+            pResults->nLine=0;
+            pResults->nColumn=0;
+        }
+        return emptyXMLNode;
+    }
+
+    XMLNode xnode(NULL,NULL,FALSE);
+    struct XML xml={ lpszXML, lpszXML, 0, 0, eXMLErrorNone, NULL, 0, NULL, 0, TRUE };
+
+    // Create header element
+    xnode.ParseXMLElement(&xml);
+    enum XMLError error = xml.error;
+    if ((xnode.nChildNode()==1)&&(xnode.nElement()==1)) xnode=xnode.getChildNode(); // skip the empty node
+
+    // If no error occurred
+    if ((error==eXMLErrorNone)||(error==eXMLErrorMissingEndTag))
+    {
+        XMLCSTR name=xnode.getName();
+        if (tag&&_tcslen(tag)&&((!name)||(_tcsicmp(xnode.getName(),tag))))
+        {
+            XMLNode nodeTmp;
+            int i=0;
+            while (i<xnode.nChildNode())
+            {
+                nodeTmp=xnode.getChildNode(i);
+                if (_tcsicmp(nodeTmp.getName(),tag)==0) break;
+                if (nodeTmp.isDeclaration()) { xnode=nodeTmp; i=0; } else i++;
+            }
+            if (i>=xnode.nChildNode())
+            {
+                if (pResults)
+                {
+                    pResults->error=eXMLErrorFirstTagNotFound;
+                    pResults->nLine=0;
+                    pResults->nColumn=0;
+                }
+                return emptyXMLNode;
+            }
+            xnode=nodeTmp;
+        }
+    } else
+    {
+        // Cleanup: this will destroy all the nodes
+        xnode = emptyXMLNode;
+    }
+
+
+    // If we have been given somewhere to place results
+    if (pResults)
+    {
+        pResults->error = error;
+
+        // If we have an error
+        if (error!=eXMLErrorNone)
+        {
+            if (error==eXMLErrorMissingEndTag) xml.nIndex=xml.nIndexMissigEndTag;
+            // Find which line and column it starts on.
+            CountLinesAndColumns(xml.lpXML, xml.nIndex, pResults);
+        }
+    }
+    return xnode;
+}
+
+XMLNode XMLNode::parseFile(XMLCSTR filename, XMLCSTR tag, XMLResults *pResults)
+{
+    if (pResults) { pResults->nLine=0; pResults->nColumn=0; }
+    FILE *f=_tfopen(filename,_T("rb"));
+    if (f==NULL) { if (pResults) pResults->error=eXMLErrorFileNotFound; return emptyXMLNode; }
+    fseek(f,0,SEEK_END);
+    int l=ftell(f),headerSz=0;
+    if (!l) { if (pResults) pResults->error=eXMLErrorEmpty; return emptyXMLNode; }
+    fseek(f,0,SEEK_SET);
+    unsigned char *buf=(unsigned char*)malloc(l+1);
+    fread(buf,l,1,f);
+    fclose(f);
+    buf[l]=0;
+#ifdef _XMLUNICODE
+    if (guessUnicodeChars)
+    {
+        if (!myIsTextUnicode(buf,l))
+        {
+            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
+            XMLSTR b2=myMultiByteToWideChar((const char*)(buf+headerSz),l-headerSz);
+            free(buf); buf=(unsigned char*)b2; headerSz=0;
+        } else
+        {
+            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
+            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
+        }
+    }
+#else
+    if (guessUnicodeChars)
+    {
+        if (myIsTextUnicode(buf,l))
+        {
+            l/=sizeof(wchar_t);
+            if ((buf[0]==0xef)&&(buf[1]==0xff)) headerSz=2;
+            if ((buf[0]==0xff)&&(buf[1]==0xfe)) headerSz=2;
+            char *b2=myWideCharToMultiByte((const wchar_t*)(buf+headerSz),l-headerSz);
+            free(buf); buf=(unsigned char*)b2; headerSz=0;
+        } else
+        {
+            if ((buf[0]==0xef)&&(buf[1]==0xbb)&&(buf[2]==0xbf)) headerSz=3;
+        }
+    }
+#endif
+
+    if (!buf) { if (pResults) pResults->error=eXMLErrorCharConversionError; return emptyXMLNode; }
+    XMLNode x=parseString((XMLSTR)(buf+headerSz),tag,pResults);
+    free(buf);
+    return x;
+}
+
+static inline void charmemset(XMLSTR dest,XMLCHAR c,int l) { while (l--) *(dest++)=c; }
+// private:
+// Creates an user friendly XML string from a given element with
+// appropriate white space and carriage returns.
+//
+// This recurses through all subnodes then adds contents of the nodes to the
+// string.
+int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat)
+{
+    int nResult = 0;
+    int cb;
+    int cbElement;
+    int nChildFormat=-1;
+    int nElementI=pEntry->nChild+pEntry->nText+pEntry->nClear;
+    int i,j;
+
+    assert(pEntry);
+
+#define LENSTR(lpsz) (lpsz ? _tcslen(lpsz) : 0)
+
+    // If the element has no name then assume this is the head node.
+    cbElement = (int)LENSTR(pEntry->lpszName);
+
+    if (cbElement)
+    {
+        // "<elementname "
+        cb = nFormat == -1 ? 0 : nFormat;
+
+        if (lpszMarker)
+        {
+            if (cb) charmemset(lpszMarker, INDENTCHAR, sizeof(XMLCHAR)*cb);
+            nResult = cb;
+            lpszMarker[nResult++]=_T('<');
+            if (pEntry->isDeclaration) lpszMarker[nResult++]=_T('?');
+            _tcscpy(&lpszMarker[nResult], pEntry->lpszName);
+            nResult+=cbElement;
+            lpszMarker[nResult++]=_T(' ');
+
+        } else
+        {
+            nResult+=cbElement+2+cb;
+            if (pEntry->isDeclaration) nResult++;
+        }
+
+        // Enumerate attributes and add them to the string
+        XMLAttribute *pAttr=pEntry->pAttribute;
+        for (i=0; i<pEntry->nAttribute; i++)
+        {
+            // "Attrib
+            cb = (int)LENSTR(pAttr->lpszName);
+            if (cb)
+            {
+                if (lpszMarker) _tcscpy(&lpszMarker[nResult], pAttr->lpszName);
+                nResult += cb;
+                // "Attrib=Value "
+                if (pAttr->lpszValue)
+                {
+                    cb=(int)lengthXMLString(pAttr->lpszValue);
+                    if (lpszMarker)
+                    {
+                        lpszMarker[nResult]=_T('=');
+                        lpszMarker[nResult+1]=_T('"');
+                        if (cb) toXMLString(&lpszMarker[nResult+2],pAttr->lpszValue);
+                        lpszMarker[nResult+cb+2]=_T('"');
+                    }
+                    nResult+=cb+3;
+                }
+                if (lpszMarker) lpszMarker[nResult] = _T(' ');
+                nResult++;
+            }
+            pAttr++;
+        }
+
+        if (pEntry->isDeclaration)
+        {
+            if (lpszMarker)
+            {
+                lpszMarker[nResult-1]=_T('?');
+                lpszMarker[nResult]=_T('>');
+            }
+            nResult++;
+            if (nFormat!=-1)
+            {
+                if (lpszMarker) lpszMarker[nResult]=_T('\n');
+                nResult++;
+            }
+        } else
+            // If there are child nodes we need to terminate the start tag
+            if (nElementI)
+            {
+                if (lpszMarker) lpszMarker[nResult-1]=_T('>');
+                if (nFormat!=-1)
+                {
+                    if (lpszMarker) lpszMarker[nResult]=_T('\n');
+                    nResult++;
+                }
+            } else nResult--;
+    }
+
+    // Calculate the child format for when we recurse.  This is used to
+    // determine the number of spaces used for prefixes.
+    if (nFormat!=-1)
+    {
+        if (cbElement&&(!pEntry->isDeclaration)) nChildFormat=nFormat+1;
+        else nChildFormat=nFormat;
+    }
+
+    // Enumerate through remaining children
+    for (i=0; i<nElementI; i++)
+    {
+        j=pEntry->pOrder[i];
+        switch((XMLElementType)(j&3))
+        {
+        // Text nodes
+        case eNodeText:
+            {
+                // "Text"
+                XMLCSTR pChild=pEntry->pText[j>>2];
+                cb = (int)lengthXMLString(pChild);
+                if (cb)
+                {
+                    if (nFormat!=-1)
+                    {
+                        if (lpszMarker)
+                        {
+                            charmemset(&lpszMarker[nResult],INDENTCHAR,sizeof(XMLCHAR)*(nFormat + 1));
+                            toXMLString(&lpszMarker[nResult+nFormat+1],pChild);
+                            lpszMarker[nResult+nFormat+1+cb]=_T('\n');
+                        }
+                        nResult+=cb+nFormat+2;
+                    } else
+                    {
+                        if (lpszMarker) toXMLString(&lpszMarker[nResult], pChild);
+                        nResult += cb;
+                    }
+                }
+                break;
+            }
+
+        // Clear type nodes
+        case eNodeClear:
+            {
+                XMLClear *pChild=pEntry->pClear+(j>>2);
+                // "OpenTag"
+                cb = (int)LENSTR(pChild->lpszOpenTag);
+                if (cb)
+                {
+                    if (nFormat!=-1)
+                    {
+                        if (lpszMarker)
+                        {
+                            charmemset(&lpszMarker[nResult], INDENTCHAR, sizeof(XMLCHAR)*(nFormat + 1));
+                            _tcscpy(&lpszMarker[nResult+nFormat+1], pChild->lpszOpenTag);
+                        }
+                        nResult+=cb+nFormat+1;
+                    }
+                    else
+                    {
+                        if (lpszMarker)_tcscpy(&lpszMarker[nResult], pChild->lpszOpenTag);
+                        nResult += cb;
+                    }
+                }
+
+                // "OpenTag Value"
+                cb = (int)LENSTR(pChild->lpszValue);
+                if (cb)
+                {
+                    if (lpszMarker) _tcscpy(&lpszMarker[nResult], pChild->lpszValue);
+                    nResult += cb;
+                }
+
+                // "OpenTag Value CloseTag"
+                cb = (int)LENSTR(pChild->lpszCloseTag);
+                if (cb)
+                {
+                    if (lpszMarker) _tcscpy(&lpszMarker[nResult], pChild->lpszCloseTag);
+                    nResult += cb;
+                }
+
+                if (nFormat!=-1)
+                {
+                    if (lpszMarker) lpszMarker[nResult] = _T('\n');
+                    nResult++;
+                }
+                break;
+            }
+
+        // Element nodes
+        case eNodeChild:
+            {
+                // Recursively add child nodes
+                nResult += CreateXMLStringR(pEntry->pChild[j>>2].d, lpszMarker ? lpszMarker + nResult : 0, nChildFormat);
+                break;
+            }
+        default: break;
+        }
+    }
+
+    if ((cbElement)&&(!pEntry->isDeclaration))
+    {
+        // If we have child entries we need to use long XML notation for
+        // closing the element - "<elementname>blah blah blah</elementname>"
+        if (nElementI)
+        {
+            // "</elementname>\0"
+            if (lpszMarker)
+            {
+                if (nFormat != -1)
+                {
+                    if (nFormat)
+                    {
+                        charmemset(&lpszMarker[nResult], INDENTCHAR,sizeof(XMLCHAR)*nFormat);
+                        nResult+=nFormat;
+                    }
+                }
+
+                _tcscpy(&lpszMarker[nResult], _T("</"));
+                nResult += 2;
+                _tcscpy(&lpszMarker[nResult], pEntry->lpszName);
+                nResult += cbElement;
+
+                if (nFormat == -1)
+                {
+                    _tcscpy(&lpszMarker[nResult], _T(">"));
+                    nResult++;
+                } else
+                {
+                    _tcscpy(&lpszMarker[nResult], _T(">\n"));
+                    nResult+=2;
+                }
+            } else
+            {
+                if (nFormat != -1) nResult+=cbElement+4+nFormat;
+                else nResult+=cbElement+3;
+            }
+        } else
+        {
+            // If there are no children we can use shorthand XML notation -
+            // "<elementname/>"
+            // "/>\0"
+            if (lpszMarker)
+            {
+                if (nFormat == -1)
+                {
+                    _tcscpy(&lpszMarker[nResult], _T("/>"));
+                    nResult += 2;
+                }
+                else
+                {
+                    _tcscpy(&lpszMarker[nResult], _T("/>\n"));
+                    nResult += 3;
+                }
+            }
+            else
+            {
+                nResult += nFormat == -1 ? 2 : 3;
+            }
+        }
+    }
+
+    return nResult;
+}
+
+#undef LENSTR
+
+// Create an XML string
+// @param       int nFormat             - 0 if no formatting is required
+//                                        otherwise nonzero for formatted text
+//                                        with carriage returns and indentation.
+// @param       int *pnSize             - [out] pointer to the size of the
+//                                        returned string not including the
+//                                        NULL terminator.
+// @return      XMLSTR                  - Allocated XML string, you must free
+//                                        this with free().
+XMLSTR XMLNode::createXMLString(int nFormat, int *pnSize) const
+{
+    if (!d) { if (pnSize) *pnSize=0; return NULL; }
+
+    XMLSTR lpszResult = NULL;
+    int cbStr;
+
+    // Recursively Calculate the size of the XML string
+    if (!dropWhiteSpace) nFormat=0;
+    nFormat = nFormat ? 0 : -1;
+    cbStr = CreateXMLStringR(d, 0, nFormat);
+    assert(cbStr);
+    // Alllocate memory for the XML string + the NULL terminator and
+    // create the recursively XML string.
+    lpszResult=(XMLSTR)malloc((cbStr+1)*sizeof(XMLCHAR));
+    CreateXMLStringR(d, lpszResult, nFormat);
+    if (pnSize) *pnSize = cbStr;
+    return lpszResult;
+}
+
+XMLNode::~XMLNode() { deleteNodeContent(); }
+
+int XMLNode::detachFromParent(XMLNodeData *d)
+{
+    XMLNode *pa=d->pParent->pChild;
+    int i=0;
+    while (((void*)(pa[i].d))!=((void*)d)) i++;
+    d->pParent->nChild--;
+    if (d->pParent->nChild) memmove(pa+i,pa+i+1,(d->pParent->nChild-i)*sizeof(XMLNode));
+    else { free(pa); d->pParent->pChild=NULL; }
+    return removeOrderElement(d->pParent,eNodeChild,i);
+}
+
+void XMLNode::deleteNodeContent(char force)
+{
+    if (!d) return;
+    (d->ref_count) --;
+    if ((d->ref_count==0)||force)
+    {
+        int i;
+        if (d->pParent) detachFromParent(d);
+        for(i=0; i<d->nChild; i++) { d->pChild[i].d->pParent=NULL; d->pChild[i].deleteNodeContent(force); }
+        free(d->pChild);
+        for(i=0; i<d->nText; i++) free((void*)d->pText[i]);
+        free(d->pText);
+        for(i=0; i<d->nClear; i++) free((void*)d->pClear[i].lpszValue);
+        free(d->pClear);
+        for(i=0; i<d->nAttribute; i++)
+        {
+            free((void*)d->pAttribute[i].lpszName);
+            if (d->pAttribute[i].lpszValue) free((void*)d->pAttribute[i].lpszValue);
+        }
+        free(d->pAttribute);
+        free(d->pOrder);
+        free((void*)d->lpszName);
+        free(d);
+        d=NULL;
+    }
+}
+
+XMLNode XMLNode::addChild(XMLNode childNode, int pos)
+{
+    XMLNodeData *dc=childNode.d;
+    if ((!dc)||(!d)) return childNode;
+    if (dc->pParent) { if ((detachFromParent(dc)<=pos)&&(dc->pParent==d)) pos--; } else dc->ref_count++;
+    dc->pParent=d;
+//     int nc=d->nChild;
+//     d->pChild=(XMLNode*)myRealloc(d->pChild,(nc+1),memoryIncrease,sizeof(XMLNode));
+    d->pChild=(XMLNode*)addToOrder(0,&pos,d->nChild,d->pChild,sizeof(XMLNode),eNodeChild);
+    d->pChild[pos].d=dc;
+    d->nChild++;
+    return childNode;
+}
+
+void XMLNode::deleteAttribute(int i)
+{
+    if ((!d)||(i<0)||(i>=d->nAttribute)) return;
+    d->nAttribute--;
+    XMLAttribute *p=d->pAttribute+i;
+    free((void*)p->lpszName);
+    if (p->lpszValue) free((void*)p->lpszValue);
+    if (d->nAttribute) memmove(p,p+1,(d->nAttribute-i)*sizeof(XMLAttribute)); else { free(p); d->pAttribute=NULL; }
+}
+
+void XMLNode::deleteAttribute(XMLAttribute *a){ if (a) deleteAttribute(a->lpszName); }
+void XMLNode::deleteAttribute(XMLCSTR lpszName)
+{
+    int j=0;
+    getAttribute(lpszName,&j);
+    if (j) deleteAttribute(j-1);
+}
+
+XMLAttribute *XMLNode::updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i)
+{
+    if (!d) return NULL;
+    if (i>=d->nAttribute)
+    {
+        if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue);
+        return NULL;
+    }
+    XMLAttribute *p=d->pAttribute+i;
+    if (p->lpszValue&&p->lpszValue!=lpszNewValue) free((void*)p->lpszValue);
+    p->lpszValue=lpszNewValue;
+    if (lpszNewName&&p->lpszName!=lpszNewName) { free((void*)p->lpszName); p->lpszName=lpszNewName; };
+    return p;
+}
+
+XMLAttribute *XMLNode::updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
+{
+    if (oldAttribute) return updateAttribute_WOSD(newAttribute->lpszValue,newAttribute->lpszName,oldAttribute->lpszName);
+    return addAttribute_WOSD(newAttribute->lpszName,newAttribute->lpszValue);
+}
+
+XMLAttribute *XMLNode::updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName)
+{
+    int j=0;
+    getAttribute(lpszOldName,&j);
+    if (j) return updateAttribute_WOSD(lpszNewValue,lpszNewName,j-1);
+    else
+    {
+        if (lpszNewName) return addAttribute_WOSD(lpszNewName,lpszNewValue);
+        else             return addAttribute_WOSD(stringDup(lpszOldName),lpszNewValue);
+    }
+}
+
+int XMLNode::indexText(XMLCSTR lpszValue) const
+{
+    if (!d) return -1;
+    int i,l=d->nText;
+    if (!lpszValue) { if (l) return 0; return -1; }
+    XMLCSTR *p=d->pText;
+    for (i=0; i<l; i++) if (lpszValue==p[i]) return i;
+    return -1;
+}
+
+void XMLNode::deleteText(int i)
+{
+    if ((!d)||(i<0)||(i>=d->nText)) return;
+    d->nText--;
+    XMLCSTR *p=d->pText+i;
+    free((void*)*p);
+    if (d->nText) memmove(p,p+1,(d->nText-i)*sizeof(XMLCSTR)); else { free(p); d->pText=NULL; }
+    removeOrderElement(d,eNodeText,i);
+}
+
+void XMLNode::deleteText(XMLCSTR lpszValue) { deleteText(indexText(lpszValue)); }
+
+XMLCSTR XMLNode::updateText_WOSD(XMLCSTR lpszNewValue, int i)
+{
+    if (!d) return NULL;
+    if (i>=d->nText) return addText_WOSD(lpszNewValue);
+    XMLCSTR *p=d->pText+i;
+    if (*p!=lpszNewValue) { free((void*)*p); *p=lpszNewValue; }
+    return lpszNewValue;
+}
+
+XMLCSTR XMLNode::updateText_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+{
+    if (!d) return NULL;
+    int i=indexText(lpszOldValue);
+    if (i>=0) return updateText_WOSD(lpszNewValue,i);
+    return addText_WOSD(lpszNewValue);
+}
+
+void XMLNode::deleteClear(int i)
+{
+    if ((!d)||(i<0)||(i>=d->nClear)) return;
+    d->nClear--;
+    XMLClear *p=d->pClear+i;
+    free((void*)p->lpszValue);
+    if (d->nClear) memmove(p,p+1,(d->nText-i)*sizeof(XMLClear)); else { free(p); d->pClear=NULL; }
+    removeOrderElement(d,eNodeClear,i);
+}
+
+int XMLNode::indexClear(XMLCSTR lpszValue) const
+{
+    if (!d) return -1;
+    int i,l=d->nClear;
+    if (!lpszValue) { if (l) return 0; return -1; }
+    XMLClear *p=d->pClear;
+    for (i=0; i<l; i++) if (lpszValue==p[i].lpszValue) return i;
+    return -1;
+}
+
+void XMLNode::deleteClear(XMLCSTR lpszValue) { deleteClear(indexClear(lpszValue)); }
+void XMLNode::deleteClear(XMLClear *a) { if (a) deleteClear(a->lpszValue); }
+
+XMLClear *XMLNode::updateClear_WOSD(XMLCSTR lpszNewContent, int i)
+{
+    if (!d) return NULL;
+    if (i>=d->nClear)
+    {
+        return addClear_WOSD(XMLClearTags[0].lpszOpen,lpszNewContent,XMLClearTags[0].lpszClose);
+    }
+    XMLClear *p=d->pClear+i;
+    if (lpszNewContent!=p->lpszValue) { free((void*)p->lpszValue); p->lpszValue=lpszNewContent; }
+    return p;
+}
+
+XMLClear *XMLNode::updateClear_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+{
+    if (!d) return NULL;
+    int i=indexClear(lpszOldValue);
+    if (i>=0) return updateClear_WOSD(lpszNewValue,i);
+    return addClear_WOSD(lpszNewValue,XMLClearTags[0].lpszOpen,XMLClearTags[0].lpszClose);
+}
+
+XMLClear *XMLNode::updateClear_WOSD(XMLClear *newP,XMLClear *oldP)
+{
+    if (oldP) return updateClear_WOSD(newP->lpszValue,oldP->lpszValue);
+    return NULL;
+}
+
+XMLNode& XMLNode::operator=( const XMLNode& A )
+{
+    // shallow copy
+    if (this != &A)
+    {
+        deleteNodeContent();
+        d=A.d;
+        if (d) (d->ref_count) ++ ;
+    }
+    return *this;
+}
+
+XMLNode::XMLNode(const XMLNode &A)
+{
+    // shallow copy
+    d=A.d;
+    if (d) (d->ref_count)++ ;
+}
+
+int XMLNode::nChildNode(XMLCSTR name) const
+{
+    if (!d) return 0;
+    int i,j=0,n=d->nChild;
+    XMLNode *pc=d->pChild;
+    for (i=0; i<n; i++)
+    {
+        if (_tcsicmp(pc->d->lpszName, name)==0) j++;
+        pc++;
+    }
+    return j;
+}
+
+XMLNode XMLNode::getChildNode(XMLCSTR name, int *j) const
+{
+    if (!d) return emptyXMLNode;
+    int i=0,n=d->nChild;
+    if (j) i=*j;
+    XMLNode *pc=d->pChild+i;
+    for (; i<n; i++)
+    {
+        if (_tcsicmp(pc->d->lpszName, name)==0)
+        {
+            if (j) *j=i+1;
+            return *pc;
+        }
+        pc++;
+    }
+    return emptyXMLNode;
+}
+
+XMLNode XMLNode::getChildNode(XMLCSTR name, int j) const
+{
+    if (!d) return emptyXMLNode;
+    int i=0;
+    while (j-->0) getChildNode(name,&i);
+    return getChildNode(name,&i);
+}
+
+int XMLNode::positionOfText     (int i) const { if (i>=d->nText ) i=d->nText-1;  return findPosition(d,i,eNodeText ); }
+int XMLNode::positionOfClear    (int i) const { if (i>=d->nClear) i=d->nClear-1; return findPosition(d,i,eNodeClear); }
+int XMLNode::positionOfChildNode(int i) const { if (i>=d->nChild) i=d->nChild-1; return findPosition(d,i,eNodeChild); }
+int XMLNode::positionOfText (XMLCSTR lpszValue) const { return positionOfText (indexText (lpszValue)); }
+int XMLNode::positionOfClear(XMLCSTR lpszValue) const { return positionOfClear(indexClear(lpszValue)); }
+int XMLNode::positionOfClear(XMLClear *a) const { if (a) return positionOfClear(a->lpszValue); return positionOfClear(); }
+int XMLNode::positionOfChildNode(XMLNode x)  const
+{
+    if ((!d)||(!x.d)) return -1;
+    XMLNodeData *dd=x.d;
+    XMLNode *pc=d->pChild;
+    int i=d->nChild;
+    while (i--) if (pc[i].d==dd) return findPosition(d,i,eNodeChild);
+    return -1;
+}
+int XMLNode::positionOfChildNode(XMLCSTR name, int count) const
+{
+    if (!name) return positionOfChildNode(count);
+    int j=0;
+    do { getChildNode(name,&j); if (j<0) return -1; } while (count--);
+    return findPosition(d,j-1,eNodeChild);
+}
+
+XMLNode XMLNode::getChildNodeWithAttribute(XMLCSTR name,XMLCSTR attributeName,XMLCSTR attributeValue, int *k) const
+{
+     int i=0,j;
+     if (k) i=*k;
+     XMLNode x;
+     XMLCSTR t;
+     do
+     {
+         x=getChildNode(name,&i);
+         if (!x.isEmpty())
+         {
+             if (attributeValue)
+             {
+                 j=0;
+                 do
+                 {
+                     t=x.getAttribute(attributeName,&j);
+                     if (t&&(_tcsicmp(attributeValue,t)==0)) { if (k) *k=i+1; return x; }
+                 } while (t);
+             } else
+             {
+                 if (x.isAttributeSet(attributeName)) { if (k) *k=i+1; return x; }
+             }
+         }
+     } while (!x.isEmpty());
+     return emptyXMLNode;
+}
+
+// Find an attribute on an node.
+XMLCSTR XMLNode::getAttribute(XMLCSTR lpszAttrib, int *j) const
+{
+    if (!d) return NULL;
+    int i=0,n=d->nAttribute;
+    if (j) i=*j;
+    XMLAttribute *pAttr=d->pAttribute+i;
+    for (; i<n; i++)
+    {
+        if (_tcsicmp(pAttr->lpszName, lpszAttrib)==0)
+        {
+            if (j) *j=i+1;
+            return pAttr->lpszValue;
+        }
+        pAttr++;
+    }
+    return NULL;
+}
+
+char XMLNode::isAttributeSet(XMLCSTR lpszAttrib) const
+{
+    if (!d) return FALSE;
+    int i,n=d->nAttribute;
+    XMLAttribute *pAttr=d->pAttribute;
+    for (i=0; i<n; i++)
+    {
+        if (_tcsicmp(pAttr->lpszName, lpszAttrib)==0)
+        {
+            return TRUE;
+        }
+        pAttr++;
+    }
+    return FALSE;
+}
+
+XMLCSTR XMLNode::getAttribute(XMLCSTR name, int j) const
+{
+    if (!d) return NULL;
+    int i=0;
+    while (j-->0) getAttribute(name,&i);
+    return getAttribute(name,&i);
+}
+
+XMLNodeContents XMLNode::enumContents(int i) const
+{
+    XMLNodeContents c;
+    if (!d) { c.type=eNodeNULL; return c; }
+    if (i<d->nAttribute)
+    {
+        c.type=eNodeAttribute;
+        c.attrib=d->pAttribute[i];
+        return c;
+    }
+    i-=d->nAttribute;
+    c.type=(XMLElementType)(d->pOrder[i]&3);
+    i=(d->pOrder[i])>>2;
+    switch (c.type)
+    {
+    case eNodeChild:     c.child = d->pChild[i];      break;
+    case eNodeText:      c.text  = d->pText[i];       break;
+    case eNodeClear:     c.clear = d->pClear[i];      break;
+    default: break;
+    }
+    return c;
+}
+
+XMLCSTR XMLNode::getName() const { if (!d) return NULL; return d->lpszName;   }
+int XMLNode::nText()       const { if (!d) return 0;    return d->nText;      }
+int XMLNode::nChildNode()  const { if (!d) return 0;    return d->nChild;     }
+int XMLNode::nAttribute()  const { if (!d) return 0;    return d->nAttribute; }
+int XMLNode::nClear()      const { if (!d) return 0;    return d->nClear;     }
+int XMLNode::nElement()    const { if (!d) return 0;    return d->nAttribute+d->nChild+d->nText+d->nClear; }
+XMLClear     XMLNode::getClear         (int i) const { if ((!d)||(i>=d->nClear    )) return emptyXMLClear;     return d->pClear[i];     }
+XMLAttribute XMLNode::getAttribute     (int i) const { if ((!d)||(i>=d->nAttribute)) return emptyXMLAttribute; return d->pAttribute[i]; }
+XMLCSTR      XMLNode::getAttributeName (int i) const { if ((!d)||(i>=d->nAttribute)) return NULL;              return d->pAttribute[i].lpszName;  }
+XMLCSTR      XMLNode::getAttributeValue(int i) const { if ((!d)||(i>=d->nAttribute)) return NULL;              return d->pAttribute[i].lpszValue; }
+XMLCSTR      XMLNode::getText          (int i) const { if ((!d)||(i>=d->nText     )) return NULL;              return d->pText[i];      }
+XMLNode      XMLNode::getChildNode     (int i) const { if ((!d)||(i>=d->nChild    )) return emptyXMLNode;      return d->pChild[i];     }
+XMLNode      XMLNode::getParentNode    (     ) const { if ((!d)||(!d->pParent     )) return emptyXMLNode;      return XMLNode(d->pParent); }
+char         XMLNode::isDeclaration    (     ) const { if (!d) return 0;             return d->isDeclaration; }
+char         XMLNode::isEmpty          (     ) const { return (d==NULL); }
+
+XMLNode       XMLNode::addChild(XMLCSTR lpszName, char isDeclaration, int pos)
+              { return addChild_priv(0,stringDup(lpszName),isDeclaration,pos); }
+XMLNode       XMLNode::addChild_WOSD(XMLCSTR lpszName, char isDeclaration, int pos)
+              { return addChild_priv(0,lpszName,isDeclaration,pos); }
+XMLAttribute *XMLNode::addAttribute(XMLCSTR lpszName, XMLCSTR lpszValue)
+              { return addAttribute_priv(0,stringDup(lpszName),stringDup(lpszValue)); }
+XMLAttribute *XMLNode::addAttribute_WOSD(XMLCSTR lpszName, XMLCSTR lpszValuev)
+              { return addAttribute_priv(0,lpszName,lpszValuev); }
+XMLCSTR       XMLNode::addText(XMLCSTR lpszValue, int pos)
+              { return addText_priv(0,stringDup(lpszValue),pos); }
+XMLCSTR       XMLNode::addText_WOSD(XMLCSTR lpszValue, int pos)
+              { return addText_priv(0,lpszValue,pos); }
+XMLClear     *XMLNode::addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
+              { return addClear_priv(0,stringDup(lpszValue),lpszOpen,lpszClose,pos); }
+XMLClear     *XMLNode::addClear_WOSD(XMLCSTR lpszValue, XMLCSTR lpszOpen, XMLCSTR lpszClose, int pos)
+              { return addClear_priv(0,lpszValue,lpszOpen,lpszClose,pos); }
+XMLCSTR       XMLNode::updateName(XMLCSTR lpszName)
+              { return updateName_WOSD(stringDup(lpszName)); }
+XMLAttribute *XMLNode::updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute)
+              { return updateAttribute_WOSD(stringDup(newAttribute->lpszValue),stringDup(newAttribute->lpszName),oldAttribute->lpszName); }
+XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,int i)
+              { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),i); }
+XMLAttribute *XMLNode::updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName)
+              { return updateAttribute_WOSD(stringDup(lpszNewValue),stringDup(lpszNewName),lpszOldName); }
+XMLCSTR       XMLNode::updateText(XMLCSTR lpszNewValue, int i)
+              { return updateText_WOSD(stringDup(lpszNewValue),i); }
+XMLCSTR       XMLNode::updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+              { return updateText_WOSD(stringDup(lpszNewValue),lpszOldValue); }
+XMLClear     *XMLNode::updateClear(XMLCSTR lpszNewContent, int i)
+              { return updateClear_WOSD(stringDup(lpszNewContent),i); }
+XMLClear     *XMLNode::updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue)
+              { return updateClear_WOSD(stringDup(lpszNewValue),lpszOldValue); }
+XMLClear     *XMLNode::updateClear(XMLClear *newP,XMLClear *oldP)
+              { return updateClear_WOSD(stringDup(newP->lpszValue),oldP->lpszValue); }
+
+void XMLNode::setGlobalOptions(char _guessUnicodeChars, char _strictUTF8Parsing, char _dropWhiteSpace)
+{
+    guessUnicodeChars=_guessUnicodeChars; dropWhiteSpace=_dropWhiteSpace; strictUTF8Parsing=_strictUTF8Parsing;
+#ifndef _XMLUNICODE
+    if (_strictUTF8Parsing) XML_ByteTable=XML_utf8ByteTable; else XML_ByteTable=XML_asciiByteTable;
+#endif
+}
+
+char XMLNode::guessUTF8ParsingParameterValue(void *buf,int l, char useXMLEncodingAttribute)
+{
+#ifdef _XMLUNICODE
+    return 0;
+#else
+    if (l<25) return 0;
+    if (myIsTextUnicode(buf,l)) return 0;
+    unsigned char *b=(unsigned char*)buf;
+    if ((b[0]==0xef)&&(b[1]==0xbb)&&(b[2]==0xbf)) return 1;
+
+    // Match utf-8 model ?
+    int i=0;
+    while (i<l)
+        switch (XML_utf8ByteTable[b[i]])
+        {
+        case 4: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) return 0; // 10bbbbbb ?
+        case 3: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) return 0; // 10bbbbbb ?
+        case 2: i++; if ((i<l)&&(b[i]& 0xC0)!=0x80) return 0; // 10bbbbbb ?
+        case 1: i++; break;
+        case 0: i=l;
+        }
+    if (!useXMLEncodingAttribute) return 1;
+    // if encoding is specified and different from utf-8 than it's non-utf8
+    // otherwise it's utf-8
+    char bb[201];
+    l=mmin(l,200);
+    memcpy(bb,buf,l); // copy buf into bb to be able to do "bb[l]=0"
+    bb[l]=0;
+    b=(unsigned char*)strstr(bb,"encoding");
+    if (!b) return 1;
+    b+=8; while XML_isSPACECHAR(*b) b++; if (*b!='=') return 1;
+    b++;  while XML_isSPACECHAR(*b) b++; if ((*b!='\'')&&(*b!='"')) return 1;
+    b++;  while XML_isSPACECHAR(*b) b++; if ((_strnicmp((char*)b,"utf-8",5)==0)||
+                                             (_strnicmp((char*)b,"utf8",4)==0)) return 1;
+    return 0;
+#endif
+}
+#undef XML_isSPACECHAR
+
+//////////////////////////////////////////////////////////
+//      Here starts the base64 conversion functions.    //
+//////////////////////////////////////////////////////////
+
+static const char base64Fillchar = _T('='); // used to mark partial words at the end
+
+// this lookup table defines the base64 encoding
+XMLCSTR base64EncodeTable=_T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
+
+// Decode Table gives the index of any valid base64 character in the Base64 table]
+// 96: '='  -   97: space char   -   98: illegal char   -   99: end of string
+const unsigned char base64DecodeTable[] = {
+    99,98,98,98,98,98,98,98,98,97,  97,98,98,97,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //00 -29
+    98,98,97,98,98,98,98,98,98,98,  98,98,98,62,98,98,98,63,52,53,  54,55,56,57,58,59,60,61,98,98,  //30 -59
+    98,96,98,98,98, 0, 1, 2, 3, 4,   5, 6, 7, 8, 9,10,11,12,13,14,  15,16,17,18,19,20,21,22,23,24,  //60 -89
+    25,98,98,98,98,98,98,26,27,28,  29,30,31,32,33,34,35,36,37,38,  39,40,41,42,43,44,45,46,47,48,  //90 -119
+    49,50,51,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //120 -149
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //150 -179
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //180 -209
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98,98,98,98,98,  //210 -239
+    98,98,98,98,98,98,98,98,98,98,  98,98,98,98,98,98                                               //240 -255
+};
+
+XMLParserBase64Tool::~XMLParserBase64Tool(){ freeBuffer(); }
+
+void XMLParserBase64Tool::freeBuffer(){ if (buf) free(buf); buf=NULL; buflen=0; }
+
+int XMLParserBase64Tool::encodeLength(int inlen, char formatted)
+{
+    unsigned int i=((inlen-1)/3*4+4+1);
+    if (formatted) i+=inlen/54;
+    return i;
+}
+
+XMLSTR XMLParserBase64Tool::encode(unsigned char *inbuf, unsigned int inlen, char formatted)
+{
+    int i=encodeLength(inlen,formatted),k=17,eLen=inlen/3,j;
+    alloc(i*sizeof(XMLCHAR));
+    XMLSTR curr=(XMLSTR)buf;
+    for(i=0;i<eLen;i++)
+    {
+        // Copy next three bytes into lower 24 bits of int, paying attention to sign.
+        j=(inbuf[0]<<16)|(inbuf[1]<<8)|inbuf[2]; inbuf+=3;
+        // Encode the int into four chars
+        *(curr++)=base64EncodeTable[ j>>18      ];
+        *(curr++)=base64EncodeTable[(j>>12)&0x3f];
+        *(curr++)=base64EncodeTable[(j>> 6)&0x3f];
+        *(curr++)=base64EncodeTable[(j    )&0x3f];
+        if (formatted) { if (!k) { *(curr++)=_T('\n'); k=18; } k--; }
+    }
+    eLen=inlen-eLen*3; // 0 - 2.
+    if (eLen==1)
+    {
+        *(curr++)=base64EncodeTable[ inbuf[0]>>2      ];
+        *(curr++)=base64EncodeTable[(inbuf[0]<<4)&0x3F];
+        *(curr++)=base64Fillchar;
+        *(curr++)=base64Fillchar;
+    } else if (eLen==2)
+    {
+        j=(inbuf[0]<<8)|inbuf[1];
+        *(curr++)=base64EncodeTable[ j>>10      ];
+        *(curr++)=base64EncodeTable[(j>> 4)&0x3f];
+        *(curr++)=base64EncodeTable[(j<< 2)&0x3f];
+        *(curr++)=base64Fillchar;
+    }
+    *(curr++)=0;
+    return (XMLSTR)buf;
+}
+
+unsigned int XMLParserBase64Tool::decodeSize(XMLCSTR data,XMLError *xe)
+{
+     if (xe) *xe=eXMLErrorNone;
+    int size=0;
+    unsigned char c;
+    //skip any extra characters (e.g. newlines or spaces)
+    while (*data)
+    {
+#ifdef _XMLUNICODE
+        if (*data>255) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+#endif
+        c=base64DecodeTable[(unsigned char)(*data)];
+        if (c<97) size++;
+        else if (c==98) { if (xe) *xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+        data++;
+    }
+    if (xe&&(size%4!=0)) *xe=eXMLErrorBase64DataSizeIsNotMultipleOf4;
+    if (size==0) return 0;
+    do { data--; size--; } while(*data==base64Fillchar); size++;
+    return (unsigned int)((size*3)/4);
+}
+
+unsigned char XMLParserBase64Tool::decode(XMLCSTR data, unsigned char *buf, int len, XMLError *xe)
+{
+    if (xe) *xe=eXMLErrorNone;
+    int i=0,p=0;
+    unsigned char d,c;
+    for(;;)
+    {
+
+#ifdef _XMLUNICODE
+#define BASE64DECODE_READ_NEXT_CHAR(c)                                              \
+        do {                                                                        \
+            if (data[i]>255){ c=98; break; }                                        \
+            c=base64DecodeTable[(unsigned char)data[i++]];                       \
+        }while (c==97);                                                             \
+        if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+#else
+#define BASE64DECODE_READ_NEXT_CHAR(c)                                           \
+        do { c=base64DecodeTable[(unsigned char)data[i++]]; }while (c==97);   \
+        if(c==98){ if(xe)*xe=eXMLErrorBase64DecodeIllegalCharacter; return 0; }
+#endif
+
+        BASE64DECODE_READ_NEXT_CHAR(c)
+        if (c==99) { return 2; }
+        if (c==96)
+        {
+            if (p==(int)len) return 2;
+            if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;
+            return 1;
+        }
+
+        BASE64DECODE_READ_NEXT_CHAR(d)
+        if ((d==99)||(d==96)) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        if (p==(int)len) {      if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall; return 0; }
+        buf[p++]=(c<<2)|((d>>4)&0x3);
+
+        BASE64DECODE_READ_NEXT_CHAR(c)
+        if (c==99) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        if (p==(int)len)
+        {
+            if (c==96) return 2;
+            if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
+            return 0;
+        }
+        if (c==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        buf[p++]=((d<<4)&0xf0)|((c>>2)&0xf);
+
+        BASE64DECODE_READ_NEXT_CHAR(d)
+        if (d==99 ) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        if (p==(int)len)
+        {
+            if (d==96) return 2;
+            if (xe) *xe=eXMLErrorBase64DecodeBufferTooSmall;
+            return 0;
+        }
+        if (d==96) { if (xe) *xe=eXMLErrorBase64DecodeTruncatedData;  return 1; }
+        buf[p++]=((c<<6)&0xc0)|d;
+    }
+}
+#undef BASE64DECODE_READ_NEXT_CHAR
+
+void XMLParserBase64Tool::alloc(int newsize)
+{
+    if ((!buf)&&(newsize)) { buf=malloc(newsize); buflen=newsize; return; }
+    if (newsize>buflen) { buf=realloc(buf,newsize); buflen=newsize; }
+}
+
+unsigned char *XMLParserBase64Tool::decode(XMLCSTR data, int *outlen, XMLError *xe)
+{
+    if (xe) *xe=eXMLErrorNone;
+    unsigned int len=decodeSize(data,xe);
+    if (outlen) *outlen=len;
+    if (!len) return NULL;
+    alloc(len+1);
+    if(!decode(data,(unsigned char*)buf,len,xe)){ return NULL; }
+    return (unsigned char*)buf;
+}
+
diff --git a/dol/src/dol/visitor/hds/lib/xmlParser.h b/dol/src/dol/visitor/hds/lib/xmlParser.h
new file mode 100644 (file)
index 0000000..7da09a5
--- /dev/null
@@ -0,0 +1,529 @@
+/**
+ ****************************************************************************
+ * <P> XML.c - implementation file for basic XML parser written in ANSI C++
+ * for portability. It works by using recursion and a node tree for breaking
+ * down the elements of an XML document.  </P>
+ *
+ * @version     V2.23
+ * @author      Frank Vanden Berghen
+ *
+ * BSD license:
+ * Copyright (c) 2002, Frank Vanden Berghen
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Frank Vanden Berghen nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************
+ */
+#ifndef __INCLUDE_XML_NODE__
+#define __INCLUDE_XML_NODE__
+
+#include <stdlib.h>
+
+#ifdef _UNICODE
+// If you comment the next "define" line then the library will never "switch to" _UNICODE (wchar_t*) mode (16/32 bits per characters).
+// This is useful when you get error messages like:
+//    'XMLNode::openFileHelper' : cannot convert parameter 2 from 'const char [5]' to 'const wchar_t *'
+// The _XMLUNICODE preprocessor variable force the XMLParser library into either utf16/32-mode (the proprocessor variable
+// must be defined) or utf8-mode(the pre-processor variable must be undefined).
+#define _XMLUNICODE
+#endif
+
+#if defined(WIN32) || defined(UNDER_CE)
+// comment the next line if you are under windows and the compiler is not Microsoft Visual Studio (6.0 or .NET)
+#define _XMLWINDOWS
+#endif
+
+#ifdef DLLENTRY
+#undef  DLLENTRY
+#endif
+#ifdef _USE_XMLPARSER_DLL
+#ifdef _DLL_EXPORTS_
+#define DLLENTRY __declspec(dllexport)
+#else
+#define DLLENTRY __declspec(dllimport)
+#endif
+#else
+#define DLLENTRY
+#endif
+
+// uncomment the next line if you want no support for wchar_t* (no need for the <wchar.h> or <tchar.h> libraries anymore to compile)
+//#define XML_NO_WIDE_CHAR
+
+#ifdef XML_NO_WIDE_CHAR
+#undef _XMLWINDOWS
+#undef _XMLUNICODE
+#endif
+
+#ifdef _XMLWINDOWS
+#include <tchar.h>
+#else
+#define DLLENTRY
+#ifndef XML_NO_WIDE_CHAR
+#include <wchar.h> // to have 'wcsrtombs' for ANSI version
+                   // to have 'mbsrtowcs' for UNICODE version
+#endif
+#endif
+
+// Some common types for char set portable code
+#ifdef _XMLUNICODE
+    #ifndef _T
+        #define _T(c) L ## c
+    #endif
+    #define XMLCSTR const wchar_t *
+    #define XMLSTR  wchar_t *
+    #define XMLCHAR wchar_t
+#else
+    #ifndef _T
+        #define _T(c) c
+    #endif
+    #define XMLCSTR const char *
+    #define XMLSTR  char *
+    #define XMLCHAR char
+#endif
+#ifndef FALSE
+    #define FALSE 0
+#endif /* FALSE */
+#ifndef TRUE
+    #define TRUE 1
+#endif /* TRUE */
+
+
+// Enumeration for XML parse errors.
+typedef enum XMLError
+{
+    eXMLErrorNone = 0,
+    eXMLErrorMissingEndTag,
+    eXMLErrorEmpty,
+    eXMLErrorFirstNotStartTag,
+    eXMLErrorMissingTagName,
+    eXMLErrorMissingEndTagName,
+    eXMLErrorNoMatchingQuote,
+    eXMLErrorUnmatchedEndTag,
+    eXMLErrorUnmatchedEndClearTag,
+    eXMLErrorUnexpectedToken,
+    eXMLErrorInvalidTag,
+    eXMLErrorNoElements,
+    eXMLErrorFileNotFound,
+    eXMLErrorFirstTagNotFound,
+    eXMLErrorUnknownCharacterEntity,
+    eXMLErrorCharConversionError,
+    eXMLErrorCannotOpenWriteFile,
+    eXMLErrorCannotWriteFile,
+
+    eXMLErrorBase64DataSizeIsNotMultipleOf4,
+    eXMLErrorBase64DecodeIllegalCharacter,
+    eXMLErrorBase64DecodeTruncatedData,
+    eXMLErrorBase64DecodeBufferTooSmall
+} XMLError;
+
+// Enumeration used to manage type of data. Use in conjunction with structure XMLNodeContents
+typedef enum XMLElementType
+{
+    eNodeChild=0,
+    eNodeAttribute=1,
+    eNodeText=2,
+    eNodeClear=3,
+    eNodeNULL=4
+} XMLElementType;
+
+// Structure used to obtain error details if the parse fails.
+typedef struct XMLResults
+{
+    enum XMLError error;
+    int  nLine,nColumn;
+} XMLResults;
+
+// Structure for XML clear (unformatted) node (usually comments)
+typedef struct {
+    XMLCSTR lpszValue; XMLCSTR lpszOpenTag; XMLCSTR lpszCloseTag;
+} XMLClear;
+
+// Structure for XML attribute.
+typedef struct {
+    XMLCSTR lpszName; XMLCSTR lpszValue;
+} XMLAttribute;
+
+// Structure for XML clear tags.
+typedef struct {
+    XMLCSTR lpszOpen; int openTagLen; XMLCSTR lpszClose;
+} ALLXMLClearTag;
+
+struct XMLNodeContents;
+
+typedef struct DLLENTRY XMLNode
+{
+  private:
+
+    struct XMLNodeDataTag;
+
+    // protected constructors: use one of these four methods to get your first instance of XMLNode:
+    //  - parseString
+    //  - parseFile
+    //  - openFileHelper
+    //  - createXMLTopNode
+    XMLNode(struct XMLNodeDataTag *pParent, XMLCSTR lpszName, char isDeclaration);
+    XMLNode(struct XMLNodeDataTag *p);
+
+  public:
+
+    // You can create your first instance of XMLNode with these 4 functions:
+    // (see complete explanation of parameters below)
+
+    static XMLNode createXMLTopNode(XMLCSTR lpszName, char isDeclaration=FALSE);
+    static XMLNode parseString   (XMLCSTR  lpXMLString, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
+    static XMLNode parseFile     (XMLCSTR     filename, XMLCSTR tag=NULL, XMLResults *pResults=NULL);
+    static XMLNode openFileHelper(XMLCSTR     filename, XMLCSTR tag=NULL                           );
+
+    // The tag parameter should be the name of the first tag inside the XML file.
+    // If the tag parameter is omitted, the 3 functions return a node that represents
+    // the head of the xml document including the declaration term (<? ... ?>).
+
+    // The "openFileHelper" reports to the screen all the warnings & errors that occurred during
+    // parsing of the XML file. Since each application has its own way to report and deal with errors,
+    // you should rather use the "parseFile" function to parse XML files and program yourself thereafter
+    // an "error reporting" tailored for your needs (instead of using the very crude "error reporting"
+    // mechanism included inside the "openFileHelper" function).
+
+    // If the XML document is corrupted:
+    //   * The "openFileHelper" method will:
+    //         - display an error message on the console (or inside a messageBox for windows).
+    //         - stop execution (exit).
+    //     I suggest that you write your own "openFileHelper" method tailored to your needs.
+    //   * The 2 other methods will initialize the "pResults" variable with some information that
+    //     can be used to trace the error.
+    //   * If you still want to parse the file, you can use the APPROXIMATE_PARSING option as
+    //     explained inside the note at the beginning of the "xmlParser.cpp" file.
+    // You can have a user-friendly explanation of the parsing error with this function:
+    static XMLCSTR getError(XMLError error);
+    static XMLCSTR getVersion();
+    static ALLXMLClearTag* getClearTagTable();
+
+    XMLCSTR getName() const;                                         // name of the node
+    XMLCSTR getText(int i=0) const;                                  // return ith text field
+    int nText() const;                                               // nbr of text field
+    XMLNode getParentNode() const;                                   // return the parent node
+    XMLNode getChildNode(int i=0) const;                             // return ith child node
+    XMLNode getChildNode(XMLCSTR name, int i)  const;                // return ith child node with specific name
+                                                                     //     (return an empty node if failing)
+    XMLNode getChildNode(XMLCSTR name, int *i=NULL) const;           // return next child node with specific name
+                                                                     //     (return an empty node if failing)
+    XMLNode getChildNodeWithAttribute(XMLCSTR tagName,               // return child node with specific name/attribute
+                                      XMLCSTR attributeName,         //     (return an empty node if failing)
+                                      XMLCSTR attributeValue=NULL,   //
+                                      int *i=NULL)  const;           //
+    int nChildNode(XMLCSTR name) const;                              // return the number of child node with specific name
+    int nChildNode() const;                                          // nbr of child node
+    XMLAttribute getAttribute(int i=0) const;                        // return ith attribute
+    XMLCSTR      getAttributeName(int i=0) const;                    // return ith attribute name
+    XMLCSTR      getAttributeValue(int i=0) const;                   // return ith attribute value
+    char  isAttributeSet(XMLCSTR name) const;                        // test if an attribute with a specific name is given
+    XMLCSTR getAttribute(XMLCSTR name, int i) const;                 // return ith attribute content with specific name
+                                                                     //     (return a NULL if failing)
+    XMLCSTR getAttribute(XMLCSTR name, int *i=NULL) const;           // return next attribute content with specific name
+                                                                     //     (return a NULL if failing)
+    int nAttribute() const;                                          // nbr of attribute
+    XMLClear getClear(int i=0) const;                                // return ith clear field (comments)
+    int nClear() const;                                              // nbr of clear field
+    XMLSTR createXMLString(int nFormat=1, int *pnSize=NULL) const;   // create XML string starting from current XMLNode
+                                                                     // if nFormat==0, no formatting is required
+                                                                     // otherwise this returns an user friendly XML string from a
+                                                                     // given element with appropriate white spaces and carriage returns.
+                                                                     // if pnSize is given it returns the size in character of the string.
+    XMLError writeToFile(XMLCSTR filename, const char *encoding=NULL, char nFormat=1) const;
+                                                                     // save the content of an xmlNode inside a file.
+                                                                     // the nFormat parameter has the same meaning as in the
+                                                                     // createXMLString function. If "strictUTF8Parsing=1", the
+                                                                     // the encoding parameter is ignored and always set to
+                                                                     // "utf-8". If "_XMLUNICODE=1", the encoding parameter is
+                                                                     // ignored and always set to "utf-16".
+    XMLNodeContents enumContents(int i) const;                       // enumerate all the different contents (attribute,child,text,
+                                                                     //     clear) of the current XMLNode. The order is reflecting
+                                                                     //     the order of the original file/string.
+                                                                     //     NOTE: 0 <= i < nElement();
+    int nElement() const;                                            // nbr of different contents for current node
+    char isEmpty() const;                                            // is this node Empty?
+    char isDeclaration() const;                                      // is this node a declaration <? .... ?>
+
+// to allow shallow/fast copy:
+    ~XMLNode();
+    XMLNode(const XMLNode &A);
+    XMLNode& operator=( const XMLNode& A );
+
+    XMLNode(): d(NULL){};
+    static XMLNode emptyXMLNode;
+    static XMLClear emptyXMLClear;
+    static XMLAttribute emptyXMLAttribute;
+
+    // The following functions allows you to create from scratch (or update) a XMLNode structure
+    // Start by creating your top node with the "createXMLTopNode" function and then add new nodes with the "addChild" function.
+    // The parameter 'pos' gives the position where the childNode, the text or the XMLClearTag will be inserted.
+    // The default value (pos=-1) inserts at the end. The value (pos=0) insert at the beginning (Insertion at the beginning is slower than at the end).
+    // REMARK: 0 <= pos < nChild()+nText()+nClear()
+    XMLNode       addChild(XMLCSTR lpszName, char isDeclaration=FALSE, int pos=-1);
+    XMLAttribute *addAttribute(XMLCSTR lpszName, XMLCSTR lpszValuev);
+    XMLCSTR       addText(XMLCSTR lpszValue, int pos=-1);
+    XMLClear     *addClear(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, int pos=-1);
+                                                                    // default values: lpszOpen=XMLNode::getClearTagTable()->lpszOpen;
+                                                                    //                 lpszClose=XMLNode::getClearTagTable()->lpszClose;
+    XMLNode       addChild(XMLNode nodeToAdd, int pos=-1);          // If the "nodeToAdd" has some parents, it will be detached
+                                                                    // from it's parents before being attached to the current XMLNode
+    // Some update functions:
+    XMLCSTR       updateName(XMLCSTR lpszName);                                                    // change node's name
+    XMLAttribute *updateAttribute(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);         // if the attribute to update is missing, a new one will be added
+    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);         // if the attribute to update is missing, a new one will be added
+    XMLAttribute *updateAttribute(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);  // set lpszNewName=NULL if you don't want to change the name of the attribute
+                                                                                                   // if the attribute to update is missing, a new one will be added
+    XMLCSTR       updateText(XMLCSTR lpszNewValue, int i=0);                                       // if the text to update is missing, a new one will be added
+    XMLCSTR       updateText(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                          // if the text to update is missing, a new one will be added
+    XMLClear     *updateClear(XMLCSTR lpszNewContent, int i=0);                                    // if the clearTag to update is missing, a new one will be added
+    XMLClear     *updateClear(XMLClear *newP,XMLClear *oldP);                                      // if the clearTag to update is missing, a new one will be added
+    XMLClear     *updateClear(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);                         // if the clearTag to update is missing, a new one will be added
+
+    // Some deletion functions:
+    void deleteNodeContent(char force=0);  // delete the content of this XMLNode and the subtree.
+                                           // if force=0, while (references to this node still exist), no memory free occurs
+                                           // if force=1, always delete the content of this XMLNode and the subtree and free associated memory
+    void deleteAttribute(XMLCSTR lpszName);
+    void deleteAttribute(int i=0);
+    void deleteAttribute(XMLAttribute *anAttribute);
+    void deleteText(int i=0);
+    void deleteText(XMLCSTR lpszValue);
+    void deleteClear(int i=0);
+    void deleteClear(XMLClear *p);
+    void deleteClear(XMLCSTR lpszValue);
+
+    // The strings given as parameters for the following add and update methods (all these methods have
+    // a name with the postfix "_WOSD" that means "WithOut String Duplication" ) will be free'd by the
+    // XMLNode class. For example, it means that this is incorrect:
+    //    xNode.addText_WOSD("foo");
+    //    xNode.updateAttribute_WOSD("#newcolor" ,NULL,"color");
+    // In opposition, this is correct:
+    //    xNode.addText("foo");
+    //    xNode.addText_WOSD(stringDup("foo"));
+    //    xNode.updateAttribute("#newcolor" ,NULL,"color");
+    //    xNode.updateAttribute_WOSD(stringDup("#newcolor"),NULL,"color");
+    // Typically, you will never do:
+    //    char *b=(char*)malloc(...);
+    //    xNode.addText(b);
+    //    free(b);
+    // ... but rather:
+    //    char *b=(char*)malloc(...);
+    //    xNode.addText_WOSD(b);
+    //    ('free(b)' is performed by the XMLNode class)
+
+    static XMLNode createXMLTopNode_WOSD(XMLCSTR lpszName, char isDeclaration=FALSE);
+    XMLNode        addChild_WOSD(XMLCSTR lpszName, char isDeclaration=FALSE, int pos=-1);
+    XMLAttribute  *addAttribute_WOSD(XMLCSTR lpszName, XMLCSTR lpszValue);
+    XMLCSTR        addText_WOSD(XMLCSTR lpszValue, int pos=-1);
+    XMLClear      *addClear_WOSD(XMLCSTR lpszValue, XMLCSTR lpszOpen=NULL, XMLCSTR lpszClose=NULL, int pos=-1);
+
+    XMLCSTR        updateName_WOSD(XMLCSTR lpszName);
+    XMLAttribute  *updateAttribute_WOSD(XMLAttribute *newAttribute, XMLAttribute *oldAttribute);
+    XMLAttribute  *updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName=NULL,int i=0);
+    XMLAttribute  *updateAttribute_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszNewName,XMLCSTR lpszOldName);
+    XMLCSTR        updateText_WOSD(XMLCSTR lpszNewValue, int i=0);
+    XMLCSTR        updateText_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);
+    XMLClear      *updateClear_WOSD(XMLCSTR lpszNewContent, int i=0);
+    XMLClear      *updateClear_WOSD(XMLClear *newP,XMLClear *oldP);
+    XMLClear      *updateClear_WOSD(XMLCSTR lpszNewValue, XMLCSTR lpszOldValue);
+
+    // These are some useful functions when you want to insert a childNode, a text or a XMLClearTag in the
+    // middle (at a specified position) of a XMLNode tree already constructed. The value returned by these
+    // methods is to be used as last parameter (parameter 'pos') of addChild, addText or addClear.
+    int positionOfText(int i=0) const;
+    int positionOfText(XMLCSTR lpszValue) const;
+    int positionOfClear(int i=0) const;
+    int positionOfClear(XMLCSTR lpszValue) const;
+    int positionOfClear(XMLClear *a) const;
+    int positionOfChildNode(int i=0) const;
+    int positionOfChildNode(XMLNode x) const;
+    int positionOfChildNode(XMLCSTR name, int i=0) const; // return the position of the ith childNode with the specified name
+                                                          // if (name==NULL) return the position of the ith childNode
+
+    // The setGlobalOptions function allows you to change two global parameters that affect string&file
+    // parsing. First of all, you most-probably will never have to change these 2 global parameters.
+    // About the "guessUnicodeChars" parameter:
+    //     If "guessUnicodeChars=1" and if this library is compiled in UNICODE mode, then the
+    //     "parseFile" and "openFileHelper" functions will test if the file contains ASCII
+    //     characters. If this is the case, then the file will be loaded and converted in memory to
+    //     UNICODE before being parsed. If "guessUnicodeChars=0", no conversion will
+    //     be performed.
+    //
+    //     If "guessUnicodeChars=1" and if this library is compiled in ASCII/UTF8 mode, then the
+    //     "parseFile" and "openFileHelper" functions will test if the file contains UNICODE
+    //     characters. If this is the case, then the file will be loaded and converted in memory to
+    //     ASCII/UTF8 before being parsed. If "guessUnicodeChars=0", no conversion will
+    //     be performed
+    //
+    //     Sometime, it's useful to set "guessUnicodeChars=0" to disable any conversion
+    //     because the test to detect the file-type (ASCII/UTF8 or UNICODE) may fail (rarely).
+    //
+    // About the "strictUTF8Parsing" parameter:
+    //     If "strictUTF8Parsing=0" then we assume that all characters have the same length of 1 byte.
+    //     If "strictUTF8Parsing=1" then the characters have different lengths (from 1 byte to 4 bytes)
+    //     depending on the content of the first byte of the character.
+    // About the "dropWhiteSpace" parameter:
+    //
+
+    static void setGlobalOptions(char guessUnicodeChars=1, char strictUTF8Parsing=1, char dropWhiteSpace=1);
+
+    // The next function try to guess if the character encoding is UTF-8. You most-probably will never
+    // have to use this function. It then returns the appropriate value of the global parameter
+    // "strictUTF8Parsing" described above. The guess is based on the content of a buffer of length
+    // "bufLen" bytes that contains the first bytes (minimum 25 bytes; 200 bytes is a good value) of the
+    // file to be parsed. The "openFileHelper" function is using this function to automatically compute
+    // the value of the "strictUTF8Parsing" global parameter. There are several heuristics used to do the
+    // guess. One of the heuristic is based on the "encoding" attribute. The original XML specifications
+    // forbids to use this attribute to do the guess but you can still use it if you set
+    // "useXMLEncodingAttribute" to 1 (this is the default behavior and the behavior of most parsers).
+
+    static char guessUTF8ParsingParameterValue(void *buffer, int bufLen, char useXMLEncodingAttribute=1);
+
+  private:
+
+// these are functions and structures used internally by the XMLNode class (don't bother about them):
+
+      typedef struct XMLNodeDataTag // to allow shallow copy and "intelligent/smart" pointers (automatic delete):
+      {
+          XMLCSTR                lpszName;        // Element name (=NULL if root)
+          int                    nChild,          // Number of child nodes
+                                 nText,           // Number of text fields
+                                 nClear,          // Number of Clear fields (comments)
+                                 nAttribute;      // Number of attributes
+          char                   isDeclaration;   // Whether node is an XML declaration - '<?xml ?>'
+          struct XMLNodeDataTag  *pParent;        // Pointer to parent element (=NULL if root)
+          XMLNode                *pChild;         // Array of child nodes
+          XMLCSTR                *pText;          // Array of text fields
+          XMLClear               *pClear;         // Array of clear fields
+          XMLAttribute           *pAttribute;     // Array of attributes
+          int                    *pOrder;         // order of the child_nodes,text_fields,clear_fields
+          int                    ref_count;       // for garbage collection (smart pointers)
+      } XMLNodeData;
+      XMLNodeData *d;
+
+      char parseClearTag(void *px, ALLXMLClearTag *pa);
+      char maybeAddTxT(void *pa, XMLCSTR tokenPStr);
+      int ParseXMLElement(void *pXML);
+      void *addToOrder(int memInc, int *_pos, int nc, void *p, int size, XMLElementType xtype);
+      int indexText(XMLCSTR lpszValue) const;
+      int indexClear(XMLCSTR lpszValue) const;
+      XMLNode addChild_priv(int,XMLCSTR,char,int);
+      XMLAttribute *addAttribute_priv(int,XMLCSTR,XMLCSTR);
+      XMLCSTR addText_priv(int,XMLCSTR,int);
+      XMLClear *addClear_priv(int,XMLCSTR,XMLCSTR,XMLCSTR,int);
+      static inline int findPosition(XMLNodeData *d, int index, XMLElementType xtype);
+      static int CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, int nFormat);
+      static int removeOrderElement(XMLNodeData *d, XMLElementType t, int index);
+      static void exactMemory(XMLNodeData *d);
+      static int detachFromParent(XMLNodeData *d);
+} XMLNode;
+
+// This structure is given by the function "enumContents".
+typedef struct XMLNodeContents
+{
+    // This dictates what's the content of the XMLNodeContent
+    enum XMLElementType type;
+    // should be an union to access the appropriate data.
+    // compiler does not allow union of object with constructor... too bad.
+    XMLNode child;
+    XMLAttribute attrib;
+    XMLCSTR text;
+    XMLClear clear;
+
+} XMLNodeContents;
+
+DLLENTRY void free_XMLDLL(void *t); // {free(t);}
+
+// Duplicate (copy in a new allocated buffer) the source string. This is
+// a very handy function when used with all the "XMLNode::*_WOSD" functions.
+// (If (cbData!=0) then cbData is the number of chars to duplicate)
+DLLENTRY XMLSTR stringDup(XMLCSTR source, int cbData=0);
+
+// The 3 following functions are processing strings so that all the characters
+// &,",',<,> are replaced by their XML equivalent: &amp;, &quot;, &apos;, &lt;, &gt;.
+// These 3 functions are useful when creating from scratch an XML file using the
+// "printf", "fprintf", "cout",... functions. If you are creating from scratch an
+// XML file using the provided XMLNode class you cannot use these functions (the
+// XMLNode class does the processing job for you during rendering). The second
+// function ("toXMLStringFast") allows you to re-use the same output buffer
+// for all the conversions so that only a few memory allocations are performed.
+// If the output buffer is too small to contain thee resulting string, it will
+// be enlarged.
+DLLENTRY XMLSTR toXMLString(XMLCSTR source);
+DLLENTRY XMLSTR toXMLStringFast(XMLSTR *destBuffer,int *destSz, XMLCSTR source);
+
+// you should not use this one (there is a possibility of "destination-buffer-overflow"):
+DLLENTRY XMLSTR toXMLString(XMLSTR dest,XMLCSTR source);
+
+// Below is a class that allows you to include any binary data (images, sounds,...)
+// into an XML document using "Base64 encoding". This class is completely
+// separated from the rest of the xmlParser library and can be removed without any problem.
+// To include some binary data into an XML file, you must convert the binary data into
+// standard text (using "encode"). To retrieve the original binary data from the
+// b64-encoded text included inside the XML file use "decode". Alternatively, these
+// functions can also be used to "encrypt/decrypt" some critical data contained inside
+// the XML.
+
+class DLLENTRY XMLParserBase64Tool
+{
+public:
+    XMLParserBase64Tool(): buf(NULL),buflen(0){}
+    ~XMLParserBase64Tool();
+
+    void freeBuffer();
+
+    // returns the length of the base64 string that encodes a data buffer of size inBufLen bytes.
+    // If "formatted" parameter is true, some space will be reserved for a carriage-return every 72 chars.
+    static int encodeLength(int inBufLen, char formatted=0);
+
+    // The "base64Encode" function returns a string containing the base64 encoding of "inByteLen" bytes
+    // from "inByteBuf". If "formatted" parameter is true, then there will be a carriage-return every 72 chars.
+    // The string will be free'd when the XMLParserBase64Tool object is deleted.
+    // All returned strings are sharing the same memory space.
+    XMLSTR encode(unsigned char *inByteBuf, unsigned int inByteLen, char formatted=0);
+
+    // returns the number of bytes which will be decoded from "inString".
+    static unsigned int decodeSize(XMLCSTR inString, XMLError *xe=NULL);
+
+    // returns a pointer to a buffer containing the binary data decoded from "inString"
+    // If "inString" is malformed NULL will be returned
+    // The output buffer will be free'd when the XMLParserBase64Tool object is deleted.
+    // All output buffer are sharing the same memory space.
+    unsigned char* decode(XMLCSTR inString, int *outByteLen=NULL, XMLError *xe=NULL);
+
+    // The next function is deprecated.
+    // decodes data from "inString" to "outByteBuf". You need to provide the size (in byte) of "outByteBuf"
+    // in "inMaxByteOutBuflen". If "outByteBuf" is not large enough or if data is malformed, then "FALSE"
+    // will be returned; otherwise "TRUE".
+    static unsigned char decode(XMLCSTR inString, unsigned char *outByteBuf, int inMaxByteOutBuflen, XMLError *xe=NULL);
+
+private:
+    void *buf;
+    int buflen;
+    void alloc(int newsize);
+};
+
+#undef  DLLENTRY
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/HdsdMakefileVisitor.java b/dol/src/dol/visitor/hdsd/HdsdMakefileVisitor.java
new file mode 100644 (file)
index 0000000..8458b32
--- /dev/null
@@ -0,0 +1,134 @@
+package dol.visitor.hdsd;
+
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Process;
+import dol.visitor.MapVisitor;
+
+/**
+ *  Visitor that is used to generate
+ *  a HdS package Makefile for a distributed simulation.
+ */
+public class HdsdMakefileVisitor extends MapVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of the Makefile
+     */
+    public HdsdMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * Create a Makefile for the given mapping.
+     *
+     * @param x mapping that needs to be rendered.
+     */
+    public void visitComponent(Mapping x) {
+        try {
+            String filename = _dir + "/" + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("CXX = g++");
+            ps.println("CC = g++");
+            ps.println();
+            ps.println("PREPROC_MACROS = -D __DOL_ETHZ_GEN__ -DINCLUDE_PROFILER");
+            ps.println();
+            ps.println("SYSTEMC_INC = -I" + _ui.getSystemCINC());
+            ps.println("SYSTEMC_LIB = " + _ui.getSystemCLIB());
+            ps.println("MY_LIB_INC = -Ilib -Iscd -Isc_wrappers -Iprocesses");
+            ps.println("VPATH = lib:scd:scd/fsm:sc_wrappers:processes");
+            ps.println();
+            ps.println("# append '-rdynamic' for name resolution in exception stack traces");
+            ps.println("# append '-g' for debugging");
+            ps.println("CXXFLAGS = -O0 $(PREPROC_MACROS) $(SYSTEMC_INC) $(MY_LIB_INC)");
+            ps.println("CFLAGS = $(CXXFLAGS)");
+            ps.println();
+            
+            // scd library objects
+            ps.println("# scd library objects");
+            ps.println("SCD_OBJS = scd_logging.o scd_exception.o scd_socket.o scd_sock_poller.o \\");
+            ps.println("\tscd_init_listener.o scd_in_connector.o scd_out_connector.o \\");
+            ps.println("\tscd_command.o scd_command_reader.o scd_command_writer.o \\");
+            ps.println("\tscd_simulator.o scd_chan_man.o scd_chan_wrapper.o \\");
+            ps.println("\tscd_cont_man_master.o scd_cont_man_slave.o scd_cont_slave_wrapper.o \\");
+            ps.println("\tscd_rem_fifo_in.o scd_rem_fifo_out.o scd_cont_fsm.o \\");
+            ps.println("\tscd_sts_base.o scd_sts_init.o scd_sts_busy.o scd_sts_idle.o \\");
+            ps.println("\tscd_sts_done.o scd_sts_time_ack.o scd_sts_time.o scd_sts_term_ack.o \\");
+            ps.println("\tscd_sts_terminated.o scd_sts_fail.o scd_sts_failed.o \\");
+            ps.println("\tscd_stm_base.o scd_stm_init.o scd_stm_busy.o scd_stm_idle.o \\");
+            ps.println("\tscd_stm_done.o scd_stm_time_req.o scd_stm_time.o scd_stm_term_req.o \\");
+            ps.println("\tscd_stm_terminate.o scd_stm_terminated.o \\");
+            ps.println("\tscd_stm_fail.o scd_stm_failed.o \\");
+            ps.println("\tscd_stsw_base.o scd_stsw_init.o scd_stsw_busy.o \\");
+            ps.println("\tscd_stsw_idle.o scd_stsw_done.o scd_stsw_time_req.o \\");
+            ps.println("\tscd_stsw_time_ack.o scd_stsw_term_req.o scd_stsw_term_ack.o \\");
+            ps.println("\tscd_stsw_terminate.o scd_stsw_terminated.o \\");
+            ps.println("\tscd_stsw_fail.o scd_stsw_failed.o");
+            ps.println();
+            
+            // process objects
+            ps.println("# process objects");
+            ps.print("PROCESS_OBJS = dol.o ");
+            Iterator<Process> i = x.getProcessList().iterator();
+            Set<String> pSet = new HashSet<String>();
+            while (i.hasNext()) {
+                String basename = i.next().getBasename();
+                if (pSet.add(basename))
+                    ps.print(basename + "_wrapper.o ");
+            }
+            ps.println();
+            ps.println();
+            
+            // target all
+            Iterator<Processor> iter = x.getProcessorList().iterator();
+            String processorList = new String();
+            while (iter.hasNext())
+            {
+                Processor p = iter.next();
+                if (x.getProcessList().isEmpty())
+                    continue;
+                processorList += " scd_" + p.getName();
+            }
+            ps.println("all:" + processorList);
+            ps.println();
+            
+            // processor targets
+            iter = x.getProcessorList().iterator();
+            while (iter.hasNext())
+            {
+                Processor p = iter.next();
+                if (x.getProcessList().isEmpty())
+                    continue;
+                ps.println("scd_" + p.getName() + ": scd_"
+                        + p.getName() + ".o $(PROCESS_OBJS)" 
+                        + " $(SCD_OBJS)");
+                ps.println("\t$(CXX) $(CXXFLAGS) -o $@ $^ $(SYSTEMC_LIB)");
+                ps.println();
+            }
+            
+            // clean target
+            ps.println("clean:");
+            ps.println("\t-rm -f *.o core core.* *.core" + processorList);
+
+        } catch (Exception e) {
+            System.out.println("HdsdMakefileVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
+
+    protected String _dir = null;
+}
+
diff --git a/dol/src/dol/visitor/hdsd/HdsdModuleArchVisitor.java b/dol/src/dol/visitor/hdsd/HdsdModuleArchVisitor.java
new file mode 100644 (file)
index 0000000..4b89646
--- /dev/null
@@ -0,0 +1,491 @@
+package dol.visitor.hdsd;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Configuration;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.Resource;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+import dol.visitor.ArchiVisitor;
+
+/**
+ * Visitor that generates the main program for one distributed simulator.
+ */
+public class HdsdModuleArchVisitor extends ArchiVisitor {
+
+    /**
+     * Constructor.
+     * @param map mapping of this code generation
+     * @param dir path of this file
+     */
+    public HdsdModuleArchVisitor(Mapping map, String dir) {
+        _map = map;
+        _dir = dir;
+        _channels = new LinkedHashSet<String>();
+        _remInChannels = new LinkedHashSet<String>();
+        _remOutChannels = new LinkedHashSet<String>();
+        _locChannels = new LinkedHashSet<String>();
+    }
+
+    /**
+     *
+     * @param x Processor that needs to be rendered
+     */
+    public void visitComponent(Processor x) {
+        
+        // get channels for this processor
+        _getChannels(x);
+        
+        try {
+            String filename = _dir + "/" + "scd_" + 
+                    x.getName() + ".cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            _mainPS.printPrefixln("#include <systemc>");
+            _mainPS.printPrefixln("#include <list>");
+
+            /* begin of profiling: standard i/o file handling routines */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("#include <stdio.h>");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("#include \"dol_sched_if.h\"");
+            _mainPS.printPrefixln("#include \"simple_fifo.h\"");
+            _mainPS.printPrefixln("#include \"scd_logging.h\"");
+            _mainPS.printPrefixln("#include \"scd_simulator.h\"");
+            _mainPS.printPrefixln("#include \"scd_rem_fifo_in.h\"");
+            _mainPS.printPrefixln("#include \"scd_rem_fifo_out.h\"");
+            _mainPS.println();
+
+            // include process files
+            Iterator<Process> pIt = x.getProcessList().iterator();
+            Vector<String> pList = new Vector<String>();
+            while (pIt.hasNext()) {
+                Process p = pIt.next();
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    _mainPS.printPrefixln("#include \"" + p.getBasename()
+                            + "_wrapper.h\"");
+                    pList.add(basename);
+                }
+            }
+            _mainPS.println();
+            
+            // namespaces
+            _mainPS.printPrefixln("using namespace std;");
+            _mainPS.printPrefixln("using sc_core::sc_module;");
+            _mainPS.printPrefixln("using sc_core::sc_event;");
+            _mainPS.printPrefixln("using sc_core::sc_prim_channel;");
+
+
+            /* begin of profiling: global variables */
+            _mainPS.println();
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("#define PROFILER_OUTPUT_FILENAME "
+                    + "\"profile_" + x.getName() + ".txt\"");
+            _mainPS.printPrefixln("FILE *profiler_output_file;");
+            _mainPS.printPrefixln("unsigned int profiler_event_counter;");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.println();
+            _mainPS.printPrefixln("class sc_application : public sc_module ");
+            _mainPS.printLeftBracket();
+
+            _mainPS.printPrefixln("public:");
+            _mainPS.printPrefixln("SC_HAS_PROCESS(sc_application);");
+
+            //declare processes
+            _mainPS.println();
+            pIt = x.getProcessList().iterator();
+            while (pIt.hasNext()) {
+                Process p = pIt.next();
+                _mainPS.printPrefixln(p.getBasename() + "_wrapper "
+                        + p.getName() + "_ins"+ ";");
+                _mainPS.printPrefixln("sc_event " + p.getName()
+                        + "_event;");
+            }
+            _mainPS.println();
+
+            //define the scheduler
+            _mainPS.printPrefixln("sc_event sched_event;");
+            _mainPS.printPrefixln("list<sc_event* > eventList;");
+            _mainPS.printPrefixln("list<sc_event* >::iterator iter;");
+            _mainPS.println();
+
+            //declare channels
+            _mainPS.println();
+            Iterator<String> cIt;
+            cIt = _locChannels.iterator();
+            while (cIt.hasNext())
+                _mainPS.printPrefixln("fifo " + cIt.next() + "_ins;");
+            cIt = _remInChannels.iterator();
+            while (cIt.hasNext())
+                _mainPS.printPrefixln("scd_rem_fifo_in " + cIt.next() + "_ins;");
+            cIt = _remOutChannels.iterator();
+            while (cIt.hasNext())
+                _mainPS.printPrefixln("scd_rem_fifo_out " + cIt.next() + "_ins;");
+            _mainPS.println();
+
+            // model constructor
+            _mainPS.printPrefixln("sc_application(sc_module_name name)");
+
+            // parameter of constructor (processes)
+            _mainPS.printPrefixln(":       sc_module(name),");
+            pIt = x.getProcessList().iterator();
+            while (pIt.hasNext()) {
+                Process p = pIt.next();
+                _mainPS.printPrefixln(p.getName() + "_ins(\""
+                        + p.getName() +"\"),");
+            }
+            
+            // parameter of constructor (channels)
+            cIt = _channels.iterator();
+            while (cIt.hasNext()) {
+                Channel c = _map.getPN().getChannel( cIt.next() );
+                _mainPS.printPrefix(c.getName() + "_ins(\""
+                                    + c.getName() +"\", "
+                                    + c.getSize()*c.getTokenSize()
+                                    + ")");
+                if (cIt.hasNext())
+                    _mainPS.println(",");
+                else
+                    _mainPS.println();
+            }
+            _mainPS.printLeftBracket();
+
+            //construtor content
+            //build the network
+            cIt = _channels.iterator();
+            while (cIt.hasNext())
+            {
+                Channel c = _map.getPN().getChannel(cIt.next());
+                c.accept( new HdsdModulePNVisitor(x, _mainPS) );
+            }
+            _mainPS.println();
+
+            _mainPS.println();
+
+            _mainPS.printPrefixln("SC_THREAD(thread_init);");
+            // init thread
+            _mainPS.printPrefixln("SC_THREAD(thread_sched);");
+
+            // declare concurrent non-terminating threads
+            pIt = x.getProcessList().iterator();
+            while (pIt.hasNext()) {
+                _mainPS.printPrefixln("SC_THREAD(thread_" +
+                        pIt.next().getName() + ");");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define scheduler thread
+            _mainPS.printPrefixln("void thread_init()");
+            _mainPS.printLeftBracket();
+            //init
+            pIt = x.getProcessList().iterator();
+            while (pIt.hasNext()) {
+                Process p = pIt.next();
+                _mainPS.printPrefixln(p.getName() + "_ins.initialize();");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+
+            //different scheduling algorithm can be put here
+            _mainPS.printPrefixln("void thread_sched()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("while (1)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("for (iter=eventList.begin(); iter != "
+                    + "eventList.end(); ++iter)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_event* e = (*iter);");
+            _mainPS.printPrefixln("e->notify();");
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("eventList.clear();");
+            _mainPS.printPrefixln("wait(sched_event);");
+            _mainPS.printRightBracket();
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define threads
+            pIt = x.getProcessList().iterator();
+            while (pIt.hasNext())
+                pIt.next().accept( new HdsdModulePNVisitor(x, _mainPS) );
+
+            /* begin of profiling: initialization function. */
+            /* - opens file */
+            /* - writes a list of all channels with the connected ports to the file. */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("void initialize_profiler()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("if ((profiler_output_file = fopen(PROFILER_OUTPUT_FILENAME,\"w\"))==NULL)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("printf(\"Unable to open profiler output file. No profiling output is written.\\n\");");
+            _mainPS.printPrefixln("return;");
+            _mainPS.printRightBracket();
+            //_mainPS.printPrefixln("printf(\"Profiling data is written to %s.\\n\", PROFILER_OUTPUT_FILENAME);");
+            _mainPS.println();
+
+            cIt = _channels.iterator();
+            while (cIt.hasNext()) {
+                String cName = cIt.next();
+                Channel ch = _map.getPN().getChannel(cName);
+                Iterator<Port> poIt = ch.getPortList().iterator();
+                String outputString = "fprintf(profiler_output_file, \"c " + ch.getName() + " " + ch.getSize();
+                String outputStringAppendix = "";
+                while (poIt.hasNext()) {
+                    Port p = poIt.next();
+                    Port peerPort = p.getPeerPort();
+                    Resource peerResource = p.getPeerResource();
+
+                    if (p.isOutPort()) {
+                        // channel.out == process.in
+                        String portAddr = null;
+                        if ( x.hasProcess(peerResource.getName()) )
+                            portAddr = "&(" + peerResource.getName()
+                            + "_ins.INPORT_" + peerPort.getBasename()
+                            + peerPort.getName().replace(
+                            peerPort.getBasename(), "").replaceAll(
+                            "_([0-9]+)", "[$1]") + ")";
+                        else
+                            portAddr = "0x00000000";
+                        outputString += " i " + peerResource.getName() + " %p";// + p.getPeerPort().getName();
+                        outputStringAppendix += "," + portAddr;
+                    } else {
+                        String portAddr = null;
+                        if ( x.hasProcess(peerResource.getName()) )
+                            portAddr = "&(" + peerResource.getName()
+                            + "_ins.OUTPORT_" + peerPort.getBasename()
+                            + peerPort.getName().replace(
+                            peerPort.getBasename(), "").replaceAll(
+                            "_([0-9]+)", "[$1]") + ")";
+                        else
+                            portAddr = "0x00000000";
+                        outputString += " o " + peerResource.getName() + " %p";// + p.getPeerPort().getName();
+                        outputStringAppendix += "," + portAddr;
+                    }
+                }
+                outputString += "\\n\"" + outputStringAppendix + ");";
+                _mainPS.printPrefixln(outputString);
+            }
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("#endif");
+            _mainPS.println();
+            /* end of profiling */
+
+            _mainPS.printRightBracket(); // end of class
+            _mainPS.println(";");
+
+            //create and run the simulator
+            _mainPS.printPrefixln("int sc_main (int argc, char *argv[])");
+            _mainPS.printLeftBracket();
+
+            //create an instance of the application model
+            //remove potential whitespaces before using the process
+            //network name as a systemc identifier
+            _mainPS.printPrefixln("sc_application my_app_mdl(\""
+                    + x.getName().replaceAll(" ", "")  + "\");");
+
+            /* begin of profiling: initialize the profiler */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("my_app_mdl.initialize_profiler();");
+            _mainPS.printPrefixln("#endif");
+            _mainPS.printPrefixln();
+            /* end of profiling */
+
+            /* begin distributed simulation */
+            if (UserInterface.getInstance().getDebugFlag())
+                _mainPS.printPrefixln("scd_set_loglevel(SCD_DEBUG);");
+            else
+                _mainPS.printPrefixln("scd_set_loglevel(SCD_INFO);");
+            // simulator && master/slaves
+            Configuration opt = x.getCfg("master"); 
+            if (opt != null && opt.getValue().equals("true")) // master
+            {
+                // simulator constructor
+                _mainPS.printPrefixln("scd_simulator sim(\"" 
+                        + x.getName() + "\", \""
+                        + x.getCfg("address").getValue() + "\", "
+                        + x.getCfg("port").getValue() + ", SCD_MASTER);");
+                // register slaves
+                Iterator<Processor> iter = _map.getProcessorList().iterator();
+                while (iter.hasNext())
+                {
+                    Processor p = iter.next();
+                    opt = p.getCfg("master");
+                    if ( !(opt != null && opt.getValue().equals("true")) )
+                    {
+                        _mainPS.printPrefixln("sim.get_cont_man()."
+                                + "register_slave(\"" + p.getName()
+                                + "\");");
+                    }
+                }
+            } // end master
+            else // slave
+            {
+                // simulator constructor
+                _mainPS.printPrefixln("scd_simulator sim(\"" 
+                        + x.getName() + "\", \""
+                        + x.getCfg("address").getValue() + "\", "
+                        + x.getCfg("port").getValue() + ", SCD_SLAVE);");
+                // find and set master
+                Iterator<Processor> iter = _map.getProcessorList().iterator();
+                while (iter.hasNext())
+                {
+                    Processor p = iter.next();
+                    opt = p.getCfg("master");
+                    if (opt != null && opt.getValue().equals("true"))
+                    {
+                        _mainPS.printPrefixln("sim.get_cont_man().set_master(\""
+                                + p.getCfg("address").getValue() + "\", "
+                                + p.getCfg("port").getValue() + ");");
+                        break;
+                    }
+                }
+            } // end slave
+            
+            // register channels
+            // remote out channels
+            cIt = _remOutChannels.iterator();
+            while (cIt.hasNext())
+            {
+                String cName = cIt.next();
+                Channel c = _map.getPN().getChannel(cName);
+                Iterator<Port> poIt = c.getPortList().iterator();
+                Processor p = null;
+                while (poIt.hasNext())
+                {
+                    Port po = poIt.next();
+                    if (po.isOutPort())
+                    {
+                        Process pr = _map.getProcess(
+                                po.getPeerResource().getName() );
+                        p = pr.getProcessor();
+                    }
+                }
+                _mainPS.printPrefixln("sim.get_chan_man()."
+                        + "register_channel(\"" + cName + "\",");
+                _mainPS.printPrefixln("        my_app_mdl." + cName
+                        + "_ins, \"" + p.getCfg("address").getValue() + "\", "
+                        + p.getCfg("port").getValue() + ");");
+            }
+            // remote in channels
+            cIt = _remInChannels.iterator();
+            while (cIt.hasNext())
+            {
+                String cName = cIt.next();
+                _mainPS.printPrefixln("sim.get_chan_man().register_channel("
+                        + "\"" + cName + "\",");
+                _mainPS.printPrefixln("        my_app_mdl." + cName + "_ins);");
+            }
+            
+            // init & start
+            _mainPS.printPrefixln("bool ret = sim.init();");
+            _mainPS.printPrefixln("if (ret)");
+            _mainPS.prefixInc();
+                _mainPS.printPrefixln("ret = sim.start();");
+            _mainPS.prefixDec();
+            _mainPS.printPrefixln();
+            /* end distributed simulation */
+            
+            /* begin of profiling: close the output file */
+            _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+            _mainPS.printPrefixln("if (profiler_output_file != NULL) fclose(profiler_output_file);");
+            _mainPS.printPrefixln("#endif");
+            /* end of profiling */
+
+            _mainPS.printPrefixln("if (ret)");
+            _mainPS.prefixInc();
+            _mainPS.printPrefixln("return 0;");
+            _mainPS.prefixDec();
+            _mainPS.printPrefixln("else");
+            _mainPS.prefixInc();
+            _mainPS.printPrefixln("return 1;");
+            _mainPS.prefixDec();
+            
+            _mainPS.printRightBracket();
+
+        }
+        catch (Exception e) {
+            System.out.println("HdsdModuleVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+    
+    
+    /**
+     * Retrieves all channels that have an endpoint on the specified
+     * processor and fills them into the channel sets.
+     * @param x the processor to get the channels for
+     */
+    private void _getChannels(Processor x)
+    {
+        Iterator<Channel> iter = _map.getPN().getChannelList().iterator();
+        
+        while (iter.hasNext())
+        {
+            Channel c = iter.next();
+            
+            boolean isIn = false;
+            boolean isOut = false;
+            
+            /* check if the in/out endpoint of this channel is on this
+             * processor
+             */
+            Iterator<Port> poIt = c.getPortList().iterator();
+            while (poIt.hasNext())
+            {
+                Port p = poIt.next();
+                if (x.hasProcess(p.getPeerResource().getName()))
+                {
+                    if (p.isInPort())   // inPort of channel = outport
+                        isOut = true;
+                    if (p.isOutPort()) // outPort of channel  = inport
+                        isIn = true;
+                }
+            }
+            
+            // add name to channel lists
+            if (isIn && isOut)
+            {
+                _channels.add(c.getName());
+                _locChannels.add(c.getName());
+            }
+            else if (isIn && !isOut)
+            {
+                _channels.add(c.getName());
+                _remInChannels.add(c.getName());
+            }
+            else if (!isIn && isOut)
+            {
+                _channels.add(c.getName());
+                _remOutChannels.add(c.getName());
+            }
+        }
+    } // _getChannels()
+    
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected Mapping _map = null;
+    
+    protected Set<String> _channels = null;
+    protected Set<String> _remInChannels = null;
+    protected Set<String> _remOutChannels = null;
+    protected Set<String> _locChannels = null;
+}
diff --git a/dol/src/dol/visitor/hdsd/HdsdModulePNVisitor.java b/dol/src/dol/visitor/hdsd/HdsdModulePNVisitor.java
new file mode 100644 (file)
index 0000000..466dba3
--- /dev/null
@@ -0,0 +1,113 @@
+package dol.visitor.hdsd;
+
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.Resource;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * Visitor that generates the main program thread of a process
+ * and the process network in the constructor.
+ */
+public class HdsdModulePNVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public HdsdModulePNVisitor(Processor processor, CodePrintStream stream) {
+        _processor = processor;
+        _mainPS = stream;
+    }
+
+    /**
+     * Generates the thread for this process.
+     *
+     * @param x process that needs to be rendered
+     */
+    public void visitComponent(Process x) {
+        _mainPS.printPrefixln("void thread_" + x.getName() + "()");
+        _mainPS.printLeftBracket();
+        _mainPS.printPrefixln("while (!" + x.getName()
+                + "_ins.isDetached())");
+        _mainPS.printLeftBracket();
+
+        /* begin of profiling: start event */
+        _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+        _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " started.\\n\", profiler_event_counter++);");
+        _mainPS.printPrefixln("#endif");
+        /* end of profiling */
+
+        _mainPS.printPrefixln(x.getName() + "_ins.fire();");
+
+        /* begin of profiling: stop event */
+        _mainPS.printPrefixln("#ifdef INCLUDE_PROFILER");
+        _mainPS.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u "+ x.getName() + " stopped.\\n\", profiler_event_counter++);");
+        _mainPS.printPrefixln("#endif");
+        /* end of profiling */
+
+        _mainPS.printPrefixln("eventList.push_back(&" + x.getName()
+                              + "_event);");
+        _mainPS.printPrefixln("sched_event.notify(SC_ZERO_TIME);");
+        _mainPS.printPrefixln("wait(" + x.getName() + "_event);");
+
+        _mainPS.printRightBracket();
+        _mainPS.printRightBracket();
+    }
+
+    /**
+     * Generates the process network. This is the channel content
+     * in the model constructor.
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        for (Port p : x.getPortList()) {
+            Port peerPort = (Port)(p.getPeerPort());
+            Resource peerResource = p.getPeerResource();
+
+            if (!_processor.hasProcess(peerResource.getName()))
+                continue;
+
+            if (peerPort.getRange() != null) {
+                if (p.isOutPort()) {
+                    _mainPS.printPrefixln(peerResource.getName()
+                            + "_ins.INPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replace(
+                            peerPort.getBasename(), "").replaceAll(
+                            "_([0-9]+)", "[$1]") + "(" + x.getName()
+                            + "_ins);");
+                }
+                else if (p.isInPort()) {
+                    _mainPS.printPrefixln(peerResource.getName()
+                            + "_ins.OUTPORT_"
+                            + peerPort.getBasename()
+                            + peerPort.getName().replace(
+                            peerPort.getBasename(), "").replaceAll(
+                            "_([0-9]+)", "[$1]") + "(" + x.getName()
+                            + "_ins);");
+                }
+            }
+            else {
+                if (p.isOutPort()) {
+                    _mainPS.printPrefixln(peerResource.getName()
+                            + "_ins.INPORT_" + peerPort.getName()
+                            + "(" + x.getName() + "_ins);");
+                }
+                else if (p.isInPort()) {
+                    _mainPS.printPrefixln(peerResource.getName()
+                            + "_ins.OUTPORT_" + peerPort.getName()
+                            + "(" + x.getName() + "_ins);");
+                }
+            }
+        }
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected Mapping _map = null;
+    protected Processor _processor = null;
+}
diff --git a/dol/src/dol/visitor/hdsd/HdsdModuleVisitor.java b/dol/src/dol/visitor/hdsd/HdsdModuleVisitor.java
new file mode 100644 (file)
index 0000000..e7b316f
--- /dev/null
@@ -0,0 +1,38 @@
+package dol.visitor.hdsd;
+
+import java.util.Iterator;
+
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.visitor.MapVisitor;
+
+/**
+ * Visitor that generates the main programs of distributed simulators.
+ */
+public class HdsdModuleVisitor extends MapVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public HdsdModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x mapping that needs to be rendered
+     */
+    public void visitComponent(Mapping x) {
+        Iterator<Processor> iter;
+        iter = x.getProcessorList().iterator();
+        while (iter.hasNext())
+        {
+            Processor p = iter.next();
+            p.accept(new HdsdModuleArchVisitor(x, _dir));
+        }
+    }
+
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/hdsd/HdsdProcessVisitor.java b/dol/src/dol/visitor/hdsd/HdsdProcessVisitor.java
new file mode 100644 (file)
index 0000000..2ba1044
--- /dev/null
@@ -0,0 +1,364 @@
+package dol.visitor.hdsd;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * Visitor that is used to generate
+ * a wrapper class for a process: process_wrapper.[h/cpp].
+ */
+public class HdsdProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public HdsdProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> pList = new Vector<String>();
+
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    p.accept(this);
+                }
+            }
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param p process that needs to be rendered
+     */
+    public void visitComponent(Process p) {
+        try {
+            _createCppFile(p);
+            _createHeaderFile(p);
+            _adaptSources(p);
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _adaptSources(Process p) throws IOException {
+        Sed sed = new Sed();
+        for (Port port : p.getPortList()) {
+            String processHeaderFile;
+
+            for (SourceCode sr : p.getSrcList()) {
+                processHeaderFile = _dir + _delimiter + ".."
+                        + _delimiter + "processes" + _delimiter
+                        + sr.getLocality().
+                        replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                if (port.isOutPort()) {
+                    sed.sed(processHeaderFile,
+                            "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + "&((static_cast<" + p.getBasename()
+                            + "_wrapper *>(p->wptr))->OUTPORT_"
+                            + port.getBasename() + ")");
+
+                }
+                else if (port.isInPort()) {
+                    sed.sed(processHeaderFile,
+                            "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + "&((static_cast<" + p.getBasename()
+                            + "_wrapper *>(p->wptr))->INPORT_"
+                            + port.getBasename() + ")");
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _createCppFile(Process p) throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.cpp";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#include \"" + p.getBasename()
+                + "_wrapper.h\"");
+        ps.printPrefixln();
+
+        //define the write/read
+        if (p.hasOutPorts()) {
+            ps.printPrefixln("static inline int DOL_write(void *port, "
+                    + "void *buf, int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<write_if> *write_port = static_cast"
+                    + "<sc_port<write_if> *>(port);");
+            ps.printPrefixln("char *str = static_cast<char*>(buf);");
+
+            /* begin of profiling: write event */
+            ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+            ps.printPrefixln("(static_cast<" + p.getBasename()
+                  + "_wrapper *>(process->wptr))" + "->addToProfile(\"w\", port, len);");
+            ps.printPrefixln("#endif");
+            /* end of profiling */
+
+            ps.printPrefixln("while (len-- > 0) ");
+            ps.printPrefixln("    (*write_port)->write(*str++);");
+            ps.printRightBracket();
+            ps.printPrefixln();
+            ps.printPrefixln("static inline int DOL_wtest(void *port, "
+                    + "int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<write_if> *write_port = static_cast"
+                    + "<sc_port<write_if> *>(port);");
+            ps.printPrefixln("return (*write_port)->wtest(len);");
+            ps.printRightBracket();
+            ps.printPrefixln();
+        }
+        if (p.hasInPorts()) {
+            ps.printPrefixln("static inline int DOL_read(void *port, "
+                    + "void *buf, int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<read_if> *read_port = static_cast"
+                    + "<sc_port<read_if> *>(port);");
+            ps.printPrefixln("char *str = static_cast<char*>(buf);");
+
+            /* begin of profiling: read event */
+            ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+            ps.printPrefixln("(static_cast<" + p.getBasename()
+                  + "_wrapper *>(process->wptr))" + "->addToProfile(\"r\", port, len);");
+            ps.printPrefixln("#endif");
+            /* end of profiling */
+
+            ps.printPrefixln("while (len-- > 0) ");
+            ps.printPrefixln("    (*read_port)->read(*str++);");
+            ps.printRightBracket();
+            ps.printPrefixln();
+            ps.printPrefixln("static inline int DOL_rtest(void *port, "
+                    + "int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("sc_port<read_if> *read_port = static_cast"
+                    + "<sc_port<read_if> *>(port);");
+            ps.printPrefixln("return (*read_port)->rtest(len);");
+            ps.printRightBracket();
+        }
+        ps.printPrefixln();
+        ps.printPrefixln("static inline int DOL_detach(DOLProcess *p)");
+        ps.printLeftBracket();
+        ps.printPrefixln("(static_cast<" + p.getBasename()
+                + "_wrapper *>(p->wptr))" + "->setDetached();");
+        ps.printRightBracket();
+        ps.printPrefixln();
+
+        ps.printPrefixln("#define GETINDEX(dimension) \\");
+        ps.printPrefixln("(static_cast<" + p.getBasename()
+                + "_wrapper *>(p->wptr))->_processIndex[dimension]");
+        ps.printPrefixln();
+        //include c file
+        for (SourceCode sr : p.getSrcList()) {
+            ps.printPrefixln("#include \"" + sr.getLocality() + "\"");
+        }
+        ps.printPrefixln();
+
+        /* begin of profiling: function that adds an entry to the profile */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("void " + p.getBasename() + "_wrapper::addToProfile(const char *evnt, void *port, int length)");
+        ps.printLeftBracket();
+        ps.printPrefixln("if (profiler_output_file != NULL) fprintf(profiler_output_file, \"%u %s %s %p %d\\n\", profiler_event_counter++, _uniqueName, evnt, port, length);");
+        ps.printRightBracket();
+        ps.printPrefixln("#endif");
+        /* end of profiling */
+
+        ps.printPrefixln("void " + p.getBasename()
+                + "_wrapper::setDetached() { _detached = 1; }");
+        ps.printPrefixln("int " + p.getBasename()
+                + "_wrapper::isDetached() { return _detached; }");
+        ps.printPrefixln();
+
+        //constructor
+        ps.printPrefixln(p.getBasename() + "_wrapper::" + p.getBasename()
+                + "_wrapper(sc_module_name name=sc_gen_unique_name(\""
+                + p.getBasename() + "\" ))  : sc_module(name),  _process("
+                + p.getBasename() +  ")" + ", _detached(0)");
+        ps.printLeftBracket();
+        ps.printPrefixln("struct _local_states *_state = "
+                + "new struct _local_states;");
+        ps.printPrefixln("memcpy(_state, " + p.getBasename()
+                + ".local, sizeof(struct _local_states));");
+        ps.printPrefixln("_process.local = _state;");
+        //ps.printPrefixln("sprintf(_process.local->id, name);");
+        ps.printPrefixln("_process.wptr = this;");
+        ps.printPrefixln();
+        ps.printPrefixln("char buffer[255];");
+        ps.printPrefixln("sprintf(buffer, name);");
+
+        /* begin of profiling: save unique name for writing it to
+           the profile later */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("sprintf(_uniqueName, name);");
+        ps.printPrefixln("#endif");
+        /* end of profiling */
+
+        ps.printPrefixln("for (int i = 0; i < 4; i++)");
+        ps.printPrefixln("    _processIndex[i] = "
+                + "getIndex(buffer, \"_\", i);");
+
+        ps.printPrefixln();
+        ps.printRightBracket();
+
+        ps.printPrefixln();
+        ps.printPrefixln("void " + p.getBasename()
+                + "_wrapper::initialize()");
+        ps.printLeftBracket();
+        ps.printPrefixln("_process.init(&_process);");
+        ps.printRightBracket();
+        ps.printPrefixln();
+        ps.printPrefixln("int " + p.getBasename() + "_wrapper::fire()");
+        ps.printLeftBracket();
+        ps.printPrefixln();
+        ps.printPrefixln("return _process.fire(&_process);");
+        ps.printRightBracket();
+    }
+
+    protected void _createHeaderFile(Process p)
+        throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#ifndef " + p.getBasename() + "_WRAPPER_H");
+        ps.printPrefixln("#define " + p.getBasename() + "_WRAPPER_H");
+        ps.printPrefixln();
+        ps.printPrefixln("#include \"systemc.h\"");
+        ps.printPrefixln();
+        ps.printPrefixln("#include \"dol_sched_if.h\"");
+        ps.printPrefixln("#include \"simple_fifo.h\"");
+        ps.printPrefixln();
+        ps.printPrefixln("#include <dol.h>");
+        ps.printPrefixln();
+
+        /* begin of profiling: externally defined global variables */
+        ps.println();
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("extern FILE *profiler_output_file;");
+        ps.printPrefixln("extern unsigned int profiler_event_counter;");
+        ps.printPrefixln("#endif");
+        ps.printPrefixln();
+        /* end of profiling */
+
+        ps.printPrefixln("class " + p.getBasename() +
+                         "_wrapper : virtual public dol_sched_if, " +
+                         "public sc_module");
+        ps.printLeftBracket();
+        ps.printPrefixln("public:");
+
+
+        Vector<String> portList = new Vector<String>();
+        for (Port port : p.getPortList()) {
+            String basename = port.getBasename();
+
+            if (!portList.contains(basename)) {
+                portList.add(basename);
+
+                if (!port.getRange().equals("")) {
+                    if (port.isOutPort()) {
+                        ps.printPrefixln("sc_port<write_if> OUTPORT_"
+                                + port.getBasename() + "["
+                                + port.getRange().replaceAll(
+                                ";", "\\]\\[") + "];");
+                    }
+                    else if (port.isInPort()) {
+                        ps.printPrefixln("sc_port<read_if> INPORT_"
+                                + port.getBasename() + "["
+                                + port.getRange().replaceAll(
+                                ";", "\\]\\[") + "];");
+                    }
+                }
+                else {
+                    if (port.isOutPort()) {
+                        ps.printPrefixln("sc_port<write_if> OUTPORT_"
+                                + port.getName() + ";");
+                    }
+                    else if (port.isInPort()) {
+                        ps.printPrefixln("sc_port<read_if> INPORT_"
+                                + port.getName() + ";");
+                    }
+                }
+            }
+        }
+        ps.printPrefixln("int _processIndex[4];");
+
+        /* begin of profiling: name variable declaration */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("char _uniqueName[255];");
+        ps.printPrefixln("#endif");
+        /* end of profiling */
+
+        ps.printPrefixln();
+        ps.printPrefixln("" + p.getBasename()
+                + "_wrapper(sc_module_name name);");
+        ps.printPrefixln();
+        ps.printPrefixln("~" + p.getBasename() + "_wrapper() {}");
+        ps.printPrefixln();
+
+        /* begin of profiling: addtoprofile member function */
+        ps.printPrefixln("#ifdef INCLUDE_PROFILER");
+        ps.printPrefixln("void addToProfile(const char *, void *, int);");
+        ps.printPrefixln("#endif");
+        ps.printPrefixln();
+        /* end of profiling */
+
+        ps.printPrefixln("// DOL scheduler interface");
+        ps.printPrefixln("void initialize();");
+        ps.printPrefixln("int fire();");
+        ps.printPrefixln("void setDetached();");
+        ps.printPrefixln("int isDetached();");
+        ps.printPrefixln();
+        ps.printPrefixln();
+        ps.printPrefixln("protected:");
+        ps.printPrefixln();
+        ps.printPrefixln("private:");
+        ps.printPrefixln("" + p.getBasename() + "_wrapper( const "
+                + p.getBasename() + "_wrapper& );");
+        ps.printPrefixln("" + p.getBasename() + "_wrapper& operator = "
+                + "( const " + p.getBasename() + "_wrapper& );");
+        ps.printPrefixln("DOLProcess _process;");
+        ps.printPrefixln("int _detached;");
+        ps.printRightBracket();
+        ps.printPrefixln(";");
+        ps.printPrefixln("#endif");
+    }
+
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/hdsd/HdsdScriptVisitor.java b/dol/src/dol/visitor/hdsd/HdsdScriptVisitor.java
new file mode 100644 (file)
index 0000000..322cb77
--- /dev/null
@@ -0,0 +1,376 @@
+package dol.visitor.hdsd;
+
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import dol.datamodel.architecture.Configuration;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.main.UserInterface;
+import dol.util.CodePrintStream;
+import dol.visitor.MapVisitor;
+
+/**
+ *  Visitor that is used to generate a shell script to
+ *  distribute, run, monitor, profile and clean up a distributed
+ *  simulation.
+ */
+public class HdsdScriptVisitor extends MapVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of the shell script
+     */
+    public HdsdScriptVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * Create the shell script for the given mapping.
+     *
+     * @param x mapping that needs to be rendered.
+     */
+    public void visitComponent(Mapping x) {
+        try {
+            String filename = _dir + "/" + "scd.sh";
+            OutputStream file = new FileOutputStream(filename);
+            CodePrintStream ps = new CodePrintStream(file);
+
+            List<Processor> pList = x.getProcessorList();
+            int numProcessors = pList.size();
+            
+            // arrays to hold strings for generation
+            String[] hNames = new String[numProcessors];
+            String[] hAddrs = new String[numProcessors];
+            String[] hDirs = new String[numProcessors];
+            String[] hUsers = new String[numProcessors];
+            
+            // get processor information and fill to string arrays
+            int numSlaves = 0;
+            Iterator<Processor> iter = pList.iterator();
+            while (iter.hasNext())
+            {
+                Processor p = iter.next();
+                int pIdx = numSlaves;
+                boolean master = false;
+                Configuration c = p.getCfg("master"); 
+                if (c != null && c.getValue().equals("true"))
+                    master = true;
+                
+                // if it is the master, it will be the last processor
+                if (master)
+                    pIdx = numProcessors-1;
+                
+                // fill information to string arrays
+                hNames[pIdx] = p.getName();
+                hAddrs[pIdx] = p.getCfg("address").getValue();
+                c = p.getCfg("basedir");
+                if (c != null)
+                {
+                    String dir = c.getValue();
+                    // remove tailing '/'
+                    if ( dir.endsWith("/") )
+                        dir = dir.replaceAll("/" + "$", "");
+                    if (dir.equals(""))
+                        hDirs[pIdx] = hNames[pIdx];
+                    else
+                        hDirs[pIdx] = dir + "/" + hNames[pIdx];
+                }
+                else
+                    hDirs[pIdx] = hNames[pIdx];
+                c = p.getCfg("username");
+                if (c != null)
+                    hUsers[pIdx] = c.getValue() + "@";
+                else
+                    hUsers[pIdx] = "";
+                
+                if (!master)
+                    numSlaves++;
+            } // end get and fill information
+            
+            /* generate script */
+            // head
+            ps.println("#!/bin/bash");
+            ps.println();
+            ps.println("SCRIPTNAME=\"`echo $0 | sed 's/.*\\///'`\"");
+            ps.println();
+            
+            // host configuration
+            ps.println("### host configuration");
+            ps.print("NAME=( ");
+            for (int i=0; i<numProcessors; i++)
+                ps.print("\"" + hNames[i] + "\" ");
+            ps.println(")");
+            ps.print("ADDR=( ");
+            for (int i=0; i<numProcessors; i++)
+                ps.print("\"" + hAddrs[i] + "\" ");
+            ps.println(")");
+            ps.print("DIR=( ");
+            for (int i=0; i<numProcessors; i++)
+                ps.print("\"" + hDirs[i] + "\" ");
+            ps.println(")");
+            ps.print("USER=( ");
+            for (int i=0; i<numProcessors; i++)
+                ps.print("\"" + hUsers[i] + "\" ");
+            ps.println(")");
+            ps.println();
+
+            // paths
+            ps.println("### dol classpath");
+            ps.println("DOLPATH=\"" + _ui.getDOLPath() + "\"");
+            ps.println("CLASSPATH=\"${DOLPATH}/jars/jdom.jar:"
+                    + "${DOLPATH}/jars/xercesImpl.jar:"
+                    + "${DOLPATH}/build/bin/main\"");
+            ps.println("export CLASSPATH");
+            ps.println();
+            ps.println("### systemcd path");
+            ps.println("SCDPATH=\"" + System.getProperty("user.dir")
+                    + "/" + _dir + "\"");
+            ps.println();
+            
+            // function usage
+            ps.println("### function declarations");
+            ps.println();
+            ps.println("# function: prints usage information");
+            ps.println("function usage()");
+            ps.println("{");
+            ps.prefixInc();
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo \"Usage: ${SCRIPTNAME} COMMAND [OPTION]\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"distribute\\tdistributes the binaries to the simulators\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"run\\t\\truns the simulation and prints stdout of the master\"");
+                ps.printPrefixln("echo -e \"\\t\\tall stdouts are written to stdout_NETSIM.txt\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"check\\t\\tchecks which simulators are still active\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"kill\\t\\tkills all simulators\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"profile PN.xml\\tretrieves the profiles from the simulators,\" \\");
+                ps.prefixInc();
+                    ps.printPrefixln("\"processes them and\"");
+                ps.prefixDec();
+                ps.printPrefixln("echo -e \"\\t\\tstores the cumulative results in PN_annotaded.xml\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"cleanup\\t\\tremoves the simulation directory on all simulators\"");
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo -e \"help, -h\\tprints this help\"");
+                ps.printPrefixln("echo");
+            ps.prefixDec();
+            ps.println("}");
+            ps.println();
+
+            // function profile
+            ps.println("# function: adds profiling information of one simulator to xml");
+            ps.println("function profile()");
+            ps.println("{");
+            ps.prefixInc();
+                ps.printPrefixln("echo \"Retrieving profile from ${ADDR[$1]}\"");
+                ps.printPrefixln("scp ${USER[$1]}${ADDR[$1]}:${DIR[$1]}/profile_${NAME[$1]}.txt .");
+                ps.printPrefixln("if [ $? -ne 0 ]; then");
+                ps.prefixInc();
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"Retrieving profile from ${NAME[$1]} failed!\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("rm scd_tmp_profiled.xml");
+                    ps.printPrefixln("exit 1");
+                ps.prefixDec();
+                ps.printPrefixln("fi");
+                ps.printPrefixln("echo \"Profiling ${NAME[$1]}\"");
+                ps.printPrefixln("java dol.main.Main -P scd_tmp_profiled.xml -T profile_${NAME[$1]}.txt > scd_profilerout.txt 2>&1");
+                ps.printPrefixln("if [ $? -ne 0 ]; then");
+                ps.prefixInc();
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"Profiling ${NAME[$1]} failed!\"");
+                    ps.printPrefixln("echo \"Check scd_tmp_profilerout.txt for more information.\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("rm scd_tmp_profiled.xml");
+                    ps.printPrefixln("exit 1");
+                ps.prefixDec();
+                ps.printPrefixln("fi");
+                ps.printPrefixln("rm scd_profilerout.txt");
+                ps.printPrefixln("mv scd_tmp_profiled_annotated.xml scd_tmp_profiled.xml");
+                ps.printPrefixln("rm profile_${NAME[$1]}.txt");
+            ps.prefixDec();
+            ps.println("}");
+            ps.println();
+
+            // main programm start
+            ps.println("### main program");
+            ps.println();
+            ps.println("# require at least one argument");
+            ps.println("if [ ! $# -ge 1 ]; then");
+            ps.prefixInc();
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo \"Error: At least one argument is required!\"");
+                ps.printPrefixln("usage");
+                ps.printPrefixln("exit 1");
+            ps.prefixDec();
+            ps.println("fi");
+            ps.println();
+            ps.println("# switch on operation");
+            ps.println("case \"$1\" in");
+            
+            // distribute binaries to simulators
+            ps.println("\"distribute\")");
+            ps.prefixInc();
+                ps.printPrefixln("echo \"Distributing binaries to simulators...\"");
+                ps.printPrefixln("# prepare directories");
+                for (int i=0; i<numProcessors; i++)
+                    ps.printPrefixln("ssh ${USER[" + i + "]}${ADDR[" + i
+                            + "]} \"test -d ${DIR[" + i + "]} || mkdir -p "
+                            + "${DIR[" + i + "]}\"");
+                ps.printPrefixln("# copy files");
+                for (int i=0; i<numProcessors; i++)
+                    ps.printPrefixln("scp ${SCDPATH}/scd_${NAME[" + i
+                            + "]} ${USER[" + i + "]}${ADDR[" + i
+                            + "]}:${DIR[" + i + "]}/");
+            ps.prefixDec();
+            ps.println(";;");
+            
+            // run the simulation
+            ps.println("\"run\")");
+            ps.prefixInc();
+                ps.printPrefixln("echo \"Running simulation...\"");
+                for (int i=0; i<numProcessors-1; i++)
+                    ps.printPrefixln("ssh ${USER[" + i + "]}${ADDR[" + i
+                            + "]}  \"cd ${DIR[" + i + "]}; ./scd_${NAME["
+                            + i + "]}\" > stdout_${NAME[" + i + "]}.txt 2>&1 &");
+                ps.printPrefixln("ssh ${USER[" + (numProcessors-1)
+                        + "]}${ADDR[" + (numProcessors-1)
+                        + "]}  \"cd ${DIR[" + (numProcessors-1)
+                        + "]}; ./scd_${NAME[" + (numProcessors-1)
+                        + "]}\" 2>&1 | tee stdout_${NAME["
+                        + (numProcessors-1) + "]}.txt");
+            ps.prefixDec();
+            ps.println(";;");
+            
+            // check if simulators are running
+            ps.println("\"check\")");
+            ps.prefixInc();
+                ps.printPrefixln("echo \"Checking which simulators are active...\"");
+                for (int i=0; i<numProcessors; i++)
+                    ps.printPrefixln("ssh ${USER[" + i + "]}${ADDR[" + i + "]} \"pgrep -x scd_${NAME[" + i + "]} > /dev/null && echo ${NAME[" + i + "]} is active || echo ${NAME[" + i + "]} is not active\"");
+            ps.prefixDec();
+            ps.println(";;");
+            
+            // kill all simulators
+            ps.println("\"kill\")");
+            ps.prefixInc();
+                ps.printPrefixln("echo \"Killing all simulators...\"");
+                for (int i=0; i<numProcessors; i++)
+                    ps.printPrefixln("ssh ${USER[" + i + "]}${ADDR[" + i + "]} \"killall -e scd_${NAME[" + i + "]}\"");
+            ps.prefixDec();
+            ps.println(";;");
+            
+            // get and process profiles
+            ps.println("\"profile\")");
+            ps.prefixInc();
+                ps.printPrefixln("# require 2 arguments");
+                ps.printPrefixln("if [ $# -ne 2 ]; then");
+                ps.prefixInc();
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"Error: Illegal number of arguments!\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"Usage: ${SCRIPTNAME} profile processnetwork.xml\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("exit 1");
+                ps.prefixDec();
+                ps.printPrefixln("fi");
+                ps.println();
+                ps.printPrefixln("# check if process nework file exists");
+                ps.printPrefixln("if [ ! -f \"$2\" ]; then");
+                ps.prefixInc();
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"Error: File not found!\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("exit 1");
+                ps.prefixDec();
+                ps.printPrefixln("fi");
+                ps.println();
+                ps.printPrefixln("# check file extension");
+                ps.printPrefixln("echo $2 | grep -e '\\.xml$' > /dev/null");
+                ps.printPrefixln("if [ $? -ne 0 ]; then");
+                ps.prefixInc();
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"Error: Illegal file extension: required .xml!\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("exit 1");
+                ps.prefixDec();
+                ps.printPrefixln("fi");
+                ps.println();
+                ps.printPrefixln("PFILE=`echo $2 | sed 's/.*\\///' | sed 's/\\.xml$/_annotated.xml/'`");
+                ps.printPrefixln("echo \"Profiling into ${PFILE}...\"");
+                ps.println();
+                ps.printPrefixln("# check that the DOL is found and the classpath set correctly");
+                ps.printPrefixln("java dol.main.Main > /dev/null 2>&1");
+                ps.printPrefixln("if [ $? -eq 1 ]; then");
+                ps.prefixInc();
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("echo \"DOL framework not found!\"");
+                    ps.printPrefixln("echo");
+                    ps.printPrefixln("exit 1");
+                ps.prefixDec();
+                ps.printPrefixln("fi");
+                ps.printPrefixln("cp \"$2\" scd_tmp_profiled.xml");
+                ps.println();
+                for (int i=0; i<numProcessors; i++)
+                    ps.printPrefixln("profile " + i);
+                ps.println();
+                ps.printPrefixln("mv scd_tmp_profiled.xml \"${PFILE}\""); 
+            ps.prefixDec();
+            ps.println(";;");
+            
+            // deleting remote files
+            ps.printPrefixln("\"cleanup\")");
+            ps.prefixInc();
+                ps.printPrefixln("echo \"Deleting simulator directory on simulators...\"");
+                for (int i=0; i<numProcessors; i++)
+                    ps.printPrefixln("ssh ${USER[" + i + "]}${ADDR[" + i
+                            + "]} \"rm -r ${DIR[" + i + "]}\"");
+            ps.prefixDec();
+            ps.println(";;");
+            
+            // tail
+            ps.println("\"help\")");
+            ps.prefixInc();
+                ps.printPrefixln("usage");
+            ps.prefixDec();
+            ps.println(";;");
+            ps.println("\"-h\")");
+            ps.prefixInc();
+                ps.printPrefixln("usage");
+            ps.prefixDec();
+            ps.println(";;");
+            ps.println("\"--help\")");
+            ps.prefixInc();
+                ps.printPrefixln("usage");
+            ps.prefixDec();
+            ps.println(";;");
+            ps.println("*)");
+            ps.prefixInc();
+                ps.printPrefixln("echo");
+                ps.printPrefixln("echo \"Error: Illegal command: $1\"");
+                ps.printPrefixln("usage");
+                ps.printPrefixln("exit 1");
+            ps.prefixDec();
+            ps.println(";;");
+            ps.println("esac");
+
+        } catch (Exception e) {
+            System.out.println("HdsdMakefileVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+
+    } // end visitor
+
+    protected String _dir = null;
+    protected UserInterface _ui = UserInterface.getInstance();
+}
+
diff --git a/dol/src/dol/visitor/hdsd/HdsdVisitor.java b/dol/src/dol/visitor/hdsd/HdsdVisitor.java
new file mode 100644 (file)
index 0000000..56421b8
--- /dev/null
@@ -0,0 +1,113 @@
+package dol.visitor.hdsd;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import dol.datamodel.mapping.Mapping;
+import dol.util.CodePrintStream;
+import dol.util.Copier;
+import dol.visitor.MapVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a HdS package with distributed simulation support.
+ */
+public class HdsdVisitor extends MapVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param packageName name of the HdSd directory
+     */
+    public HdsdVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     *
+     * @param x mapping that needs to be rendered.
+     */
+    public void visitComponent(Mapping x) {
+        try {
+            _generateDirHierarchy();
+
+            x.accept(new HdsdMakefileVisitor(_srcDir));
+            x.accept(new HdsdModuleVisitor(_srcDir));
+            x.getPN().accept(new HdsdProcessVisitor(_wrapperDir));
+            x.accept(new HdsdScriptVisitor(_srcDir));
+        }
+        catch (Exception e) {
+            System.out.println("HdSdVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _generateDirHierarchy()
+        throws IOException, FileNotFoundException {
+        File dir = new File(_packageName);
+        dir.mkdirs();
+
+        _srcDir = _packageName + "/" + _srcDirName;
+        dir = new File(_srcDir);
+        dir.mkdirs();
+
+        _libDir = _srcDir + "/" + _libDirName;
+        dir = new File(_libDir);
+        dir.mkdirs();
+        
+        _scdDir = _srcDir + "/" + _scdDirName;
+        dir = new File(_scdDir);
+        dir.mkdirs();
+
+        _processDir = _srcDir + "/" + _processDirName;
+        dir = new File(_processDir);
+        dir.mkdirs();
+
+        _wrapperDir = _srcDir + "/" + _wrapperDirName;
+        dir = new File(_wrapperDir);
+        dir.mkdirs();
+
+        //copy library files
+        String sdir = _ui.getVisitorDir() + "hdsd" + "/" + "lib";
+        File source = new File(sdir);
+        File destination = new File(_libDir);
+        new Copier().copy(source, destination);
+        
+        // copy scd library files
+        sdir = _ui.getVisitorDir() + "hdsd" + "/" + "scd";
+        source = new File(sdir);
+        destination = new File(_scdDir);
+        new Copier().copy(source, destination);
+
+        //copy process source code
+        source = new File(_srcDirName);
+        destination = new File(_processDir);
+        new Copier().copy(source, destination);
+    }
+
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+
+    protected String _libDir = "";
+    protected static String _libDirName = "lib";
+    
+    protected String _scdDir = "";
+    protected static String _scdDirName = "scd";
+
+    protected String _processDir = "";
+    protected static String _processDirName = "processes";
+
+    protected String _wrapperDir = "";
+    protected static String _wrapperDirName = "sc_wrappers";
+
+    protected String _threadPostfix = "_thread";
+
+    protected CodePrintStream _mainPS = null;
+}
diff --git a/dol/src/dol/visitor/hdsd/lib/dol.c b/dol/src/dol/visitor/hdsd/lib/dol.c
new file mode 100644 (file)
index 0000000..8945c8b
--- /dev/null
@@ -0,0 +1,42 @@
+#include "dol.h"
+
+/**
+ * Gets an index of a string, where the index must be separated by
+ * a character specified in tokens.
+ * Returns -1, when an error occurs.
+ *
+ * Example:
+ * getIndex("name_1_2", "_", 0) will return 1.
+ * getIndex("name_1_2", "_", 1) will return 2.
+ *
+ * @param string string to parse
+ * @param tokens delimiter of indices
+ * @param indexNumber position of index (starting at 0)
+ */
+int getIndex(const char* string, char* tokens, int indexNumber) {
+  char* string_copy;
+  char* token_pointer;
+  int index = 0;
+
+  string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));
+  if (!string_copy) {
+    fprintf(stderr, "getIndex(): could not allocate memory.\n");
+    return -1;
+  }
+
+  strcpy(string_copy, string);
+
+  token_pointer = strtok(string_copy, tokens);
+  do {
+    token_pointer = strtok(NULL, tokens);
+    index++;
+  } while (index <= indexNumber && token_pointer != 0);
+
+  if (token_pointer) {
+    index = atoi(token_pointer);
+    free(string_copy);
+    return index;
+  }
+
+  return -1;
+}
diff --git a/dol/src/dol/visitor/hdsd/lib/dol.h b/dol/src/dol/visitor/hdsd/lib/dol.h
new file mode 100644 (file)
index 0000000..8e99671
--- /dev/null
@@ -0,0 +1,141 @@
+#ifndef DOL_H
+#define DOL_H
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __DOL_ETHZ_GEN__
+#include <systemc>
+using sc_core::sc_port;
+#endif
+
+/************************************************************************
+ * do not add code to this header
+ ************************************************************************/
+
+/**
+ *  Define the DOL process handler scheme.
+ *  - Local variables are defined in structure LocalState. Local
+ *    variables may vary from different processes.
+ *  - The ProcessInit function pointer points to a function which
+ *    initializes a process.
+ *  - The ProcessFire function pointer points to a function which
+ *    performs the actual computation. The communication between
+ *    processes is inside the ProcessFire function.
+ *  - The WPTR is a placeholder for callback. One can just
+ *    leave it blank.
+ */
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//additional behavioral functions could be declared here
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+//process handler
+struct _process;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr; //placeholder for wrapper instance
+} DOLProcess;
+
+
+//macros to deal with iterated ports
+/**
+ ******************************************************
+ * The HdS code is needed to replace the current ETHZ *
+ * implementation.                                    *
+ ******************************************************
+ *
+ * Macro to create a variable to store a port name.
+ *
+ * @param name name of the variable
+ */
+#ifdef __DOL_ETHZ_GEN__
+#define CREATEPORTVAR(name) sc_port<sc_interface> *name
+#else
+#define  CREATEPORTVAR(name) // Hds Code
+#endif
+
+/**
+ * Create the port name of an iterated port based on its basename and the
+ * given indices.
+ *
+ * @param port buffer where the result is stored (created using
+ *             CREATEPORTVAR)
+ * @param base basename of the port
+ * @param number_of_indices number of dimensions of the port
+ * @param index_range_pairs index and range values for each dimension
+ */
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \
+  createPort(&port, base, number_of_indices, index_range_pairs)
+
+int getIndex(const char* string, char* tokens, int indexNumber);
+
+/*
+ ******************************************************
+ * The HdS code is needed to replace the current ETHZ *
+ * implementation.                                    *
+ ******************************************************
+ */
+#ifdef __DOL_ETHZ_GEN__
+template <class interface>
+sc_port<interface> *createPort(sc_port<interface> **port,
+                               void *base,
+                               int number_of_indices,
+                               int index0, int range0) {
+    *port = &((static_cast<sc_port<interface> *>(base))[index0]);
+    return &((static_cast<sc_port<interface> *>(base))[index0]);
+}
+
+template <class interface>
+sc_port<interface> *createPort(sc_port<interface> **port,
+                               void *base,
+                               int number_of_indices,
+                               int index0, int range0,
+                               int index1, int range1) {
+    *port = &((static_cast<sc_port<interface> *>(base))[
+            index0 * range1 + index1]);
+    return &((static_cast<sc_port<interface> *>(base))[
+            index0 * range1 + index1]);
+}
+
+template <class interface>
+sc_port<interface> *createPort(sc_port<interface> **port,
+                               void *base,
+                               int number_of_indices,
+                               int index0, int range0,
+                               int index1, int range1,
+                               int index2, int range2) {
+    *port = &((static_cast<sc_port<interface> *>(base))[
+            index0 * range1 * range2 + index1 * range0 + index2]);
+    return &((static_cast<sc_port<interface> *>(base))[
+            index0 * range1 * range2 + index1 * range0 + index2]);
+}
+
+template <class interface>
+sc_port<interface> *createPort(sc_port<interface> **port,
+                               void *base,
+                               int number_of_indices,
+                               int index0, int range0,
+                               int index1, int range1,
+                               int index2, int range2,
+                               int index3, int range3) {
+    *port = &((static_cast<sc_port<interface> *>(base))[
+            index0 * range1 * range2 * range3
+            + index1 * range2 * range3 + index2 * range3 + index3]);
+    return &((static_cast<sc_port<interface> *>(base))[
+            index0 * range1 * range2 * range3
+            + index1 * range2 * range3 + index2 * range3 + index3]);
+}
+#else
+#define createPort() //HdS code
+#endif
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/lib/dol_sched_if.h b/dol/src/dol/visitor/hdsd/lib/dol_sched_if.h
new file mode 100644 (file)
index 0000000..d861b1e
--- /dev/null
@@ -0,0 +1,43 @@
+/**************************************************************************\r
+       dol_sched_if.h\r
\r
+       Scheduler interface for a DOL process    \r
+\r
+       (c) 2006 by Alexander Maxiaguine <maxiagui@tik.ee.ethz.ch>\r
+\r
+       Computer Engineering and Networks Laboratory, TIK\r
+       Swiss Federal Institute of Technology, ETHZ Zurich \r
+       Switzerland\r
+\r
+**************************************************************************/\r
+\r
+/**************************************************************************\r
+       Change Log:\r
+\r
+       14.03.06 -- creation\r
+\r
+**************************************************************************/\r
+\r
+#ifndef DOL_SCHED_IF_H\r
+#define DOL_SCHED_IF_H\r
+\r
+class dol_sched_if \r
+{\r
+\r
+public:\r
+       virtual void initialize() = 0;\r
+       virtual int fire() = 0;\r
+\r
+\r
+protected:\r
+       dol_sched_if()  {}\r
+\r
+\r
+private:\r
+\r
+    // disabled\r
+    dol_sched_if( const dol_sched_if& );\r
+    dol_sched_if& operator = ( const dol_sched_if& );\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/hdsd/lib/simple_fifo.h b/dol/src/dol/visitor/hdsd/lib/simple_fifo.h
new file mode 100644 (file)
index 0000000..b070b8b
--- /dev/null
@@ -0,0 +1,186 @@
+/*****************************************************************************
+
+  The following code is derived, directly or indirectly, from the SystemC
+  source code Copyright (c) 1996-2004 by all Contributors.
+  All Rights reserved.
+
+  The contents of this file are subject to the restrictions and limitations
+  set forth in the SystemC Open Source License Version 2.4 (the "License");
+  You may not use this file except in compliance with such restrictions and
+  limitations. You may obtain instructions on how to receive a copy of the
+  License at http://www.systemc.org/. Software distributed by Contributors
+  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
+  ANY KIND, either express or implied. See the License for the specific
+  language governing rights and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  simple_fifo.cpp -- Simple SystemC 2.0 producer/consumer example.
+
+                     From "An Introduction to System Level Modeling in
+                     SystemC 2.0". By Stuart Swan, Cadence Design Systems.
+                     Available at www.systemc.org
+
+  Original Author: Stuart Swan, Cadence Design Systems, 2001-06-18
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+#ifndef _SIMPLE_FIFO_H_
+#define _SIMPLE_FIFO_H_
+
+#include <systemc>
+using sc_core::sc_interface;
+using sc_core::sc_channel;
+using sc_core::sc_event;
+using sc_core::sc_module_name;
+
+class write_if : virtual public sc_interface
+{
+   public:
+     virtual void write(char) = 0;
+     virtual void reset() = 0;
+     virtual int wtest(int) = 0;
+};
+
+class read_if : virtual public sc_interface
+{
+   public:
+     virtual void read(char &) = 0;
+     virtual int num_available() = 0;
+     virtual int rtest(int) = 0;
+};
+
+class fifo : public sc_channel, public write_if, public read_if
+{
+   public:
+     fifo(sc_module_name name, int size)
+         : sc_channel(name), num_elements(0), first(0), max(size) {
+         data = new char[size];
+     }
+
+     void write(char c) {
+       if (num_elements == max)
+         wait(read_event);
+
+       data[(first + num_elements) % max] = c;
+       ++ num_elements;
+       write_event.notify();
+     }
+
+     void read(char &c){
+       if (num_elements == 0)
+         wait(write_event);
+
+       c = data[first];
+       -- num_elements;
+       first = (first + 1) % max;
+       read_event.notify();
+     }
+
+     int rtest(int size) { return (size <= num_elements) ? 1 : 0; }
+     int wtest(int size) { return (size <= max - num_elements) ? 1 : 0; }
+
+    
+     void reset() { num_elements = first = 0; }
+
+     int num_available() { return num_elements;}
+
+   private:
+     int max;
+     char *data;
+     int num_elements, first;
+     sc_event write_event, read_event;
+};
+
+
+#endif
+
+/*
+class producer : public sc_module
+{
+   public:
+     sc_port<write_if> out;
+
+     SC_HAS_PROCESS(producer);
+
+     producer(sc_module_name name) : sc_module(name)
+     {
+       SC_THREAD(main);
+     }
+
+     void main()
+     {
+       const char *str =
+         "Visit www.systemc.org and see what SystemC can do for you today!\n";
+
+       while (*str)
+         out->write(*str++);
+     }
+};
+
+class consumer : public sc_module
+{
+   public:
+     sc_port<read_if> in;
+
+     SC_HAS_PROCESS(consumer);
+
+     consumer(sc_module_name name) : sc_module(name)
+     {
+       SC_THREAD(main);
+     }
+
+     void main()
+     {
+       char c;
+       cout << endl << endl;
+
+       while (true) {
+         in->read(c);
+         cout << c << flush;
+
+         if (in->num_available() == 1)
+          cout << "<1>" << flush;
+         if (in->num_available() == 9)
+          cout << "<9>" << flush;
+       }
+     }
+};
+
+class top : public sc_module
+{
+   public:
+     fifo *fifo_inst;
+     producer *prod_inst;
+     consumer *cons_inst;
+
+     top(sc_module_name name) : sc_module(name)
+     {
+       fifo_inst = new fifo("Fifo1");
+
+       prod_inst = new producer("Producer1");
+       prod_inst->out(*fifo_inst);
+
+       cons_inst = new consumer("Consumer1");
+       cons_inst->in(*fifo_inst);
+     }
+};
+
+int sc_main (int argc , char *argv[]) {
+   top top1("Top1");
+   sc_start(-1);
+   return 0;
+}
+*/
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm.cpp
new file mode 100644 (file)
index 0000000..68fc296
--- /dev/null
@@ -0,0 +1,30 @@
+#include "fsm/scd_cont_fsm.h"
+
+#include "scd_logging.h"
+#include "scd_cont_state.h"
+
+
+void scd_cont_fsm::set_state(scd_cont_state& state)
+{
+    _state = &state;
+    scd_debug(_name + ": [" + _state->get_name() +"]");
+}
+
+
+void scd_cont_fsm::save_state()
+{
+    _hist_state = _state;
+}
+
+
+void scd_cont_fsm::save_state(scd_cont_state& state)
+{
+    _hist_state = &state;
+}
+
+
+void scd_cont_fsm::load_state()
+{
+    _state = _hist_state;
+    scd_debug(_name + ": [" + _state->get_name() +"]");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm.h
new file mode 100644 (file)
index 0000000..f5d2eb4
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef SCD_CONT_FSM_H
+#define SCD_CONT_FSM_H
+
+#include <string>
+
+/* forward declaration */
+class scd_cont_state;
+
+
+/**
+ * FSM base class. Holds the current and the history state and allows
+ * state transitions. Transitions are logged in debug loglevel.
+ */
+class scd_cont_fsm
+{
+
+public:
+    /**
+     * Constructor.
+     * \param name the name of the state machine
+     */
+    scd_cont_fsm(const std::string& name): _name(name) {}
+
+    virtual ~scd_cont_fsm() {}
+
+    /**
+     * Sets a new state. This is a state transition.
+     */
+    void set_state(scd_cont_state& state);
+
+    /**
+     * Saves the current state as the history state. This is not a state
+     * transition.
+     */
+    void save_state();
+
+    /**
+     * Saves a specified state as the history state. This is not a state
+     * transition.
+     */
+    void save_state(scd_cont_state& state);
+
+    /**
+     * Restores the saved history state. This is a state transition.
+     */
+    void load_state();
+
+protected:
+    scd_cont_state* _state;
+    scd_cont_state* _hist_state;
+    std::string _name;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm_if.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_fsm_if.h
new file mode 100644 (file)
index 0000000..b8897a5
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef SCD_CONT_FSM_IF_H
+#define SCD_CONT_FSM_IF_H
+
+#include "systemc"
+
+
+/**
+ * Public interface for control manager state machines (master, slave, slave
+ * wrapper).
+ */
+class scd_cont_fsm_if
+{
+public:
+    virtual ~scd_cont_fsm_if() {}
+
+    /**
+     * Signalize the FSM that the simulation is idle and the next event
+     * is in a specific amount of time (relative).
+     * \param time time of next event relative to current time
+     */
+    virtual void set_idle(const sc_core::sc_time& time) = 0;
+
+    /**
+     * Signalizes the FSM that the simulation can be run.
+     */
+    virtual void set_busy() = 0;
+
+    /**
+     * Signalizes the FSM that the simulation on this simulator has finished.
+     * No more events exist right now.
+     */
+    virtual void set_done() = 0;
+
+    /**
+     * Signalizes the FSM that an error has occured and the simulation
+     * has to be brought down.
+     */
+    virtual void set_fail() = 0;
+
+    /**
+     * Drives the control FSM. Shall be called repeatedly (i.e. from the
+     * main loop).
+     */
+    virtual void process() = 0;
+
+    /**
+     * Indicates if the FSM is initiated and still working.
+     * \return true if the state is not init, terminated or failed
+     */
+    virtual bool active() const = 0;
+
+    /**
+     * Indicates if another step should be simulated (i.e. the FSM is in
+     * the busy state).
+     * \return true if the FSM is in busy state
+     */
+    virtual bool busy() const = 0;
+
+    /**
+     * Indicates if the FSM is in the failed state.
+     * \return false if an error occured and the FSM stopped working
+     */
+    virtual bool failed() const = 0;
+
+    /**
+     * Indicates if simulation time has to be advanced (i.e. the FSM
+     * is in the time state). If this is the case, the time step
+     * shall be obtained by calling get_time_step().
+     * \return true if the time has to be advanced
+     */
+    virtual bool advance_time() const = 0;
+
+    /**
+     * Returns the time step by which the simulation time has to be advanced.
+     * Shall only be called in time state.
+     */
+    virtual const sc_core::sc_time& get_time_step() = 0;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_state.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_state.h
new file mode 100644 (file)
index 0000000..82e09d3
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef SCD_CONT_STATE_H
+#define SCD_CONT_STATE_H
+
+#include <string>
+
+#include "scd_simulator.h"
+#include "fsm/scd_cont_fsm_if.h"
+
+
+/* forward declaration */
+class scd_simulator;
+
+
+/**
+ * Base class of all FSM states.
+ */
+class scd_cont_state : public scd_cont_fsm_if
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     */
+    scd_cont_state(scd_simulator& sim): _sim(sim) {}
+
+    virtual ~scd_cont_state() {}
+
+    /**
+     * Returns the name of the state.
+     */
+    const std::string& get_name() const { return _name; }
+
+protected:
+    scd_simulator& _sim;
+    std::string _name;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_wrapper_if.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_cont_wrapper_if.h
new file mode 100644 (file)
index 0000000..12d6f50
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef SCD_CONT_WRAPPER_IF_H
+#define SCD_CONT_WRAPPER_IF_H
+
+#include "systemc"
+
+
+/**
+ * Extends the public interface of the slave wrapper FSM.
+ */
+class scd_cont_wrapper_if
+{
+public:
+    /**
+     * Sends a time_req command to the slave.
+     */
+    virtual void send_time_req() = 0;
+
+    /**
+     * Sends a time_nack command to the slave.
+     */
+    virtual void send_time_nack() = 0;
+
+    /**
+     * Sends a time command to the slave.
+     */
+    virtual void send_time(const sc_core::sc_time& time) = 0;
+
+    /**
+     * Sends a term_req command to the slave.
+     */
+    virtual void send_term_req() = 0;
+
+    /**
+     * Sends a term_nack command to the slave.
+     */
+    virtual void send_term_nack() = 0;
+
+    /**
+     * Sends a term command to the slave.
+     */
+    virtual void send_term() = 0;
+
+    /**
+     * Inidcates if the slave is in term_req state.
+     * \return true if the slave seems to be in time_req state
+     */
+    virtual bool time_req() const = 0;
+
+    /**
+     * Inidcates if the slave is in time_ack state.
+     * \return true if the slave seems to be in time_ack state
+     */
+    virtual bool time_ack() const = 0;
+
+    /**
+     * Inidcates if the slave is in term_req state.
+     * \return true if the slave seems to be in term_req state
+     */
+    virtual bool term_req() const = 0;
+
+    /**
+     * Inidcates if the slave is in term_ack state.
+     * \return true if the slave seems to be in term_ack state
+     */
+    virtual bool term_ack() const = 0;
+
+    /**
+     * Inidcates if the slave is in idle state.
+     * \return true if the slave seems to be in idle state
+     */
+    virtual bool idle() const = 0;
+
+    /**
+     * Indicates if the slave is in done state.
+     * \return true if the slave seems to be in done state
+     */
+    virtual bool done() const = 0;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_base.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_base.cpp
new file mode 100644 (file)
index 0000000..a0175a3
--- /dev/null
@@ -0,0 +1,103 @@
+#include "fsm/scd_stm_base.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+#include "scd_command.h"
+#include "scd_cont_man.h"
+
+
+scd_stm_base::scd_stm_base(scd_simulator& sim, scd_cont_man_master& fsm):
+    scd_cont_state(sim), _fsm(fsm), _slaves(fsm._slaves),
+    _time_step(fsm._time_step),
+    _st_init(fsm._st_init), _st_busy(fsm._st_busy), _st_idle(fsm._st_idle),
+    _st_done(fsm._st_done), _st_time_req(fsm._st_time_req),
+    _st_time(fsm._st_time), _st_term_req(fsm._st_term_req),
+    _st_terminate(fsm._st_terminate), _st_terminated(fsm._st_terminated),
+    _st_fail(fsm._st_fail), _st_failed(fsm._st_failed)
+{
+}
+
+
+void scd_stm_base::set_fail()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator it;
+
+    for (it = _slaves.begin(); it != _slaves.end(); it++)
+    {
+        (*it)->set_fail();
+    }
+
+    _fsm.set_state(_st_fail);
+} // set_fail()
+
+
+void scd_stm_base::process()
+{
+    // check for failed slaves and react
+    if (!_check_slaves())
+        return;
+}
+
+
+bool scd_stm_base::active() const { return true; }
+
+
+bool scd_stm_base::busy() const { return false; }
+
+
+bool scd_stm_base::failed() const { return false; }
+
+
+bool scd_stm_base::advance_time() const { return false; }
+
+
+const sc_core::sc_time& scd_stm_base::get_time_step()
+{
+    scd_error("illegal call to get_time_step()");
+    throw scd_exception("illegal call");
+}
+
+
+bool scd_stm_base::_check_slaves()
+{
+
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if ( (*iter)->failed() )
+        {
+            scd_error("slave \"" + (*iter)->get_name() + "\" failed");
+            set_fail();
+            return false;
+        }
+    }
+
+    return true;
+
+} // _check_slaves()
+
+
+bool scd_stm_base::_some_slaves_active()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if ( (*iter)->active() )
+            return true;
+    }
+
+    return false;
+
+} // _some_slaves_active()
+
+
+void scd_stm_base::_close_slaves()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+        (*iter)->close();
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_base.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_base.h
new file mode 100644 (file)
index 0000000..6b8463f
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef SCD_STM_BASE_H
+#define SCD_STM_BASE_H
+
+#include <list>
+
+#include "scd_simulator.h"
+#include "scd_cont_slave_wrapper.h"
+#include "fsm/scd_cont_state.h"
+
+
+/* forward declaration */
+class scd_cont_man_master;
+
+
+/**
+ * Base class for all control master states.
+ */
+class scd_stm_base : public scd_cont_state
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     * \param fsm the FSM of this state
+     */
+    scd_stm_base(scd_simulator& sim, scd_cont_man_master& fsm);
+
+    virtual ~scd_stm_base() {}
+
+    /* scd_cont_fsm_if */
+    void set_busy() {}
+    void set_idle(const sc_core::sc_time& time) {}
+    void set_done() {}
+    void set_fail();
+    void process();
+    bool active() const;
+    bool busy() const;
+    bool failed() const;
+    bool advance_time() const;
+    const sc_core::sc_time& get_time_step();
+
+protected:
+    scd_cont_man_master& _fsm;
+    std::list<scd_cont_slave_wrapper*>& _slaves;
+    sc_core::sc_time& _time_step;
+    scd_cont_state& _st_init;
+    scd_cont_state& _st_busy;
+    scd_cont_state& _st_idle;
+    scd_cont_state& _st_done;
+    scd_cont_state& _st_time_req;
+    scd_cont_state& _st_time;
+    scd_cont_state& _st_term_req;
+    scd_cont_state& _st_terminate;
+    scd_cont_state& _st_terminated;
+    scd_cont_state& _st_fail;
+    scd_cont_state& _st_failed;
+
+    /* member functions */
+    bool _check_slaves();
+    bool _some_slaves_active();
+    void _close_slaves();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_busy.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_busy.cpp
new file mode 100644 (file)
index 0000000..fcb322c
--- /dev/null
@@ -0,0 +1,34 @@
+#include "fsm/scd_stm_busy.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_busy::set_idle(const sc_core::sc_time& time)
+{
+    /* prevents the situation where no events exist, but a huge
+     * ammount of data is being transferred that will generate events later
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    _time_step = time;
+    _fsm.set_state(_st_idle);
+}
+
+
+void scd_stm_busy::set_done()
+{
+    /* prevents the situation where no events exist, but a huge
+     * ammount of data is being transferred that will generate events later
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    _time_step = sc_core::SC_ZERO_TIME;
+    _fsm.set_state(_st_done);
+}
+
+
+bool scd_stm_busy::busy() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_busy.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_busy.h
new file mode 100644 (file)
index 0000000..ae9eb1d
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef SCD_STM_BUSY_H
+#define SCD_STM_BUSY_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_busy : public scd_stm_base
+{
+public:
+    scd_stm_busy(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "busy"; }
+    virtual ~scd_stm_busy() {}
+
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_done();
+    bool busy() const;
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.cpp
new file mode 100644 (file)
index 0000000..9d54d60
--- /dev/null
@@ -0,0 +1,64 @@
+#include "fsm/scd_stm_done.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_done::set_busy()
+{
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_stm_done::set_idle(const sc_core::sc_time& time)
+{
+    _time_step = time;
+    _fsm.set_state(_st_idle);
+}
+
+
+void scd_stm_done::process()
+{
+    if (!_check_slaves())
+        return;
+    
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+    bool terminate = true;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if (!(*iter)->idle() && !(*iter)->done())
+        {
+            // this slave is not ready yet
+            return;
+        }
+
+        if (!(*iter)->done())
+            terminate = false;
+    }
+
+    /* all slaves seem idle or done. wait a short moment, to prevent
+     * race conditions (channel data in transit but both endpoints done).
+     * if no socket activity occured we can move on, else we cancel.
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    if (terminate)
+    {
+        // all slaves seem to be done
+        for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+            (*iter)->send_term_req();
+        _fsm.save_state();
+        _fsm.set_state(_st_term_req);
+    }
+    else
+    {
+        // some slaves are not done yet
+        for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+            (*iter)->send_time_req();
+        _fsm.save_state();
+        _fsm.set_state(_st_time_req);
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_done.h
new file mode 100644 (file)
index 0000000..de20874
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SCD_STM_DONE_H
+#define SCD_STM_DONE_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_done : public scd_stm_base
+{
+public:
+    scd_stm_done(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "done"; }
+    virtual ~scd_stm_done() {}
+
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void process();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_fail.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_fail.cpp
new file mode 100644 (file)
index 0000000..53b13d3
--- /dev/null
@@ -0,0 +1,17 @@
+#include "fsm/scd_stm_fail.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_fail::process()
+{
+    if (!_some_slaves_active())
+    {
+        // all slaves have terminated
+        _sim.get_chan_man().close();
+        _close_slaves();
+        _fsm.set_state(_st_failed);
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_fail.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_fail.h
new file mode 100644 (file)
index 0000000..38b9e87
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SCD_STM_FAIL_H
+#define SCD_STM_FAIL_H
+
+#include "fsm/scd_stm_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_master;
+
+
+class scd_stm_fail : public scd_stm_base
+{
+public:
+    scd_stm_fail(scd_simulator& sim, scd_cont_man_master& fsm):
+        scd_stm_base(sim, fsm) { _name = "fail"; }
+
+    virtual ~scd_stm_fail() {}
+
+
+    /* scd_cont_fsm_if */
+    void set_fail() {}
+    void process();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_failed.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_failed.cpp
new file mode 100644 (file)
index 0000000..fd0cd9b
--- /dev/null
@@ -0,0 +1,10 @@
+#include "fsm/scd_stm_failed.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+bool scd_stm_failed::active() const { return false; }
+
+
+bool scd_stm_failed::failed() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_failed.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_failed.h
new file mode 100644 (file)
index 0000000..148a56b
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SCD_STM_FAILED_H
+#define SCD_STM_FAILED_H
+
+#include "fsm/scd_stm_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_master;
+
+
+class scd_stm_failed : public scd_stm_base
+{
+public:
+    scd_stm_failed(scd_simulator& sim, scd_cont_man_master& fsm):
+        scd_stm_base(sim, fsm) { _name = "failed"; }
+    virtual ~scd_stm_failed() {}
+
+    /* scd_cont_fsm_if */
+    void set_fail() {}
+    void process() {}
+    bool active() const;
+    bool failed() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_idle.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_idle.cpp
new file mode 100644 (file)
index 0000000..1138ab7
--- /dev/null
@@ -0,0 +1,50 @@
+#include "fsm/scd_stm_idle.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_idle::set_busy()
+{
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_stm_idle::set_done()
+{
+    _time_step = sc_core::SC_ZERO_TIME;
+    _fsm.set_state(_st_done);
+}
+
+
+void scd_stm_idle::process()
+{
+    if (!_check_slaves())
+        return;
+    
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if (!(*iter)->idle() && !(*iter)->done())
+        {
+            // this slave is not ready yet
+            return;
+        }
+    }
+
+    /* all slaves seem idle or done. wait a short moment, to prevent
+     * race conditions (channel data in transit but both endpoints done).
+     * if no socket activity occured we can move on, else we cancel.
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    // all slaves seem to be ready to advance time
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+        (*iter)->send_time_req();
+
+    _fsm.save_state();
+    _fsm.set_state(_st_time_req);
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_idle.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_idle.h
new file mode 100644 (file)
index 0000000..b19e4f0
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef SCD_STM_IDLE_H
+#define SCD_STM_IDLE_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_idle : public scd_stm_base
+{
+public:
+    scd_stm_idle(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "idle"; }
+    virtual ~scd_stm_idle() {}
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_done();
+    void process();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_init.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_init.cpp
new file mode 100644 (file)
index 0000000..3027ad8
--- /dev/null
@@ -0,0 +1,58 @@
+#include "fsm/scd_stm_init.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_init::set_idle(const sc_core::sc_time& time)
+{
+    scd_error("init: illegal call to set_idle()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stm_init::set_busy()
+{
+    scd_error("init: illegal call to set_busy()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stm_init::set_done()
+{
+    scd_error("init: illegal call to set_done()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stm_init::process()
+{
+    // check for failed slaves and react
+    if (!_check_slaves())
+        return;
+
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        // if this is still in init state we terminate
+        if ( !(*iter)->active() )
+            return;
+    }
+
+    // all slaves are active
+    scd_info("all slaves connected");
+    _fsm.set_state(_st_busy);
+
+} // process()
+
+
+bool scd_stm_init::active() const { return false; }
+
+
+bool scd_stm_init::advance_time() const
+{
+    scd_error("illegal call to advance_time()");
+    throw scd_exception("illegal call");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_init.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_init.h
new file mode 100644 (file)
index 0000000..b146a46
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef SCD_STM_INIT_H
+#define SCD_STM_INIT_H
+
+#include "fsm/scd_stm_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_master;
+
+
+class scd_stm_init : public scd_stm_base
+{
+public:
+    scd_stm_init(scd_simulator& sim, scd_cont_man_master& fsm):
+        scd_stm_base(sim, fsm) { _name = "init"; }
+    virtual ~scd_stm_init() {}
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_busy();
+    void set_done();
+    void process();
+    bool active() const;
+    bool advance_time() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_term_req.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_term_req.cpp
new file mode 100644 (file)
index 0000000..1d65952
--- /dev/null
@@ -0,0 +1,59 @@
+#include "fsm/scd_stm_term_req.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_term_req::set_busy()
+{
+    _send_term_nack();
+    _fsm.load_state();
+}
+
+
+void scd_stm_term_req::set_idle(const sc_core::sc_time& time)
+{
+    _send_term_nack();
+    _fsm.load_state();
+}
+
+
+void scd_stm_term_req::process()
+{
+    if (!_check_slaves())
+            return;
+
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if ( !(*iter)->term_req() && !(*iter)->term_ack() )
+        {
+            // received term_nack from this slave
+            _send_term_nack();
+            _fsm.load_state();
+            return;
+        }
+        else if ( !(*iter)->term_ack() )
+        {
+            // this slave did not respond yet
+            return;
+        }
+    }
+
+    // all slaves acknkowledged
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+        (*iter)->send_term();
+
+    _fsm.set_state(_st_terminate);
+}
+
+
+void scd_stm_term_req::_send_term_nack()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+        (*iter)->send_term_nack();
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_term_req.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_term_req.h
new file mode 100644 (file)
index 0000000..b93e082
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef SCD_STM_TERM_REQ_H
+#define SCD_STM_TERM_REQ_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_term_req : public scd_stm_base
+{
+public:
+    scd_stm_term_req(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "term_req"; }
+    virtual ~scd_stm_term_req() {}
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void process();
+
+private:
+    void _send_term_nack();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminate.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminate.cpp
new file mode 100644 (file)
index 0000000..3035321
--- /dev/null
@@ -0,0 +1,40 @@
+#include "fsm/scd_stm_terminate.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_terminate::set_busy()
+{
+    scd_error("received further events while terminating");
+    set_fail();
+}
+
+
+void scd_stm_terminate::set_idle(const sc_core::sc_time& time)
+{
+    scd_error("received future events while terminating");
+    set_fail();
+}
+
+
+void scd_stm_terminate::process()
+{
+    // check for failed slaves and react
+    if (!_check_slaves())
+        return;
+
+    if (_some_slaves_active())
+    {
+        // not all slaves have terminated yet
+        return;
+    }
+    else
+    {
+        // all slaves terminated
+        _sim.get_chan_man().close();
+        _close_slaves();
+        _fsm.set_state(_st_terminated);
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminate.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminate.h
new file mode 100644 (file)
index 0000000..f568d8c
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SCD_STM_TERMINATE_H
+#define SCD_STM_TERMINATE_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_terminate : public scd_stm_base
+{
+public:
+    scd_stm_terminate(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "terminate"; }
+    virtual ~scd_stm_terminate() {}
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void process();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminated.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminated.cpp
new file mode 100644 (file)
index 0000000..5d7e165
--- /dev/null
@@ -0,0 +1,8 @@
+#include "fsm/scd_stm_terminated.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+bool scd_stm_terminated::active() const { return false; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminated.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_terminated.h
new file mode 100644 (file)
index 0000000..2551b78
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SCD_STM_TERMINATED_H
+#define SCD_STM_TERMINATED_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_terminated : public scd_stm_base
+{
+public:
+    scd_stm_terminated(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "terminated"; }
+    virtual ~scd_stm_terminated() {}
+
+    /* scd_cont_fsm_if */
+    void set_fail() {}
+    void process() {}
+    bool active() const;
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time.cpp
new file mode 100644 (file)
index 0000000..89df203
--- /dev/null
@@ -0,0 +1,15 @@
+#include "fsm/scd_stm_time.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+bool scd_stm_time::advance_time() const { return true; }
+
+
+const sc_core::sc_time& scd_stm_time::get_time_step()
+{
+    _fsm.set_state(_st_busy);
+    return _time_step;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time.h
new file mode 100644 (file)
index 0000000..52e0a59
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef SCD_STM_TIME_H
+#define SCD_STM_TIME_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_time : public scd_stm_base
+{
+public:
+    scd_stm_time(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "time"; }
+    virtual ~scd_stm_time() {}
+
+    /* scd_cont_fsm_if */
+    bool advance_time() const;
+    const sc_core::sc_time& get_time_step();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time_req.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time_req.cpp
new file mode 100644 (file)
index 0000000..fb96b26
--- /dev/null
@@ -0,0 +1,64 @@
+#include "fsm/scd_stm_time_req.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_master.h"
+
+
+void scd_stm_time_req::set_busy()
+{
+    _send_time_nack();
+    _fsm.load_state();
+}
+
+
+void scd_stm_time_req::process()
+{
+    if (!_check_slaves())
+            return;
+
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+    sc_core::sc_time min_step = _time_step;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+    {
+        if ( !(*iter)->time_req() && !(*iter)->time_ack() )
+        {
+            // received time_nack from this slave
+            _send_time_nack();
+            _fsm.load_state();
+            return;
+        }
+        else if ( !(*iter)->time_ack() )
+        {
+            // this slave did not respond yet
+            return;
+        }
+        else
+        {
+            // received time_ack => search the smallest step
+            sc_core::sc_time time_slave = (*iter)->get_time_step();
+            if (min_step == sc_core::SC_ZERO_TIME)
+                min_step = time_slave;
+            else if (min_step > time_slave &&
+                    time_slave != sc_core::SC_ZERO_TIME)
+                min_step = time_slave;
+        }
+    }
+
+    // all slaves acknkowledged
+    _time_step = min_step;
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+        (*iter)->send_time(min_step);
+
+    _fsm.set_state(_st_time);
+}
+
+
+void scd_stm_time_req::_send_time_nack()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator iter;
+
+    for (iter = _slaves.begin(); iter != _slaves.end(); iter++)
+        (*iter)->send_time_nack();
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time_req.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stm_time_req.h
new file mode 100644 (file)
index 0000000..275bd95
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef SCD_STM_TIME_REQ_H
+#define SCD_STM_TIME_REQ_H
+
+#include "fsm/scd_stm_base.h"
+
+
+class scd_stm_time_req : public scd_stm_base
+{
+public:
+    scd_stm_time_req(scd_simulator& sim, scd_cont_man_master& fsm):
+       scd_stm_base(sim, fsm) { _name = "time_req"; }
+    virtual ~scd_stm_time_req() {}
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void process();
+
+private:
+    void _send_time_nack();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_base.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_base.cpp
new file mode 100644 (file)
index 0000000..b4d0af0
--- /dev/null
@@ -0,0 +1,81 @@
+#include "fsm/scd_sts_base.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+#include "scd_command.h"
+#include "scd_cont_man.h"
+
+
+
+scd_sts_base::scd_sts_base(scd_simulator& sim, scd_cont_man_slave& fsm):
+    scd_cont_state(sim), _fsm(fsm),
+    _st_init(fsm._st_init), _st_busy(fsm._st_busy), _st_idle(fsm._st_idle),
+    _st_done(fsm._st_done), _st_time_ack(fsm._st_time_ack),
+    _st_time(fsm._st_time), _st_term_ack(fsm._st_term_ack),
+    _st_terminated(fsm._st_terminated), _st_fail(fsm._st_fail),
+    _st_failed(fsm._st_failed),
+    _writer(fsm._writer), _reader(fsm._reader), _connector(fsm._connector)
+{
+}
+
+
+void scd_sts_base::set_failed()
+{
+    _sim.get_poller().remove_handler(_fsm);
+    _sim.get_chan_man().close();
+    _fsm.set_state(_st_failed);
+}
+
+
+void scd_sts_base::recv_time_req()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_NACK);
+    _fsm.send_command(cmd);
+}
+
+
+void scd_sts_base::recv_time(const sc_core::sc_time& time)
+{
+    scd_warn("received time message in wrong state");
+}
+
+
+void scd_sts_base::recv_term_req()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM_NACK);
+    _fsm.send_command(cmd);
+}
+
+
+void scd_sts_base::recv_term()
+{
+    scd_warn("received terminate message in wrong state");
+}
+
+
+void scd_sts_base::set_fail()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_FAILED);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_fail);
+}
+
+
+bool scd_sts_base::active() const { return true; }
+
+
+bool scd_sts_base::busy() const { return false; }
+
+
+bool scd_sts_base::failed() const { return false; }
+
+
+bool scd_sts_base::advance_time() const { return false; }
+
+
+const sc_core::sc_time& scd_sts_base::get_time_step()
+{
+    scd_warn("illegal call to get_time_step()");
+    throw scd_exception("illegal call");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_base.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_base.h
new file mode 100644 (file)
index 0000000..05c1e8d
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef SCD_STS_BASE_H
+#define SCD_STS_BASE_H
+
+#include "scd_simulator.h"
+#include "scd_out_connector.h"
+#include "scd_command_writer.h"
+#include "scd_command_reader.h"
+#include "fsm/scd_cont_state.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+/**
+ * Base class for all control slave states.
+ */
+class scd_sts_base : public scd_cont_state
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     * \param fsm the FSM of this state
+     */
+    scd_sts_base(scd_simulator& sim, scd_cont_man_slave& fsm);
+
+    virtual ~scd_sts_base() {}
+
+    /**
+     * Signalizes the state, that a failed message has been received
+     * from the master.
+     */
+    virtual void set_failed();
+
+    /**
+     * Signalizes the state, that a time_req message has been received
+     * from the master.
+     */
+    virtual void recv_time_req();
+
+    /**
+     * Signalizes the state, that a time_nack message has been received
+     * from the master.
+     */
+    virtual void recv_time_nack() {}
+
+    /**
+     * Signalizes the state, that a time message has been received
+     * from the master.
+     */
+    virtual void recv_time(const sc_core::sc_time& time);
+
+    /**
+     * Signalizes the state, that a term_req message has been received
+     * from the master.
+     */
+    virtual void recv_term_req();
+
+    /**
+     * Signalizes the state, that a term_nack message has been received
+     * from the master.
+     */
+    virtual void recv_term_nack() {}
+
+    /**
+     * Signalizes the state, that a term message has been received
+     * from the master.
+     */
+    virtual void recv_term();
+
+    /* scd_cont_fsm_if */
+    void set_busy() {}
+    void set_idle(const sc_core::sc_time& time) {}
+    void set_done() {}
+    void set_fail();
+    void process() {}
+    bool active() const;
+    bool busy() const;
+    bool failed() const;
+    bool advance_time() const;
+    const sc_core::sc_time& get_time_step();
+
+protected:
+    scd_cont_man_slave& _fsm;
+    scd_command_writer& _writer;
+    scd_command_reader& _reader;
+    scd_out_connector& _connector;
+    scd_cont_state& _st_init;
+    scd_cont_state& _st_busy;
+    scd_cont_state& _st_idle;
+    scd_cont_state& _st_done;
+    scd_cont_state& _st_time_ack;
+    scd_cont_state& _st_time;
+    scd_cont_state& _st_term_ack;
+    scd_cont_state& _st_terminated;
+    scd_cont_state& _st_fail;
+    scd_cont_state& _st_failed;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_busy.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_busy.cpp
new file mode 100644 (file)
index 0000000..a9bb214
--- /dev/null
@@ -0,0 +1,36 @@
+#include "fsm/scd_sts_busy.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_busy::set_idle(const sc_core::sc_time& time)
+{
+    /* prevents the situation where no events exist, but a huge
+     * ammount of data is being transferred that will generate events later
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_IDLE, time);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_idle);
+}
+
+
+void scd_sts_busy::set_done()
+{
+    /* prevents the situation where no events exist, but a huge
+     * ammount of data is being transferred that will generate events later
+     */
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+        return;
+
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_DONE);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_done);
+}
+
+
+bool scd_sts_busy::busy() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_busy.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_busy.h
new file mode 100644 (file)
index 0000000..b2130ad
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SCD_STS_BUSY_H
+#define SCD_STS_BUSY_H
+
+#include "fsm/scd_sts_base.h"
+
+
+class scd_sts_busy : public scd_sts_base
+{
+public:
+    scd_sts_busy(scd_simulator& sim, scd_cont_man_slave& fsm):
+       scd_sts_base(sim, fsm) { _name = "busy"; }
+    virtual ~scd_sts_busy() {}
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_done();
+    bool busy() const;
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_done.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_done.cpp
new file mode 100644 (file)
index 0000000..ddd8203
--- /dev/null
@@ -0,0 +1,58 @@
+#include "fsm/scd_sts_done.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+#include "scd_cont_man.h"
+
+
+void scd_sts_done::recv_time_req()
+{
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+    {
+        // had activity on sockets => we might be receiving data
+        scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_NACK);
+        _fsm.send_command(cmd);
+    }
+    else
+    {
+        scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_ACK);
+        _fsm.send_command(cmd);
+        _fsm.save_state();
+        _fsm.set_state(_st_time_ack);
+    }
+}
+
+
+void scd_sts_done::recv_term_req()
+{
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+    {
+        // had activity on sockets => we might be receiving data
+        scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM_NACK);
+        _fsm.send_command(cmd);
+    }
+    else
+    {
+        scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM_ACK);
+        _fsm.send_command(cmd);
+        _fsm.save_state();
+        _fsm.set_state(_st_term_ack);
+    }
+}
+
+
+void scd_sts_done::set_idle(const sc_core::sc_time& time)
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_IDLE, time);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_idle);
+}
+
+
+void scd_sts_done::set_busy()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_BUSY);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_busy);
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_done.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_done.h
new file mode 100644 (file)
index 0000000..14e762f
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef SCD_STS_DONE_H
+#define SCD_STS_DONE_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_done : public scd_sts_base
+{
+public:
+    scd_sts_done(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "done"; }
+    virtual ~scd_sts_done() {}
+
+    void recv_time_req();
+    void recv_term_req();
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_busy();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_fail.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_fail.cpp
new file mode 100644 (file)
index 0000000..b026fa2
--- /dev/null
@@ -0,0 +1,17 @@
+#include "fsm/scd_sts_fail.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_fail::process()
+{
+    if (!_fsm.is_sending())
+    {
+        _sim.get_poller().remove_handler(_fsm);
+        _sim.get_chan_man().close();
+        _fsm.close();
+        _fsm.set_state(_st_failed);
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_fail.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_fail.h
new file mode 100644 (file)
index 0000000..dc2fb1d
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STS_FAIL_H
+#define SCD_STS_FAIL_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_fail : public scd_sts_base
+{
+public:
+    scd_sts_fail(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "fail"; }
+    virtual ~scd_sts_fail() {}
+
+    void recv_time_req() {}
+    void recv_time(const sc_core::sc_time& time) {}
+    void recv_term_req() {}
+    void recv_term() {}
+
+    /* scd_cont_fsm_if */
+    void set_fail() {}
+    void process();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_failed.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_failed.cpp
new file mode 100644 (file)
index 0000000..5e6966d
--- /dev/null
@@ -0,0 +1,11 @@
+#include "fsm/scd_sts_failed.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+
+bool scd_sts_failed::active() const { return false; }
+
+
+bool scd_sts_failed::failed() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_failed.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_failed.h
new file mode 100644 (file)
index 0000000..c699dbb
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef SCD_STS_FAILED_H
+#define SCD_STS_FAILED_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_failed : public scd_sts_base
+{
+public:
+    scd_sts_failed(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "failed"; }
+    virtual ~scd_sts_failed() {}
+
+    void set_failed() {}
+
+    void recv_time_req() {}
+    void recv_time(const sc_core::sc_time& time) {}
+    void recv_term_req() {}
+    void recv_term() {}
+
+    /* scd_cont_fsm_if */
+    void set_fail() {}
+    bool active() const;
+    bool failed() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_idle.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_idle.cpp
new file mode 100644 (file)
index 0000000..cbb0f94
--- /dev/null
@@ -0,0 +1,37 @@
+#include "fsm/scd_sts_idle.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_idle::recv_time_req()
+{
+    if (_sim.get_poller().wait(SCD_CONT_DELAY))
+    {
+        // had activity on sockets => we might be receiving data
+        scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_NACK);
+        _fsm.send_command(cmd);
+    }
+    else
+    {
+        scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_ACK);
+        _fsm.send_command(cmd);
+        _fsm.save_state();
+        _fsm.set_state(_st_time_ack);
+    }
+}
+
+
+void scd_sts_idle::set_busy()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_BUSY);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_sts_idle::set_done()
+{
+    scd_warn("slave: transition attempt from idle to done");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_idle.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_idle.h
new file mode 100644 (file)
index 0000000..df68cd1
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SCD_STS_IDLE_H
+#define SCD_STS_IDLE_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_idle : public scd_sts_base
+{
+public:
+    scd_sts_idle(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "idle"; }
+    virtual ~scd_sts_idle() {}
+
+    void recv_time_req();
+    
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_done();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_init.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_init.cpp
new file mode 100644 (file)
index 0000000..d4d05e9
--- /dev/null
@@ -0,0 +1,70 @@
+#include "fsm/scd_sts_init.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_init::set_failed()
+{
+    _fsm.set_state(_st_failed);
+}
+
+
+void scd_sts_init::set_idle(const sc_core::sc_time& time)
+{
+    scd_error("init: illegal call to set_idle()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_sts_init::set_busy()
+{
+    scd_error("init: illegal call to set_busy()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_sts_init::set_done()
+{
+    scd_error("init: illegal call to set_done()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_sts_init::set_fail()
+{
+    _fsm.set_state(_st_failed);
+}
+
+
+void scd_sts_init::process()
+{
+    _connector.process();
+
+    if (!_connector.is_connecting() && !_connector.has_connection())
+    {
+        // unable to connect to master
+        scd_error("connecting to master failed");
+        _fsm.set_state(_st_failed);
+    }
+    else if (!_connector.is_connecting() && _connector.has_connection())
+    {
+        // successfully connected to master
+        scd_info("connected to master");
+        _fsm.set_socket();
+        _sim.get_poller().register_handler(_fsm, SOCK_EV_READ | SOCK_EV_CLOSE);
+        _fsm.set_state(_st_busy);
+    }
+
+} // process()
+
+
+bool scd_sts_init::active() const { return false; }
+
+
+bool scd_sts_init::advance_time() const
+{
+    scd_error("illegal call to advance_time()");
+    throw scd_exception("illegal call");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_init.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_init.h
new file mode 100644 (file)
index 0000000..3fff4ea
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef SCD_STS_INIT_H
+#define SCD_STS_INIT_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_init : public scd_sts_base
+{
+public:
+    scd_sts_init(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "init"; }
+    virtual ~scd_sts_init() {}
+
+    void set_failed();
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_busy();
+    void set_done();
+    void set_fail();
+    void process();
+    bool active() const;
+    bool advance_time() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_term_ack.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_term_ack.cpp
new file mode 100644 (file)
index 0000000..e3433ff
--- /dev/null
@@ -0,0 +1,36 @@
+#include "fsm/scd_sts_term_ack.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_term_ack::recv_time_req()
+{
+    scd_warn("received time request in illegal state");
+}
+
+
+void scd_sts_term_ack::recv_term_req()
+{
+    scd_warn("received terminate request in illegal state");
+}
+
+
+void scd_sts_term_ack::recv_term_nack()
+{
+    _fsm.load_state();
+}
+
+
+void scd_sts_term_ack::recv_term()
+{
+    _sim.get_poller().remove_handler(_fsm);
+    _fsm.set_state(_st_terminated);
+}
+
+
+void scd_sts_term_ack::set_busy()
+{
+    scd_warn("received channel data while synchronizing to terminate");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_term_ack.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_term_ack.h
new file mode 100644 (file)
index 0000000..2a32250
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STS_TERM_ACK_H
+#define SCD_STS_TERM_ACK_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_term_ack : public scd_sts_base
+{
+public:
+    scd_sts_term_ack(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "term_ack"; }
+    virtual ~scd_sts_term_ack() {}
+
+    void recv_time_req();
+    void recv_term_req();
+    void recv_term_nack();
+    void recv_term();
+
+    void set_fail() {}
+    void set_busy();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_terminated.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_terminated.cpp
new file mode 100644 (file)
index 0000000..7bd4233
--- /dev/null
@@ -0,0 +1,19 @@
+#include "fsm/scd_sts_terminated.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+void scd_sts_terminated::set_busy()
+{
+    scd_error("received further events while synchronizing (terminate)");
+}
+
+
+void scd_sts_terminated::set_idle(const sc_core::sc_time& time)
+{
+    scd_error("received future events while synchronizing (terminate)");
+}
+
+
+bool scd_sts_terminated::active() const { return false; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_terminated.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_terminated.h
new file mode 100644 (file)
index 0000000..d05996a
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef SCD_STS_TERMINATED_H
+#define SCD_STS_TERMINATED_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_terminated : public scd_sts_base
+{
+public:
+    scd_sts_terminated(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "terminated"; }
+    virtual ~scd_sts_terminated() {}
+
+    void set_failed() {}
+    void recv_time_req() {}
+    void recv_term_req() {}
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void set_fail() {}
+    bool active() const;
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time.cpp
new file mode 100644 (file)
index 0000000..09e69e5
--- /dev/null
@@ -0,0 +1,21 @@
+#include "fsm/scd_sts_time.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_time::set_time_step(const sc_core::sc_time& time)
+{
+    _time_step = time;
+}
+
+
+bool scd_sts_time::advance_time() const { return true; }
+
+
+const sc_core::sc_time& scd_sts_time::get_time_step()
+{
+    _fsm.set_state(_st_busy);
+    return _time_step;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time.h
new file mode 100644 (file)
index 0000000..8467342
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STS_TIME_H
+#define SCD_STS_TIME_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_time : public scd_sts_base
+{
+public:
+    scd_sts_time(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "time"; }
+    virtual ~scd_sts_time() {}
+
+    void set_time_step(const sc_core::sc_time& time);
+
+    /* scd_cont_fsm_if */
+    bool advance_time() const;
+    const sc_core::sc_time& get_time_step();
+
+private:
+    sc_core::sc_time _time_step;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time_ack.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time_ack.cpp
new file mode 100644 (file)
index 0000000..53c6827
--- /dev/null
@@ -0,0 +1,36 @@
+#include "fsm/scd_sts_time_ack.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_man_slave.h"
+
+
+void scd_sts_time_ack::recv_time_req()
+{
+    scd_warn("received time request in wrong state");
+}
+
+
+void scd_sts_time_ack::recv_time_nack()
+{
+    _fsm.load_state();
+}
+
+
+void scd_sts_time_ack::recv_time(const sc_core::sc_time& time)
+{
+    static_cast<scd_sts_time&>(_st_time).set_time_step(time);
+    _fsm.set_state(_st_time);
+}
+
+
+void scd_sts_time_ack::recv_term_req()
+{
+    scd_warn("received terminate request in wrong state");
+}
+
+
+void scd_sts_time_ack::set_busy()
+{
+    scd_warn("received channel data while synchronizing to terminate");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time_ack.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_sts_time_ack.h
new file mode 100644 (file)
index 0000000..ef2c39a
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STS_TIME_ACK_H
+#define SCD_STS_TIME_ACK_H
+
+#include "fsm/scd_sts_base.h"
+
+
+/* forward declaration */
+class scd_cont_man_slave;
+
+
+class scd_sts_time_ack : public scd_sts_base
+{
+public:
+    scd_sts_time_ack(scd_simulator& sim, scd_cont_man_slave& fsm):
+        scd_sts_base(sim, fsm) { _name = "time_ack"; }
+    virtual ~scd_sts_time_ack() {}
+
+    /* scd_sts_base */
+    void recv_time_req();
+    void recv_time_nack();
+    void recv_time(const sc_core::sc_time& time);
+    void recv_term_req();
+
+    void set_busy();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_base.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_base.cpp
new file mode 100644 (file)
index 0000000..a4f0c46
--- /dev/null
@@ -0,0 +1,125 @@
+#include "fsm/scd_stsw_base.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+#include "scd_command.h"
+
+
+scd_stsw_base::scd_stsw_base(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+    scd_cont_state(sim), _fsm(fsm), _time_step(fsm._time_step),
+    _st_init(fsm._st_init), _st_busy(fsm._st_busy), _st_idle(fsm._st_idle),
+    _st_done(fsm._st_done), _st_time_req(fsm._st_time_req),
+    _st_time_ack(fsm._st_time_ack), _st_term_req(fsm._st_term_req),
+    _st_term_ack(fsm._st_term_ack), _st_terminate(fsm._st_terminate),
+    _st_terminated(fsm._st_terminated), _st_fail(fsm._st_fail),
+    _st_failed(fsm._st_failed)
+{
+}
+
+
+void scd_stsw_base::set_connected()
+{
+    scd_warn("illegal call to set_connected()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_base::set_failed()
+{
+    _sim.get_poller().remove_handler(_fsm);
+    _fsm.set_state(_st_failed);
+}
+
+
+void scd_stsw_base::send_time_req()
+{
+    scd_warn("illegal call to send_time_req()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_base::send_time(const sc_core::sc_time& time)
+{
+    scd_warn("illegal call to send_time()");
+    throw scd_exception("illegal call");
+}
+
+void scd_stsw_base::send_term_req()
+{
+    scd_warn("illegal call to send_term_req()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_base::send_term()
+{
+    scd_warn("illegal call to send_term()");
+    throw scd_exception("illegal call");
+}
+
+
+bool scd_stsw_base::time_req() const { return false; }
+
+
+bool scd_stsw_base::time_ack() const { return false; }
+
+
+bool scd_stsw_base::term_req() const { return false; }
+
+
+bool scd_stsw_base::term_ack() const { return false; }
+
+
+bool scd_stsw_base::idle() const { return false; }
+
+
+bool scd_stsw_base::done() const { return false; }
+
+
+void scd_stsw_base::set_busy()
+{
+    scd_error("illegal call to set_busy()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_base::set_idle(const sc_core::sc_time& time)
+{
+    scd_error("illegal call to set_idle()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_base::set_done()
+{
+    scd_error("illegal call to set_done()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_base::set_fail()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_FAILED);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_fail);
+}
+
+
+bool scd_stsw_base::active() const { return true; }
+
+
+bool scd_stsw_base::busy() const { return false; }
+
+
+bool scd_stsw_base::failed() const { return false; }
+
+
+bool scd_stsw_base::advance_time() const { return false; }
+
+
+const sc_core::sc_time& scd_stsw_base::get_time_step()
+{
+    scd_error("illegal call to get_time_step()");
+    throw scd_exception("illegal call");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_base.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_base.h
new file mode 100644 (file)
index 0000000..8ac5750
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef SCD_STSW_BASE_H
+#define SCD_STSW_BASE_H
+
+#include "scd_simulator.h"
+#include "fsm/scd_cont_state.h"
+#include "fsm/scd_cont_wrapper_if.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+/**
+ * Base class for all control slave wrapper states.
+ */
+class scd_stsw_base : public scd_cont_state, public scd_cont_wrapper_if
+{
+public:    
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     * \param fsm the FSM of this state
+     */
+    scd_stsw_base(scd_simulator& sim, scd_cont_slave_wrapper& fsm);
+
+    virtual ~scd_stsw_base() {}
+
+    /**
+     * Signalizes the state that the slave has been connected to the wrapper.
+     */
+    virtual void set_connected();
+
+    /**
+     * Signalizes the state that a failed command has been received
+     * from the slave.
+     */
+    virtual void set_failed();
+
+    /**
+     * Signalizes the state that a time_nack command has been received
+     * from the slave.
+     */
+    virtual void recv_time_nack() {}
+
+    /**
+     * Signalizes the state that a time_ack command has been received
+     * from the slave.
+     */
+    virtual void recv_time_ack() {}
+
+    /**
+     * Signalizes the state that a term_nack command has been received
+     * from the slave.
+     */
+    virtual void recv_term_nack() {}
+
+    /**
+     * Signalizes the state that a term_ack command has been received
+     * from the slave.
+     */
+    virtual void recv_term_ack() {}
+
+    /* scd_cont_wrapper_if */
+    void send_time_req();
+    void send_time_nack() {}
+    void send_time(const sc_core::sc_time& time);
+    void send_term_req();
+    void send_term_nack() {};
+    void send_term();
+    bool time_req() const;
+    bool time_ack() const;
+    bool term_req() const;
+    bool term_ack() const;
+    bool idle() const;
+    bool done() const;
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void set_done();
+    void set_fail();
+    void process() {};
+    bool active() const;
+    bool busy() const;
+    bool failed() const;
+    bool advance_time() const;
+    const sc_core::sc_time& get_time_step();
+
+protected:
+    scd_cont_slave_wrapper& _fsm;
+    sc_core::sc_time& _time_step;
+    scd_cont_state& _st_init;
+    scd_cont_state& _st_busy;
+    scd_cont_state& _st_idle;
+    scd_cont_state& _st_done;
+    scd_cont_state& _st_time_req;
+    scd_cont_state& _st_time_ack;
+    scd_cont_state& _st_term_req;
+    scd_cont_state& _st_term_ack;
+    scd_cont_state& _st_terminate;
+    scd_cont_state& _st_terminated;
+    scd_cont_state& _st_fail;
+    scd_cont_state& _st_failed;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_busy.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_busy.cpp
new file mode 100644 (file)
index 0000000..f96ba77
--- /dev/null
@@ -0,0 +1,22 @@
+#include "fsm/scd_stsw_busy.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_busy::set_idle(const sc_core::sc_time& time)
+{
+    _time_step = time;
+    _fsm.set_state(_st_idle);
+}
+
+
+void scd_stsw_busy::set_done()
+{
+    _time_step = sc_core::SC_ZERO_TIME;
+    _fsm.set_state(_st_done);
+}
+
+
+bool scd_stsw_busy::busy() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_busy.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_busy.h
new file mode 100644 (file)
index 0000000..1194bdf
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SCD_STSW_BUSY_H
+#define SCD_STSW_BUSY_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+class scd_stsw_busy : public scd_stsw_base
+{
+public:
+    scd_stsw_busy(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+       scd_stsw_base(sim, fsm) { _name = "busy"; }
+    virtual ~scd_stsw_busy() {}
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_done();
+    bool busy() const;
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_done.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_done.cpp
new file mode 100644 (file)
index 0000000..329b81b
--- /dev/null
@@ -0,0 +1,39 @@
+#include "fsm/scd_stsw_done.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_done::send_time_req()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_REQ);
+    _fsm.send_command(cmd);
+    _fsm.save_state();
+    _fsm.set_state(_st_time_req);
+}
+
+
+void scd_stsw_done::send_term_req()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM_REQ);
+    _fsm.send_command(cmd);
+    _fsm.save_state();
+    _fsm.set_state(_st_term_req);
+}
+
+
+bool scd_stsw_done::done() const { return true; }
+
+
+void scd_stsw_done::set_busy()
+{
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_stsw_done::set_idle(const sc_core::sc_time& time)
+{
+    _time_step = time;
+    _fsm.set_state(_st_idle);
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_done.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_done.h
new file mode 100644 (file)
index 0000000..148d973
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STSW_DONE_H
+#define SCD_STSW_DONE_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_done : public scd_stsw_base
+{
+public:
+    scd_stsw_done(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "done"; }
+    virtual ~scd_stsw_done() {}
+
+    /* scd_cont_wrapper_if */
+    void send_time_req();
+    void send_term_req();
+    bool done() const;
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_fail.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_fail.cpp
new file mode 100644 (file)
index 0000000..51348d3
--- /dev/null
@@ -0,0 +1,18 @@
+#include "fsm/scd_stsw_fail.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_fail::set_fail() {}
+
+
+void scd_stsw_fail::process()
+{
+    if (!_fsm.is_sending())
+    {
+        _sim.get_poller().remove_handler(_fsm);
+        _fsm.set_state(_st_failed);
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_fail.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_fail.h
new file mode 100644 (file)
index 0000000..cb8fe22
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef SCD_STSW_FAIL_H
+#define SCD_STSW_FAIL_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_fail : public scd_stsw_base
+{
+public:
+    scd_stsw_fail(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "fail"; }
+    virtual ~scd_stsw_fail() {}
+
+    /* scd_cont_fsm_if */
+    void set_fail();
+    void process();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_failed.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_failed.cpp
new file mode 100644 (file)
index 0000000..ab2db2e
--- /dev/null
@@ -0,0 +1,16 @@
+#include "fsm/scd_stsw_failed.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+void scd_stsw_failed::set_failed() {}
+
+
+void scd_stsw_failed::set_fail() {}
+
+
+bool scd_stsw_failed::active() const { return false; }
+
+
+bool scd_stsw_failed::failed() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_failed.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_failed.h
new file mode 100644 (file)
index 0000000..cf13d9d
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef SCD_STSW_FAILED_H
+#define SCD_STSW_FAILED_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_failed : public scd_stsw_base
+{
+public:
+    scd_stsw_failed(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "failed"; }
+    virtual ~scd_stsw_failed() {}
+
+    void set_failed();
+
+    /* scd_cont_fsm_if */
+    void set_fail();
+    bool active() const;
+    bool failed() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_idle.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_idle.cpp
new file mode 100644 (file)
index 0000000..6883648
--- /dev/null
@@ -0,0 +1,29 @@
+#include "fsm/scd_stsw_idle.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_idle::send_time_req()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_REQ);
+    _fsm.send_command(cmd);
+    _fsm.save_state();
+    _fsm.set_state(_st_time_req);
+}
+
+
+bool scd_stsw_idle::idle() const { return true; }
+
+
+void scd_stsw_idle::set_busy()
+{
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_stsw_idle::set_done()
+{
+    scd_warn("slave " + _fsm.get_name() + " transition attempt from idle to done");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_idle.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_idle.h
new file mode 100644 (file)
index 0000000..4af1c6d
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STSW_IDLE_H
+#define SCD_STSW_IDLE_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_idle : public scd_stsw_base
+{
+public:
+    scd_stsw_idle(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "idle"; }
+    virtual ~scd_stsw_idle() {}
+    
+    /* scd_cont_wrapper_if */
+    void send_time_req();
+    bool idle() const;
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_done();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_init.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_init.cpp
new file mode 100644 (file)
index 0000000..d4f27bd
--- /dev/null
@@ -0,0 +1,58 @@
+#include "fsm/scd_stsw_init.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_init::set_connected()
+{
+    _sim.get_poller().register_handler(_fsm, SOCK_EV_READ | SOCK_EV_CLOSE);
+    _fsm.set_state(_st_busy);
+}
+
+
+void scd_stsw_init::set_failed()
+{
+    _fsm.set_state(_st_failed);
+}
+
+
+void scd_stsw_init::set_idle(const sc_core::sc_time& time)
+{
+    scd_error("init: illegal call to set_idle()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_init::set_busy()
+{
+    scd_error("init: illegal call to set_idle()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_init::set_done()
+{
+    scd_error("init: illegal call to set_done()");
+    throw scd_exception("illegal call");
+}
+
+
+void scd_stsw_init::set_fail()
+{
+    _fsm.set_state(_st_failed);
+}
+
+
+void scd_stsw_init::process() {}
+
+
+bool scd_stsw_init::active() const { return false; }
+
+
+bool scd_stsw_init::advance_time() const
+{
+    scd_error("illegal call to advance_time()");
+    throw scd_exception("illegal call");
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_init.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_init.h
new file mode 100644 (file)
index 0000000..aa4d8a3
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef SCD_STSW_INIT_H
+#define SCD_STSW_INIT_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_init : public scd_stsw_base
+{
+public:
+    scd_stsw_init(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "init"; }
+    virtual ~scd_stsw_init() {}
+
+    void set_connected();
+    void set_failed();
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& time);
+    void set_busy();
+    void set_done();
+    void set_fail();
+    void process();
+    bool active() const;
+    bool advance_time() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_ack.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_ack.cpp
new file mode 100644 (file)
index 0000000..5fc0a51
--- /dev/null
@@ -0,0 +1,36 @@
+#include "fsm/scd_stsw_term_ack.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_term_ack::recv_term_nack()
+{
+    scd_warn("received term_nack message in wrong state");
+}
+
+
+void scd_stsw_term_ack::recv_term_ack()
+{
+    scd_warn("received term_nack message in wrong state");
+}
+
+
+void scd_stsw_term_ack::send_term_nack()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM_NACK);
+    _fsm.send_command(cmd);
+    _fsm.load_state();
+}
+
+
+void scd_stsw_term_ack::send_term()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_terminate);
+}
+
+
+bool scd_stsw_term_ack::term_ack() const { return true; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_ack.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_ack.h
new file mode 100644 (file)
index 0000000..19ae78d
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef SCD_STSW_TERM_ACK_H
+#define SCD_STSW_TERM_ACK_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_term_ack : public scd_stsw_base
+{
+public:
+    scd_stsw_term_ack(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "term_ack"; }
+    virtual ~scd_stsw_term_ack() {}
+
+    /* scd_stsw_base */
+    void recv_term_nack();
+    void recv_term_ack();
+
+    /* scd_cont_wrapper_if */
+    void send_term_nack();
+    void send_term();
+    bool term_ack() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_req.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_req.cpp
new file mode 100644 (file)
index 0000000..3bd39dc
--- /dev/null
@@ -0,0 +1,48 @@
+#include "fsm/scd_stsw_term_req.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_term_req::recv_term_nack()
+{
+    _fsm.load_state();
+}
+
+
+void scd_stsw_term_req::recv_term_ack()
+{
+    _fsm.set_state(_st_term_ack);
+}
+
+
+void scd_stsw_term_req::send_term_nack()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TERM_NACK);
+    _fsm.send_command(cmd);
+    _fsm.load_state();
+}
+
+
+bool scd_stsw_term_req::term_req() const { return true; }
+
+
+void scd_stsw_term_req::set_busy()
+{
+    _time_step = sc_core::SC_ZERO_TIME;
+    _fsm.save_state(_st_busy);
+}
+
+
+void scd_stsw_term_req::set_idle(const sc_core::sc_time& time)
+{
+    _time_step = time;
+    _fsm.save_state(_st_idle);
+}
+
+
+void scd_stsw_term_req::set_done()
+{
+    _fsm.save_state(_st_done);
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_req.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_term_req.h
new file mode 100644 (file)
index 0000000..1c39d7f
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef SCD_STSW_TERM_REQ_H
+#define SCD_STSW_TERM_REQ_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_term_req : public scd_stsw_base
+{
+public:
+    scd_stsw_term_req(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "term_req"; }
+    virtual ~scd_stsw_term_req() {}
+
+    /* sdc_stsw_base */
+    void recv_term_nack();
+    void recv_term_ack();
+
+    /* scd_cont_wrapper_if */
+    void send_term_nack();
+    bool term_req() const;
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void set_done();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminate.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminate.cpp
new file mode 100644 (file)
index 0000000..98fa64f
--- /dev/null
@@ -0,0 +1,18 @@
+#include "fsm/scd_stsw_terminate.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_terminate::set_fail() {}
+
+
+void scd_stsw_terminate::process()
+{
+    if (!_fsm.is_sending())
+    {
+        _sim.get_poller().remove_handler(_fsm);
+        _fsm.set_state(_st_terminated);
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminate.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminate.h
new file mode 100644 (file)
index 0000000..3671316
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef SCD_STSW_TERMINATE_H
+#define SCD_STSW_TERMINATE_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_terminate : public scd_stsw_base
+{
+public:
+    scd_stsw_terminate(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "terminate"; }
+    virtual ~scd_stsw_terminate() {}
+
+    /* scd_cont_fsm_if */
+    void set_fail();
+    void process();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminated.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminated.cpp
new file mode 100644 (file)
index 0000000..8a9a045
--- /dev/null
@@ -0,0 +1,13 @@
+#include "fsm/scd_stsw_terminated.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+void scd_stsw_terminated::set_failed() {}
+
+
+void scd_stsw_terminated::set_fail() {}
+
+
+bool scd_stsw_terminated::active() const { return false; }
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminated.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_terminated.h
new file mode 100644 (file)
index 0000000..b0d22b1
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef SCD_STSW_TERMINATED_H
+#define SCD_STSW_TERMINATED_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_terminated : public scd_stsw_base
+{
+public:
+    scd_stsw_terminated(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "terminated"; }
+    virtual ~scd_stsw_terminated() {}
+
+    void set_failed();
+
+    /* scd_cont_fsm_if */
+    void set_fail();
+    bool active() const;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_ack.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_ack.cpp
new file mode 100644 (file)
index 0000000..53d0a4c
--- /dev/null
@@ -0,0 +1,42 @@
+#include "fsm/scd_stsw_time_ack.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_time_ack::recv_time_nack()
+{
+    scd_warn("received time_nack message in wrong state");
+}
+
+
+void scd_stsw_time_ack::recv_time_ack()
+{
+    scd_warn("received time_nack message in wrong state");
+}
+
+
+void scd_stsw_time_ack::send_time_nack()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_NACK);
+    _fsm.send_command(cmd);
+    _fsm.load_state();
+}
+
+
+void scd_stsw_time_ack::send_time(const sc_core::sc_time& time)
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME, time);
+    _fsm.send_command(cmd);
+    _fsm.set_state(_st_busy);
+}
+
+
+bool scd_stsw_time_ack::time_ack() const { return true; }
+
+
+const sc_core::sc_time& scd_stsw_time_ack::get_time_step()
+{
+    return _time_step;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_ack.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_ack.h
new file mode 100644 (file)
index 0000000..a71ca7e
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef SCD_STSW_TIME_ACK_H
+#define SCD_STSW_TIME_ACK_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_time_ack : public scd_stsw_base
+{
+public:
+    scd_stsw_time_ack(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "time_ack"; }
+    virtual ~scd_stsw_time_ack() {}
+
+    /* scd_stsw_base */
+    void recv_time_nack();
+    void recv_time_ack();
+
+    /* scd_cont_wrapper_if */
+    void send_time_nack();
+    void send_time(const sc_core::sc_time& time);
+    bool time_ack() const;
+    const sc_core::sc_time& get_time_step();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_req.cpp b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_req.cpp
new file mode 100644 (file)
index 0000000..0336c06
--- /dev/null
@@ -0,0 +1,48 @@
+#include "fsm/scd_stsw_time_req.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_cont_slave_wrapper.h"
+
+
+void scd_stsw_time_req::recv_time_nack()
+{
+    _fsm.load_state();
+}
+
+
+void scd_stsw_time_req::recv_time_ack()
+{
+    _fsm.set_state(_st_time_ack);
+}
+
+
+void scd_stsw_time_req::send_time_nack()
+{
+    scd_command* cmd = new scd_command(SCD_CM_CONTROL, SCD_CM_TIME_NACK);
+    _fsm.send_command(cmd);
+    _fsm.load_state();
+}
+
+
+bool scd_stsw_time_req::time_req() const { return true; }
+
+
+void scd_stsw_time_req::set_busy()
+{
+    _fsm.save_state(_st_busy);
+}
+
+
+void scd_stsw_time_req::set_idle(const sc_core::sc_time& time)
+{
+    _time_step = time;
+    _fsm.save_state(_st_idle);
+}
+
+
+void scd_stsw_time_req::set_done()
+{
+    _time_step = sc_core::SC_ZERO_TIME;
+    _fsm.save_state(_st_done);
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_req.h b/dol/src/dol/visitor/hdsd/scd/fsm/scd_stsw_time_req.h
new file mode 100644 (file)
index 0000000..2f45f84
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef SCD_STSW_TIME_REQ_H
+#define SCD_STSW_TIME_REQ_H
+
+#include "fsm/scd_stsw_base.h"
+
+
+/* forward declaration */
+class scd_cont_slave_wrapper;
+
+
+class scd_stsw_time_req : public scd_stsw_base
+{
+public:
+    scd_stsw_time_req(scd_simulator& sim, scd_cont_slave_wrapper& fsm):
+        scd_stsw_base(sim, fsm) { _name = "time_req"; }
+    virtual ~scd_stsw_time_req() {}
+
+    /* sdc_stsw_base */
+    void recv_time_nack();
+    void recv_time_ack();
+
+    /* scd_cont_wrapper_if */
+    void send_time_nack();
+    bool time_req() const;
+
+    /* scd_cont_fsm_if */
+    void set_busy();
+    void set_idle(const sc_core::sc_time& time);
+    void set_done();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_chan_man.cpp b/dol/src/dol/visitor/hdsd/scd/scd_chan_man.cpp
new file mode 100644 (file)
index 0000000..d98e8ea
--- /dev/null
@@ -0,0 +1,216 @@
+#include "scd_chan_man.h"
+
+#include "scd_logging.h"
+
+
+scd_chan_man::scd_chan_man(scd_simulator &sim):
+    _sim(sim), _is_ready(false) {}
+
+
+scd_chan_man::~scd_chan_man()
+{
+    std::list<scd_out_connector*>::iterator coit;
+    std::list<scd_chan_wrapper*>::iterator chit;
+
+    for (coit = _connectors.begin(); coit != _connectors.end(); coit++)
+        delete *coit;
+
+    for (chit = _channels.begin(); chit != _channels.end(); chit++)
+        delete *chit;
+}
+
+
+void scd_chan_man::register_channel(const std::string &name, sc_prim_channel& mchan)
+{
+    if ( _get_channel(name) != NULL )
+    {
+        scd_warn("channel \"" + name + "\" already registered, ignoring...");
+    }
+    else
+    {
+        scd_chan_wrapper* wrap = new scd_chan_wrapper(_sim, name, mchan);
+        _channels.push_back(wrap);
+    }
+
+} // register_channel() - master
+
+
+void scd_chan_man::register_channel(const std::string &name,
+        sc_prim_channel& schan, const std::string &host, const uint16_t port)
+{
+    if ( _get_channel(name) != NULL )
+    {
+        scd_warn("channel \"" + name + "\" already registered, ignoring...");
+    }
+    else
+    {
+        // register channel
+        scd_chan_wrapper* wrap = new scd_chan_wrapper(_sim, name, schan);
+        _channels.push_back(wrap);
+
+        // create connector
+        scd_out_connector* conn = new scd_out_connector(_sim, SCD_CM_CHANNEL,
+                name);
+        conn->connect_to(host, port);
+        _connectors.push_back(conn);
+    }
+
+} // register_channel() - slave
+
+
+void scd_chan_man::init_process()
+{
+    if (_is_ready)
+        return;
+
+    std::list<scd_out_connector*>::iterator coit;
+
+    // check all connectors
+    for (coit = _connectors.begin(); coit != _connectors.end();)
+    {
+        scd_out_connector& conn = **coit;
+
+        // retry to connect if necessary
+        conn.process();
+
+        if (!conn.is_connecting() && !conn.has_connection())
+        {
+            // an error occured
+            scd_error("failed to connect channel \""
+                    + conn.get_name() + "\"");
+
+            delete *coit;
+            coit = _connectors.erase(coit);
+
+            _sim.get_cont_man().set_fail();
+            return;
+        }
+        else if (!conn.is_connecting() && conn.has_connection())
+        {
+            // channel is connected
+            scd_chan_wrapper& chan = *_get_channel(conn.get_name());
+
+            if (chan.is_initialized())
+            {
+                scd_error("channel \""
+                        + conn.get_name() + "\" already connected");
+
+                delete *coit;
+                coit = _connectors.erase(coit);
+
+                _sim.get_cont_man().set_fail();
+                return;
+            }
+            else
+            {
+                scd_info("connected channel \"" + conn.get_name() + "\"");
+                chan.connect(conn.get_connection());
+
+                delete *coit;
+                coit = _connectors.erase(coit);
+            }
+        } // end channel connected
+        else
+        {
+            // still trying to connect
+            coit++;
+        }
+        // end this connector
+    } // end check all connectors
+
+    // check if everything is initiated
+    _check_ready();
+
+} // init_process()
+
+
+void scd_chan_man::connect_channel(const scd_command &c, scd_socket* sock)
+{
+    std::string name = c.get_string();
+
+    scd_chan_wrapper* chan = _get_channel(name);
+
+    if (chan == NULL)
+    {
+        scd_warn("unknown channel \"" + name + "\" supplied by peer");
+        delete sock;
+    }
+    else if (chan->is_initialized())
+    {
+        scd_warn("channel \"" + name + "\" supplied by peer already connected");
+    }
+    else
+    {
+        scd_info("connected channel \"" + name + "\"");
+        chan->connect(sock);
+    }
+    
+} // connect()
+
+
+bool scd_chan_man::ready() const { return _is_ready; }
+
+
+void scd_chan_man::process()
+{
+    std::list<scd_chan_wrapper*>::iterator chit;
+
+    for (chit = _channels.begin(); chit != _channels.end(); chit++)
+        (*chit)->process();
+
+} // process()
+
+
+void scd_chan_man::close()
+{
+    std::list<scd_out_connector*>::iterator coit;
+    std::list<scd_chan_wrapper*>::iterator chit;
+
+    for (coit = _connectors.begin(); coit != _connectors.end(); coit++)
+        (*coit)->close();
+
+    for (chit = _channels.begin(); chit != _channels.end(); chit++)
+        (*chit)->close();
+
+} // close()
+
+
+bool scd_chan_man::_check_ready()
+{
+    if (_is_ready)
+        return true;
+
+    if (_connectors.empty())
+    {
+        std::list<scd_chan_wrapper*>::iterator chit;
+
+        // check all channels
+        for (chit = _channels.begin(); chit != _channels.end(); chit++)
+        {
+            if ( !(*chit)->is_initialized() )
+                return false;
+        }
+
+        // all channels initiated
+        _is_ready = true;
+        return true;
+    }
+    else
+        return false;
+
+} // _check_ready()
+
+
+scd_chan_wrapper* scd_chan_man::_get_channel(const std::string& name)
+{
+    std::list<scd_chan_wrapper*>::iterator chit;
+
+    for (chit = _channels.begin(); chit != _channels.end(); chit++)
+    {
+        if ( (*chit)->get_name() == name )
+            return *chit;
+    }
+
+    return NULL;
+
+} // _get_channel()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_chan_man.h b/dol/src/dol/visitor/hdsd/scd/scd_chan_man.h
new file mode 100644 (file)
index 0000000..0b026cc
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef SCD_CHAN_MAN_H
+#define SCD_CHAN_MAN_H
+
+#include <string>
+#include <list>
+
+#include <systemc>
+using sc_core::sc_prim_channel;
+
+#include "scd_simulator.h"
+#include "scd_command.h"
+#include "scd_chan_wrapper.h"
+#include "scd_out_connector.h"
+
+
+/* forward declaration */
+class scd_out_connector;
+class scd_chan_wrapper;
+
+
+/**
+ * The channel manager holds all remote channels. The channels have
+ * to be registered before the simulator is initiated. The channel
+ * manager will then initiate connections to other simulators
+ * and will handle channels from incomming connections.
+ * During simulation data is sent from the channel output buffers
+ * to remote hosts and data is received and stored in the input buffers.
+ * The channel implementation will then generate events to resume
+ * simulation processes.
+ */
+class scd_chan_man
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulator
+     */
+    scd_chan_man(scd_simulator &sim);
+
+    virtual ~scd_chan_man();
+
+    /**
+     * Registers a remote channel with master endpoint on this host.
+     * Another host will initiate the connection and the channel will
+     * be connected by an in-connector calling connect_channel().
+     * \param name the name of the remote channel
+     * \param mchan the SystemC channel implementing the
+     * remote-in and/or the remote-out interface.
+     */
+    void register_channel(const std::string &name, sc_prim_channel& mchan);
+
+    /**
+     * Registers a remote channel with slave endpoint on this host.
+     * This host will initiate the connection to the host with the
+     * master endpoint. To drive this process init_process() has to
+     * be called periodically.
+     * \param name the name of the remote channel
+     * \param mchan the SystemC channel implementing the
+     * remote-in and/or the remote-out interface.
+     * \param host the FQDN or IP address of the remote simulator
+     * with the master endpoint of the channel
+     * \param port TCP port of the remote simulator
+     */
+    void register_channel(const std::string &name, sc_prim_channel& schan,
+            const std::string &host, const uint16_t port);
+    /**
+     * Drives the initialization process. Restarts outgoing connection
+     * attempts to connect channels to other simulators if previous
+     * attempts have timed out. ready() indicates the end of the
+     * initialization.
+     */
+    void init_process();
+
+    /**
+     * Connects a channel from an incomming connection. Is intended to be
+     * called from an in-connector.
+     * \param c the register command received by the in-connector (contains
+     * the channel name)
+     * \param sock the socket of the incoming connection that is used
+     * as the data channel
+     */
+    void connect_channel(const scd_command &c, scd_socket* sock);
+
+    /**
+     * Indicates if all clients have been connected.
+     * \return true if the channel manager completed initialization
+     */
+    bool ready() const;
+
+    /**
+     * Checks if channels have data in the output buffers and activates
+     * the transmission if necessary. Receiption is resumed if the input
+     * buffer can accept data again. Call this function after each
+     * simulation step (which might fill data into the buffers that has
+     * to be sent).
+     */
+    void process();
+
+    /**
+     * Closes all channels.
+     */
+    void close();
+
+private:
+    /* member variables */
+    scd_simulator& _sim;
+    std::list<scd_chan_wrapper*> _channels;
+    std::list<scd_out_connector*> _connectors;
+
+    bool _is_ready;
+
+    /* member functions */
+    bool _check_ready();
+    scd_chan_wrapper* _get_channel(const std::string& name);
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_chan_wrapper.cpp b/dol/src/dol/visitor/hdsd/scd/scd_chan_wrapper.cpp
new file mode 100644 (file)
index 0000000..2629240
--- /dev/null
@@ -0,0 +1,201 @@
+#include "scd_chan_wrapper.h"
+
+#include <cassert>
+#include <cstdio>
+
+#include "scd_logging.h"
+
+
+scd_chan_wrapper::scd_chan_wrapper(scd_simulator& sim, const std::string& name,
+        sc_prim_channel& chan):
+    _sim(sim), _name(name), _is_initialized(false),
+    _is_writing(false), _is_reading(false)
+{
+    try
+    {
+        _chan_in = &dynamic_cast<scd_rem_chan_in_if&>(chan);
+    } catch (std::bad_cast e)
+    {
+        _chan_in = NULL;
+    }
+
+    try
+    {
+        _chan_out = &dynamic_cast<scd_rem_chan_out_if&>(chan);
+    } catch (std::bad_cast e)
+    {
+        _chan_out = NULL;
+    }
+
+    if (_chan_in == NULL && _chan_out == NULL)
+        scd_warn("channel \"" + _name + "\" is not a remote channel");
+}
+
+
+scd_chan_wrapper::~scd_chan_wrapper()
+{
+    if ( _is_initialized )
+    {
+        _sim.get_poller().remove_handler(*this);
+        _socket->close();
+        delete _socket;
+    }
+}
+
+
+bool scd_chan_wrapper::is_initialized() const { return _is_initialized; }
+
+
+const std::string& scd_chan_wrapper::get_name() const { return _name; }
+
+
+void scd_chan_wrapper::connect(scd_socket* sock)
+{
+    assert(!_is_initialized);
+
+    _socket = sock;
+    _is_initialized = true;
+
+    sock_ev flags = SOCK_EV_CLOSE;
+    if (_chan_in != NULL)
+    {
+        flags |= SOCK_EV_READ;
+        _is_reading = true;
+    }
+    _sim.get_poller().register_handler(*this, flags);
+
+} // connect()
+
+
+void scd_chan_wrapper::process()
+{
+    // check if channel has data to send
+    if (_chan_out != NULL && _is_initialized )
+    {
+        if (!_is_writing && _socket->is_valid() && _chan_out->available() > 0 )
+        {
+            // register write event
+            sock_ev events;
+            _sim.get_poller().get_ev(*this, events);
+            events |= SOCK_EV_WRITE;
+            _sim.get_poller().set_ev( *this, events );
+            _is_writing = true;
+        }
+    }
+
+    // check if channel has data to read
+    if (_chan_in != NULL && _is_initialized )
+    {
+        if (!_is_reading && _socket->is_valid() && _chan_in->free() > 0 )
+        {
+            // register read event
+            sock_ev events;
+            _sim.get_poller().get_ev(*this, events);
+            events |= SOCK_EV_READ;
+            _sim.get_poller().set_ev( *this, events );
+            _is_reading = true;
+        }
+    }
+
+} // process()
+
+
+void scd_chan_wrapper::close()
+{
+    if (_is_initialized)
+        _socket->close();
+
+} // close()
+
+
+void scd_chan_wrapper::handle_sock_ev(sock_ev events)
+{
+    if (events & SOCK_EV_CLOSE)
+    {
+        scd_debug("channel \"" + _name + "\" closed connection");
+        _sim.get_poller().set_ev(*this, 0);
+        _sim.get_cont_man().set_fail();
+        close();
+        return;
+    } // end close event
+
+    if (events & SOCK_EV_READ)
+    {
+        _read_event();
+    }
+
+    if (events & SOCK_EV_WRITE)
+    {
+        _write_event();
+    }
+
+} // handle_sock_ev()
+
+
+const scd_socket& scd_chan_wrapper::get_sock() { return *_socket; }
+
+
+void scd_chan_wrapper::_read_event()
+{
+    size_t free = _chan_in->free();
+
+    /* receive portions as long as they can be received */
+    size_t recv = 0xFF; //dummy
+    while ( free != 0 && recv != 0)
+    {
+        free = ( free < SCD_CHAN_BUFLEN ) ? free : SCD_CHAN_BUFLEN ;
+        recv = _socket->recv(_buf, free);
+        if (recv != 0)
+            _chan_in->receive(_buf, recv);
+        free = _chan_in->free();
+    }
+
+    if (free == 0)
+    {
+        sock_ev events;
+        _sim.get_poller().get_ev(*this, events);
+        events &= ~SOCK_EV_READ;
+        _sim.get_poller().set_ev(*this, events );
+        _is_reading = false;
+        return;
+    }
+
+    if (!_socket->is_valid())
+    {
+        scd_debug("channel \"" + _name + "\" closed connection");
+        _sim.get_poller().set_ev(*this, 0);
+        _sim.get_cont_man().set_fail();
+        return;
+    }
+
+} // end _read_event()
+
+
+void scd_chan_wrapper::_write_event()
+{
+    /* send portions as long as they can be sent */
+    size_t sent = 0xFF; //dummy
+    while ( sent )
+    {
+        sent = _socket->send( _chan_out->send(), _chan_out->available() );
+        if (sent != 0)
+            _chan_out->remove(sent);
+    }
+
+    if (_chan_out->available() == 0)
+    {
+        sock_ev events;
+        _sim.get_poller().get_ev(*this, events);
+        events &= ~SOCK_EV_WRITE;
+        _sim.get_poller().set_ev(*this, events );
+        _is_writing = false;
+        return;
+    }
+
+    if (!_socket->is_valid())
+    {
+        scd_debug("channel \"" + _name + "\" closed connection");
+        _sim.get_poller().set_ev(*this, 0);
+        _sim.get_cont_man().set_fail();
+    }
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_chan_wrapper.h b/dol/src/dol/visitor/hdsd/scd/scd_chan_wrapper.h
new file mode 100644 (file)
index 0000000..44115b0
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef SCD_CHAN_WRAPPER_H
+#define SCD_CHAN_WRAPPER_H
+
+#include <string>
+
+#include <systemc>
+using sc_core::sc_prim_channel;
+
+#include "scd_sock_poller.h"
+#include "scd_socket.h"
+#include "scd_simulator.h"
+#include "scd_rem_chan_if.h"
+
+
+/**
+ * Size of the input buffer. Limits the ammount of data that
+ * can be read from the socket in one system call.
+ */
+static const size_t SCD_CHAN_BUFLEN = 512;
+
+/* forward declaration */
+class scd_simulator;
+
+
+/**
+ * Wrapper for a remote channel. Writes data from the output buffer
+ * of the channel to the socket. Receives data from the socket and 
+ * writes it to the input buffer of the channel.
+ */
+class scd_chan_wrapper : public scd_sock_ev_handler_if
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     * \param name the name of the channel
+     * \param chan the SystemC channel implementing 
+     * remote channel interface(s)
+     */
+    scd_chan_wrapper(scd_simulator& sim, const std::string& name,
+            sc_prim_channel& chan);
+
+    virtual ~scd_chan_wrapper();
+
+    /**
+     * Indicates if a socket has been set for this channel.
+     * \return true if a socket has been set
+     */
+    bool is_initialized() const;
+
+    /**
+     * Returns the name of the channel.
+     */
+    const std::string& get_name() const;
+
+    /**
+     * Sets the socket of the channel.
+     */
+    void connect(scd_socket* sock);
+
+    /**
+     * Checks if data has to be send or can be received again and activates
+     * transmission if necessary. Call this function after every simulation
+     * step.
+     */
+    void process();
+
+    /**
+     * Closes the connection to the peer.
+     */
+    void close();
+    
+
+    /* scd_sock_ev_handler_if */
+    void handle_sock_ev(sock_ev events);
+    const scd_socket &get_sock();
+
+private:
+    scd_simulator& _sim;
+    std::string _name;
+    bool _is_initialized;
+
+    scd_socket* _socket;
+    scd_rem_chan_in_if* _chan_in;
+    scd_rem_chan_out_if* _chan_out;
+    char _buf[SCD_CHAN_BUFLEN];
+    bool _is_writing;
+    bool _is_reading;
+
+    /* member functions */
+    void _write_event();
+    void _read_event();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command.cpp b/dol/src/dol/visitor/hdsd/scd/scd_command.cpp
new file mode 100644 (file)
index 0000000..008171d
--- /dev/null
@@ -0,0 +1,105 @@
+#include "scd_command.h"
+
+#include "cstring"
+#include "arpa/inet.h"
+
+
+scd_command::scd_command(): _type(0), _subtype(0), _msglen(0)
+{
+    _msg = NULL;
+}
+
+
+scd_command::scd_command(uint16_t type, uint16_t subtype):
+    _type(type), _subtype(subtype), _msglen(0)
+{
+    _msg = NULL;
+}
+
+
+scd_command::scd_command(uint16_t type, uint16_t subtype, 
+        const std::string& msg):
+    _type(type), _subtype(subtype)
+{
+    if (msg.length() > 0)
+    {
+        _msglen = msg.length()+1;
+        _msg = new char[_msglen];
+        strncpy(_msg, msg.c_str(), _msglen);
+        _msg[_msglen-1] = 0;
+    }
+    else
+    {
+        _msglen = 0;
+        _msg = NULL;
+    }
+}
+
+
+scd_command::scd_command(uint16_t type, uint16_t subtype,
+        const sc_core::sc_time& time) : _type(type), _subtype(subtype)
+{
+    uint64_t value;
+    uint32_t hi, lo;
+
+    _msglen = 8;
+    _msg = new char[_msglen];
+
+    // obtain high and low words
+    value = time.value();
+    lo = value & 0xFFFFFFFF;
+    value >>= 32;
+    hi = value & 0xFFFFFFFF;
+
+    // do network conversion
+    hi = htonl(hi);
+    lo = htonl(lo);
+
+    // store to buffer
+    memcpy(_msg, &hi, 4);
+    memcpy(_msg + 4, &lo, 4);
+}
+
+
+
+scd_command::~scd_command()
+{
+    if (_msg != NULL)
+        delete _msg;
+}
+
+
+uint16_t scd_command::get_type() const { return _type; }
+
+
+uint16_t scd_command::get_subtype() const { return _subtype; }
+
+
+std::string scd_command::get_string() const
+{
+    if (_msglen <= 1)
+        return std::string();
+    else
+        return std::string(_msg, _msglen-1);
+}
+
+
+sc_core::sc_time scd_command::get_time() const
+{
+    if (_msglen != 8)
+        return sc_core::SC_ZERO_TIME;
+
+    uint64_t value;
+    uint32_t hi, lo;
+    
+    // get value from buffer
+    memcpy(&hi, _msg, 4);
+    memcpy(&lo, _msg+4, 4);
+
+    // do network conversion
+    value = ntohl(hi);
+    value <<= 32;
+    value |= ntohl(lo);
+
+    return sc_core::sc_time(value, false);
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command.h b/dol/src/dol/visitor/hdsd/scd/scd_command.h
new file mode 100644 (file)
index 0000000..cbb3bed
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef SCD_COMMAND_H
+#define SCD_COMMAND_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <string>
+
+#include "systemc"
+
+
+const size_t SCD_CM_MAXLEN = 512;
+const size_t SCD_CM_HEADER = 3*2;
+
+/* command types */
+const uint16_t SCD_CM_REGISTER = 1;
+const uint16_t SCD_CM_CONFIG = 2;
+const uint16_t SCD_CM_CONTROL = 3;
+
+/* command subtypes */
+// register
+const uint16_t SCD_CM_NETSIM = 1;
+const uint16_t SCD_CM_CHANNEL = 2;
+// control
+const uint16_t SCD_CM_BUSY = 1;
+const uint16_t SCD_CM_IDLE = 2;
+const uint16_t SCD_CM_DONE = 3;
+const uint16_t SCD_CM_FAILED = 4;
+const uint16_t SCD_CM_TIME_REQ = 5;
+const uint16_t SCD_CM_TIME_ACK = 6;
+const uint16_t SCD_CM_TIME_NACK = 7;
+const uint16_t SCD_CM_TIME = 8;
+const uint16_t SCD_CM_TERM_REQ = 9;
+const uint16_t SCD_CM_TERM_ACK = 10;
+const uint16_t SCD_CM_TERM_NACK = 11;
+const uint16_t SCD_CM_TERM = 12;
+
+/* forward declarations */
+class scd_command_reader;
+class scd_command_writer;
+
+
+/**
+ * Command class. Commands are control messages that are sent between
+ * the different simulators. A command has a type, a subtype and a potential
+ * message part.
+ */
+class scd_command
+{
+friend class scd_command_reader;
+friend class scd_command_writer;
+
+public:
+    /**
+     * Default constructor. Creates an empty command.
+     */
+    scd_command();
+    
+    /*
+     * Constructor. Creates a command with no message part.
+     * \param type the type of this command
+     * \param subtype the subtype of this command
+     */
+    scd_command(uint16_t type, uint16_t subtype);
+
+    /**
+     * Constructor. Creates a new command with a string as message
+     * part.
+     */
+    scd_command(uint16_t type, uint16_t subtype, const std::string& msg);
+
+    /**
+     * Constructor. Creates a new command with a SystemC time value as
+     * message part.
+     */
+    scd_command(uint16_t type, uint16_t subtype, const sc_core::sc_time& time);
+
+    virtual ~scd_command();
+
+    /**
+     * Returns the type of the command.
+     */
+    uint16_t get_type() const;
+
+    /**
+     * Returns the subtype of the command.
+     */
+    uint16_t get_subtype() const;
+
+    /**
+     * Returns the message part interpreted as a string.
+     */
+    std::string get_string() const;
+    
+    /**
+     * Returns the message part interpreted as a SystemC time.
+     * If the message part does not have the correct size SC_ZERO_TIME
+     * is returned instead.
+     */
+    sc_core::sc_time get_time() const;
+
+private:
+        uint16_t _type;
+        uint16_t _subtype;
+        uint16_t _msglen;
+        char* _msg;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command_reader.cpp b/dol/src/dol/visitor/hdsd/scd/scd_command_reader.cpp
new file mode 100644 (file)
index 0000000..7c9d904
--- /dev/null
@@ -0,0 +1,119 @@
+#include "scd_command_reader.h"
+
+#include <arpa/inet.h>
+
+#include "scd_logging.h"
+
+
+scd_command_reader::scd_command_reader():
+    _command(NULL), _is_reading(false), _success(false) {}
+
+
+scd_command_reader::~scd_command_reader()
+{
+    if (_is_reading || _success)
+    {
+        delete _command;
+    }
+}
+
+
+void scd_command_reader::set_socket(scd_socket& sock) { _socket = &sock; }
+
+
+void scd_command_reader::read()
+{
+    if (!_is_reading)
+    {
+        if (_success)
+            return;
+
+        _is_reading = true;
+        _header_read = false;
+        _remaining = SCD_CM_HEADER;
+        _off = 0;
+        _command = new scd_command;
+    }
+
+    // receive header
+    if (!_header_read)
+    {
+        // read header
+        size_t read = _socket->recv(_header_buf + _off, _remaining);
+        _remaining -= read;
+        _off += read;
+
+        if (_remaining == 0)
+        {
+            // read values from buffer
+            uint16_t* intbuf = reinterpret_cast<uint16_t*>(_header_buf);
+            _command->_type = ntohs( intbuf[0] );
+            _command->_subtype = ntohs( intbuf[1] );
+            _command->_msglen = ntohs( intbuf[2] );
+
+            _header_read = true;
+
+            // allocate buffer for further receiption
+            if (_command->_msglen > 0)
+            {
+                if (_command->_msglen > SCD_CM_MAXLEN)
+                {
+                    // illegal command
+                    _command->_msglen = 0;
+                    delete _command;
+                    _is_reading = false;
+                }
+                else
+                {
+                    _command->_msg = new char[_command->_msglen];
+                    _remaining = _command->_msglen;
+                    _off = 0;
+                }
+            }
+            else
+            {
+                // command without payload
+                _command->_msglen = 0; // to prevent negative values
+                _remaining = 0;
+                _is_reading = false;
+                _success = true;
+            }
+        }
+    }
+
+    // receive msg
+    if (_header_read && _is_reading)
+    {
+        size_t read = _socket->recv(_command->_msg + _off, _remaining);
+        _remaining -= read;
+        _off += read;
+
+        if (_remaining == 0)
+        {
+            _is_reading = false;
+            _success = true;
+        }
+    }
+
+} // read()
+
+
+bool scd_command_reader::is_reading() { return _is_reading; }
+
+
+bool scd_command_reader::has_command() { return _success; }
+
+
+scd_command* scd_command_reader::get_command()
+{
+    if (!_success)
+    {
+        return NULL;
+    }
+    else
+    {
+        _success = false;
+        return _command;
+    }
+
+} // get_command()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command_reader.h b/dol/src/dol/visitor/hdsd/scd/scd_command_reader.h
new file mode 100644 (file)
index 0000000..db06830
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef SCD_COMMAND_READER_H
+#define SCD_COMMAND_READER_H
+
+#include "scd_command.h"
+#include "scd_socket.h"
+
+/**
+ * Reads commands from a socket. The receiption does not have to complete
+ * withing one call. As long as it is ongoing the socket shall not be read
+ * by the application.
+ */
+class scd_command_reader
+{
+public:
+    scd_command_reader();
+
+    virtual ~scd_command_reader();
+
+    /**
+     * Sets the socket to read from. Do not try to read before setting the
+     * socket.
+     */
+    void set_socket(scd_socket &sock);
+
+    /**
+     * Initiates reading a command if it is not reading yet or continues
+     * to read a previously unfinished command.
+     */
+    void read();
+
+    /**
+     * Indicates if a command is being read. This is the case between calling
+     * read() and the completion of the command (or failure if an illegal
+     * command was received).
+     * \return true if a command is currently being received
+     */
+    bool is_reading();
+
+    /**
+     * Indicates if a command has been received successfully and is ready
+     * to be picked up.
+     * \return true if a command can be collected
+     */
+    bool has_command();
+
+    /**
+     * Returns a successfully received command. The application has to free
+     * it by itself. The reader does not keep a reference.
+     * \return the command or NULL if has_command() is false
+     */
+    scd_command* get_command();
+
+private:
+    scd_socket* _socket;
+    scd_command* _command;
+    bool _is_reading;
+    bool _header_read;
+    bool _success;
+    size_t _remaining;
+    size_t _off;
+    char _header_buf[SCD_CM_HEADER];
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command_writer.cpp b/dol/src/dol/visitor/hdsd/scd/scd_command_writer.cpp
new file mode 100644 (file)
index 0000000..64193ff
--- /dev/null
@@ -0,0 +1,93 @@
+#include "scd_command_writer.h"
+
+#include <string.h>
+
+#include "scd_logging.h"
+
+
+scd_command_writer::scd_command_writer():
+    _is_writing(false), _remaining(0) {}
+
+
+scd_command_writer::~scd_command_writer()
+{
+    std::list<scd_command*>::iterator iter;
+    for ( iter = _commands.begin(); iter != _commands.end(); iter++)
+        delete *iter;
+}
+
+
+void scd_command_writer::set_socket(scd_socket& sock) { _socket = &sock; }
+
+
+bool scd_command_writer::is_writing() const { return _is_writing; }
+
+
+bool scd_command_writer::queue_command(scd_command* cmd)
+{
+    if (cmd->_msglen <= SCD_CM_MAXLEN)
+    {
+        _commands.push_back(cmd);
+        _is_writing = true;
+        return true;
+    }
+    else
+    {
+        scd_warn("command too long");
+        delete cmd;
+        return false;
+    }
+}
+
+void scd_command_writer::write()
+{
+    bool finishedmsg;
+    do
+    {
+        finishedmsg = _send_cmd();
+    }
+    while (finishedmsg);
+
+} // write()
+
+
+inline bool scd_command_writer::_send_cmd()
+{
+    if (!_is_writing)
+        return false;
+
+    if (_remaining == 0)
+    {
+        /* fetch next command */
+        scd_command* cmd = _commands.front();
+        _commands.pop_front();
+
+        // store header to buffer
+        uint16_t* intbuf = reinterpret_cast<uint16_t*>(_buf);
+        intbuf[0] = htons(cmd->_type);
+        intbuf[1] = htons(cmd->_subtype);
+        intbuf[2] = htons(cmd->_msglen);
+
+        // store message to buffer
+        memcpy(_buf + SCD_CM_HEADER, cmd->_msg, cmd->_msglen);
+
+        _remaining = SCD_CM_HEADER + cmd->_msglen;
+        _off = 0;
+        delete cmd;
+    }
+
+    size_t sent = _socket->send(_buf + _off, _remaining);
+
+    _off += sent;
+    _remaining -= sent;
+
+    if (_remaining == 0)
+    {
+        if (_commands.empty())
+            _is_writing = false;
+        return true;
+    }
+    else
+        return false;
+    
+} // _send_cmd()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_command_writer.h b/dol/src/dol/visitor/hdsd/scd/scd_command_writer.h
new file mode 100644 (file)
index 0000000..a8bb427
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef SCD_COMMAND_WRITER_H
+#define SCD_COMMAND_WRITER_H
+
+#include <list>
+
+#include "scd_command.h"
+#include "scd_socket.h"
+
+
+/**
+ * Queues multiple commands and writes then to a socket continuously.
+ */
+class scd_command_writer
+{
+public:
+    scd_command_writer();
+
+    virtual ~scd_command_writer();
+
+    /**
+     * Sets the socket to write to. Do not try to write before
+     * setting the socket.
+     */
+    void set_socket(scd_socket& sock);
+
+    /**
+     * Indicates if the writer is currently sending a command.
+     * \return true if the writer is busy sending commands
+     */
+    bool is_writing() const;
+
+    /**
+     * Queues a command to be sent. Commands will be sent out in FIFO
+     * manner. Sending is not initiated by this call.
+     * \param message to send
+     * \return false if the message is longet than SCD_CM_MAXLEN. In this
+     * case the message is destroyed.
+     */
+    bool queue_command(scd_command* cmd);
+
+    /**
+     * Write commands or part of commands to the socket. As many queued
+     * commands as possible are sent but none has to be finished.
+     * \exception scd_exception if unexpected errors occured
+     */
+    void write();
+
+private:
+    scd_socket* _socket;
+    bool _is_writing;
+
+    std::list<scd_command*>_commands;
+    char _buf[SCD_CM_HEADER + SCD_CM_MAXLEN];
+    size_t _remaining;
+    size_t _off;
+
+    inline bool _send_cmd();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_man.h b/dol/src/dol/visitor/hdsd/scd/scd_cont_man.h
new file mode 100644 (file)
index 0000000..5499984
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef SCD_CONT_MAN_H
+#define SCD_CONT_MAN_H
+
+#include <string>
+
+#include "fsm/scd_cont_fsm_if.h"
+
+
+const bool SCD_MASTER = true;
+const bool SCD_SLAVE = false;
+
+const int SCD_CONT_DELAY = 20;
+
+/**
+ * Control manager. Shall be set up before the simulation is initialized.
+ */
+class scd_cont_man : public scd_cont_fsm_if
+{
+public:
+    virtual ~scd_cont_man() {};
+
+    /**
+     * Sets the master simulator for a slave.
+     * \param host the FQDN or IP of the master simulator
+     * \param port the TCP port of the master simulator
+     * \exception scd_exception if the simulator is not a slave
+     */
+    virtual void set_master(const std::string& host, uint16_t port) = 0;
+    
+    /**
+     * Registers a slave simulator for the master.
+     * \param name the name of the slave
+     * \exception scd_exception if the simulator is not the master
+     */
+    virtual void register_slave(const std::string& name) = 0;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_man_master.cpp b/dol/src/dol/visitor/hdsd/scd/scd_cont_man_master.cpp
new file mode 100644 (file)
index 0000000..932644c
--- /dev/null
@@ -0,0 +1,93 @@
+#include "scd_cont_man_master.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+scd_cont_man_master::scd_cont_man_master(scd_simulator& sim):
+    _sim(sim), scd_cont_fsm("master"),
+    _st_init(sim, *this), _st_busy(sim, *this), _st_idle(sim, *this),
+    _st_done(sim, *this), _st_time_req(sim, *this), _st_time(sim, *this),
+    _st_term_req(sim, *this), _st_terminate(sim, *this),
+    _st_terminated(sim, *this), _st_fail(sim, *this), _st_failed(sim, *this)
+{
+    // set initial state
+    set_state(_st_init);
+}
+
+
+scd_cont_man_master::~scd_cont_man_master()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator it;
+
+    for (it = _slaves.begin(); it != _slaves.end(); it++)
+        delete *it;
+}
+
+
+void scd_cont_man_master::connect_slave(const scd_command &c, scd_socket* sock)
+{
+    std::string name = c.get_string();
+
+    scd_cont_slave_wrapper* slave = _get_slave(name);
+
+    if (slave == NULL)
+    {
+        scd_warn("unknown slave \"" + name + "\"");
+        delete sock;
+    }
+    else
+        slave->connect(sock);
+    
+} // connect()
+
+
+void scd_cont_man_master::set_master(const std::string& host, uint16_t port)
+{
+    scd_error("simulator is master, can not have another master");
+    throw scd_exception("simulator is master");
+} // set_master()
+
+
+void scd_cont_man_master::register_slave(const std::string& name)
+{
+    if ( _get_slave(name) != NULL )
+    {
+        scd_warn("slave \"" + name + "\" already registered, ignoring...");
+    }
+    else
+    {
+        scd_cont_slave_wrapper* wrap;
+        wrap = new scd_cont_slave_wrapper(_sim, name);
+        _slaves.push_back(wrap);
+    }
+
+} // register_slave
+
+
+void scd_cont_man_master::process()
+{
+    std::list<scd_cont_slave_wrapper*>::iterator it;
+
+    // process all slaves
+    for (it = _slaves.begin(); it != _slaves.end(); it++)
+        (*it)->process();
+
+    // process the local state
+    _state->process();
+}
+
+
+scd_cont_slave_wrapper* scd_cont_man_master::_get_slave(const std::string& name)
+{
+    std::list<scd_cont_slave_wrapper*>::iterator it;
+
+    for (it = _slaves.begin(); it != _slaves.end(); it++)
+    {
+        if ( (*it)->get_name() == name )
+            return *it;
+    }
+
+    return NULL;
+
+} // _get_slave()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_man_master.h b/dol/src/dol/visitor/hdsd/scd/scd_cont_man_master.h
new file mode 100644 (file)
index 0000000..f240321
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef SCD_CONT_MAN_MASTER_H
+#define SCD_CONT_MAN_MASTER_H
+
+#include <list>
+
+#include "scd_simulator.h"
+#include "scd_cont_man.h"
+#include "scd_cont_slave_wrapper.h"
+#include "fsm/scd_cont_fsm.h"
+
+#include "fsm/scd_stm_init.h"
+#include "fsm/scd_stm_busy.h"
+#include "fsm/scd_stm_idle.h"
+#include "fsm/scd_stm_done.h"
+#include "fsm/scd_stm_time_req.h"
+#include "fsm/scd_stm_time.h"
+#include "fsm/scd_stm_term_req.h"
+#include "fsm/scd_stm_terminate.h"
+#include "fsm/scd_stm_terminated.h"
+#include "fsm/scd_stm_fail.h"
+#include "fsm/scd_stm_failed.h"
+
+/**
+ * Control manager for the master. Waits for all slaves to connect.
+ * Synchronizes the global simulation state.
+ */
+class scd_cont_man_master : public scd_cont_man, public scd_cont_fsm
+{
+    friend class scd_stm_base;
+
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     */
+    scd_cont_man_master(scd_simulator& sim);
+
+    virtual ~scd_cont_man_master();
+
+    /**
+     * Connects a slave. Is called from an in-connector.
+     * \param c the register command that has been received by the in-connector
+     * (contains the slave name).
+     * \param sock the incomming connection
+     */
+    void connect_slave(const scd_command& c, scd_socket* sock);
+
+    /* scd_cont_man */
+    void set_master(const std::string& host, uint16_t port);
+    void register_slave(const std::string& name);
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& t) { return _state->set_idle(t); }
+    void set_busy() { return _state->set_busy(); }
+    void set_done() { return _state->set_done(); }
+    void set_fail() { return _state->set_fail(); }
+    void process();
+    bool active() const { return _state->active(); }
+    bool busy() const { return _state->busy(); }
+    bool failed() const { return _state->failed(); }
+    bool advance_time() const { return _state->advance_time(); }
+    const sc_core::sc_time& get_time_step() { return _state->get_time_step(); }
+
+private:
+    scd_simulator& _sim;
+    std::list<scd_cont_slave_wrapper*> _slaves;
+    sc_core::sc_time _time_step;
+    
+    /* states */
+    scd_stm_init _st_init;
+    scd_stm_busy _st_busy;
+    scd_stm_idle _st_idle;
+    scd_stm_done _st_done;
+    scd_stm_time_req _st_time_req;
+    scd_stm_time _st_time;
+    scd_stm_term_req _st_term_req;
+    scd_stm_terminate _st_terminate;
+    scd_stm_terminated _st_terminated;
+    scd_stm_fail _st_fail;
+    scd_stm_failed _st_failed;
+
+    /* member functions */
+    scd_cont_slave_wrapper* _get_slave(const std::string& name);
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.cpp b/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.cpp
new file mode 100644 (file)
index 0000000..7368ef9
--- /dev/null
@@ -0,0 +1,181 @@
+#include "scd_cont_man_slave.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+scd_cont_man_slave::scd_cont_man_slave(scd_simulator& sim):
+    scd_cont_fsm("slave"), _sim(sim),
+    _connector(sim, SCD_CM_NETSIM, sim.get_name()), _has_master(false),
+    _st_init(sim, *this), _st_busy(sim, *this), _st_fail(sim, *this),
+    _st_failed(sim, *this), _st_idle(sim, *this), _st_done(sim, *this),
+    _st_time_ack(sim, *this), _st_time(sim, *this), _st_term_ack(sim, *this),
+    _st_terminated(sim, *this)
+{
+    // set initial state
+    set_state(_st_init);
+}
+
+
+scd_cont_man_slave::~scd_cont_man_slave()
+{
+    if (_socket != NULL)
+        delete _socket;
+}
+
+
+void scd_cont_man_slave::set_socket()
+{
+    _socket = _connector.get_connection();
+    _writer.set_socket(*_socket);
+    _reader.set_socket(*_socket);
+} // set_socket()
+
+
+void scd_cont_man_slave::send_command(scd_command* cmd)
+{
+    // register write event if not registered
+    if (!_writer.is_writing() && _socket->is_valid())
+        _sim.get_poller().set_ev(*this, SOCK_EV_WRITE | SOCK_EV_READ
+                | SOCK_EV_CLOSE);
+
+    // queue command to be written
+    _writer.queue_command(cmd);
+}
+
+
+bool scd_cont_man_slave::is_sending()
+{
+    return _writer.is_writing() && _socket->is_valid();
+}
+
+
+void scd_cont_man_slave::close()
+{
+    if (_socket != NULL)
+        _socket->close();
+}
+
+
+void scd_cont_man_slave::set_master(const std::string& host, uint16_t port)
+{
+    if (!_has_master)
+        _connector.connect_to(host, port);
+    else
+    {
+        scd_error("master already set");
+        throw scd_exception("master already set");
+    }
+} // set_master()
+
+
+void scd_cont_man_slave::register_slave(const std::string& name)
+{
+    scd_error("simulator is slave, can not have other slaves");
+    throw scd_exception("simulator is slave");
+
+} // register_slave
+
+
+void scd_cont_man_slave::handle_sock_ev(sock_ev events)
+{
+    scd_sts_base& state = *static_cast<scd_sts_base*>(_state);
+
+    if (events & SOCK_EV_CLOSE)
+    {
+        scd_error("connection to master lost");
+        _socket->close();
+        state.set_failed();
+        return;
+    }
+
+    if (events & SOCK_EV_READ)
+    {
+        _reader.read();
+     
+        if (!_socket->is_valid())
+        {
+            // connection closed
+            scd_error("connection to master lost");
+            state.set_failed();
+            return;
+        }
+
+        if (!_reader.is_reading() && !_reader.has_command())
+        {
+            // received an illegal command
+            scd_error("received illegal command");
+            state.set_fail();
+            return;
+        }
+
+        if (_reader.has_command())
+        {
+            scd_command* cmd = _reader.get_command();
+            _process_cmd(*cmd);
+            delete cmd;
+        }
+
+    } // end read event
+
+    if (events & SOCK_EV_WRITE)
+    {
+        _writer.write();
+        if (!_writer.is_writing())
+        {
+            // done sending commands
+            _sim.get_poller().set_ev(*this, SOCK_EV_READ | SOCK_EV_CLOSE);
+        }
+    } // end write event
+
+    if (!_socket->is_valid())
+    {
+        scd_error("connection to master lost");
+        state.set_failed();
+    }
+    
+} // handle_sock_ev()
+
+
+const scd_socket& scd_cont_man_slave::get_sock() { return *_socket; }
+
+
+void scd_cont_man_slave::_process_cmd(scd_command& cmd)
+{
+    if (cmd.get_type() != SCD_CM_CONTROL)
+    {
+        scd_warn("received non-control command");
+        return;
+    }
+
+    scd_sts_base* state = static_cast<scd_sts_base*>(_state);
+
+    switch (cmd.get_subtype())
+    {
+    case SCD_CM_FAILED:
+        scd_error("master failed");
+        state->set_failed();
+        break;
+    case SCD_CM_TIME_REQ:
+        state->recv_time_req();
+        break;
+    case SCD_CM_TIME_NACK:
+        state->recv_time_nack();
+        break;
+    case SCD_CM_TIME:
+        state->recv_time(cmd.get_time());
+        break;
+    case SCD_CM_TERM_REQ:
+        state->recv_term_req();
+        break;
+    case SCD_CM_TERM_NACK:
+        state->recv_term_nack();
+        break;
+    case SCD_CM_TERM:
+        state->recv_term();
+        break;
+    default:
+        scd_warn("received unknown command");
+        break;
+    }
+} // _process_cmd()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.h b/dol/src/dol/visitor/hdsd/scd/scd_cont_man_slave.h
new file mode 100644 (file)
index 0000000..4156f7c
--- /dev/null
@@ -0,0 +1,111 @@
+#ifndef SCD_CONT_MAN_SLAVE_H
+#define SCD_CONT_MAN_SLAVE_H
+
+#include "scd_simulator.h"
+#include "scd_socket.h"
+#include "scd_out_connector.h"
+#include "scd_command_writer.h"
+#include "scd_command_reader.h"
+#include "scd_cont_man.h"
+#include "scd_sock_poller.h"
+
+#include "fsm/scd_cont_fsm.h"
+#include "fsm/scd_sts_init.h"
+#include "fsm/scd_sts_busy.h"
+#include "fsm/scd_sts_idle.h"
+#include "fsm/scd_sts_done.h"
+#include "fsm/scd_sts_time_ack.h"
+#include "fsm/scd_sts_time.h"
+#include "fsm/scd_sts_term_ack.h"
+#include "fsm/scd_sts_terminated.h"
+#include "fsm/scd_sts_fail.h"
+#include "fsm/scd_sts_failed.h"
+
+/**
+ * Control manager for a slave. Connects to the master controller and
+ * synchronizes the local and global simulation state.
+ */
+class scd_cont_man_slave : public scd_cont_man, public scd_cont_fsm,
+    public scd_sock_ev_handler_if
+{
+    friend class scd_sts_base;
+
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     */
+    scd_cont_man_slave(scd_simulator& sim);
+
+    virtual ~scd_cont_man_slave();
+
+    /**
+     * Sets the socket where to read from and write to after the connection
+     * has been established to the master.
+     */
+    void set_socket();
+
+    /**
+     * Sends a command to the master.
+     * \param cmd the command to send
+     */
+    void send_command(scd_command* cmd);
+
+    /**
+     * Indicates if a command is being sent to the master (and did not finish
+     * yet).
+     * \return true if a command is currently being sent
+     */
+    bool is_sending();
+
+    /**
+     * Closes the connection to the master controller.
+     */
+    void close();
+    /* scd_cont_man */
+    void set_master(const std::string& host, uint16_t port);
+    void register_slave(const std::string& name);
+
+    /* scd_cont_fsm_if */
+    void set_idle(const sc_core::sc_time& t) { return _state->set_idle(t); }
+    void set_busy() { return _state->set_busy(); }
+    void set_done() { return _state->set_done(); }
+    void set_fail() { return _state->set_fail(); }
+    void process() { return _state->process(); }
+    bool active() const { return _state->active(); }
+    bool busy() const { return _state->busy(); }
+    bool failed() const { return _state->failed(); }
+    bool advance_time() const { return _state->advance_time(); }
+    const sc_core::sc_time& get_time_step() { return _state->get_time_step(); }
+
+    /* scd_sock_ev_handler_if */
+    void handle_sock_ev(sock_ev events);
+    const scd_socket& get_sock();
+
+private:
+    scd_simulator& _sim;
+    
+    scd_socket* _socket;
+    scd_out_connector _connector;
+    scd_command_writer _writer;
+    scd_command_reader _reader;
+    bool _has_master;
+
+    /* states */
+    scd_sts_init _st_init;
+    scd_sts_busy _st_busy;
+    scd_sts_idle _st_idle;
+    scd_sts_done _st_done;
+    scd_sts_time_ack _st_time_ack;
+    scd_sts_time _st_time;
+    scd_sts_term_ack _st_term_ack;
+    scd_sts_terminated _st_terminated;
+    scd_sts_fail _st_fail;
+    scd_sts_failed _st_failed;
+
+    /* member functions */
+    void _process_cmd(scd_command& cmd);
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_slave_wrapper.cpp b/dol/src/dol/visitor/hdsd/scd/scd_cont_slave_wrapper.cpp
new file mode 100644 (file)
index 0000000..0bc710a
--- /dev/null
@@ -0,0 +1,182 @@
+#include "scd_cont_slave_wrapper.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+
+scd_cont_slave_wrapper::scd_cont_slave_wrapper(scd_simulator& sim,
+        const std::string& name):
+    _sim(sim), scd_cont_fsm(name), _name(name), _is_connected(false),
+    _st_init(sim, *this), _st_busy(sim, *this), _st_idle(sim, *this),
+    _st_done(sim, *this), _st_time_req(sim, *this), _st_time_ack(sim, *this),
+    _st_term_req(sim, *this), _st_term_ack(sim, *this),
+    _st_terminate(sim, *this), _st_terminated(sim, *this), _st_fail(sim, *this),
+    _st_failed(sim, *this)
+{
+    // set initial state
+    set_state(_st_init);
+}
+
+
+scd_cont_slave_wrapper::~scd_cont_slave_wrapper()
+{
+    if (_socket != NULL)
+        delete _socket;
+}
+
+
+const std::string& scd_cont_slave_wrapper::get_name() const { return _name; }
+
+
+void scd_cont_slave_wrapper::connect(scd_socket* sock)
+{
+    if (!_is_connected)
+    {
+        _socket = sock;
+        _writer.set_socket(*_socket);
+        _reader.set_socket(*_socket);
+        _is_connected = true;
+        scd_info("slave \"" + _name + "\" connected");
+        static_cast<scd_stsw_base*>(_state)->set_connected();
+    }
+    else
+    {
+        scd_warn("slave " + _name + " has already been connected");
+        delete sock;
+    }
+} // connect()
+
+
+void scd_cont_slave_wrapper::send_command(scd_command* cmd)
+{
+    // register write event if not registered
+    if (!_writer.is_writing() && _is_connected && _socket->is_valid())
+        _sim.get_poller().set_ev(*this, SOCK_EV_WRITE | SOCK_EV_READ
+                | SOCK_EV_CLOSE);
+
+    // queue command to be written
+    _writer.queue_command(cmd);
+}
+
+
+bool scd_cont_slave_wrapper::is_sending() const
+{
+    return _writer.is_writing() && _is_connected && _socket->is_valid();
+}
+
+
+void scd_cont_slave_wrapper::close() 
+{
+    if (_is_connected)
+        _socket->close();
+}
+
+
+void scd_cont_slave_wrapper::handle_sock_ev(sock_ev events)
+{
+    scd_stsw_base& state = *static_cast<scd_stsw_base*>(_state);
+
+    if (events & SOCK_EV_CLOSE)
+    {
+        _socket->close();
+        scd_error("connection to slave \"" + _name + "\" lost");
+        state.set_failed();
+        return;
+    }
+
+    if (events & SOCK_EV_READ)
+    {
+        _reader.read();
+     
+        if (!_socket->is_valid())
+        {
+            // connection closed
+            scd_error("connection to slave \"" + _name + "\" lost");
+            state.set_failed();
+            return;
+        }
+
+        if (!_reader.is_reading() && !_reader.has_command())
+        {
+            // received an illegal command
+            scd_error("received illegal command");
+            state.set_fail();
+            return;
+        }
+
+        if (_reader.has_command())
+        {
+            scd_command* cmd = _reader.get_command();
+            _process_cmd(*cmd);
+            delete cmd;
+        }
+
+    } // end read event
+
+    if (events & SOCK_EV_WRITE)
+    {
+        _writer.write();
+
+        if (!_writer.is_writing())
+        {
+            // done sending commands
+            _sim.get_poller().set_ev(*this, SOCK_EV_READ | SOCK_EV_CLOSE);
+        }
+
+        if (!_socket->is_valid())
+        {
+            scd_error("connection to slave \"" + _name + "\" lost");
+            state.set_failed();
+            return;
+        }
+    } // end write event
+
+    
+} // handle_sock_ev()
+
+
+const scd_socket& scd_cont_slave_wrapper::get_sock() { return *_socket; }
+
+
+void scd_cont_slave_wrapper::_process_cmd(const scd_command& cmd)
+{
+    if (cmd.get_type() != SCD_CM_CONTROL)
+    {
+        scd_warn("received non-control command");
+        return;
+    }
+
+    scd_stsw_base* state = static_cast<scd_stsw_base*>(_state);
+    
+    switch(cmd.get_subtype())
+    {
+    case SCD_CM_BUSY:
+        state->set_busy();
+        break;
+    case SCD_CM_IDLE:
+        state->set_idle(cmd.get_time());
+        break;
+    case SCD_CM_DONE:
+        state->set_done();
+        break;
+    case SCD_CM_TIME_NACK:
+        state->recv_time_nack();
+        break;
+    case SCD_CM_TIME_ACK:
+        state->recv_time_ack();
+        break;
+    case SCD_CM_TERM_NACK:
+        state->recv_term_nack();
+        break;
+    case SCD_CM_TERM_ACK:
+        state->recv_term_ack();
+        break;
+    case SCD_CM_FAILED:
+        scd_error("slave \"" + _name + "\" failed");
+        state->set_failed();
+        break;
+    default:
+        scd_warn("received unknown command");
+        break;
+    }
+} // _process_cmd()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_cont_slave_wrapper.h b/dol/src/dol/visitor/hdsd/scd/scd_cont_slave_wrapper.h
new file mode 100644 (file)
index 0000000..882f9ac
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef SCD_CONT_SLAVE_WRAPPER_H
+#define SCD_CONT_SLAVE_WRAPPER_H
+
+#include "scd_simulator.h"
+#include "scd_socket.h"
+#include "scd_command_writer.h"
+#include "scd_command_reader.h"
+#include "scd_cont_man.h"
+#include "scd_sock_poller.h"
+#include "fsm/scd_cont_fsm.h"
+#include "fsm/scd_cont_wrapper_if.h"
+
+#include "fsm/scd_stsw_init.h"
+#include "fsm/scd_stsw_busy.h"
+#include "fsm/scd_stsw_idle.h"
+#include "fsm/scd_stsw_done.h"
+#include "fsm/scd_stsw_time_req.h"
+#include "fsm/scd_stsw_time_ack.h"
+#include "fsm/scd_stsw_term_req.h"
+#include "fsm/scd_stsw_term_ack.h"
+#include "fsm/scd_stsw_terminate.h"
+#include "fsm/scd_stsw_terminated.h"
+#include "fsm/scd_stsw_fail.h"
+#include "fsm/scd_stsw_failed.h"
+
+/**
+ * Control manager wrapper for a slave. Reflects the masters view of the
+ * slaves state.
+ */
+class scd_cont_slave_wrapper : public scd_cont_fsm_if, public scd_cont_fsm,
+    public scd_cont_wrapper_if, public scd_sock_ev_handler_if
+{
+    friend class scd_stsw_base;
+
+public:
+    /**
+     * Constructor.
+     * \param sim the simulation environment
+     * \param name the name of the slave
+     */
+    scd_cont_slave_wrapper(scd_simulator& sim, const std::string& name);
+
+    virtual ~scd_cont_slave_wrapper();
+
+    /**
+     * Returns the name of the slave.
+     */
+    const std::string& get_name() const;
+
+    /**
+     * Sets the socket of the slave.
+     * \param sock the connection to the slave
+     */
+    void connect(scd_socket* sock);
+
+    /**
+     * Sends a command to the slave.
+     */
+    void send_command(scd_command* cmd);
+
+    /**
+     * Indicates if a command is being sent to the slave.
+     * \return true if a command is still being sent
+     */
+    bool is_sending() const;
+
+    /**
+     * Closes the connection to the slave.
+     */
+    void close();
+    /* scd_cont_slave_wrapper_if */
+    void send_time_req()
+        { return static_cast<scd_stsw_base*>(_state)->send_time_req(); }
+    void send_time_nack()
+        { return static_cast<scd_stsw_base*>(_state)->send_time_nack(); }
+    void send_time(const sc_core::sc_time& time)
+        { return static_cast<scd_stsw_base*>(_state)->send_time(time); }
+    void send_term_req()
+        { return static_cast<scd_stsw_base*>(_state)->send_term_req(); }
+    void send_term_nack()
+        { return static_cast<scd_stsw_base*>(_state)->send_term_nack(); }
+    void send_term()
+        { return static_cast<scd_stsw_base*>(_state)->send_term(); }
+    bool time_req() const
+        { return static_cast<scd_stsw_base*>(_state)->time_req(); }
+    bool time_ack() const
+        { return static_cast<scd_stsw_base*>(_state)->time_ack(); }
+    bool term_req() const
+        { return static_cast<scd_stsw_base*>(_state)->term_req(); }
+    bool term_ack() const
+        { return static_cast<scd_stsw_base*>(_state)->term_ack(); }
+    bool idle() const
+        { return static_cast<scd_stsw_base*>(_state)->idle(); }
+    bool done() const
+        { return static_cast<scd_stsw_base*>(_state)->done(); }
+
+    /* scd_cont_fsm_if */
+    void set_busy() { return _state->set_busy(); }
+    void set_idle(const sc_core::sc_time& t) { return _state->set_idle(t); }
+    void set_done() { return _state->set_done(); }
+    void set_fail() { return _state->set_fail(); }
+    void process() { return _state->process(); }
+    bool active() const { return _state->active(); }
+    bool busy() const { return _state->busy(); }
+    bool failed() const { return _state->failed(); }
+    bool advance_time() const { return _state->advance_time(); }
+    const sc_core::sc_time& get_time_step() { return _state->get_time_step(); }
+
+    /* scd_sock_ev_handler_if */
+    void handle_sock_ev(sock_ev events);
+    const scd_socket& get_sock();
+
+private:
+    scd_simulator& _sim;
+    std::string _name;
+    bool _is_connected;
+    
+    scd_socket* _socket;
+    scd_command_writer _writer;
+    scd_command_reader _reader;
+    sc_core::sc_time _time_step;
+
+    /* states */
+    scd_stsw_init _st_init;
+    scd_stsw_busy _st_busy;
+    scd_stsw_idle _st_idle;
+    scd_stsw_done _st_done;
+    scd_stsw_time_req _st_time_req;
+    scd_stsw_time_ack _st_time_ack;
+    scd_stsw_term_req _st_term_req;
+    scd_stsw_term_ack _st_term_ack;
+    scd_stsw_terminate _st_terminate;
+    scd_stsw_terminated _st_terminated;
+    scd_stsw_fail _st_fail;
+    scd_stsw_failed _st_failed;
+
+    /* member functions */
+    void _process_cmd(const scd_command& cmd);
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_exception.cpp b/dol/src/dol/visitor/hdsd/scd/scd_exception.cpp
new file mode 100644 (file)
index 0000000..f5eb4f8
--- /dev/null
@@ -0,0 +1,35 @@
+#include "scd_exception.h"
+
+
+scd_exception::scd_exception(const std::string& msg): _msg(msg)
+{
+    _get_backtrace();
+}
+
+
+scd_exception::scd_exception(const std::string& msg, int errn)
+{
+    _msg = msg + ": " + std::string(strerror(errn));
+    _get_backtrace();
+}
+
+
+const char* scd_exception::what() throw() { return _msg.c_str(); }
+
+
+const char* scd_exception::stacktrace() { return _backtrace.c_str(); }
+
+
+void scd_exception::_get_backtrace()
+{
+    void* traces[SCD_EX_TRACES];
+    int num_traces = backtrace(traces, SCD_EX_TRACES);
+    char ** symbols = backtrace_symbols(traces, num_traces);
+    for (int i = 0; i < num_traces; i++)
+    {
+        _backtrace += std::string(symbols[i]);
+        _backtrace += "\r\n";
+    }
+
+    free(symbols);
+} // _obtain_backtrace()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_exception.h b/dol/src/dol/visitor/hdsd/scd/scd_exception.h
new file mode 100644 (file)
index 0000000..aa12e28
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef SCD_EXCEPTION_H
+#define SCD_EXCEPTION_H
+
+#include <string>
+#include <exception>
+#include <execinfo.h>
+
+
+/**
+ * Maximum level of stacktrace.
+ */
+const int SCD_EX_TRACES = 15;
+
+
+/**
+ * General exeption. Can give a stack trace and generates error messages
+ * from error numbers.
+ */
+class scd_exception : public std::exception
+{
+public:
+    /**
+     * Constructor to create an exception with a string as cause.
+     * \param the cause
+     */
+    scd_exception(const std::string& msg);
+
+    /**
+     * Constroctor to create an exception with a string and an error
+     * message generated from an error number (errno) as cause.
+     * \param the cause prefix
+     * \param the error number to generate the error message for
+     */
+    scd_exception(const std::string& msg, int errn);
+
+    virtual ~scd_exception() throw() {}
+
+    /**
+     * Returns a C-String showing the cause of the exception.
+     */
+    virtual const char* what() throw();
+
+    /**
+     * Returns a C-String showing the stack trace. For name resolution
+     * -rdynamic has to be used while compiling.
+     */
+    const char* stacktrace();
+
+private:
+    std::string _msg;
+    std::string _backtrace;
+
+    void _get_backtrace();
+
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_in_connector.cpp b/dol/src/dol/visitor/hdsd/scd/scd_in_connector.cpp
new file mode 100644 (file)
index 0000000..e289d25
--- /dev/null
@@ -0,0 +1,130 @@
+#include "scd_in_connector.h"
+
+#include "scd_logging.h"
+#include "scd_cont_man_master.h"
+
+
+scd_in_connector::scd_in_connector(scd_simulator &sim, scd_socket* sock):
+    _sim(sim), _socket(sock), _is_connecting(true)
+{
+    // register this event handler
+    _sim.get_poller().register_handler(*this, SOCK_EV_READ | SOCK_EV_CLOSE);
+
+    // set the socket for the reader
+    _reader.set_socket(*sock);
+}
+
+
+scd_in_connector::~scd_in_connector()
+{
+    if (_is_connecting)
+    {
+        _cleanup();
+    }
+}
+
+
+bool scd_in_connector::is_connecting() { return _is_connecting; }
+
+
+void scd_in_connector::handle_sock_ev(sock_ev events)
+{
+    if (events & SOCK_EV_CLOSE)
+    {
+        scd_debug("in_connector: received close event");
+        _cleanup();
+    }
+    else if (events & SOCK_EV_READ)
+    {
+        _reader.read();
+
+        if (!_socket->is_valid())
+        {
+            // connection closed
+            _cleanup();
+            scd_debug("in_connector: connection closed");
+            return;
+        }
+
+        if (!_reader.is_reading() && !_reader.has_command())
+        {
+            // received an illegal command
+            scd_debug("in_connector: received illegal command");
+            _cleanup();
+            return;
+        }
+
+        if (_reader.has_command())
+        {
+            scd_command* cmd = _reader.get_command();
+
+            if (cmd->get_type() == SCD_CM_REGISTER &&
+                    cmd->get_subtype() == SCD_CM_NETSIM)
+            {
+                // register host
+                scd_debug("in_connector: received cmd \"register host\"");
+
+                try
+                {
+                    // check if we are the master
+                    scd_cont_man_master& master =
+                        dynamic_cast<scd_cont_man_master&>(_sim.get_cont_man());
+
+                    _sim.get_poller().remove_handler(*this);
+
+                    master.connect_slave(*cmd, _socket);
+
+                    delete cmd;
+                    _is_connecting = false;
+                    return;
+                }
+                catch ( std::bad_cast e)
+                {
+                    scd_warn("slave tried to register");
+                    delete cmd;
+                    _cleanup();
+                    return;
+                }
+            } // end register host
+            else if (cmd->get_type() == SCD_CM_REGISTER &&
+                    cmd->get_subtype() == SCD_CM_CHANNEL)
+            {
+                // register channel
+                scd_debug("in_connector: received cmd \"register channel\"");
+
+                _sim.get_poller().remove_handler(*this);
+
+                _sim.get_chan_man().connect_channel(*cmd, _socket);
+
+                delete cmd;
+                _is_connecting = false;
+                return;
+            } // end register channel
+            else
+            {
+                // received wrong command
+                scd_debug("in_connector: received unknown command");
+                delete cmd;
+                _cleanup();
+                return;
+            }
+        } // end receive command
+    } // end read event
+
+} // handle_sock_ev()
+
+
+const scd_socket& scd_in_connector::get_sock()
+{
+    return *_socket;
+}
+
+
+void scd_in_connector::_cleanup()
+{
+    if (_is_connecting)
+        _sim.get_poller().remove_handler(*this);
+    _socket->close();
+    delete _socket;
+    _is_connecting = false;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_in_connector.h b/dol/src/dol/visitor/hdsd/scd/scd_in_connector.h
new file mode 100644 (file)
index 0000000..46e3c10
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef SCD_IN_CONNECTOR_H
+#define SCD_IN_CONNECTOR_H
+
+#include "scd_socket.h"
+#include "scd_sock_poller.h"
+#include "scd_simulator.h"
+#include "scd_command_reader.h"
+
+/**
+ * Reads a command from a socket handled over by scd_init_listener
+ * and dispatches the connection to either the control or channel manager.
+ * This is used during the initialization phase.
+ */
+class scd_in_connector : public scd_sock_ev_handler_if
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulator
+     * \param sock the socket of the connection to read the command from
+     */
+    scd_in_connector(scd_simulator &sim, scd_socket* sock);
+
+    ~scd_in_connector();
+
+    /**
+     * Indicates if this in_connector is still reading the incomming command.
+     * It can be deconstructed when this indicates false.
+     * \return true if this in_connector is still working
+     */
+    bool is_connecting();
+
+    /* scd_sock_ev_handler_if */
+    void handle_sock_ev(sock_ev events);
+    const scd_socket& get_sock();
+
+private:
+    scd_socket* _socket;
+    scd_simulator &_sim;
+    bool _is_connecting;
+    scd_command_reader _reader;
+
+    void _cleanup();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_init_listener.cpp b/dol/src/dol/visitor/hdsd/scd/scd_init_listener.cpp
new file mode 100644 (file)
index 0000000..700df8b
--- /dev/null
@@ -0,0 +1,126 @@
+#include "scd_init_listener.h"
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_in_connector.h"
+
+
+scd_init_listener::scd_init_listener(scd_simulator &sim, uint16_t port):
+    _sim(sim), _host(""), _port(port), _handler(false) {}
+
+
+scd_init_listener::scd_init_listener(scd_simulator &sim,
+        const std::string &host, uint16_t port):
+    _sim(sim), _host(host), _port(port), _handler(false) {}
+
+
+scd_init_listener::~scd_init_listener()
+{
+    cleanup(true);
+    close();
+}
+
+
+void scd_init_listener::listen()
+{
+    if (!_socket.is_valid())
+    {
+        // create listening socket
+        if (!_socket.create())
+            throw scd_exception("creating listening socket failed");
+        if (!_socket.bind(_host, _port))
+            throw scd_exception("binding listening socket failed");
+        if (!_socket.listen())
+            throw scd_exception("listening to socket failed");
+
+        // register socket
+        if (!_handler)
+        {
+            _sim.get_poller().register_handler(*this,
+                    SOCK_EV_READ | SOCK_EV_CLOSE);
+            _handler = true;
+        }
+
+        scd_debug("socket listening");
+    }
+    else
+        scd_warn("socket is already listening");
+
+} // listen()
+
+
+void scd_init_listener::close()
+{
+    if (_handler)
+    {
+        _sim.get_poller().remove_handler(*this);
+        _handler = false;
+    }
+
+    if (_socket.is_valid())
+    {
+        _socket.close();
+        scd_debug("listener socket closed");
+    }
+
+} // close()
+
+
+void scd_init_listener::cleanup(bool hard)
+{
+    std::list<scd_in_connector*>::iterator iter;
+
+    for( iter=_connectors.begin(); iter!=_connectors.end();)
+    {
+        if ( hard || !(*iter)->is_connecting() )
+        {
+            delete *iter;
+            iter = _connectors.erase(iter);
+        }
+        else
+            iter++;
+    }
+} // cleanup()
+
+
+void scd_init_listener::handle_sock_ev(sock_ev events)
+{
+    if (events & SOCK_EV_READ)
+    {
+        scd_debug("incomming connection");
+
+        scd_socket* newconn = new scd_socket();
+
+        if (_socket.accept(*newconn))
+        {
+            /* create a new connector that handles the connection
+             * and store it in the list of connectors */
+            scd_in_connector* connector;
+            connector = new scd_in_connector(_sim, newconn);
+            _connectors.push_back(connector);
+        }
+        else
+        {
+            // connection could not be accepted
+            scd_debug("accepting connection failed");
+            delete newconn;
+        }
+    }
+    
+    if (events & SOCK_EV_CLOSE)
+    {
+        throw scd_exception("init_listener: experienced an error");
+    }
+
+    if (!_socket.is_valid())
+    {
+        throw scd_exception("init_listener: unexpectedly closed");
+    }
+
+} // sock_ev_handler()
+
+
+const scd_socket& scd_init_listener::get_sock()
+{
+    return _socket;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_init_listener.h b/dol/src/dol/visitor/hdsd/scd/scd_init_listener.h
new file mode 100644 (file)
index 0000000..5ae7b5a
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef SCD_INIT_LISTENER_H
+#define SCD_INIT_LISTENER_H
+
+#include <list>
+
+#include "scd_sock_poller.h"
+#include "scd_socket.h"
+#include "scd_simulator.h"
+#include "scd_in_connector.h"
+
+/**
+ * Accepts incomming connection during initialization and instanciates
+ * a connector that handles the new connection.
+ */
+class scd_init_listener : public scd_sock_ev_handler_if
+{
+public:
+    /**
+     * Constructor. Binds the listener to the specified TCP port on all
+     * available network interfaces.
+     * \param sim the simulator
+     * \param port TCP port to bind to
+     */
+    scd_init_listener(scd_simulator &sim, uint16_t port);
+
+    /**
+     * Constructor. Binds the listener to the specified TCP port
+     * only on the specified network interface.
+     * \param sim the simulator
+     * \param host IP or domain name of the interface to bind to
+     * \param port TCP port to bind to
+     */
+    scd_init_listener(scd_simulator &sim, 
+            const std::string &host, uint16_t port);
+
+    /**
+     * Deconstructor.
+     */
+    virtual ~scd_init_listener();
+
+    /**
+     * Creates the listening socket.
+     * \exception scd_exception if unexpected errors occure
+     */
+    void listen();
+
+    /**
+     * Closes the listening socket.
+     */
+    void close();
+
+    /**
+     * Removes connectors that finished their job. If the optional argument
+     * hard is true all connectors are destroyed independend if they
+     * have finished or not.
+     * \param hard if true all connectors will be destroyed
+     */
+    void cleanup(bool hard = false);
+
+    /* scd_sock_ev_handler_if */
+    void handle_sock_ev(sock_ev events);
+    const scd_socket& get_sock();
+
+private:
+    scd_simulator &_sim;
+    std::string _host;
+    uint16_t _port;
+    scd_socket _socket;
+    std::list<scd_in_connector*>_connectors;
+    bool _handler;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_logging.cpp b/dol/src/dol/visitor/hdsd/scd/scd_logging.cpp
new file mode 100644 (file)
index 0000000..5b3fc4c
--- /dev/null
@@ -0,0 +1,40 @@
+#include <iostream>
+#include <string>
+
+#include "scd_logging.h"
+
+static scd_loglevel _curr_level = SCD_INFO;
+
+void scd_log(const scd_loglevel &level, const string &str)
+{
+    std::ostream &out = std::clog;
+
+    if (_curr_level > level)
+        return;
+
+    switch(level)
+    {
+    case SCD_DEBUG:
+        out << "debug: ";
+        break;
+    case SCD_INFO:
+        out << "info: ";
+        break;
+    case SCD_WARN:
+        out << "warn: ";
+        break;
+    case SCD_ERROR:
+        out << "error: ";
+        break;
+    default:
+        out << "unknown: ";
+        break;
+    }
+
+    out << str << std::endl;
+}
+
+void scd_set_loglevel(const scd_loglevel &level)
+{
+    _curr_level = level;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_logging.h b/dol/src/dol/visitor/hdsd/scd/scd_logging.h
new file mode 100644 (file)
index 0000000..9112dc8
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef SCD_LOGGING_H
+#define SCD_LOGGING_H
+
+#include <string>
+using std::string;
+
+/* Loglevels. Default is SCD_INFO */
+typedef int scd_loglevel;
+const scd_loglevel SCD_DEBUG = 0;
+const scd_loglevel SCD_INFO = 1;
+const scd_loglevel SCD_WARN = 2;
+const scd_loglevel SCD_ERROR = 3;
+
+/**
+ * Log message if the current loglevel is low enough.
+ */
+void scd_log(const scd_loglevel &level, const string &str);
+
+/**
+ * Log message with loglevel SCD_DEBUG.
+ */
+inline void scd_debug(const string &str)
+{
+    scd_log(SCD_DEBUG, str);
+}
+
+/**
+ * Log message with loglevel SCD_INFO.
+ */
+inline void scd_info(const string &str)
+{
+    scd_log(SCD_INFO, str);
+}
+
+/**
+ * Log message with loglevel SCD_WARN.
+ */
+inline void scd_warn(const string &str)
+{
+    scd_log(SCD_WARN, str);
+}
+
+/**
+ * Log message with loglevel SCD_ERROR.
+ */
+inline void scd_error(const string &str)
+{
+    scd_log(SCD_ERROR, str);
+}
+
+/**
+ * Set the current loglevel. Events with lower priorities are not logged.
+ */
+void scd_set_loglevel(const scd_loglevel &level);
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_out_connector.cpp b/dol/src/dol/visitor/hdsd/scd/scd_out_connector.cpp
new file mode 100644 (file)
index 0000000..999a423
--- /dev/null
@@ -0,0 +1,185 @@
+#include "scd_out_connector.h"
+
+#include <assert.h>
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+#include "scd_command.h"
+
+
+scd_out_connector::scd_out_connector(scd_simulator& sim, uint16_t type,
+        const std::string& name):
+    _sim(sim), _name(name),
+    _is_connecting(true), _is_connected(false), _has_connection(false)
+{
+    // create socket
+    _socket = new scd_socket;
+    _socket->create();
+
+    // prepare register command (do not send yet)
+    scd_command* cmd = new scd_command(SCD_CM_REGISTER, type, name);
+    _writer = new scd_command_writer();
+    _writer->set_socket(*_socket);
+    _writer->queue_command(cmd);
+}
+
+
+scd_out_connector::~scd_out_connector()
+{
+    close();
+    delete _writer;
+}
+
+
+void scd_out_connector::connect_to(const std::string& host, uint16_t port)
+{
+    _host = host;
+    _port = port;
+
+    // register the handler to check if a connection attempt succeeded
+    _sim.get_poller().register_handler(*this, SOCK_EV_WRITE);
+
+    // start connection attempt
+    _conn_attempt();
+
+} // connect_to()
+
+
+bool scd_out_connector::is_connecting() { return _is_connecting; }
+
+
+bool scd_out_connector::has_connection() { return _has_connection; }
+
+
+scd_socket* scd_out_connector::get_connection()
+{
+    if (_has_connection)
+    {
+        _has_connection = false;
+        return _socket;
+    }
+    else
+        return NULL;
+}
+
+
+void scd_out_connector::process()
+{
+    if (_is_connecting && !_is_connected)
+    {
+        struct timeval now;
+        gettimeofday(&now, NULL);
+
+        // check if an attempt had timed out (i.e. because of "drop" FW policy)
+        if ( _socket->is_connecting() &&
+                (now.tv_sec - _last_con.tv_sec >= SCD_CON_TIMEOUT) )
+        {
+            // close and reopen the socket
+            scd_debug("connecting to " + _host + " timed out");
+            _sim.get_poller().remove_handler(*this);
+            _socket->close();
+            _socket->create();
+            _sim.get_poller().register_handler(*this, 0);
+        }
+
+        // check if it is time to try again
+        if ( !_socket->is_connecting() && 
+                (now.tv_sec - _last_con.tv_sec >= SCD_CON_RETRY) )
+        {
+            scd_debug("reconnecting to " + _host);
+            _conn_attempt();
+            _sim.get_poller().set_ev(*this, SOCK_EV_WRITE);
+        }
+    } // still trying to tcp-connect
+
+} // process()
+
+
+void scd_out_connector::close()
+{
+    if (_is_connecting)
+    {
+        _sim.get_poller().remove_handler(*this);
+    }
+    
+    if (_is_connecting || _has_connection)
+    {
+        _socket->close();
+        delete _socket;
+
+        _is_connecting = false;
+        _has_connection = false;
+    }
+
+    _is_connected = false;
+
+} // close()
+
+
+const std::string& scd_out_connector::get_name() const { return _name; }
+
+
+void scd_out_connector::handle_sock_ev(sock_ev events)
+{
+    if (events & SOCK_EV_CLOSE)
+    {
+        // the close event is only polled if _is_connected is true
+        scd_error("outgoing connection closed");
+        close();
+        return;
+    } // end close event
+    else if (events & SOCK_EV_WRITE)
+    {
+        if (!_is_connected)
+        {
+            if (_socket->connected_event())
+            {
+                // connection established
+                scd_debug("ougoing connection established to " + _host);
+                _is_connected = true;
+                _sim.get_poller().set_ev(*this, SOCK_EV_WRITE | SOCK_EV_CLOSE);
+            }
+            else
+            {
+                // connection attempt failed
+                _sim.get_poller().set_ev(*this, 0);
+                return;
+            }
+        }
+
+        assert( _is_connected || !_socket->is_connecting());
+
+        _writer->write();
+        if (!_writer->is_writing())
+        {
+            // done sending the command
+            _is_connecting = false;
+            _has_connection = true;
+            _sim.get_poller().remove_handler(*this);
+        }
+
+        if (!_socket->is_valid())
+        {
+            close();
+        }
+    } // end write event
+
+} // handle_sock_ev()
+
+
+const scd_socket& scd_out_connector::get_sock() { return *_socket; }
+
+
+void scd_out_connector::_conn_attempt()
+{
+    if (_socket->connect(_host, _port))
+    {
+        gettimeofday(&_last_con, NULL);
+    }
+    else
+    {
+        scd_error("unable to connect to " + _host);
+        close();
+    }
+
+} // _conn_attempt()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_out_connector.h b/dol/src/dol/visitor/hdsd/scd/scd_out_connector.h
new file mode 100644 (file)
index 0000000..f8a9a9c
--- /dev/null
@@ -0,0 +1,110 @@
+#ifndef SCD_OUT_CONNECTOR_H
+#define SCD_OUT_CONNECTOR_H
+
+#include <string>
+#include <time.h>
+#include <sys/time.h>
+
+#include "scd_socket.h"
+#include "scd_sock_poller.h"
+#include "scd_simulator.h"
+#include "scd_command_writer.h"
+
+
+const time_t SCD_CON_TIMEOUT = 2;
+const time_t SCD_CON_RETRY = 1;
+
+
+/* forward declaration */
+class scd_simulator;
+
+
+/**
+ * Initiates an outgoing connection and sends the register command
+ * to the other side. If an attempt to connect failes it is
+ * retried after some time. To drive this, process() has to be called
+ * repeatedly.
+ */
+class scd_out_connector : public scd_sock_ev_handler_if
+{
+public:
+    /**
+     * Constructor.
+     * \param sim the simulator
+     * \param type what should be connected (SCD_CM_NETSIM or SCD_CM_CHANNEL)
+     * \param name the name of the ressource to connect (i.e. channel name
+     * or slave name)
+     */
+    scd_out_connector(scd_simulator& sim, uint16_t type,
+            const std::string& name);
+
+    virtual ~scd_out_connector();
+
+    /**
+     * Sets the host to connect to and starts the first connection attempt.
+     *
+     * \param host the IP or hostname to connect to
+     * \param port the port to connect to
+     */
+    void connect_to(const std::string& host, uint16_t port);
+
+    /**
+     * Indicates if this out_connector is still trying to connect or 
+     * sending the command.
+     * * \return true if this out_connector is still working
+     */
+    bool is_connecting();
+
+    /**
+     * Indicates if the command has been sent successfully and the registered
+     * connection can be collected.
+     * \return true if a connection is registered
+     */
+    bool has_connection();
+
+    /**
+     * Returns the established and registered connection.
+     */
+    scd_socket* get_connection();
+
+
+    /**
+     * Checks if a time outs have occured. A connection attempt that is running
+     * for more than SCD_CON_TIMEOUT seconds is terminated and failed
+     * connection attempts are retried after SCD_CON_RETRY seconds.
+     */
+    void process();
+
+    /**
+     * Stops to try to connect or terminates an already established
+     * connection.
+     */
+    void close();
+
+    /**
+     * Returns the name of the ressource to connect.
+     */
+    const std::string& get_name() const;
+
+    /* scd_sock_ev_handler_if */
+    void handle_sock_ev(sock_ev events);
+    const scd_socket& get_sock();
+
+private:
+    scd_simulator &_sim;
+    std::string _name;
+    std::string _host;
+    uint16_t _port;
+
+    bool _is_connecting;
+    bool _has_connection;
+    scd_socket* _socket;
+    scd_command_writer* _writer;
+
+    bool _is_connected;
+    struct timeval _last_con;
+
+    void _conn_attempt();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_rem_chan_if.h b/dol/src/dol/visitor/hdsd/scd/scd_rem_chan_if.h
new file mode 100644 (file)
index 0000000..e478cc6
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef SCD_REM_CHAN_IF_H
+#define SCD_REM_CHAN_IF_H
+
+#include <sys/types.h>
+
+
+/**
+ * Interface for SystemC channels with remote input.
+ */
+class scd_rem_chan_in_if
+{
+public:
+
+    /**
+     * Indicates how many bytes can be received by this channel.
+     */
+    virtual size_t free() const = 0;
+
+    /**
+     * Receive bytes, convert to internal data structures and generate
+     * notifications if necessary.
+     * 
+     * \param buf pointer to buffer to read data from
+     * \param len number of bytes to receive (not larger than free())
+     */
+    virtual void receive(const void* buf, size_t len) = 0;
+
+    /**
+     * Virtual deconstructor
+     */
+    virtual ~scd_rem_chan_in_if() {}
+};
+
+
+/**
+ * Interface for SystemC channels with remote output.
+ */
+class scd_rem_chan_out_if
+{
+public:
+
+    /**
+     * Inidcates how many bytes are available to be sent from this channel.
+     */
+    virtual size_t available() const = 0;
+    
+    /**
+     * Get the available data to be sent. Does not guarantee that it is
+     * actually sent. At most available() bytes are sent.
+     */
+    virtual const void* send() const = 0;
+
+    /**
+     * Remove bytes from channel that have been successully sent.
+     *
+     * \param len number of bytes that have been sent (not larger than
+     * available())
+     */
+    virtual void remove(size_t len) = 0;
+
+    /**
+     * Virtual deconstructor
+     */
+    virtual ~scd_rem_chan_out_if() {}
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_in.cpp b/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_in.cpp
new file mode 100644 (file)
index 0000000..62346fc
--- /dev/null
@@ -0,0 +1,62 @@
+#include "scd_rem_fifo_in.h"
+
+#include <cassert>
+
+#include "scd_logging.h"
+
+
+scd_rem_fifo_in::scd_rem_fifo_in(sc_module_name name, int size):
+    sc_prim_channel(name), _num_elements(0), _first(0), _size(size)
+{
+    assert(size > 0);
+    _data = new char[size];
+}
+
+
+scd_rem_fifo_in::~scd_rem_fifo_in()
+{
+    delete _data;
+}
+
+
+void scd_rem_fifo_in::read(char &c)
+{
+    while (_num_elements == 0)
+        wait(_write_event);
+
+    c = _data[_first];
+    _num_elements--;
+    _first = (_first + 1) % _size;
+}
+
+
+int scd_rem_fifo_in::rtest(int size)
+{
+    return (size <= _num_elements) ? 1 : 0;
+}
+
+
+void scd_rem_fifo_in::reset() { _num_elements = _first = 0; }
+
+
+int scd_rem_fifo_in::num_available() { return _num_elements ;}
+
+
+size_t scd_rem_fifo_in::free() const { return _size - _num_elements; }
+
+
+void scd_rem_fifo_in::receive(const void* buf, size_t len)
+{
+    if (len == 0)
+        return;
+
+    assert(_num_elements + len <= _size);
+
+    for (int i=0; i<len; i++)
+    {
+        _data[(_first + _num_elements) % _size] = *((char*)buf+i);
+        _num_elements++;
+    }
+
+    _write_event.notify();
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_in.h b/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_in.h
new file mode 100644 (file)
index 0000000..f95f548
--- /dev/null
@@ -0,0 +1,83 @@
+/*****************************************************************************
+
+  The following code is derived, directly or inror: pointdirectly, from the SystemC
+  source code Copyright (c) 1996-2007 by all Contributors.
+  All Rights reserved.
+
+  The contents of this file are subject to the restrictions and limitations
+  set forth in the SystemC Open Source License Version 2.4 (the "License");
+  You may not use this file except in compliance with such restrictions and
+  limitations. You may obtain instructions on how to receive a copy of the
+  License at http://www.systemc.org/. Software distributed by Contributors
+  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
+  ANY KIND, either express or implied. See the License for the specific
+  language governing rights and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  simple_fifo.cpp -- Simple SystemC 2.0 producer/consumer example.
+
+                     From "An Introduction to System Level Modeling in
+                     SystemC 2.0". By Stuart Swan, Cadence Design Systems.
+                     Available at www.systemc.org
+
+  Original Author: Stuart Swan, Cadence Design Systems, 2001-06-18
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:  Fabian Hugelshofer, ETH Zurich, 13.11.2007
+  Description of Modification:  Used code as base for remote fifo channels.
+
+ *****************************************************************************/
+
+#ifndef SCD_REM_FIFO_IN_H_
+#define SCD_REM_FIFO_IN_H_
+
+#include "systemc"
+
+#include "simple_fifo.h" // for read_if
+#include "scd_rem_chan_if.h"
+
+
+/**
+ * FIFO channel with remote input. Data read from this FIFO originates
+ * from another host.
+ */
+class scd_rem_fifo_in : public sc_core::sc_prim_channel, public read_if,
+    public scd_rem_chan_in_if
+{
+public:
+    /**
+     * Constructor.
+     * \param name the name of the channel (is passed to parent constructor)
+     * \param size size of the input buffer in bytes
+     */
+    scd_rem_fifo_in(sc_module_name name, int size);
+
+    virtual ~scd_rem_fifo_in();
+
+    /* read_if */
+    void read(char &c);
+    int rtest(int size);
+    void reset();
+    int num_available();
+
+    /* scd_rem_chan_out_if */
+    size_t free() const;
+    void receive(const void* buf, size_t len);
+
+private:
+    int _size;
+    char* _data;
+    int _num_elements, _first;
+    sc_event _write_event;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_out.cpp b/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_out.cpp
new file mode 100644 (file)
index 0000000..e6cb762
--- /dev/null
@@ -0,0 +1,69 @@
+#include "scd_rem_fifo_out.h"
+
+#include <cassert>
+
+#include "scd_logging.h"
+
+
+scd_rem_fifo_out::scd_rem_fifo_out(sc_module_name name, int size):
+    sc_prim_channel(name), _num_elements(0), _first(0), _size(size)
+{
+    assert(size > 0);
+    _data = new char[size];
+}
+
+
+scd_rem_fifo_out::~scd_rem_fifo_out()
+{
+    delete _data;
+}
+
+
+void scd_rem_fifo_out::write(char c)
+{
+    while (_num_elements == _size)
+        wait(_read_event);
+
+    _data[ (_first + _num_elements) % _size ] = c;
+    _num_elements++;
+}
+
+
+int scd_rem_fifo_out::wtest(int size)
+{
+    return (size <= _size - _num_elements) ? 1 : 0;
+}
+
+
+void scd_rem_fifo_out::reset() { _num_elements = _first = 0; }
+
+
+size_t scd_rem_fifo_out::available() const
+{
+    size_t avail;
+
+    if (_num_elements <= _size - _first)
+        avail = _num_elements;
+    else
+        avail = _size - _first;
+
+    return avail;
+}
+
+
+const void* scd_rem_fifo_out::send() const { return _data + _first; }
+
+
+void scd_rem_fifo_out::remove(size_t len)
+{
+    if (len == 0)
+        return;
+
+    assert(_num_elements >= len);
+
+    _first = (_first + len) % _size;
+
+    _num_elements -= len;
+
+    _read_event.notify();
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_out.h b/dol/src/dol/visitor/hdsd/scd/scd_rem_fifo_out.h
new file mode 100644 (file)
index 0000000..2025a1e
--- /dev/null
@@ -0,0 +1,83 @@
+/*****************************************************************************
+
+  The following code is derived, directly or inror: pointdirectly, from the SystemC
+  source code Copyright (c) 1996-2007 by all Contributors.
+  All Rights reserved.
+
+  The contents of this file are subject to the restrictions and limitations
+  set forth in the SystemC Open Source License Version 2.4 (the "License");
+  You may not use this file except in compliance with such restrictions and
+  limitations. You may obtain instructions on how to receive a copy of the
+  License at http://www.systemc.org/. Software distributed by Contributors
+  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
+  ANY KIND, either express or implied. See the License for the specific
+  language governing rights and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  simple_fifo.cpp -- Simple SystemC 2.0 producer/consumer example.
+
+                     From "An Introduction to System Level Modeling in
+                     SystemC 2.0". By Stuart Swan, Cadence Design Systems.
+                     Available at www.systemc.org
+
+  Original Author: Stuart Swan, Cadence Design Systems, 2001-06-18
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:  Fabian Hugelshofer, ETH Zurich, 13.11.2007
+  Description of Modification:  Used code as base for remote fifo channels.
+
+ *****************************************************************************/
+
+#ifndef SCD_REM_FIFO_OUT_H_
+#define SCD_REM_FIFO_OUT_H_
+
+#include "systemc"
+
+#include "simple_fifo.h" // for write_if
+#include "scd_rem_chan_if.h"
+
+
+/**
+ * FIFO channel with remote output. Data written to this FIFO endpoint
+ * is transmitted to another host.
+ */
+class scd_rem_fifo_out : public sc_core::sc_prim_channel, public write_if,
+    public scd_rem_chan_out_if
+{
+public:
+    /**
+     * Constructor.
+     * \param name the name of the channel (is passed to parent constructor)
+     * \param size size of the output buffer in bytes
+     */
+    scd_rem_fifo_out(sc_module_name name, int size);
+
+    virtual ~scd_rem_fifo_out();
+
+    /* write_if */
+    void write(char c);
+    int wtest(int size);
+    void reset();
+
+    /* scd_rem_chan_out_if */
+    size_t available() const;
+    const void* send() const;
+    void remove(size_t len);
+
+private:
+    int _size;
+    char* _data;
+    int _num_elements, _first;
+    sc_event _read_event;
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_simulator.cpp b/dol/src/dol/visitor/hdsd/scd/scd_simulator.cpp
new file mode 100644 (file)
index 0000000..86c2196
--- /dev/null
@@ -0,0 +1,218 @@
+#include "scd_simulator.h"
+
+#include <unistd.h>
+#include <assert.h>
+
+#include "systemc"
+
+#include "scd_cont_man_master.h"
+#include "scd_cont_man_slave.h"
+#include "scd_init_listener.h"
+#include "scd_logging.h"
+
+
+scd_simulator::scd_simulator(const std::string& name,
+        const std::string &loc_host, uint16_t loc_port, bool master):
+    _name(name), _loc_host(loc_host), _loc_port(loc_port)
+{
+    _poller = new scd_sock_poller;
+
+    if (master == SCD_MASTER)
+        _cont_man = new scd_cont_man_master(*this);
+    else
+        _cont_man = new scd_cont_man_slave(*this);
+
+    _chan_man = new scd_chan_man(*this);
+}
+
+
+scd_simulator::scd_simulator(const std::string& name, uint16_t loc_port,
+        bool master):
+    _name(name), _loc_host(""), _loc_port(loc_port)
+{
+    _poller = new scd_sock_poller;
+
+    if (master == SCD_MASTER)
+        _cont_man = new scd_cont_man_master(*this);
+    else
+        _cont_man = new scd_cont_man_slave(*this);
+
+    _chan_man = new scd_chan_man(*this);
+}
+
+
+scd_simulator::~scd_simulator()
+{
+    delete _chan_man;
+    delete _cont_man;
+    delete _poller;
+}
+
+
+const std::string& scd_simulator::get_name() const { return _name; }
+
+
+scd_sock_poller& scd_simulator::get_poller() { return *_poller; }
+
+
+scd_chan_man& scd_simulator::get_chan_man() { return *_chan_man; }
+
+
+scd_cont_man& scd_simulator::get_cont_man() { return *_cont_man; }
+
+
+bool scd_simulator::init()
+{
+    scd_info("initialization start");
+
+    /* open port for incomming connections */
+    scd_init_listener listener(*this, _loc_host, _loc_port);
+    listener.listen();
+    
+    /* 
+     * init until the initialization failed or chan_man and cont_man are
+     * successfully initiated
+     */
+    while ( !_cont_man->failed() &&
+            ( !_chan_man->ready() || !_cont_man->active() )  )
+    {
+        // poll the sockets and execute callback handlers
+        _poller->process();
+
+        // connect channels
+        _chan_man->init_process();
+
+        // process state transitions
+        _cont_man->process();
+
+        /* as we might be waiting for a peer coming up we can not use
+         * a blocking poll as errors would always exist and the poller would
+         * wake up immediately
+         * => sleep some milliseconds
+         */
+        usleep(50);
+    }
+
+    listener.close();
+
+    if (_cont_man->failed())
+    {
+        scd_error("initialization failed");
+        return false;
+    }
+    else
+    {
+        scd_info("initialization done");
+        return true;
+    }
+
+} // init()
+
+
+bool scd_simulator::start()
+{
+    scd_info("simulation start");
+
+    /* first delta cycle to initialize the SystemC scheduler
+     * else the _pending*() functions would fail */
+    sc_core::sc_start(sc_core::SC_ZERO_TIME);
+
+    while (_cont_man->active())
+    {
+        /* signalize the simulation state to the controller */
+        if (_pending())
+        {
+            if (_pending_now())
+            {
+                // events in this time step
+                _cont_man->set_busy();
+            }
+            else
+            {
+                // signalize time step until next event
+                sc_core::sc_time step;
+                step = _next_time() - sc_core::sc_time_stamp();
+                _cont_man->set_idle(step);
+            }
+        }
+        else
+            _cont_man->set_done();
+
+        // check for state changes
+        _cont_man->process();
+
+        /* run simulation if something to do and in right state */
+        if (_cont_man->busy())
+        {
+            // simulate one delta cycle
+            sc_core::sc_start(sc_core::SC_ZERO_TIME);
+
+            // check if we have to wait for new socket events
+            _chan_man->process();
+
+            // poll the sockets to induce transmissions
+            _poller->process();
+        }
+        else
+        {
+            if (_cont_man->advance_time())
+            {
+                sc_core::sc_time step = _cont_man->get_time_step();
+                // advance simulation time, nothing should actually be simulated
+                sc_start(step);
+                scd_info("time advanced by " + step.to_string() + " to "
+                        + sc_core::sc_time_stamp().to_string() );
+            }
+            else if ( _cont_man->active() )
+            {
+                // wait for activity on sockets
+                _poller->wait_process();
+            }
+        }
+
+    } // while simulation is running
+
+    /* simulation terminated */
+
+    if (_cont_man->failed())
+    {
+        scd_error("simulation failed");
+        return false;
+    }
+    else
+    {
+        scd_info("simulation done");
+        return true;
+    }
+
+} // start()
+
+
+/**
+ * Returns true if events exist at current simulation time.
+ */
+bool scd_simulator::_pending_now()
+{
+    return sc_core::sc_pending_activity_at_current_time();
+}
+
+
+/**
+ * Returns true if events exist at current or later simulation time.
+ */
+bool scd_simulator::_pending()
+{
+    sc_core::sc_time next = _next_time();
+    return ( (next != sc_core::SC_ZERO_TIME) || _pending_now() );
+}
+
+
+/**
+ * Returns the time of the next earliest timed event
+ * or SC_ZERO_TIME if no such event exists.
+ */
+const sc_core::sc_time scd_simulator::_next_time()
+{
+    return sc_core::sc_get_curr_simcontext()->next_time();
+}
+
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_simulator.h b/dol/src/dol/visitor/hdsd/scd/scd_simulator.h
new file mode 100644 (file)
index 0000000..48b4b3f
--- /dev/null
@@ -0,0 +1,118 @@
+#ifndef SCD_SIMULATOR_H
+#define SCD_SIMULATOR_H
+
+#include <sys/types.h>
+#include <string>
+
+#include "scd_sock_poller.h"
+#include "scd_chan_man.h"
+#include "scd_cont_man.h"
+
+
+/* forward declaration */
+class scd_chan_man;
+class scd_cont_man_if;
+
+
+/**
+ * Simulator to run a distributed SystemC simulation. First the 
+ * channel with remote endpoints, the slave controllers and the
+ * master controller have to be registered with the channel manager
+ * and the control manager. Second the simulation has to be 
+ * initialized and third the simulation can be started.
+ */
+class scd_simulator
+{
+public:
+
+    /**
+     * Constructor. Binds the simulator to the specified TCP port
+     * only on the specified network interface.
+     * \param name the name of this simulator
+     * \param loc_host IP or domain name of the interface to bind to
+     * \param loc_port TCP port to bind to
+     * \bool master SCD_MASTER if this simulator is the master, else
+     * SCD_SLAVE
+     */
+    scd_simulator(const std::string& name, const std::string &loc_host,
+            uint16_t loc_port, bool master);
+
+    /**
+     * Constructor. Binds the simulator to the specified TCP port on all
+     * available network interfaces.
+     * \param name the name of this simulator
+     * \param loc_port TCP port to bind to
+     * \bool master SCD_MASTER if this simulator is the master, else
+     * SCD_SLAVE
+     */
+    scd_simulator(const std::string& name, uint16_t loc_port, bool master);
+
+    virtual ~scd_simulator();
+
+
+    /**
+     * Returns the name of this simulator.
+     */
+    const std::string& get_name() const;
+
+    /**
+     * Returns the socket poller of this simulation.
+     */
+    scd_sock_poller& get_poller();
+
+    /**
+     * Returns the channel manager of this simulation.
+     */
+    scd_chan_man& get_chan_man();
+
+    /**
+     * Returns the control manager of this simulation.
+     */
+    scd_cont_man& get_cont_man();
+
+    /**
+     * Initializes the distributed simulation. Connects all remote channels
+     * and the control infrastructure. The channels, the slaves and the master
+     * have to be registered before initializating. A simulation can only
+     * be initialized once.
+     */
+    bool init();
+
+    /**
+     * Runs the simulation until an error occures or no more events
+     * exist globally. A simulation can only be started once.
+     */
+    bool start();
+
+
+private:
+    scd_sock_poller* _poller;
+    scd_chan_man* _chan_man;
+    scd_cont_man* _cont_man;
+
+    std::string _name;
+    std::string _loc_host;
+    uint16_t _loc_port;
+    
+    /* member functions */
+
+    /**
+     * Indicates if events exist for the current simulation time.
+     * \return true if events exist for the current time
+     */
+    bool _pending_now();
+
+    /**
+     * Indicates if events exist in the event queues.
+     * \return true if events exist
+     */
+    bool _pending();
+
+    /**
+     * Returns the absolute time of the next event in the queues.
+     * \retunrs the absoulte time of the next event or 0 if no such event exists
+     */
+    const sc_core::sc_time _next_time();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.cpp b/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.cpp
new file mode 100644 (file)
index 0000000..1cff374
--- /dev/null
@@ -0,0 +1,201 @@
+#include "scd_sock_poller.h"
+
+#include <algorithm>
+#include <errno.h>
+#include <string>
+#include <string.h>
+
+#include "scd_exception.h"
+#include "scd_logging.h"
+
+
+bool scd_sock_poller::register_handler(scd_sock_ev_handler_if& handler,
+        sock_ev events)
+{
+    // can not register the same handler twice
+    if (_handler_exists(handler))
+    {
+        scd_warn("socket handler already registered while registering");
+        return false;
+    }
+    
+    // register handler
+    _handlers.push_back(&handler);
+
+    // register socket and events
+    struct pollfd fd;
+    fd.fd = handler.get_sock()._socket;
+    fd.events = events;
+    _events.push_back(fd);
+    return true;
+
+} // register_handler()
+
+
+bool scd_sock_poller::remove_handler(const scd_sock_ev_handler_if &handler)
+{
+    int idx = _get_index(handler);
+    
+    // check if handler was found
+    if (idx == -1)
+    {
+        scd_warn("socket handler not registered while removing poll handler");
+        return false;
+    }
+
+    // remove events and handler from vectors
+    _events.erase(_events.begin() + idx);
+    _handlers.erase(_handlers.begin() + idx);
+
+    return true;
+
+} // remove_handler()
+
+
+bool scd_sock_poller::set_ev(const scd_sock_ev_handler_if &handler,
+        sock_ev events)
+{
+    int idx = _get_index(handler);
+
+    if (idx == -1)
+    {
+        scd_warn("socket handler not registered while setting poll events");
+        return false;
+    }
+
+    _events[idx].events = events;
+
+    return true;
+} // set_ev()
+
+
+bool scd_sock_poller::get_ev(const scd_sock_ev_handler_if &handler,
+        sock_ev &events) const
+{
+    int idx = _get_index(handler);
+
+    if (idx == -1)
+    {
+        scd_warn("socket handler not registered while getting poll events");
+        return false;
+    }
+
+    events = _events[idx].events;
+
+    return true;
+
+} // get_ev()
+
+
+bool scd_sock_poller::wait(int ms)
+{
+    int ret = _poll(ms);
+    if (ret > 0)
+        return true;
+    else
+        return false;
+}
+
+
+bool scd_sock_poller::process()
+{
+    int ret = _poll(0);
+
+    if (ret != 0) // events occured
+    {
+        _callback();
+        return true;
+    }
+    else
+        return false;
+
+} // process()
+
+
+void scd_sock_poller::wait_process()
+{
+    _poll(-1);
+    _callback();
+
+} // wait_process()
+
+
+bool scd_sock_poller::_handler_exists(const scd_sock_ev_handler_if &handler)
+    const
+{
+    std::vector<scd_sock_ev_handler_if*>::const_iterator iter;
+
+    iter = std::find(_handlers.begin(), _handlers.end(), &handler);
+
+    if (iter == _handlers.end())
+        return false;
+    else
+        return true;
+
+} // _handler_exists()
+
+
+int scd_sock_poller::_get_index(const scd_sock_ev_handler_if &handler) const
+{
+    std::vector<scd_sock_ev_handler_if*>::const_iterator iter;
+
+    iter = std::find(_handlers.begin(), _handlers.end(), &handler);
+
+    if (iter == _handlers.end())
+    {
+        // handler not found
+        return -1;
+    }
+    else
+    {
+        // return index (random access iterator)
+        return iter - _handlers.begin();
+    }
+
+} // _get_index()
+
+
+int scd_sock_poller::_poll(int ms)
+{
+    int ret;
+
+    if (ms < 0 && _events.size() == 0)
+    {
+        scd_debug("immediately returning form infinite poll: no events to watch");
+        return 0;
+    }
+
+    do
+    {
+        ret = poll(&_events[0], _events.size(), ms);
+        if (ret == -1 && errno != EINTR)
+        {
+            std::string error("poll(): ");
+            error += std::string(strerror(errno));
+            throw scd_exception(error);
+        }
+    }
+    while (ret == -1 && errno == EINTR);
+
+    return ret;
+
+} // _poll()
+
+
+void scd_sock_poller::_callback()
+{
+    /* called handlers might remove themselves. as the order
+     * should not break we operate on copies here */
+    std::vector<pollfd> events_cpy = _events;
+    std::vector<scd_sock_ev_handler_if*> handlers_cpy = _handlers;
+
+    // for all handlers
+    for (int i=0; i<events_cpy.size(); i++)
+    {
+        if (events_cpy[i].events & events_cpy[i].revents)
+        {
+            // this event occured => callback handler
+            handlers_cpy[i]->handle_sock_ev(events_cpy[i].revents);
+        }
+    } // for all events
+} // _callback()
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.h b/dol/src/dol/visitor/hdsd/scd/scd_sock_poller.h
new file mode 100644 (file)
index 0000000..b19cece
--- /dev/null
@@ -0,0 +1,144 @@
+#ifndef SCD_SOCK_POLLER_H
+#define SCD_SOCK_POLLER_H
+
+#include <vector>
+#include "poll.h"
+
+#include "scd_socket.h"
+
+
+typedef short sock_ev;
+const sock_ev SOCK_EV_READ = POLLIN;
+const sock_ev SOCK_EV_WRITE = POLLOUT;
+const sock_ev SOCK_EV_CLOSE = POLLERR | POLLHUP | POLLNVAL;
+
+
+/**
+ * Interface for classes able to handle socket events.
+ */
+class scd_sock_ev_handler_if
+{
+public:
+    /**
+     * Executes the handler for socket events that have been registered
+     * and have ocured. Callback carried out by scd_sock_poller.
+     *\param events the events that occured
+     */
+    virtual void handle_sock_ev(sock_ev events) = 0;
+
+    /**
+     * Returns the socket that should be watched. The socket must
+     * be the same as long the handler is registered.
+     */
+    virtual const scd_socket &get_sock() = 0;
+
+    virtual ~scd_sock_ev_handler_if() {};
+};
+
+
+/**
+ * Dispatcher that watches sockets and executes call backs if watched
+ * event occure. Socket events (sock_ev) are an OR combination of flags
+ * supported by ::poll. See "man 2 poll". The watched events for a specific
+ * event handler stay watched until the events are overwritten or the handler
+ * is removed.
+ */
+class scd_sock_poller
+{
+public:
+    /**
+     * Register a socket event handler (a class handling socket events).
+     * Optionally the events to watch can be specified.
+     * \param handler the object that wants to watch a socket
+     * \param events (optional) the events to watch
+     * \return true if the handler could be registered succesfully
+     */
+    bool register_handler(scd_sock_ev_handler_if &handler, sock_ev events = 0);
+
+    /**
+     * Remove a socket event handler. The socket is not watched anymore.
+     * \param the object that has previously been registered
+     * \return false if no such handler was registered
+     */
+    bool remove_handler(const scd_sock_ev_handler_if &handler);
+
+    /**
+     * Set events to watch. The events expire only when overwritten
+     * by calling this function again or by removing the handler.
+     * \param handler the handler that has been registered before
+     * \param events the events the handler is interested in
+     * \return false if the handler has not been registered before
+     */
+    bool set_ev(const scd_sock_ev_handler_if &handler, sock_ev events);
+
+    /**
+     * Gets the events that are currently watched for the handler.
+     * \param the handler to get the watched events for
+     * \param events the variable where the watched events are written to
+     * \return false if the handler has not been registered before
+     */
+    bool get_ev(const scd_sock_ev_handler_if &handler, sock_ev &events) const;
+
+    /**
+     * Wait (blocking) for registered events or a timeout to occure.
+     * No callbacks are executed.
+     * \param milis timeout in milliseconds to wait for events, if omitted
+     * or -1 it is waited until events occure
+     * \return true if events occured, false otherwise
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool wait(int ms = -1);
+
+    /**
+     * Check if events occured and callback the affected handlers.
+     * \return true if some events occured
+     * \exception scd_exception if unexcpected errors occured
+     */
+    bool process();
+
+    /**
+     * Wait (blocking) for registered events to occure and callback the
+     * affected handlers.
+     * \exception scd_exception if unexcpected errors occured
+     */
+    void wait_process();
+
+private:
+    /* member variables */
+    std::vector<scd_sock_ev_handler_if *> _handlers;
+    std::vector<struct pollfd> _events;
+
+    /* member functions */
+
+    /**
+     * Checks if a handler is already registered.
+     * \param handler the handler to check for existence
+     * \return true if the handler has been registered before
+     */
+    bool _handler_exists(const scd_sock_ev_handler_if& handler) const;
+
+    /**
+     * Returns the index of an event handler in the vector. This is the same
+     * index as the corresponding pollfd.
+     * \param handler the handler to get the index of
+     * \return the index of the handler or -1 if it could not be found
+     */
+    int _get_index(const scd_sock_ev_handler_if& handler) const;
+
+    /**
+     * Polls during a specified amount of time.
+     * \param ms miliseconds to block (-1 for infinite)
+     * \exception scd_exception if an unexpected error occured
+     * \return number of sockets for witch events occured
+     */
+    int _poll(int ms);
+
+    /**
+     * Calls handlers back for which events occured.
+     */
+    void _callback();
+}; 
+
+//scd_sock_poller* scd_get_sock_poller();
+
+#endif
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_socket.cpp b/dol/src/dol/visitor/hdsd/scd/scd_socket.cpp
new file mode 100644 (file)
index 0000000..a5ca5de
--- /dev/null
@@ -0,0 +1,439 @@
+#include "scd_socket.h"
+
+#include <sys/socket.h>
+#include <netinet/tcp.h> // for TCP_NODELAY
+#include <cerrno>
+#include <fcntl.h>
+#include <cassert>
+
+#include "scd_logging.h"
+#include "scd_exception.h"
+
+scd_socket::scd_socket()
+{
+    _socket = -1;
+    _is_connecting = false;
+    _is_connected = false;
+}
+
+scd_socket::~scd_socket() {}
+
+bool scd_socket::is_valid() const
+{
+    return (_socket != -1);
+}
+
+bool scd_socket::create()
+{
+    // check if socket already created before
+    if ( is_valid() )
+    {
+        return false;
+    }
+
+    // create TCP socket
+    _socket = socket(PF_INET, SOCK_STREAM, 0);
+
+    assert(is_valid());
+    
+    _set_blocking(false);
+
+    _is_connecting = false;
+    _is_connected = false;
+
+    return true;
+
+} // create()
+
+void scd_socket::close()
+{
+    if ( is_valid() )
+    {
+        ::close(_socket);
+    }
+
+    _socket = -1;
+    _is_connecting = false;
+    _is_connected = false;
+}
+
+bool scd_socket::bind(const std::string &loc_name, const uint16_t loc_port)
+{
+    int ret;
+
+    if ( ! is_valid() )
+    {
+        return false;
+    }
+    
+    // prepare the local address
+    sockaddr_in loc_addr;
+    if ( !_get_sockaddr(loc_addr, loc_name, loc_port) )
+    {
+        return false;
+    }
+
+    // set socket reusable (to recreate listener without timeout)
+    int on = 1;
+    ret = setsockopt( _socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
+    if (ret == -1)
+    {
+        throw scd_exception("setsockopt()", errno);
+    }
+
+    ret = ::bind( _socket, reinterpret_cast<struct sockaddr*>(&loc_addr),
+                 sizeof( loc_addr ) );
+
+    if ( ret == -1 )
+    {
+        switch(errno)
+        {
+        case EACCES:
+            scd_error("must be root to bind to desired port");
+            break;
+        case EADDRINUSE:
+            scd_error("unable to bind as the address is already in use");
+            break;
+        default:
+            throw scd_exception("bind()", errno);
+        }
+        return false;
+    }
+
+    return true;
+
+} // bind()
+
+
+bool scd_socket::bind(const uint16_t loc_port)
+{
+    return bind("", loc_port);
+} // bind()
+
+
+bool scd_socket::listen()
+{
+    int ret;
+
+    if ( !is_valid() )
+    {
+        return false;
+    }
+
+    ret = ::listen(_socket, SCD_MAXCONN);
+
+    if (ret == -1)
+    {
+        throw scd_exception("listen()", errno);
+    }
+
+    return true;
+} // listen()
+
+bool scd_socket::accept(scd_socket &new_sock)
+{
+    int ret;
+
+    if ( !is_valid() )
+    {
+        return false;
+    }
+
+    ret = ::accept(_socket, NULL, NULL);
+
+    if (ret < 0)
+    {
+        switch (errno)
+        {
+        case EAGAIN:
+        case ECONNABORTED:
+        case EINTR:
+        case EPROTO:
+            return false;
+            break;
+        default:
+            throw scd_exception("accept()", errno);
+            break;
+        }
+    }
+    else
+    {
+        new_sock._is_connected = true;
+        new_sock._socket = ret;
+        new_sock._set_blocking(false);
+        #ifdef TCP_NODELAY
+        new_sock._set_nodelay();
+        #endif
+    }
+
+    return true;
+
+} // accept()
+
+
+bool scd_socket::connect(const std::string &rem_name, const uint16_t rem_port)
+{
+    int ret;
+
+    if ( !is_valid() || _is_connecting || _is_connected )
+        return false;
+
+    sockaddr_in rem_addr;
+    if ( !_get_sockaddr(rem_addr, rem_name, rem_port) )
+        return false;
+
+    ret = ::connect(_socket, reinterpret_cast<const sockaddr*>(&rem_addr),
+            sizeof(rem_addr));
+
+    if (ret == -1)
+    {
+        switch(errno)
+        {
+        case EINPROGRESS:
+            _is_connecting = true;
+            break;
+        case ECONNABORTED:
+        case ECONNREFUSED:
+        case EINTR:
+        case ENETUNREACH:
+        case ETIMEDOUT:
+            break;
+        case EALREADY: // should be prevented by _is_connecting
+        default:
+            throw scd_exception("connect()", errno);
+            break;
+        }
+    }
+    else // ret == 0
+    {
+        _is_connected = true;
+        _is_connecting = false;
+    }
+
+    return true;
+
+} // connect()
+
+bool scd_socket::is_connecting()
+{
+    if ( !is_valid() || !_is_connecting || _is_connected )
+        return false;
+
+    return true;
+
+} // is_connecting()
+
+
+bool scd_socket::is_connected()
+{
+    if ( !is_valid() || _is_connecting || !_is_connected)
+        return false;
+
+    return true;
+
+} // is_connecting()
+
+
+bool scd_socket::connected_event()
+{
+    if (_is_connected)
+        return true;
+
+    if ( !is_valid() )
+    {
+        scd_warn("write event occured on an invalid socket");
+        return false;
+    }
+    else if ( !_is_connecting )
+    {
+        scd_warn("checking connected event while not connecting");
+        return false;
+    }
+
+    // get possible errors from connection attempt
+    int err, ret;
+    socklen_t err_size = sizeof(err);
+    ret = getsockopt(_socket, SOL_SOCKET, SO_ERROR, &err, &err_size);
+
+    if (ret == -1)
+    {
+        throw scd_exception("getsockopt()", errno);
+    }
+
+    // handle errors
+    switch(err)
+    {
+    case 0:
+        // connection established
+        _is_connecting = false;
+        _is_connected = true;
+        #ifdef TCP_NODELAY
+        _set_nodelay();
+        #endif
+        return true;
+        break;
+    case ECONNABORTED:
+    case ECONNREFUSED:
+    case EINTR:
+    case ENETUNREACH:
+    case ETIMEDOUT:
+        // connection attempt failed
+        _is_connecting = false;
+        return false;
+        break;
+    case EINPROGRESS:
+        // should not be possible as we received a completion event
+        throw scd_exception("checking connected event while still connecting");
+        break;
+    case EALREADY: // should be prevented by _is_connecting
+    default:
+        throw scd_exception("connect()", errno);
+        break;
+    }
+    
+    // not reached
+} //connected_event()
+
+
+size_t scd_socket::send(const void* buf, size_t len)
+{
+    ssize_t ret;
+
+    if ( !is_valid() || len == 0 || !_is_connected )
+        return 0;
+
+    ret = ::send(_socket, buf, len, MSG_NOSIGNAL);
+
+    if (ret < 0)
+    {
+        switch(errno)
+        {
+        case ECONNRESET:
+        case EPIPE:
+        case ETIMEDOUT:
+            close();
+            break;
+        case EWOULDBLOCK:
+            break;
+        default:
+            throw scd_exception("send()", errno);
+            break;
+        }
+        return 0;
+    }
+    else
+        return ret;
+
+} // send()
+
+size_t scd_socket::recv(void* buf, size_t len)
+{
+    ssize_t ret;
+
+    if ( !is_valid() || len == 0 || !_is_connected)
+        return 0;
+
+    ret = ::recv(_socket, buf, len, MSG_NOSIGNAL);
+
+    if (ret < 0)
+    {
+        switch(errno)
+        {
+        case ETIMEDOUT:
+            close();
+            break;
+        case EAGAIN:
+        case EINTR:
+            break;
+        case ENOTCONN:
+        default:
+            throw scd_exception("recv()", errno);
+            break;
+        }
+        return 0;
+    }
+    else if (ret == 0)
+    {
+        close();
+        return 0;
+    }
+    else
+        return ret;
+
+} // recv()
+
+bool scd_socket::_get_sockaddr(sockaddr_in &addr, const std::string &name,
+            const uint16_t port) const
+{
+    // flush addr
+    memset( &addr, 0, sizeof(addr) );
+
+    /* set content */
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons( port );
+    if ( name.empty() )
+    {
+        // bind to all local addresses
+        addr.sin_addr.s_addr = INADDR_ANY;
+    }
+    else
+    {
+        // bint to specified address only
+        struct hostent* he;
+
+        // resolve name
+        he = gethostbyname2(&name[0], AF_INET);
+        if (he == NULL)
+            return false;
+
+        // copy address (network order)
+        addr.sin_addr.s_addr =
+               reinterpret_cast<struct in_addr*>(he->h_addr_list[0])->s_addr;
+    }
+
+    return true;
+
+} // _get_sockaddr()
+
+
+bool scd_socket::_set_blocking(const bool mode)
+{
+    if ( !is_valid() )
+    {
+        return false;
+    }
+
+    int opts = fcntl( _socket, F_GETFL );
+
+    if ( opts < 0 )
+    {
+        throw scd_exception("fcntl()", errno);
+    }
+
+    if ( !mode )
+        opts = ( opts | O_NONBLOCK );
+    else
+        opts = ( opts & ~O_NONBLOCK );
+
+    fcntl( _socket, F_SETFL,opts );
+
+    return true;
+
+} //_set_blocking()
+
+
+bool scd_socket::_set_nodelay()
+{
+    if ( !is_valid())
+        return false;
+
+    // disable Nagle algorithm
+    int on = 1;
+    int ret = setsockopt( _socket, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on) );
+    if (ret == -1)
+    {
+        throw scd_exception("setsockopt()", errno);
+    }
+
+    return true;
+}
diff --git a/dol/src/dol/visitor/hdsd/scd/scd_socket.h b/dol/src/dol/visitor/hdsd/scd/scd_socket.h
new file mode 100644 (file)
index 0000000..30c2e79
--- /dev/null
@@ -0,0 +1,168 @@
+#ifndef SCD_SOCKET_H
+#define SCD_SOCKET_H
+
+#include <string>
+#include <sys/types.h>
+#include <netdb.h>
+
+const int SCD_MAXCONN = 100;
+
+// forward declaration for friends
+class scd_sock_poller;
+
+/**
+ * Berkeley TCP socket API wrapper class. The socket is put into non blocking
+ * mode.
+ */
+class scd_socket
+{
+    friend class scd_sock_poller;
+
+public:
+    scd_socket();
+    virtual ~scd_socket();
+
+    /**
+     * Returns true if this socket has been successfully created and
+     * has not been closed since then. Use this function to check if an
+     * error occured.
+     */
+    bool is_valid() const;
+
+    /**
+     * Creates the socket.
+     * \return false if the socket is already valid
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool create();
+
+    /**
+     * Closes the socket and marks it as invalid.
+     */
+    void close();
+
+    /**
+     * Binds the socket to a local address and port.
+     * \param loc_name the local IP or hostname or empty string
+     * \param loc_port the local port or 0
+     * \return false if the socket is not valid or an invalid address
+     * was specified
+     * \exception scd_exception if ::bind() failed for unexpected reason
+     */
+    bool bind(const std::string &loc_name, const uint16_t loc_port);
+    
+    /**
+     * Binds the socket to a port.
+     * \param loc_port the local port
+     * \exception scd_exception if ::bind() failed for unexpected reason
+     * \return false if the sockat is not valid
+     */
+    bool bind(const uint16_t loc_port);
+
+    /**
+     * Marks a previously bound socket as listening.
+     * \return false if the socket is not valid
+     * \exception scd_exception if ::listen() failed
+     */
+    bool listen();
+
+    /**
+     * Accept a new connection from a listening socket.
+     * \param new_sock the object to hold the new connection
+     * \return true if a new connection was accepted
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool accept(scd_socket &new_sock);
+
+    /**
+     * Initiates a connection attempt to a remote host. Use is_connecting()
+     * to check whether this attempt is still in progress or is_connected()
+     * to check whether the socket is connected. If the connection attempt
+     * is in progress, the socket has to be polled for a write event.
+     * If this event occures its handler shall call connected_event()
+     * to check if the connection was established successully.
+     * It is not possible to try to connect again if the write event
+     * is not polled and processed by calling connected_event() after
+     * is_connecting() has indicated that the attempt is still in progress.
+     * \param rem_name the hostname of the remote host (IP or host name)
+     * \param rem_port the port to connect to
+     * \return true if the connection attempt was started successfully,
+     * false if the hostname could not be resolved or a connection attempt
+     * was not possible
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool connect(const std::string &rem_name, const uint16_t rem_port);
+
+    /**
+     * Indicates if a previous connection attempt is still in progress.
+     * \return true if a conneciton attempt is still in progress
+     */
+    bool is_connecting();
+
+    /**
+     * Indicates if this socket is connected to a peer either while it has
+     * been accepted from an incoming connection or the outgoing connection
+     * is established.
+     * \return true if the socket is valid and connected
+     */
+    bool is_connected();
+
+    /**
+     * Check if a connection attempt has succeeded on a write event. Shall
+     * only be called from the write event handler. Especially after a
+     * connection attempt was in progress. Can also be called if the
+     * connection has already been established.
+     * \return true if the socket is valid and the connection is established
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool connected_event();
+
+    /**
+     * Tries to send at most len data from the buffer.
+     * Might close the socket on errors.
+     * \return the number of successfully sent bytes
+     * \exception scd_exception if unexpected errors occured
+     */
+    size_t send(const void* buf, size_t len);
+
+    /**
+     * Tries to receive at most len data to the buffer.
+     * Might close the socket on errors.
+     * \return the number of successfully received bytes
+     * \exception scd_exception if unexpected errors occured
+     */
+    size_t recv(void* buf, size_t len);
+
+
+private:
+    /* member variables */
+
+    int _socket;
+    bool _is_connecting;
+    bool _is_connected;
+
+    /* member functions */
+
+    /**
+     * Initializes a sockaddr_in struct. Can resolve hostnames.
+     */
+    bool _get_sockaddr(sockaddr_in &addr, const std::string &name,
+            const uint16_t port) const;
+
+    /**
+     * Sets the socket in blocking or non blocking mode.
+     * \param mode true to set blocking mode
+     * \return false if the socket is not valid
+     * \exception scd_exception if unexpected errors occured
+     */
+    bool _set_blocking(const bool mode);
+
+    /**
+     * Disables the Nagle algorithm which buffers outgoing data up to 200ms
+     * before sending it. Disabling causes more network traffic but
+     * decreases the delay.
+     */
+    bool _set_nodelay();
+};
+
+#endif
diff --git a/dol/src/dol/visitor/package.html b/dol/src/dol/visitor/package.html
new file mode 100644 (file)
index 0000000..94a87f3
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Code generator.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/visitor/protothread/ProtothreadMakefileVisitor.java b/dol/src/dol/visitor/protothread/ProtothreadMakefileVisitor.java
new file mode 100644 (file)
index 0000000..184a928
--- /dev/null
@@ -0,0 +1,63 @@
+/* $Id: ProtothreadMakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.protothread;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class ProtothreadMakefileVisitor extends PNVisitor {
+
+    /**
+     *
+     */
+    public ProtothreadMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("CXX = g++");
+            ps.println("CXXFLAGS = -g -Wall");
+            ps.println("COMPILE = ${CXX} ${CXXFLAGS} -c");
+            ps.println("LINK = ${CXX}");
+            ps.println("LIB_INC = -Ilib -Iwrappers");
+            ps.println();
+            ps.println("src := $(wildcard lib/*.cpp) "
+                    + "$(wildcard wrappers/*.cpp) $(wildcard *.cpp)");
+            ps.println("obj = $(src:.cpp=.o)");
+            ps.println();
+            ps.println("app : ${obj} ${src}");
+            ps.println("\t${LINK} -o " + _name + " $(obj)");
+            ps.println();
+            ps.println("%.o :");
+            ps.println("\t${COMPILE} -o $(*D)/$(*F).o $(*D)/$(*F).cpp "
+                    + "$(LIB_INC)");
+            ps.println();
+            ps.println("clean :");
+            ps.println("\trm ${obj}");
+        }
+        catch (IOException e) {
+            System.out.println(" Protothread Makefile Visitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected String _name = "sc_application";
+}
+
diff --git a/dol/src/dol/visitor/protothread/ProtothreadModuleVisitor.java b/dol/src/dol/visitor/protothread/ProtothreadModuleVisitor.java
new file mode 100644 (file)
index 0000000..897d496
--- /dev/null
@@ -0,0 +1,170 @@
+/* $Id: ProtothreadModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.protothread;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class ProtothreadModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public ProtothreadModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "sc_application.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _code = new CodePrintStream(file);
+
+            _code.printPrefixln("#include \"pt.h\"");
+            _code.printPrefixln("#include \"Fifo.h\"");
+            _code.printPrefixln("#include \"WindowedFifo.h\"");
+            for (String basename : x.getProcessBasenames()) {
+                _code.printPrefixln("#include \"" + basename
+                        + "Wrapper.h\"");
+            }
+            
+            _code.println();
+            _code.printPrefixln("int main(void)");
+            _code.printLeftBracket();
+
+            //instantiate channels
+            for (Channel c : x.getChannelList()) {
+                if (c.getType().equals("fifo")) {
+                    _code.printPrefixln("Fifo " + c.getName() + "("
+                            + c.getSize() * c.getTokenSize() + ");");
+                } else if (c.getType().equals("wfifo")) {
+                    _code.printPrefixln("WindowedFifo " + c.getName() + "("
+                            + c.getSize() * c.getTokenSize() + ");");
+                }
+            }
+            _code.println();
+            
+            //instantiate processes
+            for (Process p : x.getProcessList()) {
+                _code.printPrefix("int " + p.getName()
+                        + "Indices[] = { ");
+                Vector<Integer> iteratorIndex =
+                        p.getIteratorIndices();
+                if (iteratorIndex.size() < 4) {
+                    while (iteratorIndex.size() < 4) {
+                        iteratorIndex.add(-1);
+                    }
+                } else if (iteratorIndex.size() > 4) {
+                    new RuntimeException("Error: Currently not more than "
+                            + "4 iterator dimensions are supported."
+                            + "Consider revising " + p.getBasename()
+                            + ".");
+                }
+                for (int i = 0; i < 4; i++) {
+                    if (i < 3) {
+                        _code.print(iteratorIndex.elementAt(i) + ", ");
+                    } else {
+                        _code.println(iteratorIndex.elementAt(i) + " };");
+                    }
+                }
+                _code.printPrefixln(p.getBasename() + "Wrapper *"
+                        + p.getName() + " = new "
+                        + p.getBasename() + "Wrapper(\""
+                        + p.getName() + "\", "
+                        + p.getName() + "Indices);");
+            }
+            _code.println();
+
+            //connect the network
+            for (Process p : x.getProcessList()) {
+                for (Port port : p.getPortList()) {
+                    if (port.getName().equals(port.getBasename())) {
+                        _code.printPrefixln(p.getName()
+                                + "->_port" + port.getName() + "Fifo = &"
+                                + port.getPeerResource().getName() + ";");
+                    } else {
+                        _code.printPrefix(p.getName()
+                                + "->_port" + port.getBasename()
+                                + "Fifo");
+                        StringTokenizer tokenizer =
+                                new StringTokenizer(port.getName().
+                                replaceFirst(port.getBasename(), ""), "_");
+                        while (tokenizer.hasMoreTokens()) {
+                            _code.print("[" + tokenizer.nextToken()
+                                    + "]");
+                        }
+                        _code.println(" = &"
+                                + port.getPeerResource().getName() + ";");
+                    }
+                }
+            }
+            _code.println();
+            
+            //initialize processes
+            for (Process p : x.getProcessList()) {
+                _code.printPrefixln(p.getName() + "->init();");
+            }
+            _code.println();
+            
+            /*
+            _code.printPrefix("while(");
+            int counter = 0;
+            for (Process p : x.getProcessList()) {
+                if (counter > 0) {
+                    _code.printPrefix("      ");
+                }
+                _code.print("!" + p.getName() + "->isDetached()");
+                if (counter++ < x.getProcessList().size() - 1) {
+                    _code.println(" ||");
+                } else {
+                    _code.println(")");
+                }
+            }
+            */
+            _code.printPrefixln("bool allBlocked = false;");
+            _code.printPrefixln("while(!allBlocked)");
+            _code.printLeftBracket();
+            _code.printPrefixln("allBlocked = true;");
+            for (Process p : x.getProcessList()) {
+                _code.printPrefixln("if (!" + p.getName()
+                        + "->isDetached()) {");
+                //_code.printPrefixln("    " + p.getName() + "->fire();");
+                _code.printPrefixln("    if (" + p.getName()
+                        + "->fire() == PT_ENDED) {");
+                _code.printPrefixln("        allBlocked = false;");
+                _code.printPrefixln("    }");
+                _code.printPrefixln("}");
+            }
+            _code.printRightBracket();
+            _code.println();
+            
+            for (Process p : x.getProcessList()) {
+                _code.printPrefixln("delete " + p.getName() + ";");
+            }
+            _code.println();
+            _code.printPrefixln("return 0;");
+            _code.printRightBracket();
+        }
+        catch (Exception e) {
+            System.out.println("ProtothreadModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected CodePrintStream _code = null;
+    protected String _dir = null;
+}
+
diff --git a/dol/src/dol/visitor/protothread/ProtothreadProcessVisitor.java b/dol/src/dol/visitor/protothread/ProtothreadProcessVisitor.java
new file mode 100644 (file)
index 0000000..e67ac18
--- /dev/null
@@ -0,0 +1,343 @@
+/* $Id: ProtothreadProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.protothread;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class ProtothreadProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public ProtothreadProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> processList = new Vector<String>();
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!processList.contains(basename)) {
+                    processList.add(basename);
+                    p.accept(this);
+                }
+            }
+        } catch (Exception e) {
+            System.out.println("Process Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(Process p) {
+        try {
+            _createCppFile(p);
+            _createHeaderFile(p);
+            _adaptSources(p);
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    private void _createCppFile(Process p)
+        throws IOException {
+        String classname = p.getBasename() + "Wrapper";
+        String filename = _dir + _delimiter + classname + ".cpp";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#include \"" + classname + ".h\"");
+        ps.printPrefixln("#include \"dolSupport.h\"");
+        ps.printPrefixln("#include <string.h>");
+        ps.println();
+        for (SourceCode sr : p.getSrcList()) {
+            ps.printPrefixln("#include \"" + "../processes/"
+                    + sr.getLocality() + "\"");
+        }
+        ps.println();
+        ps.printPrefixln(classname + "::" + classname
+                + "(char* name, int iteratorIndex[4]) :");
+        ps.printPrefixln("        ProcessWrapper(name, iteratorIndex)");
+        ps.printLeftBracket();
+        //ps.printPrefixln("_state = new struct _local_states;");
+        //ps.printPrefixln("memcpy(_state, " + p.getBasename() + ".local, "
+        //        + "sizeof(struct _local_states));");
+        //ps.printPrefixln("memcpy(&_process, &" + p.getBasename()
+        //        + ", sizeof(DOLProcess));");
+        ps.printPrefixln("_state = (LocalState)new "
+                + p.getBasename().substring(0, 1).toUpperCase()
+                + p.getBasename().substring(1) + "_State;");
+        ps.printPrefixln("_process.init = " + p.getBasename() + "_init;");
+        ps.printPrefixln("_process.fire = " + p.getBasename() + "_fire;");
+        ps.printPrefixln("_process.local = _state;");
+        ps.printPrefixln("_process.wptr = (void*)&_wrapper_data;");
+        ps.printPrefixln("_wrapper_data.wrapper = this;");
+        ps.printRightBracket();
+        ps.println();
+        ps.printPrefixln(classname + "::~" + classname + "()");
+        ps.printLeftBracket();
+        ps.printPrefixln("if (_state)");
+        ps.printPrefixln("    delete ("
+                + p.getBasename().substring(0, 1).toUpperCase()
+                + p.getBasename().substring(1) + "_State*)_state;");
+        //ps.printPrefixln("    delete _state;");
+        ps.printRightBracket();
+    }
+
+    /**
+     *
+     */
+    private void _createHeaderFile(Process p)
+        throws IOException {
+        String classname = p.getBasename() + "Wrapper";
+        String filename = _dir + _delimiter + classname + ".h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#ifndef " + classname.toUpperCase()
+                + "_H");
+        ps.printPrefixln("#define " + classname.toUpperCase()
+                + "_H");
+        ps.println();
+        ps.printPrefixln("#include \"ProcessWrapper.h\"");
+        ps.printPrefixln("#include \"Fifo.h\"");
+        ps.printPrefixln("#include \"WindowedFifo.h\"");
+        ps.println();
+        ps.printPrefixln("class " + classname + ";");
+        ps.println();
+        ps.printPrefixln("typedef struct _" + p.getBasename()
+                + "_data {");
+        ps.printPrefixln("    int lc;");
+        ps.printPrefixln("    " + classname + " *wrapper;");
+        ps.printPrefixln("} " + p.getBasename() + "_data;");
+        ps.println();
+        ps.printPrefixln("class " + classname +
+                " : public ProcessWrapper");
+        ps.printLeftBracket();
+        ps.printPrefixln("public:");
+        ps.printPrefixln("    " + classname + "(char* name, "
+                + "int iteratorIndex[4]);");
+        ps.printPrefixln("    virtual ~" + classname + "();");
+        ps.println();
+
+        Vector<String> basenames = new Vector<String>();
+        for (Port port : p.getPortList()) {
+            if (!basenames.contains(port.getBasename())) {
+                basenames.add(port.getBasename());
+            } else {
+                continue;
+            }
+
+            Channel c = (Channel)port.getPeerResource();
+            if (port.getName().equals(port.getBasename())) {
+                if (c.getType().equals("fifo")) {
+                    ps.printPrefixln("    Fifo* _port" + port.getName()
+                            + "Fifo;");
+                } else if (c.getType().equals("wfifo")) {
+                    ps.printPrefixln("    WindowedFifo* _port"
+                            + port.getName() + "Fifo;");
+                }
+            } else {
+                if (c.getType().equals("fifo")) {
+                    ps.printPrefix("    Fifo* _port"
+                            + port.getBasename()
+                            + "Fifo");
+                } else if (c.getType().equals("wfifo")) {
+                    ps.printPrefix("    WindowedFifo* _port"
+                            + port.getBasename()
+                            + "Fifo");
+                }
+                StringTokenizer tokenizer =
+                    new StringTokenizer(port.getRange(), ";");
+                while (tokenizer.hasMoreTokens()) {
+                    ps.print("[" + tokenizer.nextToken()
+                            + "]");
+                }
+                ps.println(";");
+            }
+        }
+        ps.println("");
+        ps.printPrefixln("protected:");
+        ps.printPrefixln("    struct _local_states *_state;");
+        ps.printPrefixln("    " + p.getBasename()
+                + "_data _wrapper_data;");
+        ps.printRightBracket();
+
+        ps.printPrefixln(";");
+        ps.println();
+        ps.printPrefixln("#endif");
+    }
+
+    /**
+     * Make modifications to source files of a process.
+     * Port names need to be strings for the SystemC code generation.
+     * Therefore, in the header files integer port names are put into
+     * quotation marks.
+     *
+     * @param p process whose sources should be adapted
+     * @throws IOException
+     */
+    protected void _adaptSources(Process p) throws IOException {
+        Sed sed = new Sed();
+        //modify header file
+        for (Port port : p.getPortList()) {
+            String processHeaderFile;
+
+            for (SourceCode sr : p.getSrcList()) {
+                processHeaderFile = _dir + _delimiter + ".."
+                        + _delimiter + "processes" + _delimiter
+                        + sr.getLocality().
+                        replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                sed.sed(processHeaderFile,
+                        "(#define[ ]+PORT_\\w*[ ]+)\"?"
+                        + port.getBasename() + "\"?",
+                        "$1 " + "static_cast<" + p.getBasename()
+                        + "Wrapper *>((static_cast<" + p.getBasename()
+                        + "_data *>(p->wptr))->wrapper)->_port"
+                        + port.getBasename() + "Fifo");
+            }
+        }
+
+        //modify source file
+        for (SourceCode sr : p.getSrcList()) {
+            String processSourceFile = _dir + _delimiter + ".."
+                    + _delimiter + "processes" + _delimiter
+                    + sr.getLocality();
+
+            String line;
+            StringBuffer buffer = new StringBuffer();
+            FileInputStream fileInputStream = new FileInputStream(
+                    processSourceFile);
+            BufferedReader reader = new BufferedReader(
+                    new InputStreamReader(fileInputStream));
+            while((line = reader.readLine()) != null) {
+                buffer.append(line + "\n");
+            }
+            reader.close();
+
+            String file = buffer.toString();
+            //insert PT_BEGIN() at beginning of fire() function
+            file = file.replaceAll(
+                    "(int[ ]*" + p.getBasename()
+                    + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
+                    + "[\\s\\S&&[^\\{]]*)\\{",
+                    "$1" + System.getProperty("line.separator") + "{"
+                    + System.getProperty("line.separator") +
+                    "    PT_BEGIN((pt*)(p->wptr));");
+
+            //replace last return statement in fire function by PT_END()
+            //find beginning of fire function
+            Matcher matcher = Pattern.compile(
+                    "(int[ ]*" + p.getBasename()
+                    + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
+                    + "[\\s\\S&&[^\\{]]*)\\{").matcher(file);
+            matcher.find();
+            int i = 0;
+            try {
+                i = matcher.start();
+            } catch (Exception e) {
+                System.out.println("Error: could not find "
+                        + p.getBasename() + "_fire() function in "
+                        + processSourceFile + ".");
+                e.printStackTrace();
+            }
+            int openBraces = 0; //counter for open curly braces
+            //position of last return statement
+            int lastReturnStartPosition = 0;
+            int lastReturnEndPosition = 0;
+            while (i < file.length()) {
+                //ignore single-line comments
+                if (i < (file.length() - 1) &&
+                        file.substring(i, i + 2).equals("//")) {
+                    while (!file.substring(i, i + 1).equals("\n")) {
+                        i++;
+                    }
+                }
+                //ignore multi-line comments
+                else if (i < (file.length() - 1) &&
+                        file.substring(i, i + 2).equals("/*")) {
+                    while (!file.substring(i, i + 2).equals("*/")) {
+                        i++;
+                    }
+                }
+                //ignore strings
+                else if (file.substring(i, i + 1).equals("\"")) {
+                    matcher = Pattern.compile("[\\s\\S&&[^\\\\]]\\\"").
+                            matcher(file);
+                    matcher.find(i + 1);
+                    i = matcher.start() + 1;
+                }
+                else if (i < (file.length() - 5) &&
+                        file.substring(i, i + 6).equals("return")) {
+                    lastReturnStartPosition = i;
+                    while (!file.substring(i, i + 1).equals(";")) {
+                        i++;
+                    }
+                    lastReturnEndPosition = i;
+                } else if (file.substring(i, i + 1).equals("{")) {
+                    openBraces++;
+                } else if (file.substring(i, i + 1).equals("}")) {
+                    openBraces--;
+                    if (openBraces == 0) {
+                        break;
+                    }
+                }
+                i++;
+            }
+
+            file = file.substring(0, lastReturnStartPosition) + "/* "
+                + file.substring(lastReturnStartPosition,
+                        lastReturnEndPosition + 1)
+                + " (commented out by DOL) */"
+                + System.getProperty("line.separator")
+                + "    PT_END((pt*)(p->wptr));"
+                + System.getProperty("line.separator")
+                + file.substring(lastReturnEndPosition + 2,
+                        file.length());
+
+            BufferedWriter out = new BufferedWriter(new
+                    FileWriter(processSourceFile));
+            out.write(file);
+            out.close();
+        }
+    }
+
+    protected String _dir = null;
+    CodePrintStream _wrapperHeader;
+}
diff --git a/dol/src/dol/visitor/protothread/ProtothreadVisitor.java b/dol/src/dol/visitor/protothread/ProtothreadVisitor.java
new file mode 100644 (file)
index 0000000..88937a7
--- /dev/null
@@ -0,0 +1,96 @@
+/* $Id: ProtothreadVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.protothread;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class ProtothreadVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public ProtothreadVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _generateDirHierarchy();
+
+            x.accept(new ProtothreadMakefileVisitor(_srcDir));
+            x.accept(new ProtothreadModuleVisitor(_srcDir));
+            x.accept(new ProtothreadProcessVisitor(_wrapperDir));
+
+        } catch (Exception e) {
+            System.out.println(" SystemC PN Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     *
+     */
+    private void _generateDirHierarchy()
+        throws IOException, FileNotFoundException {
+
+        File dir = new File(_packageName);
+        dir.mkdirs();
+
+        _srcDir = _packageName + _delimiter + _srcDirName;
+        dir = new File(_srcDir);
+        dir.mkdirs();
+
+        _libDir = _srcDir + _delimiter + _libDirName;
+        dir = new File(_libDir);
+        dir.mkdirs();
+
+        _processDir = _srcDir + _delimiter + _processDirName;
+        dir = new File(_processDir);
+        dir.mkdirs();
+
+        _wrapperDir = _srcDir + _delimiter + _wrapperDirName;
+        dir = new File(_wrapperDir);
+        dir.mkdirs();
+
+        // copy library
+        String libraryPath = _ui.getMySystemCLib();
+        libraryPath = libraryPath.replaceAll("systemC",
+                "protothread");
+        File source = new File(libraryPath);
+        File destination = new File(_libDir);
+        new Copier().copy(source, destination);
+
+        //copy process src code
+        source = new File(_srcDirName);
+        destination = new File(_processDir);
+        new Copier().copy(source, destination);
+    }
+
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+
+    protected String _libDir = "";
+    protected static String _libDirName = "lib";
+
+    protected String _processDir = "";
+    protected static String _processDirName = "processes";
+
+    protected String _wrapperDir = "";
+    protected static String _wrapperDirName = "wrappers";
+}
+
diff --git a/dol/src/dol/visitor/protothread/lib/Fifo.cpp b/dol/src/dol/visitor/protothread/lib/Fifo.cpp
new file mode 100644 (file)
index 0000000..767b784
--- /dev/null
@@ -0,0 +1,130 @@
+#include "Fifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::Fifo(unsigned size = 18) {\r
+    //std::cout << "Create Fifo." << std::endl;\r
+    _size = size;\r
+    _buffer = new char[_size];\r
+    _use = 0; \r
+    _tail = 0;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::~Fifo() {\r
+    //std::cout << "Delete Fifo." << std::endl;\r
+    if (_buffer) {\r
+        delete _buffer;\r
+    }\r
+    _buffer = 0;\r
+    _use = 0; \r
+    _tail = 0;\r
+    //std::cout << "Deleted Fifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::read(void *destination, unsigned len) {\r
+    char* buffer = (char*)destination;\r
+    unsigned read = (len <= _use ? len : 0);\r
+    //std::cout << "Try to read " << len << " bytes from Fifo." << std::endl;\r
+\r
+    if (_tail + read <= _size) {\r
+        memcpy(buffer, _buffer + _tail, read);\r
+    }\r
+    else {\r
+        memcpy(buffer, _buffer + _tail, _size - _tail);\r
+        memcpy(buffer + _size - _tail, _buffer, read - _size + _tail);\r
+    }\r
+\r
+    _tail = (_tail + read) % _size;\r
+    _use -= read;\r
+    //std::cout << "Read " << read << " bytes from Fifo." << std::endl;\r
+    return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::write(const void *source, unsigned len) {\r
+    char* buffer = (char*)source;\r
+    unsigned write = (len <= unused() ? len : 0);\r
+    unsigned head = (_tail + _use) % _size;\r
+    //std::cout << "Try to write " << len << " bytes to Fifo." << std::endl;\r
+\r
+    if (head + write <= _size) {\r
+        memcpy(_buffer + head, buffer, write);\r
+    }\r
+    else {\r
+        memcpy(_buffer + head, buffer, _size - head);\r
+        memcpy(_buffer, buffer + _size - head, write - _size + head);\r
+    }\r
+\r
+    _use += write;\r
+    //std::cout << "Wrote " << write << " bytes to Fifo." << std::endl;\r
+    return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::size() const {\r
+    return (_size);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::unused() const {\r
+    return (_size) - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::used() const {\r
+    return _use; \r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+int main() {\r
+    std::cout.width(5);\r
+    Fifo *myFifo = new Fifo();\r
+    for (int j = 0; j < 3; j++) {\r
+        for (int i = 0; i < 6; i++) {\r
+            std::cout << "write " << i << " to Fifo.    ";\r
+            int write = myFifo->write(&i, sizeof(int));\r
+            printf(" %d ", write);\r
+            if (write == sizeof(int)) {\r
+                std::cout << "used: " << std::setw(2) << myFifo->used()\r
+                        << ", unused: " << std::setw(2) << myFifo->unused()\r
+                        << ", size: "  << std::setw(2) << myFifo->size()\r
+                        << std::endl;\r
+            } else {\r
+                std::cout << std::endl;\r
+            }\r
+        }\r
+        for (int i = 0; i < 6; i++) {\r
+            int value;\r
+            int read = myFifo->read(&value, sizeof(int));\r
+            printf(" %d ", read);\r
+            if (read == sizeof(int)) {\r
+                std::cout << "read " << value << "  from Fifo   ";\r
+                std::cout << "used: " << std::setw(2) << myFifo->used()\r
+                        << ", unused: " << std::setw(2) << myFifo->unused()\r
+                        << ", size: "  << std::setw(2) << myFifo->size()\r
+                        << std::endl;\r
+            }\r
+        }\r
+    }\r
+    delete myFifo;\r
+    return 0;\r
+}\r
+*/\r
diff --git a/dol/src/dol/visitor/protothread/lib/Fifo.h b/dol/src/dol/visitor/protothread/lib/Fifo.h
new file mode 100644 (file)
index 0000000..a1929dd
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _FIFO_H_\r
+#define _FIFO_H_\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+class Fifo {\r
+    public:\r
+        Fifo(unsigned size);\r
+        virtual ~Fifo();\r
+\r
+        virtual unsigned read(void *destination, unsigned len);\r
+        virtual unsigned write(const void *source, unsigned len);\r
+        virtual unsigned used() const;\r
+        virtual unsigned unused() const;\r
+        virtual unsigned size() const;\r
+\r
+    protected:\r
+        char *_buffer;\r
+        unsigned _use;\r
+        unsigned _tail;\r
+        unsigned _size;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/protothread/lib/ProcessWrapper.cpp b/dol/src/dol/visitor/protothread/lib/ProcessWrapper.cpp
new file mode 100644 (file)
index 0000000..261f65c
--- /dev/null
@@ -0,0 +1,68 @@
+#include "ProcessWrapper.h"
+
+/**
+ *
+ */
+ProcessWrapper::ProcessWrapper(char* name, int iteratorIndex[4]) {
+    //copy name, deliberately avoid using strlen and strcpy for code size
+    //minimization
+    int nameLength = 0;
+    while (name[nameLength] != 0) {
+        nameLength++;
+    }
+    _name = new char[nameLength + 1];
+    for (int i = 0; i < nameLength; i++) {
+        _name[i] = name[i];
+    }
+
+    /*
+    _name = new char[strlen(name) + 1];
+    strcpy(_name, name);
+    */
+
+    _isDetached = false;
+    for (int i = 0; i < 4; i++) {
+        _iteratorIndex[i] = iteratorIndex[i];
+    }
+}
+
+/**
+ *
+ */
+ProcessWrapper::~ProcessWrapper() {
+    if (_name) {
+        delete _name;
+    }
+}
+
+/**
+ *
+ */
+void ProcessWrapper::init() {
+    _process.init(&_process);
+}
+
+/**
+ *
+ */
+int ProcessWrapper::fire() {
+    return _process.fire(&_process);
+}
+
+/**
+ *
+ */
+void ProcessWrapper::detach() {
+    _isDetached = true;
+}
+
+/**
+ * Get the index of this process.
+ * @param indexNumber position of index (starting at 0)
+ */
+int ProcessWrapper::getIndex(unsigned indexNumber) const {
+  if (indexNumber < 4) {
+      return _iteratorIndex[indexNumber];
+  }
+  return -1;
+}
diff --git a/dol/src/dol/visitor/protothread/lib/ProcessWrapper.h b/dol/src/dol/visitor/protothread/lib/ProcessWrapper.h
new file mode 100644 (file)
index 0000000..24ef2b2
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _PROCESSWRAPPER_H_
+#define _PROCESSWRAPPER_H_
+
+#include <dol.h>
+
+class ProcessWrapper
+{
+    public:
+        ProcessWrapper(char* name, int iteratorIndex[4]);
+        virtual ~ProcessWrapper();
+
+        virtual void init();
+        virtual int fire();
+        virtual bool isDetached() { return _isDetached; }
+        virtual void detach();
+        virtual int getIndex(unsigned indexNumber) const;
+
+    protected:
+        char* _name;;
+        DOLProcess _process;
+        bool _isDetached;
+        int _iteratorIndex[4];
+};
+
+#endif
diff --git a/dol/src/dol/visitor/protothread/lib/WindowedFifo.cpp b/dol/src/dol/visitor/protothread/lib/WindowedFifo.cpp
new file mode 100644 (file)
index 0000000..743fc0b
--- /dev/null
@@ -0,0 +1,203 @@
+#include "WindowedFifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::WindowedFifo(unsigned size = 20) {\r
+    //std::cout << "Create WindowedFifo." << std::endl;\r
+    _size = size;\r
+    _buffer = new char[_size];\r
+    _head = 0;\r
+    _tail = 0;\r
+    _headRoom = 0;\r
+    _tailRoom = 0;\r
+    _use = 0;\r
+    //indicates whether Fifo is empty or full if _head == _tail\r
+    //_isFull = false;\r
+    _isHeadReserved = false;\r
+    _isTailReserved = false;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+WindowedFifo::~WindowedFifo() {\r
+    //std::cout << "Delete WindowedFifo." << std::endl;\r
+    if (_buffer) {\r
+        delete _buffer;\r
+    }\r
+    _buffer = 0;\r
+    _head = 0;\r
+    _tail = 0;\r
+    _use = 0;\r
+    //std::cout << "Deleted WindowedFifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::reserve(void** dest, unsigned len) {\r
+    char** destination = (char**)dest;\r
+    //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;\r
+\r
+    //can only reserve once piece at a time\r
+    if (_isHeadReserved) {\r
+        *destination = 0;\r
+        return 0;\r
+    }\r
+\r
+    //reserve at most as much memory as still available in the buffer\r
+    unsigned write = (len <= _size - _use ? len : _size - _use);\r
+\r
+    if (write > 0) {\r
+        //if wrap-around in buffer: return only buffer for the\r
+        //contiguous buffer space\r
+        if (_head + write > _size) {\r
+            write = _size - _head;\r
+        }\r
+\r
+        _headRoom = (_head + write) == _size? 0 : _head + write;\r
+        *destination = &(_buffer[_head]);\r
+        _isHeadReserved = true;\r
+    }\r
+\r
+    //std::cout << "Reserved " << write << " bytes." << std::endl;\r
+    _writeReserve = write; \r
+    return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::release() {\r
+    if (_isHeadReserved) {\r
+        //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;\r
+        _head = _headRoom;\r
+        _use += _writeReserve;\r
+        _isHeadReserved = false;\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::capture(void **dest, unsigned len) {\r
+    char** destination = (char**)dest;\r
+    //std::cout << "Attempt to capture " << len << " bytes." << std::endl;\r
+\r
+    if (_isTailReserved) {\r
+        //std::cout << "Only one attempt to capture allowed." << std::endl;\r
+        *destination = 0;\r
+        return 0;\r
+    }\r
+\r
+    //capture at most as much data as available in the buffer\r
+    unsigned read = (len <= _use ? len : _use);\r
+\r
+    if (read > 0) {\r
+        //if wrap-around in buffer: return only buffer for the\r
+        //conntiguous buffer space\r
+        if (_tail + read> _size) {\r
+            read = _size - _tail;\r
+        }\r
+\r
+        _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;\r
+        *destination = &(_buffer[_tail]);\r
+        _isTailReserved = true;\r
+    }\r
+\r
+    //std::cout << "Captured " << read << " bytes." << std::endl;\r
+\r
+    _readReserve = read; \r
+    return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void WindowedFifo::consume() {\r
+    if (_isTailReserved) {\r
+        //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;\r
+        _tail = _tailRoom;\r
+        _use -= _readReserve;\r
+        _isTailReserved = false;\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::size() const {\r
+    return _size;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::unused() const {\r
+    return _size - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned WindowedFifo::used() const {\r
+       return _use;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+#include <iostream>\r
+#include <iomanip>\r
+using namespace std;\r
+\r
+int main() {\r
+    WindowedFifo *myFifo = new WindowedFifo(16);\r
+\r
+    int* buf1;\r
+    int* buf2;\r
+    int x = myFifo->reserve((void**)&buf1, 8);\r
+    *buf1 = 10;\r
+    *(buf1 + 1) = 20;\r
+    myFifo->release();\r
+    int y = myFifo->capture((void**)&buf2, 8);\r
+    std::cout << "read " << *buf2 << " " << *(buf2 + 1) << std::endl;\r
+    myFifo->consume();\r
+\r
+    for (int j = 0; j < 3; j++) {\r
+        for (int i = 0; i < 6; i++) {\r
+            std::cout << "write " << i << " to Fifo.    ";\r
+            int write = myFifo->reserve((void**)&buf1, sizeof(int));\r
+            if (write == sizeof(int)) {\r
+                *buf1 = i;\r
+                myFifo->release();\r
+                std::cout << "used: " << std::setw(2) << myFifo->used()\r
+                        << ", unused: " << std::setw(2) << myFifo->unused()\r
+                        << ", size: "  << std::setw(2) << myFifo->size()\r
+                        << std::endl;\r
+            } else {\r
+                std::cout << std::endl;\r
+            }\r
+        }\r
+        for (int i = 0; i < 16; i++) {\r
+            char* buf3;\r
+            int read = myFifo->capture((void**)&buf3, sizeof(char));\r
+            if (read == sizeof(char)) {\r
+                std::cout << "read " << (unsigned)*buf3 << "  from Fifo   ";\r
+                std::cout << "used: " << std::setw(2) << myFifo->used()\r
+                        << ", unused: " << std::setw(2) << myFifo->unused()\r
+                        << ", size: "  << std::setw(2) << myFifo->size()\r
+                        << std::endl;\r
+                myFifo->consume();\r
+            } else {\r
+                std::cout << "read nothing from Fifo." << std::endl;\r
+            }\r
+\r
+        }\r
+    }\r
+    delete myFifo;\r
+    return 0;\r
+}\r
+*/\r
diff --git a/dol/src/dol/visitor/protothread/lib/WindowedFifo.h b/dol/src/dol/visitor/protothread/lib/WindowedFifo.h
new file mode 100644 (file)
index 0000000..2803558
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _WINDOWEDFIFO_H_\r
+#define _WINDOWEDFIFO_H_\r
+\r
+class WindowedFifo {\r
+    public:\r
+        WindowedFifo(unsigned size);\r
+        virtual ~WindowedFifo();\r
+\r
+        virtual unsigned reserve(void** destination, unsigned len);\r
+        virtual void release();\r
+\r
+        virtual unsigned capture(void** destination, unsigned len);\r
+        virtual void consume();\r
+\r
+        virtual unsigned used() const;\r
+        virtual unsigned unused() const;\r
+        virtual unsigned size() const;\r
+    protected:\r
+        char *_buffer;\r
+        unsigned _head;\r
+        unsigned _tail;\r
+        unsigned _headRoom;\r
+        unsigned _tailRoom;\r
+        unsigned _size;\r
+        unsigned _use; \r
+        unsigned _writeReserve;  
+        unsigned _readReserve; 
+        bool _isHeadReserved;\r
+        bool _isTailReserved;\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/protothread/lib/dol.h b/dol/src/dol/visitor/protothread/lib/dol.h
new file mode 100644 (file)
index 0000000..8fbefe4
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef DOL_H
+#define DOL_H
+
+/************************************************************************
+ * do not add code to this header
+ ************************************************************************/
+
+/**
+ *  Define the DOL process handler scheme.
+ *  - Local variables are defined in structure LocalState. Local
+ *    variables may vary from different processes.
+ *  - The ProcessInit function pointer points to a function which
+ *    initializes a process.
+ *  - The ProcessFire function pointer points to a function which
+ *    performs the actual computation. The communication between
+ *    processes is inside the ProcessFire function.
+ *  - The WPTR is a placeholder for callback. One can just
+ *    leave it blank.
+ */
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//additional behavioral functions could be declared here
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+//process handler
+struct _process;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr; //placeholder for wrapper instance
+} DOLProcess;
+
+#endif
diff --git a/dol/src/dol/visitor/protothread/lib/dolSupport.cpp b/dol/src/dol/visitor/protothread/lib/dolSupport.cpp
new file mode 100644 (file)
index 0000000..0c73f6d
--- /dev/null
@@ -0,0 +1,89 @@
+#include "dolSupport.h"\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p) {\r
+    return ((Fifo*)fifo)->read(buf, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p) {\r
+    return ((Fifo*)fifo)->write(buf, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p) {\r
+    return ((WindowedFifo*)fifo)->reserve(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void release(void* fifo, DOLProcess* p) {\r
+    ((WindowedFifo*)fifo)->release();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p) {\r
+    return ((WindowedFifo*)fifo)->capture(destination, len);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void consume(void* fifo, DOLProcess* p) {\r
+    ((WindowedFifo*)fifo)->consume();\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void DOL_detach(DOLProcess* p) {\r
+    static_cast<ProcessWrapper *>((static_cast<process_data *>(p->wptr))->wrapper)->detach();\r
+}\r
+\r
+\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0) {\r
+    *port = (void**)((void**)base)[index0];\r
+}\r
+\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1) {\r
+    *port = (void**)((void**)base)[index0 * range1 + index1];\r
+}\r
+\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2\r
+                       + index1 * range2 + index2];\r
+}\r
+\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2 * range3\r
+                       + index1 * range2 * range3\r
+                       + index2 * range3\r
+                       + index3];\r
+}\r
diff --git a/dol/src/dol/visitor/protothread/lib/dolSupport.h b/dol/src/dol/visitor/protothread/lib/dolSupport.h
new file mode 100644 (file)
index 0000000..f07a804
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef DOLSUPPORT_H\r
+#define DOLSUPPORT_H\r
+\r
+#include "dol.h"\r
+#include "ProcessWrapper.h"\r
+#include "Fifo.h"\r
+#include "WindowedFifo.h"\r
+#include "pt.h"\r
+\r
+typedef struct _process_data {\r
+    int lc;\r
+    ProcessWrapper *wrapper;\r
+} process_data;\r
+\r
+\r
+#define DOL_read(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), read(port, buf, size, process) == size);\r
+\r
+#define DOL_write(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), write(port, buf, size, process) == size);\r
+\r
+#define DOL_reserve(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), reserve(port, (void**)buf, size, process) == size);\r
+\r
+#define DOL_release(port, process) \\r
+    release(port, process);\r
+\r
+#define DOL_capture(port, buf, size, process) \\r
+    PT_WAIT_UNTIL((pt*)(p->wptr), capture(port, (void**)buf, size, process) == size);\r
+\r
+#define DOL_consume(port, process) \\r
+    consume(port, process);\r
+\r
+void DOL_detach(DOLProcess* p);\r
+\r
+//macros to deal with iterated ports\r
+/**\r
+ * macro to create a variable to store a port name\r
+ *\r
+ * @param name name of the variable\r
+ */\r
+#define CREATEPORTVAR(name) static Fifo *name\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+  createPort((void**)(&port), base, number_of_indices, index_range_pairs)\r
+\r
+#define GETINDEX(dimension) \\r
+  static_cast<ProcessWrapper *>((static_cast<process_data *>(p->wptr))->wrapper)->getIndex(dimension)\r
+\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1, int index2, int range2);\r
+void createPort(void** port, void* base, int number_of_indices, int index0, int range0, int index1, int range1, int index2, int range2, int index3, int range3);\r
+\r
+//fifo access functions\r
+unsigned write(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+unsigned read(void* fifo, void* buf, unsigned len, DOLProcess* p);\r
+\r
+//windowed fifo access functions\r
+unsigned reserve(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void release(void* fifo, DOLProcess* p);\r
+unsigned capture(void* fifo, void** destination, unsigned len, DOLProcess* p);\r
+void consume(void* fifo, DOLProcess* p);\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/protothread/lib/lc-addrlabels.h b/dol/src/dol/visitor/protothread/lib/lc-addrlabels.h
new file mode 100644 (file)
index 0000000..b75f4e7
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+#define LC_RESUME(s)                           \
+  do {                                         \
+    if(s != NULL) {                            \
+      goto *s;                                 \
+    }                                          \
+  } while(0)
+
+#define LC_CONCAT2(s1, s2) s1##s2
+#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
+
+#define LC_SET(s)                              \
+  do {                                         \
+    LC_CONCAT(LC_LABEL, __LINE__):             \
+    (s) = &&LC_CONCAT(LC_LABEL, __LINE__);     \
+  } while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+/** @} */
diff --git a/dol/src/dol/visitor/protothread/lib/lc-switch.h b/dol/src/dol/visitor/protothread/lib/lc-switch.h
new file mode 100644 (file)
index 0000000..e47085c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWITCH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+   LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
diff --git a/dol/src/dol/visitor/protothread/lib/lc.h b/dol/src/dol/visitor/protothread/lib/lc.h
new file mode 100644 (file)
index 0000000..9ef2f0f
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the protothreads library.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer 
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+
+#ifdef LC_INCLUDE
+#include LC_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
diff --git a/dol/src/dol/visitor/protothread/lib/pt-sem.h b/dol/src/dol/visitor/protothread/lib/pt-sem.h
new file mode 100644 (file)
index 0000000..a6e1428
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ *
+ * This file is part of the protothreads library.
+ * 
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt-sem.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup ptsem Protothread semaphores
+ * @{
+ *
+ * This module implements counting semaphores on top of
+ * protothreads. Semaphores are a synchronization primitive that
+ * provide two operations: "wait" and "signal". The "wait" operation
+ * checks the semaphore counter and blocks the thread if the counter
+ * is zero. The "signal" operation increases the semaphore counter but
+ * does not block. If another thread has blocked waiting for the
+ * semaphore that is signalled, the blocked thread will become
+ * runnable again.
+ *
+ * Semaphores can be used to implement other, more structured,
+ * synchronization primitives such as monitors and message
+ * queues/bounded buffers (see below).
+ *
+ * The following example shows how the producer-consumer problem, also
+ * known as the bounded buffer problem, can be solved using
+ * protothreads and semaphores. Notes on the program follow after the
+ * example.
+ *
+ \code
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static struct pt_sem mutex, full, empty;
+
+PT_THREAD(producer(struct pt *pt))
+{
+  static int produced;
+  
+  PT_BEGIN(pt);
+  
+  for(produced = 0; produced < NUM_ITEMS; ++produced) {
+  
+    PT_SEM_WAIT(pt, &full);
+    
+    PT_SEM_WAIT(pt, &mutex);
+    add_to_buffer(produce_item());    
+    PT_SEM_SIGNAL(pt, &mutex);
+    
+    PT_SEM_SIGNAL(pt, &empty);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(consumer(struct pt *pt))
+{
+  static int consumed;
+  
+  PT_BEGIN(pt);
+
+  for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+    
+    PT_SEM_WAIT(pt, &empty);
+    
+    PT_SEM_WAIT(pt, &mutex);    
+    consume_item(get_from_buffer());    
+    PT_SEM_SIGNAL(pt, &mutex);
+    
+    PT_SEM_SIGNAL(pt, &full);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(driver_thread(struct pt *pt))
+{
+  static struct pt pt_producer, pt_consumer;
+
+  PT_BEGIN(pt);
+  
+  PT_SEM_INIT(&empty, 0);
+  PT_SEM_INIT(&full, BUFSIZE);
+  PT_SEM_INIT(&mutex, 1);
+
+  PT_INIT(&pt_producer);
+  PT_INIT(&pt_consumer);
+
+  PT_WAIT_THREAD(pt, producer(&pt_producer) &
+                    consumer(&pt_consumer));
+
+  PT_END(pt);
+}
+ \endcode
+ *
+ * The program uses three protothreads: one protothread that
+ * implements the consumer, one thread that implements the producer,
+ * and one protothread that drives the two other protothreads. The
+ * program uses three semaphores: "full", "empty" and "mutex". The
+ * "mutex" semaphore is used to provide mutual exclusion for the
+ * buffer, the "empty" semaphore is used to block the consumer is the
+ * buffer is empty, and the "full" semaphore is used to block the
+ * producer is the buffer is full.
+ *
+ * The "driver_thread" holds two protothread state variables,
+ * "pt_producer" and "pt_consumer". It is important to note that both
+ * these variables are declared as <i>static</i>. If the static
+ * keyword is not used, both variables are stored on the stack. Since
+ * protothreads do not store the stack, these variables may be
+ * overwritten during a protothread wait operation. Similarly, both
+ * the "consumer" and "producer" protothreads declare their local
+ * variables as static, to avoid them being stored on the stack.
+ * 
+ *
+ */
+   
+/**
+ * \file
+ * Couting semaphores implemented on protothreads
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_SEM_H__
+#define __PT_SEM_H__
+
+#include "pt.h"
+
+struct pt_sem {
+  unsigned int count;
+};
+
+/**
+ * Initialize a semaphore
+ *
+ * This macro initializes a semaphore with a value for the
+ * counter. Internally, the semaphores use an "unsigned int" to
+ * represent the counter, and therefore the "count" argument should be
+ * within range of an unsigned int.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \param c (unsigned int) The initial count of the semaphore.
+ * \hideinitializer
+ */
+#define PT_SEM_INIT(s, c) (s)->count = c
+
+/**
+ * Wait for a semaphore
+ *
+ * This macro carries out the "wait" operation on the semaphore. The
+ * wait operation causes the protothread to block while the counter is
+ * zero. When the counter reaches a value larger than zero, the
+ * protothread will continue.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_WAIT(pt, s)     \
+  do {                                         \
+    PT_WAIT_UNTIL(pt, (s)->count > 0);         \
+    --(s)->count;                              \
+  } while(0)
+
+/**
+ * Signal a semaphore
+ *
+ * This macro carries out the "signal" operation on the semaphore. The
+ * signal operation increments the counter inside the semaphore, which
+ * eventually will cause waiting protothreads to continue executing.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_SIGNAL(pt, s) ++(s)->count
+
+#endif /* __PT_SEM_H__ */
+
+/** @} */
+/** @} */
+   
diff --git a/dol/src/dol/visitor/protothread/lib/pt.h b/dol/src/dol/visitor/protothread/lib/pt.h
new file mode 100644 (file)
index 0000000..a7d3829
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h 1 2010-02-24 13:03:05Z haidw $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+typedef struct _pt {
+  lc_t lc;
+} pt;
+
+#define PT_WAITING 0
+#define PT_YIELDED 1
+#define PT_EXITED  2
+#define PT_ENDED   3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt)   LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+                   PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)           \
+  do {                                         \
+    LC_SET((pt)->lc);                          \
+    if(!(condition)) {                         \
+      return PT_WAITING;                       \
+    }                                          \
+  } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)            \
+  do {                                         \
+    PT_INIT((child));                          \
+    PT_WAIT_THREAD((pt), (thread));            \
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)                         \
+  do {                                         \
+    PT_INIT(pt);                               \
+    return PT_WAITING;                 \
+  } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)                            \
+  do {                                         \
+    PT_INIT(pt);                               \
+    return PT_EXITED;                  \
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)                           \
+  do {                                         \
+    PT_YIELD_FLAG = 0;                         \
+    LC_SET((pt)->lc);                          \
+    if(PT_YIELD_FLAG == 0) {                   \
+      return PT_YIELDED;                       \
+    }                                          \
+  } while(0)
+
+/**
+ * \brief      Yield from the protothread until a condition occurs.
+ * \param pt   A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ *             This function will yield the protothread, until the
+ *             specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond)               \
+  do {                                         \
+    PT_YIELD_FLAG = 0;                         \
+    LC_SET((pt)->lc);                          \
+    if((PT_YIELD_FLAG == 0) || !(cond)) {      \
+      return PT_YIELDED;                       \
+    }                                          \
+  } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */
diff --git a/dol/src/dol/visitor/rtems/RtemsMakefileVisitor.java b/dol/src/dol/visitor/rtems/RtemsMakefileVisitor.java
new file mode 100644 (file)
index 0000000..04c617e
--- /dev/null
@@ -0,0 +1,296 @@
+/* $Id: RtemsMakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.rtems;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.Configuration;
+import dol.main.UserInterface;
+import dol.parser.xml.archischema.ArchiXmlParser;
+import dol.parser.xml.mapschema.MapXmlParser;
+import dol.visitor.PNVisitor;
+
+/**
+ *  This class is a class for a visitor that is used to generate
+ *  a RTEMS package Makefile.
+ */
+public class RtemsMakefileVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of the Makefile
+     */
+    public RtemsMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * Create a Makefile for the given process network.
+     *
+     * @param pn process network
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            _ui = UserInterface.getInstance();
+            if (_ui.getRtemsBSP().equals("pc386")) {
+                ps.println(getPc386Makefile(pn));
+            } else if (_ui.getRtemsBSP().equals("mparm")) {
+                ps.println(getMparmMakefile(pn));
+            }
+        } catch (Exception e) {
+            System.out.println("RtemsMakefileVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create a makefile for the pc386 board support package.
+     *
+     * @param pn process network
+     * @return makefile for pc386 board support package
+     */
+    protected String getMparmMakefile(ProcessNetwork pn) {
+        String makefile = "";
+        String newline = System.getProperty("line.separator");
+        makefile += "ifndef SWARMDIR" + newline;
+        makefile += "  $(error Fatal error: Undefined SWARMDIR "
+                + "environment variable!)" + newline;
+        makefile += "endif" + newline;
+        makefile += "" + newline;
+        makefile += "ifndef RTEMS_MAKEFILE_PATH" + newline;
+        makefile += "  $(error Fatal error: Undefined "
+                + "RTEMS_MAKEFILE_PATH environment variable!)" + newline;
+        makefile += "endif" + newline;
+        makefile += "" + newline;
+        makefile += "ifdef EXENAME" + newline;
+        makefile += "  EXEC=$(EXENAME).exe" + newline;
+        makefile += "else" + newline;
+        makefile += "  EXEC=app.exe" + newline;
+        makefile += "endif" + newline;
+        makefile += "" + newline;
+        makefile += "PGM=${ARCH}/$(EXEC)" + newline;
+        makefile += "" + newline;
+        makefile += "# optional managers required" + newline;
+        makefile += "MANAGERS=io mp msg signal event region partition";
+        makefile += newline + newline;
+
+        if (_ui.getRtemsBSP().equals("mparm")) {
+            makefile += "# scratchpad queue lib" + newline;
+            makefile += "QUEUELIB=que_lib/lib" + newline;
+            makefile += "SS_SEMAPHORE_LIB_PATH = "
+                    + "${QUEUELIB}/ss_semaphore_lib" + newline;
+            makefile +="SCRATCH_QUEUE_LIB_PATH = "
+                    + "${QUEUELIB}/scratch_queue_lib" + newline;
+            makefile += "SCRATCH_SEMAPHORE_LIB_PATH = "
+                    + "${QUEUELIB}/scratch_semaphore_lib" + newline;
+            makefile += "EXT_INT_LIB_PATH = ${QUEUELIB}/ext_int_lib" + newline;
+        }
+
+        makefile += "" + newline;
+        makefile += "#H_files" + newline;
+        makefile += "H_FILES=buffer_test_io.h" + newline;
+
+        if (_ui.getRtemsBSP().equals("mparm")) {
+            makefile += "H_FILES += system.h tmacros.h" + newline;
+            makefile += newline;
+            makefile += "COMMON_FLAGS += -DMPARM" + newline;
+            makefile += "COMMON_FLAGS += -I$(QUEUELIB)" + newline;
+            makefile += "COMMON_FLAGS += -I$(SS_SEMAPHORE_LIB_PATH)"
+                   + newline;
+            makefile += "COMMON_FLAGS += -I$(SCRATCH_QUEUE_LIB_PATH)"
+                   + newline;
+            makefile += "COMMON_FLAGS += -I$(SCRATCH_SEMAPHORE_LIB_PATH)";
+            makefile += newline;
+            makefile += newline;
+            makefile += "# communication options" + newline;
+            makefile += "COMMON_FLAGS += -DMPARM_SCRATCHPAD_QUEUE"
+                    + newline;
+            makefile+="COMMON_FLAGS += -DQUEUE_BUFF_IN_PRODUCER "
+                    + "-Dshaper_PROCESSOR" + newline;
+            makefile+="#COMMON_FLAGS += -DQUEUE_BUFF_IN_PRODUCER_DMA "
+                    + "-Dshaper_PROCESSOR" + newline;
+            makefile+="#COMMON_FLAGS += -DQUEUE_BUFF_IN_CONSUMER "
+                    + "-Dshaper_PROCESSOR" + newline;
+            makefile+="#COMMON_FLAGS += -DQUEUE_BUFF_IN_CONSUMER_DMA "
+                    + "-Dshaper_PROCESSOR" + newline;
+            makefile+="#COMMON_FLAGS += -DQUEUE_BUFF_IN_SHARDMEM "
+                    + "-Dshaper_PROCESSOR" + newline;
+
+        int shaperProcessorID;
+        if (_ui.getMappingFileName() == null) {
+        shaperProcessorID =  pn.getProcessList().size();
+        } else {
+        ArchiXmlParser archParser = new ArchiXmlParser();
+        Architecture arch = archParser.
+                doParse(_ui.getPlatformFileName());
+        MapXmlParser mappingParser = new MapXmlParser(pn, arch);
+        Mapping  mapping = mappingParser.
+                doParse(_ui.getMappingFileName());
+        shaperProcessorID = mapping.getProcessorList().size();
+        }
+            makefile +="#COMMON_FLAGS += -DQUEUE_BUFF_SHAPER "
+                    + "-Dshaper_PROCESSOR=" + shaperProcessorID + newline;
+
+            makefile += newline;
+            makefile += "LIBFILECXX = "
+                   + "$(SS_SEMAPHORE_LIB_PATH)/ss_semaphore.cpp "
+                   + "$(SCRATCH_QUEUE_LIB_PATH)/scratch_queue.cpp"
+                   + newline;
+            makefile += "VPATH = SCRATCH_QUEUE_LIB_PATH" + newline;
+        }
+
+        makefile += "" + newline;
+        makefile += "# C source names" + newline;
+        if (_ui.getRtemsBSP().equals("pc386")) {
+            makefile += "CSRCS = main.c rtems_process_wrapper.c ";
+            for (String basename : pn.getProcessBasenames()) {
+                makefile += basename + "_wrapper.c ";
+            }
+        }
+        makefile += newline;
+        makefile += "COBJS_ = $(CSRCS:.c=.o)" + newline;
+        makefile += "COBJS = $(COBJS_:%=%)" + newline;
+        makefile += "" + newline;
+        makefile += "# C++ source names" + newline;
+        makefile += "CXXSRCS = appsupport.c" + newline;
+
+        if (_ui.getRtemsBSP().equals("mparm")) {
+            makefile += "CXXSRCS += main.c traffic_shaping.c "
+                    + "rtems_process_wrapper.c ";
+            Vector<String> pList = new Vector<String>();
+            for (Process p : pn.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    makefile += p.getBasename() + "_wrapper.c ";
+                    pList.add(basename);
+                }
+            }
+            makefile += newline;
+            makefile += "CXXSRCS += $(LIBFILECXX)" + newline;
+        }
+
+        makefile += newline;
+        makefile += newline;
+        makefile += "CXXOBJS_ = $(CXXSRCS:.cpp=.o)" + newline;
+        makefile += "CXXOBJS = $(CXXOBJS_:%=%)" + newline;
+        makefile += "" + newline;
+        makefile += "# AS source names" + newline;
+        makefile += "ASSRCS =" + newline;
+        makefile += "ASOBJS_ = $(ASSRCS:.s=.o)" + newline;
+        makefile += "ASOBJS = $(ASOBJS_:%=%)" + newline;
+        makefile += "" + newline;
+        makefile += "# Libraries" + newline;
+        makefile += "LIBS = -lrtemsall -lc" + newline;
+        makefile += "" + newline;
+        makefile += "include $(RTEMS_MAKEFILE_PATH)/Makefile.inc"
+                + newline;
+        makefile += "include $(RTEMS_CUSTOM)" + newline;
+        makefile += "include $(PROJECT_ROOT)/make/leaf.cfg" + newline;
+        makefile += "" + newline;
+        makefile += "#CXXFLAGS += -DAUTOSTARTMEASURING" + newline;
+        makefile += "#CXXFLAGS += -DVERBOSE" + newline;
+        makefile += "CXXFLAGS += -I$(SWARMDIR)/core" + newline;
+        makefile += "CFLAGS += -I$(SWARMDIR)/core" + newline;
+
+        if (_ui.getRtemsBSP().equals("mparm")) {
+            makefile += "CXXFLAGS += $(COMMON_FLAGS) -I${PWD}" + newline;
+            makefile += "CFLAGS += $(COMMON_FLAGS) -I${PWD}" + newline;
+
+            makefile += newline;
+            makefile += "#### for calibration" + newline;
+            makefile += "CXXFLAGS +=  -Ilib" + newline;
+            makefile += "CXXFLAGS += -D_GLIBCPP_HAVE_WCHAR_H "
+                + "-D_GLIBCPP_HAVE_MBSTATE_T" + newline;
+            makefile += "CXXFLAGS += -DWORKLOAD_EXTRACT" + newline;
+            makefile += "CXXFLAGS += -DPRINTF_TO_DEBUG" + newline;
+        }
+        makefile += "" + newline;
+        makefile += "SRCS=$(H_FILES)" + newline;
+        makefile += "OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)" + newline;
+        makefile += "" + newline;
+        makefile += "all:    ${ARCH} $(SRCS) $(PGM) " + newline;
+        makefile += "" + newline;
+        makefile += "$(PGM): $(OBJS) " + newline;
+        makefile += "\t$(make-exe)" + newline;
+        makefile += "clean:" + newline;
+        makefile += "\t-rm -f ${SS_SEMAPHORE_LIB_PATH}/*.o " +
+                "${SCRATCH_QUEUE_LIB_PATH}/*.o" + newline;
+
+        return makefile;
+    }
+
+    /**
+     * Create a makefile for the pc386 board support package.
+     *
+     * @param pn process network
+     * @return makefile for pc386 board support package
+     */
+    protected String getPc386Makefile(ProcessNetwork pn) {
+        String makefile = "";
+        String newline = System.getProperty("line.separator");
+        makefile += "EXEC=main.exe" + newline;
+        makefile += "PGM=${ARCH}/$(EXEC)" + newline;
+        makefile += newline;
+        makefile += "# optional managers required" + newline;
+        makefile += "MANAGERS=all" + newline;
+        makefile += newline;
+        makefile += "# C source names" + newline;
+        makefile += "CSRCS = main.c rtems_process_wrapper.c ";
+        for (String basename : pn.getProcessBasenames()) {
+            makefile += basename + "_wrapper.c ";
+        }
+       for (Configuration conf : pn.getCfgList()) {
+           if (conf.getName().equals("EXTERNAL_SRC")) {
+               makefile += conf.getValue();
+           }
+       }
+        makefile += newline;
+        makefile += "COBJS_ = $(CSRCS:.c=.o)" + newline;
+        makefile += "COBJS = $(COBJS_:%=${ARCH}/%)" + newline;
+        makefile += newline;
+        makefile += "# C++ source names" + newline;
+        makefile += "CXXSRCS =" + newline;
+        makefile += "CXXOBJS_ = $(CXXSRCS:.cc=.o)" + newline;
+        makefile += "CXXOBJS = $(CXXOBJS_:%=${ARCH}/%)" + newline;
+        makefile += newline;
+        makefile += "# AS source names" + newline;
+        makefile += "ASSRCS =" + newline;
+        makefile += "ASOBJS_ = $(ASSRCS:.s=.o)" + newline;
+        makefile += "ASOBJS = $(ASOBJS_:%=${ARCH}/%)" + newline;
+        makefile += newline;
+        makefile += "# Libraries" + newline;
+        makefile += "LIBS = -lrtemsall -lc ";
+       for (Configuration conf : pn.getCfgList()) {
+           if (conf.getName().equals("DYNAMIC_LINK"))
+               makefile += conf.getValue() + newline;
+       }
+        makefile += newline;
+        makefile += "include $(RTEMS_MAKEFILE_PATH)/Makefile.inc"
+                + newline;
+        makefile += newline;
+        makefile += "include $(RTEMS_CUSTOM)" + newline;
+        makefile += "include $(PROJECT_ROOT)/make/leaf.cfg" + newline;
+        makefile += newline;
+        makefile += "OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)" + newline;
+        makefile += newline;
+        makefile += "all:    ${ARCH} $(PGM)" + newline;
+        makefile += newline;
+        makefile += "$(PGM): $(OBJS)" + newline;
+        makefile += "\t$(make-exe)" + newline;
+        return makefile;
+    }
+
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/rtems/RtemsModuleVisitor.java b/dol/src/dol/visitor/rtems/RtemsModuleVisitor.java
new file mode 100644 (file)
index 0000000..d62eda3
--- /dev/null
@@ -0,0 +1,864 @@
+/* $Id: RtemsModuleVisitor.java 114 2010-07-05 07:47:02Z haidw $ */
+package dol.visitor.rtems;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.mapping.ComputationBinding;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.mapping.Schedule;
+import dol.datamodel.mapping.ScheduleEntry;
+import dol.datamodel.mapping.SchedulingPolicy;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.main.UserInterface;
+import dol.parser.xml.archischema.ArchiXmlParser;
+import dol.parser.xml.mapschema.MapXmlParser;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class RtemsModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public RtemsModuleVisitor(String dir, HashMap<Port, Integer> portMap) {
+        _dir = dir;
+        _portMap = portMap;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            _ui = UserInterface.getInstance();
+            String filename = _dir + _delimiter + "main.c";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            Vector<Process> pList = x.getProcessList();
+            Vector<String> processList = new Vector<String>();
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!processList.contains(basename)) {
+                    processList.add(basename);
+                }
+            }
+
+            Architecture arch = null;
+            Mapping mapping = null;
+
+            //create header section
+            if (_ui.getRtemsBSP().equals("pc386")) {
+                _mainPS.println("#include <bsp.h>");
+                _mainPS.println("#include <stdlib.h>");
+                _mainPS.println("#include <stdio.h>");
+                _mainPS.println("#include <inttypes.h>");
+                _mainPS.println();
+                _mainPS.println("rtems_task Init(rtems_task_argument argument);");
+                _mainPS.println();
+                _mainPS.println("#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER");
+                _mainPS.println("#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER");
+                _mainPS.println("#define CONFIGURE_RTEMS_INIT_TASKS_TABLE");
+                _mainPS.println("#define CONFIGURE_MAXIMUM_TASKS "
+                        + (x.getProcessList().size() + 2));
+                _mainPS.println("#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES "
+                        + x.getChannelList().size());
+                _mainPS.println("#define CONFIGURE_INIT");
+                _mainPS.println("#include <rtems/confdefs.h>");
+                _mainPS.println();
+            } else if (_ui.getRtemsBSP().equals("mparm")) {
+                _mainPS.println("#define TEST_INIT");
+                _mainPS.println("#include <bsp.h>");
+                _mainPS.println("#include <stdlib.h>");
+                _mainPS.println("#include <stdio.h>");
+                _mainPS.println();
+                _mainPS.println("#define RTEMS_TRACE_MAIN_APP");
+                _mainPS.println("#include \"system.h\"");
+                _mainPS.println("#include \"appsupport.h\"");
+                _mainPS.println("#include \"scratch_queue.h\"");
+                _mainPS.println();
+            }
+
+            _mainPS.println("#include \"dol.h\"");
+            _mainPS.println("#include \"rtems_process_wrapper.h\"");
+            _mainPS.println();
+
+            if (_ui.getRtemsBSP().equals("pc386")) {
+                _mainPS.println("rtems_task CleanupTask(rtems_task_argument arg);");
+                _mainPS.println("rtems_id queue_id["
+                                + x.getChannelList().size() + "];");
+                _mainPS.println();
+            } else if (_ui.getRtemsBSP().equals("mparm")) {
+                //if no mapping is provided, map each process to a new
+                //processor
+                //shaper
+                _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+                _mainPS.println("#include \"traffic_shaping.h\"");
+                //_mainPS.println("#define shaper_PROCESSOR "
+                //        + (pList.size()+1));
+                _mainPS.println("#endif // shaper");
+                _mainPS.println();
+
+                if (_ui.getMappingFileName() == null) {
+
+                    int i = 0;
+                    for (Process p : pList) {
+                        _mainPS.println("#define " + p.getName()
+                                + "_PROCESSOR " + ++i); //count from 1
+                    }
+                    _mainPS.println();
+
+                    _mainPS.print("unsigned int number_of_processes["
+                            + pList.size() + "] = { ");
+                    for (i = 0; i < pList.size(); i++) {
+                        _mainPS.print("1, ");
+                    }
+                    _mainPS.println("};");
+                    _mainPS.println();
+
+                } else { //map processes according to mapping file
+                    ArchiXmlParser archParser = new ArchiXmlParser();
+                    arch = archParser.doParse(_ui.getPlatformFileName());
+                    MapXmlParser mappingParser = new MapXmlParser(x, arch);
+                    mapping = mappingParser.doParse(_ui.getMappingFileName());
+                    int numOfUsedProcessors = mapping.getProcessorList().size();
+                    int numOfProcessors = arch.getProcessorList().size();
+                    int processesPerProcessor[] = new int[numOfProcessors];
+
+                    // need to check processors used start from 0 and
+                    //continuous
+                    for (Process p : pList) {
+                        for (ComputationBinding b : mapping.getCompBindList()){
+                            int processorIndex = Integer.valueOf(
+                                 b.getProcessor().getName().
+                                 replaceAll(".*_", ""));
+                            if (b.getProcess().getName().
+                                equals(p.getName())) {
+                                processesPerProcessor[processorIndex]++;
+                                //processor indices start at 1 in MPARM
+                                _mainPS.println("#define " + p.getName()
+                                        + "_PROCESSOR "
+                                        + (processorIndex + 1));
+                            }
+                        }
+                    }
+
+
+                    for (int i=0; i < numOfUsedProcessors; i++) {
+                    if (processesPerProcessor[i] < 1)
+                        throw new Exception("No process is mapped to "
+                                + "PROCESSOR[" + i + "]. For the MPARM "
+                                + "platform, processors should be used "
+                                + "starting from 0 until N (in the "
+                                + "generated code, from 1 to N + 1), and "
+                                + "every processor between 0 and N "
+                                + "should have at least one process "
+                                + "mapped on it!");
+                    }
+
+                    _mainPS.println();
+                    /*
+                    _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+                    _mainPS.println("#define shaper_PROCESSOR "
+                    + (numOfUsedProcessors+1));
+                    _mainPS.println("#endif // shaper");
+                    _mainPS.println();
+                    */
+                    _mainPS.print("unsigned int number_of_processes[]"
+                            + " = { ");
+                    for (int i = 0; i < numOfUsedProcessors; i++) {
+                        _mainPS.print(processesPerProcessor[i] + ", ");
+                    }
+                    _mainPS.println("};");
+                    _mainPS.println();
+                }
+
+                _mainPS.println("unsigned int active_processes;");
+                _mainPS.println("inline void processor_init() "
+                        + "{active_processes"
+                        + " = number_of_processes[get_id() - 1];}");
+                _mainPS.println();
+
+                for (Process p : pList) {
+                    _mainPS.println("void " + "rtems_" + p.getName()
+                            + "_init(rtems_task_argument arg);");
+                }
+                _mainPS.println();
+            }
+
+            for (String pName : x.getProcessBasenames()) {
+                _mainPS.println("extern rtems_task " + pName
+                        + "_task(rtems_task_argument argument);");
+            }
+            _mainPS.println();
+
+            //declare processes and channels
+            for (Process process : x.getProcessList()) {
+                _mainPS.println("RtemsProcessWrapper *" + process.getName()
+                        + "_wrapper;");
+            }
+            _mainPS.println();
+
+            _mainPS.println("#ifdef PRINTF_TO_DEBUG");
+            _mainPS.println("#undef printf");
+            _mainPS.println("#define printf(...) \\");
+            _mainPS.println("  do {              \\");
+            _mainPS.println("    char _buffer[128];             \\");
+            _mainPS.println("    sprintf(_buffer, __VA_ARGS__); \\");
+            _mainPS.println("    SHOW_DEBUG((int)_buffer);      \\");
+            _mainPS.println("  } while (0)");
+            _mainPS.println("#endif");
+            _mainPS.println();
+            _mainPS.println("#ifdef WORKLOAD_EXTRACT");
+            _mainPS.println("void callback(int code, int* arg, int size) "
+                    + "{");
+            _mainPS.println("  long unsigned int time = get_cycle1();");
+            _mainPS.println("  Thread_Control *x = "
+                    + "(Thread_Control*)arg;");
+            _mainPS.println("  SHOW_DEBUG(\"log callback\");");
+            _mainPS.println("  SHOW_DEBUG_INT((int)time);");
+            _mainPS.println("  SHOW_DEBUG_INT(x->Object.id);");
+            _mainPS.println("}");
+            _mainPS.println("#endif");
+            _mainPS.println();
+            _mainPS.println("rtems_id timer_sem_id;");
+            _mainPS.println();
+            //RTEMS init task
+            _mainPS.println("/**");
+            _mainPS.println(" *");
+            _mainPS.println(" */");
+            _mainPS.println("rtems_task Init(rtems_task_argument arg) {");
+
+            if (_ui.getRtemsBSP().equals("mparm")) {
+                // //////////////////// mparm /////////////////////////
+                int processCount = 0;
+
+                _mainPS.println("  rtems_id task_id;");
+                _mainPS.println("  rtems_status_code status;");
+                _mainPS.println();
+                _mainPS.println("  status = rtems_semaphore_create(rtems_build_name('c','s','e','m'), 1, RTEMS_BINARY_SEMAPHORE |RTEMS_NO_PRIORITY_CEILING |RTEMS_LOCAL |RTEMS_PRIORITY, 0,&timer_sem_id);");
+                _mainPS.println("  if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("     printf(\"[init    ] Could not create semaphore (status %d).\", status);");
+                _mainPS.println("      rtems_shutdown_executive(0);");
+                _mainPS.println("  }");
+
+
+                _mainPS.println();
+
+                _mainPS.println("  scratch_queue_autoinit_system();");
+                _mainPS.println();
+
+                _mainPS.println("#ifdef WORKLOAD_EXTRACT");
+                _mainPS.println("  rtems_monitor_register_callback"
+                        + "(callback);");
+                for (Channel c : x.getChannelList()) {
+                    _mainPS.println("  SHOW_DEBUG(\"log "
+                            + "create_channel\");");
+                    _mainPS.println("  SHOW_DEBUG(\"log " + c.getName()
+                            + "\");");
+                    _mainPS.println("  SHOW_DEBUG_INT((int)"
+                            + (c.getSize() * c.getTokenSize()) + ");");
+                }
+                _mainPS.println("#endif");
+
+                //shaper process
+                _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+                _mainPS.println("  if ((get_id()-1) == shaper_PROCESSOR) "
+                        + "{");
+                _mainPS.println("    rtems_name name = rtems_build_name"
+                                +"('s', 's', '0', ' ');");
+                _mainPS.println();
+
+                // create pre task
+                _mainPS.println("    //one more init to prevent the"
+                        + "blocking instatiation of scrach queue");
+                _mainPS.println("    status = rtems_task_create(");
+                _mainPS.println("          name,");
+                _mainPS.println("          1,");
+                _mainPS.println("          RTEMS_MINIMUM_STACK_SIZE,");
+                _mainPS.println("          RTEMS_DEFAULT_MODES,");
+                _mainPS.println("          RTEMS_LOCAL,");
+                _mainPS.println("          &task_id, -1);");
+                _mainPS.println("    if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("      printf(\"[init    ] "
+                        + "Could not create init shaper"
+                        + "(status %d).\\n\", status);");
+                _mainPS.println("      rtems_shutdown_executive(0);");
+                _mainPS.println("    }");
+                _mainPS.println();
+
+                // start pre init
+                _mainPS.println("    status = rtems_task_start(task_id, "
+                        + "shaping_init, arg);");
+                _mainPS.println("    if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("      printf(\"[init    ] "
+                        + "Could not start init shaping"
+                        + " (status %d).\\n\", status);");
+                _mainPS.println("    rtems_shutdown_executive(0);");
+                _mainPS.println("    }");
+                _mainPS.println("  }");
+                _mainPS.println("#endif // QUEUE_BUFF_SHAPER");
+                _mainPS.println();
+
+                for (Process process : x.getProcessList()) {
+                    _mainPS.println("  if (get_id() == "
+                            + process.getName() + "_PROCESSOR) {");
+                    _mainPS.println("    processor_init();");
+                    _mainPS.println("    rtems_name name = "
+                            + "rtems_build_name"
+                            + "('p', 'i', 0x" + ++processCount
+                            + ", ' ');");
+                    _mainPS.println();
+
+                    // create pre task
+                    _mainPS.println("    //one more init to prevent the"
+                            + "blocking instatiation of scrach queue");
+                    _mainPS.println("    status = rtems_task_create(");
+                    _mainPS.println("          name,");
+                    _mainPS.println("          1,");
+                    _mainPS.println("          RTEMS_MINIMUM_STACK_SIZE"
+                            + ",");
+                    _mainPS.println("          RTEMS_DEFAULT_MODES,");
+                    _mainPS.println("          RTEMS_LOCAL,");
+                    _mainPS.println("          &task_id, -1);");
+                    _mainPS.println("    if (status != RTEMS_SUCCESSFUL) "
+                            + "{");
+                    _mainPS.println("      printf(\"[init    ] "
+                            + "Could not create init task["
+                            + process.getName() + "] "
+                            +"(status %d).\\n\", status);");
+                    _mainPS.println("      rtems_shutdown_executive(0);");
+                    _mainPS.println("    }");
+                    _mainPS.println();
+
+                    // start pre init
+                    _mainPS.println("    status = rtems_task_start(task_id, "
+                            + "rtems_" + process.getName()
+                            + "_init, arg);");
+                    _mainPS.println("    if (status != RTEMS_SUCCESSFUL) {");
+                    _mainPS.println("      printf(\"[init    ] "
+                            + "Could not start init task [ "
+                            + process.getName()
+                            + "] (status %d).\\n\", status);");
+                    _mainPS.println("    rtems_shutdown_executive(0);");
+                    _mainPS.println("    }");
+                    /*
+                    _mainPS.println("    rtems_" + process.getName()
+                            + "_init(arg);");
+                    _mainPS.println("    rtems_task_delete(RTEMS_SELF);");
+                    */
+                    _mainPS.println("  }");
+                    _mainPS.println();
+                }
+
+                // shaper process
+                _mainPS.println("#ifdef QUEUE_BUFF_SHAPER");
+                _mainPS.println("  if ((get_id()-1) == shaper_PROCESSOR) "
+                        + "{");
+                _mainPS.println("    rtems_name name = rtems_build_name"
+                        +"('s', 's', '0', ' ');");
+                _mainPS.println();
+
+                // create pre task
+                _mainPS.println("    //one more init to prevent the"
+                        + "blocking instatiation of scrach queue");
+                _mainPS.println("    status = rtems_task_create(");
+                _mainPS.println("          name,");
+                _mainPS.println("          128,");
+                _mainPS.println("          RTEMS_MINIMUM_STACK_SIZE,");
+                _mainPS.println("          RTEMS_DEFAULT_MODES,");
+                _mainPS.println("          RTEMS_LOCAL,");
+                _mainPS.println("          &task_id, -1);");
+                _mainPS.println("    if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("      printf(\"[init    ] "
+                        + "Could not create init shaper"
+                        +"(status %d).\\n\", status);");
+                _mainPS.println("      rtems_shutdown_executive(0);");
+                _mainPS.println("    }");
+                _mainPS.println();
+
+                // start pre init
+                _mainPS.println("    status = rtems_task_start(task_id, "
+                        + "shaping_init, arg);");
+                _mainPS.println("    if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("      printf(\"[init    ] "
+                        + "Could not start init shaping"
+                        + " (status %d).\\n\", status);");
+                _mainPS.println("    rtems_shutdown_executive(0);");
+                _mainPS.println("    }");
+                _mainPS.println("  }");
+                _mainPS.println("#endif // QUEUE_BUFF_SHAPER");
+                _mainPS.println();
+
+                _mainPS.println("if (number_of_processes[get_id() - 1]"
+                        + " == 0) {");
+                _mainPS.println("    printf(\"No process on processor "
+                        + "%d.\", get_id());");
+                _mainPS.println("    rtems_shutdown_executive(0);");
+                _mainPS.println("}");
+                _mainPS.println();
+
+                _mainPS.println("  rtems_task_delete(RTEMS_SELF);");
+                _mainPS.println("}");
+                _mainPS.println();
+                // end of init
+
+                processCount = 0;
+                for (Process process : x.getProcessList()) {
+                    String processName = process.getName();
+                    _mainPS.println("void rtems_" + process.getName()
+                            + "_init(rtems_task_argument arg) {");
+                    _mainPS.println("  rtems_id task_id;");
+                    _mainPS.println("  rtems_status_code status;");
+
+
+                    _mainPS.println("  " + process.getName()
+                            + "_wrapper = "
+                            + "(RtemsProcessWrapper *)malloc"
+                            + "(sizeof(RtemsProcessWrapper));");
+
+                    int numOfOutports = process.getNumOfOutports();
+                    int numOfInports  = process.getNumOfInports();
+                    if (numOfOutports > 0) {
+                        _mainPS.println("  int* "
+                                + process.getName()
+                                + "_out_port_id = (int *)malloc("
+                                + numOfOutports
+                                + " * sizeof(int));");
+                        _mainPS.println("  SCRATCH_QUEUE_PRODUCER **"
+                                + process.getName()
+                                + "_out_queue_id = "
+                                + "(SCRATCH_QUEUE_PRODUCER **)"
+                                + "malloc("
+                                + numOfOutports
+                                + "*sizeof(SCRATCH_QUEUE_PRODUCER));");
+                    }
+
+                    if (numOfInports > 0) {
+                        _mainPS.println("  int *"
+                                + process.getName()
+                                + "_in_port_id = (int *)malloc("
+                                + numOfInports
+                                + " * sizeof(int));");
+                        _mainPS.println("  SCRATCH_QUEUE_CONSUMER **"
+                                + process.getName()
+                                + "_in_queue_id = "
+                                + "(SCRATCH_QUEUE_CONSUMER **)"
+                                + "malloc("
+                                + numOfOutports
+                                + "*sizeof(SCRATCH_QUEUE_CONSUMER));");
+                    }
+                    _mainPS.println();
+
+                    // create task
+                    _mainPS.println("  status = rtems_task_create(");
+                    _mainPS.println("          " + ++processCount + ",");
+                    _mainPS.println("          1,");
+                    _mainPS.println("          RTEMS_MINIMUM_STACK_SIZE,");
+                    _mainPS.println("          RTEMS_DEFAULT_MODES,");
+                    _mainPS.println("          RTEMS_LOCAL,");
+                    _mainPS.println("          &task_id, -1);");
+                    _mainPS.println("  if (status != RTEMS_SUCCESSFUL) {");
+                    _mainPS.println("    printf(\"[init    ] "
+                            + "Could not create task["
+                            + processName + "] "
+                            +"(status %d).\\n\", status);");
+                    _mainPS.println("    rtems_shutdown_executive(0);");
+                    _mainPS.println("  }");
+
+                    _mainPS.println("#ifdef WORKLOAD_EXTRACT");
+                    _mainPS.println("  SHOW_DEBUG(\"log create_task\");");
+                    _mainPS.println("  SHOW_DEBUG_INT(task_id);");
+                    _mainPS.println("  SHOW_DEBUG(\"log " + processName + "\");");
+                    for (Port port : process.getPortList()) {
+                        Channel c = (Channel) port.getPeerResource();
+                        if (port.isInPort()) {
+                            _mainPS.println("  SHOW_DEBUG(\"log in_port\");");
+                            _mainPS.println("  SHOW_DEBUG_INT((int)" + _portMap.get(port) + ");");
+                            _mainPS.println("  SHOW_DEBUG(\"log " + c.getName() + "\");");
+                        }
+                        if (port.isOutPort()) {
+                            _mainPS.println("  SHOW_DEBUG(\"log out_port\");");
+                            _mainPS.println("  SHOW_DEBUG_INT((int)" + _portMap.get(port) + ");");
+                            _mainPS.println("  SHOW_DEBUG(\"log " + c.getName() + "\");");
+                        }
+                    }
+                    _mainPS.println("#endif");
+                    _mainPS.println();
+
+                    // connect ports to channels
+                    HashMap<Channel, Integer> channel_map =
+                        new HashMap<Channel, Integer>();
+                    int channelCount = 1;
+                    for (Channel c : x.getChannelList()) {
+                        channel_map.put(c, channelCount++);
+                    }
+                    _mainPS.println();
+
+                    // fill the wrapper, instantiate queues
+                    int i = 0, j = 0;
+                    for (Port port : process.getPortList()) {
+                        Channel c = (Channel)(port.getPeerResource());
+                        if (port.isInPort()) {
+                            _mainPS.println("  " + processName + "_in_port_id["
+                                    + i + "] = "
+                                    + _portMap.get(port) + ";");
+                            _mainPS.println("  " + processName
+                                    + "_in_queue_id["
+                                    + i + "] = ");
+                            _mainPS.println("#if defined (QUEUE_BUFF_IN_PRODUCER) || (QUEUE_BUFF_IN_PRODUCER_DMA)");
+                            _mainPS.println("  scratch_queue_autoinit_consumer("
+                                    + channel_map.get(c)
+                                    + ", true);");
+                            _mainPS.println("#elif defined (QUEUE_BUFF_IN_CONSUMER) || (QUEUE_BUFF_IN_CONSUMER_DMA)");
+                            _mainPS.println("  scratch_queue_autoinit_consumer("
+                                    + c.getOrigin().getName()
+                                    + "_PROCESSOR, "
+                                    + channel_map.get(c) + ", "
+                                    + c.getSize() + ", "
+                                    + c.getTokenSize()
+                                    + ");");
+                            _mainPS.println("#elif defined (QUEUE_BUFF_IN_SHARDMEM)");
+                            _mainPS.println("  scratch_queue_autoinit_consumer("
+                                    + channel_map.get(c)
+                                    + ", true);");
+                            _mainPS.println("#elif defined (QUEUE_BUFF_SHAPER)");
+                            _mainPS.println(" scratch_queue_autoinit_consumer("
+                                    + channel_map.get(c)
+                                    + ");");
+                            _mainPS.println("#endif");
+
+
+                            i++;
+                        } else if (port.isOutPort()) {
+                            _mainPS.println("  " + processName+"_out_port_id["
+                                    + j + "] = "
+                                    + _portMap.get(port) + ";");
+                            _mainPS.println("  " + processName
+                                    + "_out_queue_id["
+                                    + j + "] = ");
+
+                            _mainPS.println("#if defined (QUEUE_BUFF_IN_PRODUCER) || (QUEUE_BUFF_IN_PRODUCER_DMA)");
+                            _mainPS.println("  scratch_queue_autoinit_producer("
+                                    + c.getTarget().getName()
+                                    + "_PROCESSOR,"
+                                    + channel_map.get(c) + ", "
+                                    + c.getSize() + ", "
+                                    + c.getTokenSize()
+                                    + ", 0);");
+                            _mainPS.println("#elif defined (QUEUE_BUFF_IN_CONSUMER) || (QUEUE_BUFF_IN_CONSUMER_DMA)");
+                            _mainPS.println("  scratch_queue_autoinit_producer("
+                                    + channel_map.get(c)
+                                    + ", true);");
+                            _mainPS.println("#elif defined (QUEUE_BUFF_IN_SHARDMEM)");
+                            _mainPS.println("  scratch_queue_autoinit_producer("
+                                    + c.getTarget().getName()
+                                    + "_PROCESSOR,"
+                                    + channel_map.get(c) + ", "
+                                    + c.getSize() + ", "
+                                    + c.getTokenSize()
+                                    + ", 1);");
+                            _mainPS.println("#elif defined (QUEUE_BUFF_SHAPER)");
+                            _mainPS.println("  scratch_queue_autoinit_producer("
+                                    + c.getTarget().getName()
+                                    + "_PROCESSOR,"
+                                    + channel_map.get(c) + ", "
+                                    + c.getSize() + ", "
+                                    + c.getTokenSize()
+                                    + ");");
+                            _mainPS.println("#endif");
+
+                            j++;
+                        }
+                    }
+
+                    if (numOfInports > 0) {
+                        _mainPS.println("  " + processName
+                                + "_wrapper->in_port_id = "
+                                + processName
+                                + "_in_port_id;");
+                        _mainPS.println("  " + processName
+                                + "_wrapper->in_queue_id = "
+                                + processName
+                                + "_in_queue_id;");
+                        _mainPS.println("  " + processName
+                                + "_wrapper->number_of_in_ports = "
+                                + numOfInports + ";");
+                    }
+
+                    if (numOfOutports > 0) {
+                        _mainPS.println("  " + processName
+                                + "_wrapper->out_port_id = "
+                                + processName
+                                + "_out_port_id;");
+                        _mainPS.println("  " + processName
+                                + "_wrapper->out_queue_id = "
+                                + processName
+                                + "_out_queue_id;");
+                        _mainPS.println("  " + processName
+                                + "_wrapper->number_of_out_ports = "
+                                + numOfOutports + ";");
+                    }
+
+                    _mainPS.println("  " + processName
+                            + "_wrapper->is_detached = 0;");
+
+                    int priority = 127;
+                    if (mapping != null) {
+                        Schedule s = mapping.getScheduleByResource(
+                                process.getProcessor().getName());
+                        if (s != null && s.getSchedPolicy() ==
+                                SchedulingPolicy.FIXEDPRIORITY) {
+                            ScheduleEntry e = s.getScheduleEntry(
+                                    process.getName());
+                            if (e != null) {
+                                String value = e.getCfgValue("priority");
+                                if (value != null) {
+                                    priority = Integer.parseInt(value);
+                                }
+                            }
+                        }
+                    }
+                    _mainPS.println("  " + processName
+                            + "_wrapper->priority = " + priority + ";");
+
+                    _mainPS.println("  " + processName
+                            + "_wrapper->name = (char *)malloc(("
+                            + processName.length()
+                            + " + 1) * sizeof(char));");
+                    _mainPS.println("  strcpy(" + processName
+                            + "_wrapper->name, " + "\""
+                            + processName + "\");");
+                    _mainPS.println();
+
+                    _mainPS.println("  status = rtems_task_start("
+                            + "task_id, " + process.getBasename()
+                            + "_task, " + "(rtems_task_argument)"
+                            + process.getName() + "_wrapper);");
+                    _mainPS.println("  if (status != RTEMS_SUCCESSFUL) "
+                            + "{");
+                    _mainPS.println("    printf(\"[init    ] "
+                            + "Could not start " + process.getName()
+                            + " (status %d).\\n\", status);");
+                    _mainPS.println("    rtems_shutdown_executive(0);");
+                    _mainPS.println("  }");
+                    _mainPS.println("  rtems_task_delete(RTEMS_SELF);");
+                    _mainPS.println("}");
+                    _mainPS.println();
+                    _mainPS.println();
+                }
+            } else if (_ui.getRtemsBSP().equals("pc386")) {
+                // //////////////////// pc386 ////////////////////////
+                _mainPS.println("  int j;");
+                _mainPS.println("  rtems_id task_id[" +
+                                + (x.getProcessList().size() + 1) + "];");
+                _mainPS.println("  rtems_status_code status;");
+                _mainPS.println();
+
+                //initialize process-specific information
+                for (Process process : x.getProcessList()) {
+                    int numberOfPorts = x.getProcess(process.getName())
+                        .getPortList().size();
+                    _mainPS.println("  " + process.getName()
+                            + "_wrapper = "
+                            + "malloc(sizeof(RtemsProcessWrapper));");
+                    _mainPS.println("  int *"
+                            + process.getName() + "_port_id = malloc("
+                            + numberOfPorts + " * sizeof(int));");
+                    _mainPS.println("  int *"
+                            + process.getName()
+                            + "_port_queue_id = malloc("
+                            + numberOfPorts + " * sizeof(int));");
+                    _mainPS.println();
+                }
+
+                //create a task for each process
+                _mainPS.println("  for (j = 0; j < "
+                        + (x.getProcessList().size()+1) + "; j++) {");
+                _mainPS.println("    status = rtems_task_create(");
+                _mainPS.println("            j + 1,");
+                _mainPS.println("            128,");
+                _mainPS.println("            RTEMS_MINIMUM_STACK_SIZE,");
+                _mainPS.println("            RTEMS_DEFAULT_MODES,");
+                _mainPS.println("            RTEMS_DEFAULT_ATTRIBUTES,");
+                _mainPS.println("            &(task_id[j]));");
+                _mainPS.println("    if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("      printf(\"[init    ] "
+                        + "Could not create task[%d] (status %d).\\n\", "
+                        + "(int)j, status);");
+                _mainPS.println("      rtems_shutdown_executive(0);");
+                _mainPS.println("    }");
+                _mainPS.println("  }");
+                _mainPS.println();
+
+                //create a message queue for each channel
+                int j = 0;
+                for (Channel channel : x.getChannelList()) {
+                    _mainPS.println("  status = "
+                            + "rtems_message_queue_create(");
+                    _mainPS.println("          " + (j + 1) + ",");
+                    _mainPS.println("          " + channel.getSize()
+                            + ",");
+                    _mainPS.println("          1,");
+                    _mainPS.println("          RTEMS_DEFAULT_ATTR"
+                            + "IBUTES,");
+                    _mainPS.println("          &queue_id[" + j + "]);");
+                    _mainPS.println("  if (status != RTEMS_SUCCESSFUL) "
+                            + "{");
+                    _mainPS.println("    printf(\"[init    ] "
+                            + "Could not create queue[" + j
+                            + "] (status %d).\\n\", status);");
+                    _mainPS.println("      rtems_shutdown_executive(0);");
+                    _mainPS.println("    }");
+                    _mainPS.println();
+                    j++;
+                }
+
+                //connect ports to channels
+                HashMap<Channel, Integer> channel_map =
+                    new HashMap<Channel, Integer>();
+                j = 0;
+                for (Channel c : x.getChannelList()) {
+                    channel_map.put(c, j++);
+                }
+
+                for (Process process : x.getProcessList()) {
+                    String processName = process.getName();
+                    int i = 0;
+                    for (Port port : process.getPortList()) {
+                        Channel c = (Channel)(port.getPeerResource());
+
+                        _mainPS.println("  " + processName + "_port_id["
+                                + i + "] = "
+                                + _portMap.get(port) + ";");
+                        _mainPS.println("  " + processName
+                                + "_port_queue_id[" + i + "] = queue_id["
+                                + channel_map.get(c) + "];");
+                        i++;
+                    }
+                    _mainPS.println("  " + processName
+                            + "_wrapper->port_id = " + processName
+                            + "_port_id;");
+                    _mainPS.println("  " + processName
+                            + "_wrapper->port_queue_id = "
+                            + processName
+                            + "_port_queue_id;");
+                    _mainPS.println("  " + processName
+                            + "_wrapper->number_of_ports = "
+                            + i + ";");
+                    _mainPS.println("  " + processName
+                            + "_wrapper->is_detached = 0;");
+                    _mainPS.println("  " + processName
+                            + "_wrapper->name = malloc(("
+                            + processName.length()
+                            + " + 1) * sizeof(char));");
+                    _mainPS.println("  strcpy(" + processName
+                            + "_wrapper->name, " + "\""
+                            + processName + "\");");
+                    _mainPS.println();
+                }
+
+                //start cleanup task
+                _mainPS.println("  printf(\"[init    ] "
+                        + "Start cleanup.\\n\");");
+                _mainPS.println("  status = rtems_task_start(task_id[0], "
+                        + "CleanupTask, 0);");
+                _mainPS.println("  if (status != RTEMS_SUCCESSFUL) {");
+                _mainPS.println("    printf(\"[init    ] Could not start "
+                        + "cleanup (status %d).\\n\", status);");
+                _mainPS.println("    rtems_shutdown_executive(0);");
+                _mainPS.println("  }");
+                _mainPS.println();
+
+                //start processes
+                j = 1;
+                for (Process process : x.getProcessList()) {
+                    _mainPS.println("  printf(\"[init    ] Start "
+                            + process.getName() + ".\\n\");");
+                    _mainPS.println("  status = rtems_task_start(task_id["
+                            + j + "], " + process.getBasename()
+                            + "_task, "
+                            + "(rtems_task_argument)"
+                            + process.getName()
+                            + "_wrapper);");
+                    _mainPS.println("  if (status != RTEMS_SUCCESSFUL) "
+                            + "{");
+                    _mainPS.println("    printf(\"[init    ] "
+                            + "Could not start " + process.getName()
+                            + " (status %d).\\n\", status);");
+                    _mainPS.println("    rtems_shutdown_executive(0);");
+                    _mainPS.println("  }");
+                    _mainPS.println();
+                    j++;
+                }
+
+                _mainPS.println("  printf(\"[init    ] Done.\\n\");");
+                _mainPS.println("  rtems_task_delete(RTEMS_SELF);");
+                _mainPS.println("}");
+                _mainPS.println();
+
+                _mainPS.println("rtems_task CleanupTask(rtems_task_argument "
+                        + "argument) {");
+                _mainPS.println("  printf(\"[cleanup ] Started.\\n\");");
+                _mainPS.println("  do {");
+                _mainPS.println("    rtems_task_wake_after(0);");
+                _mainPS.println("  } while (");
+                j = 0;
+                for (Process process : x.getProcessList()) {
+                    _mainPS.print("           !("
+                                  + process.getName()
+                                  + "_wrapper->is_detached)");
+                    j++;
+                    if (j < x.getProcessList().size()) {
+                        _mainPS.println(" || ");
+                    } else {
+                        _mainPS.println(");");
+                    }
+                }
+                _mainPS.println();
+                _mainPS.println("  printf(\"[cleanup ] Shutdown.\\n\");");
+                _mainPS.println("  rtems_shutdown_executive(0);");
+                _mainPS.println("}");
+                _mainPS.println();
+            }
+        }
+        catch (Exception e) {
+            System.out.println("RtemsModuleVisitor: exception occured: "
+                               + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param x process that needs to be processed
+     */
+    public void visitComponent(Process x) {
+    }
+
+    /**
+     *
+     * @param x channel that needs to be processed
+     */
+    public void visitComponent(Channel x) {
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+    protected HashMap<Port, Integer> _portMap;
+}
diff --git a/dol/src/dol/visitor/rtems/RtemsProcessVisitor.java b/dol/src/dol/visitor/rtems/RtemsProcessVisitor.java
new file mode 100644 (file)
index 0000000..27b02a1
--- /dev/null
@@ -0,0 +1,168 @@
+/* $Id: RtemsProcessVisitor.java 213 2010-10-20 09:40:59Z khuang $ */
+package dol.visitor.rtems;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Configuration;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.Copier;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a wrapper class for a process.
+ */
+public class RtemsProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public RtemsProcessVisitor(String dir,
+                               HashMap<Port, Integer> portMap,
+                               HashMap<Process, Integer> sinkMap) {
+        _dir = dir;
+        _portMap = portMap;
+        _sinkMap = sinkMap;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be processed
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> pList = new Vector<String>();
+
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    p.accept(this);
+                }
+            }
+        }
+        catch (Exception e) {
+            System.out.println("RtemsProcessVisitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Visit process.
+     *
+     * @param p process that needs to be processed
+     */
+    public void visitComponent(Process p) {
+        try {
+            String filename = _dir + _delimiter + p.getBasename()
+                    + "_wrapper.c";
+            File process_file = new File(filename);
+            File pattern_file = new File(_dir + _delimiter
+                    + "process_wrapper_template.c");
+            new Copier().copyFile(pattern_file, process_file);
+
+            String includes = "";
+            for (SourceCode code : p.getSrcList()) {
+                includes += "#include \"" + code.getLocality() + "\""
+                        + System.getProperty("line.separator");
+            }
+
+            Sed sed = new Sed();
+            sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
+            sed.sed(filename, "@PROCESSNAME@", p.getBasename());
+            sed.sed(filename, "@Processname@",
+                    p.getBasename().substring(0, 1).toUpperCase() +
+                    p.getBasename().substring(1));
+
+            String triggerPeriod = null;
+            String burstSize = null;
+            String burstPosition = null;
+            for (Configuration c : p.getCfgList()) {
+                if (c.getName().equals("triggerPeriod")) {
+                    triggerPeriod = c.getValue();
+                } else if (c.getName().equals("burstSize")) {
+                    burstSize = c.getValue();
+                } else if (c.getName().equals("burstPosition")) {
+                    burstPosition = c.getValue();
+                }
+            }
+            if (triggerPeriod != null) {
+                if (burstSize == null) {
+                    burstSize = "0";
+                }
+                if (burstPosition == null) {
+                    burstPosition = "0";
+                }
+
+                String periodicTrigger =
+                        "//limits the number of process activations\n"
+                        + "        while ((((int)get_cycle() - "
+                        + "1511576) / " + triggerPeriod + ") "
+                        + "< number_of_activations - (((int)get_cycle()"
+                    //  + " - 1511576) > " + burstPosition + " ? "
+                        + " ) > " + burstPosition + " ? "
+                        + burstSize + " : 0)) {\n"
+                        + "            rtems_task_set_priority("
+                        + "RTEMS_SELF, 127, &old_priority);\n"
+                        + "            rtems_task_wake_after("
+                        + "RTEMS_YIELD_PROCESSOR);\n"
+                        + "        }\n"
+                        + "        rtems_task_set_priority(RTEMS_SELF, "
+                        + "wrapper->priority, &old_priority);\n";
+
+                sed.sed(filename,
+                        "//placeholder for periodic trigger",
+                        periodicTrigger);
+            }
+
+            if (!p.hasOutPorts()) {
+                sed.sed(filename, "@ENDING_SHAPER@",
+                        "ss_sem_signal(get_sem_terminate("
+                        + _sinkMap.get(p) + "));");
+            } else {
+                sed.sed(filename, "@ENDING_SHAPER@", "");
+            }
+
+            for(SourceCode sourceCode : p.getSrcList()) {
+                filename = _dir + _delimiter
+                        + sourceCode.getLocality().replaceAll(
+                        "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+                sed.sed(filename, "<dol.h>", "\"dol.h\"");
+
+                for (Port port : p.getPortList()) {
+                    Integer portId = _portMap.get(port);
+                    if (!port.getBasename().equals(port.getName())) {
+                        for (Port port2 : p.getPortList()) {
+                            if (port2.getBasename().equals(port.getBasename())) {
+                                if (_portMap.get(port2) < _portMap.get(port)) {
+                                    portId = _portMap.get(port2);
+                                }
+                            }
+                        }
+                    }
+                    sed.sed(filename, "(#define[ ]+PORT_\\w*[ ]+)\"?"
+                            + port.getBasename() + "\"?",
+                            "$1 " + portId);
+                }
+            }
+        }
+        catch (Exception e) {
+            System.out.println("RtemsProcessVisitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected HashMap<Port, Integer> _portMap;
+    protected HashMap<Process, Integer> _sinkMap;
+}
diff --git a/dol/src/dol/visitor/rtems/RtemsPropertiesVisitor.java b/dol/src/dol/visitor/rtems/RtemsPropertiesVisitor.java
new file mode 100644 (file)
index 0000000..71d9afd
--- /dev/null
@@ -0,0 +1,93 @@
+/* $Id: RtemsPropertiesVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.rtems;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import dol.datamodel.architecture.Architecture;
+import dol.datamodel.architecture.Processor;
+import dol.datamodel.mapping.Mapping;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.parser.xml.archischema.ArchiXmlParser;
+import dol.parser.xml.mapschema.MapXmlParser;
+import dol.visitor.PNVisitor;
+
+public class RtemsPropertiesVisitor extends PNVisitor {
+
+    protected String _dir = null;
+
+    public RtemsPropertiesVisitor(String dir) {
+        _dir = dir;
+    }
+
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "properties";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println(getProperties(x));
+        } catch (Exception e) {
+            System.out.println("RtemsPropertiesVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    public String getProperties(ProcessNetwork x) {
+        String file = "";
+        String newline = System.getProperty("line.separator");
+        file += "<!-- Properties for ANT script for "
+                + "Multi-Processor System Testbed -->" + newline;
+
+        int maxProcessorIndex;
+        String processorList = null;
+        String processList = null;
+
+        if (_ui.getMappingFileName() == null) {
+            maxProcessorIndex = x.getProcessList().size() - 1;
+        } else {
+            ArchiXmlParser architectureParser =
+                new ArchiXmlParser();
+            Architecture architecture = architectureParser.doParse(
+                _ui.getPlatformFileName());
+
+            MapXmlParser mappingParser =
+                new MapXmlParser(x, architecture);
+            Mapping mapping = mappingParser.doParse(
+                _ui.getMappingFileName());
+
+            maxProcessorIndex = 0;
+            for (Processor p : mapping.getProcessorList()) {
+                if (p.getProcessList().size() > 0) {
+                    maxProcessorIndex =
+                            Math.max(p.getIteratorIndices().elementAt(0),
+                                     maxProcessorIndex);
+                }
+            }
+            //maxProcessorIndex = mapping.getProcessorList().size() - 1;
+        }
+
+        processorList = "1";
+        for (int i = 1; i <= maxProcessorIndex; i++) {
+            processorList += "," + (i + 1);
+        }
+
+        for (Process p : x.getProcessList()) {
+            if (processList == null) {
+                processList = p.getName();
+            } else {
+                processList += "," + p.getName();
+            }
+        }
+
+
+        file += "processors=" + (maxProcessorIndex + 1) + newline;
+        file += "processorList=" + processorList + newline;
+        file += "processList=" + processList + newline;
+
+        return file;
+    }
+}
diff --git a/dol/src/dol/visitor/rtems/RtemsShaperVisitor.java b/dol/src/dol/visitor/rtems/RtemsShaperVisitor.java
new file mode 100644 (file)
index 0000000..cd50166
--- /dev/null
@@ -0,0 +1,50 @@
+/* $Id: RtemsShaperVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.rtems;
+
+import java.util.HashMap;
+
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a wrapper class for the traffic shaper.
+ */
+public class RtemsShaperVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public RtemsShaperVisitor(String dir, HashMap<Process, Integer> sinkMap) {
+        _dir = dir;
+        _sinkMap = sinkMap;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be processed
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "traffic_shaping.h";
+
+            Sed sed = new Sed();
+            String tmp = "NUMBER_OF_QUEUES " + x.getChannelList().size();
+            sed.sed(filename, "@NUMBER_OF_QUEUES@", tmp);
+            tmp = "NUMBER_OF_SINKS " + _sinkMap.size();
+            sed.sed(filename, "@NUMBER_OF_SINKS@", tmp);
+        }
+        catch (Exception e) {
+            System.out.println("RtemsProcessVisitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected HashMap<Process, Integer> _sinkMap;
+}
diff --git a/dol/src/dol/visitor/rtems/RtemsVisitor.java b/dol/src/dol/visitor/rtems/RtemsVisitor.java
new file mode 100644 (file)
index 0000000..82b20ef
--- /dev/null
@@ -0,0 +1,179 @@
+/* $Id: RtemsVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.rtems;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a RTEMS package.
+ */
+public class RtemsVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param packageName name of the Rtems directory
+     */
+    public RtemsVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     * Visit process network.
+     *
+     * @param pn process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            File dir = new File(_packageName);
+            dir.mkdirs();
+
+            //copy library files
+            File source = new File(_ui.getMySystemCLib().
+                    replaceAll("systemC", "rtems"));
+            new Copier().copy(source, dir);
+
+            //copy process source code
+            source = new File(_srcDirName);
+            new Copier().copy(source, dir);
+
+            createPortMap(pn);
+            createSinkMap(pn);
+            pn.accept(new RtemsMakefileVisitor(_packageName));
+            pn.accept(new RtemsProcessVisitor(_packageName,_portMap,_sinkMap));
+            pn.accept(new RtemsModuleVisitor(_packageName, _portMap));
+            pn.accept(new RtemsShaperVisitor(_packageName, _sinkMap));
+            pn.accept(new RtemsPropertiesVisitor(_packageName));
+        }
+        catch (Exception e) {
+            System.out.println("RtemsVisitor: exception occured: "
+                    + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create a hashmap which maps each port of the given process network
+     * to an integer. For each process, ports are numbered with integers
+     * starting from 0.
+     *
+     * @param pn process network for which the map should be generated
+     */
+    protected void createPortMap(ProcessNetwork pn) {
+        _portMap = new HashMap<Port, Integer>();
+
+        for (Process process : pn.getProcessList()) {
+            int portCount = 0;
+            Vector<Port> portList = process.getPortList();
+            Vector<String> portNameList = new Vector<String>();
+            portNameList.clear();
+            HashMap<String, Integer> portMap =
+                new HashMap<String, Integer>();
+            portMap.clear();
+
+            for (int i = 0; i < portList.size(); i++) {
+                //treat single ports differently than iterated ports
+                String portName = portList.elementAt(i).getName();
+                String baseName = portList.elementAt(i).getBasename();
+
+                if (portName.equals(baseName)) {
+                    portNameList.add(portName);
+                    portMap.put(portName, portCount++);
+                } else {
+                    String range_indices = portList.elementAt(i).getRange();
+                    Vector<Integer> range_indices_values = getIndex(range_indices, ";");
+
+                    String port_indices = portName;
+                    port_indices.replaceAll(baseName, "");
+                    Vector<Integer> port_indices_values = getIndex(port_indices, "_");
+
+                    if (!portNameList.contains(baseName)) {
+                        portNameList.add(baseName);
+                        portMap.put(baseName, portCount);
+
+                        int size = 1;
+                        for (int j = 0; j < range_indices_values.size(); j++) {
+                            size *= range_indices_values.elementAt(j);
+                        }
+                        portCount += size;
+                    }
+
+                    int portId = portMap.get(baseName);
+                    for (int j = 0; j < port_indices_values.size(); j++) {
+                        int weight = 1;
+                        for (int k = j + 1; k < range_indices_values.size(); k++) {
+                            weight *= range_indices_values.elementAt(k);
+                        }
+                        portId += port_indices_values.elementAt(j) * weight;
+                    }
+                    portMap.put(portName, portId);
+                }
+            }
+
+            for (int i = 0; i < portList.size(); i++) {
+                _portMap.put(portList.elementAt(i),
+                        portMap.get(portList.elementAt(i).getName()));
+            }
+        }
+    }
+
+
+    /**
+     * Create a hashmap which maps each sink of the given process network
+     * to an integer. For each process, sinks are numbered with integers
+     * starting from 1.
+     *
+     * @param pn process network for which the map should be generated
+     */
+    protected void createSinkMap(ProcessNetwork pn) {
+        _sinkMap = new HashMap<Process, Integer>();
+        int i = 1;
+
+        for (Process process : pn.getProcessList()) {
+            if (!process.hasOutPorts()) {
+                _sinkMap.put(process, i);
+                i++;
+            }
+        }
+    }
+
+    /**
+     * Gets vector of indices of a string, where the index must be
+     * separated by the specified separator.
+     * examples:
+     * getIndex("name_1_2", "_", 0) will return 1.
+     * getIndex("name_1_2", "_", 1) will return 2.
+     *
+     * @param range string to parse
+     * @param separator delimiter of indices
+     * @return vector of indices
+     */
+    protected Vector<Integer> getIndex(String range, String separator) {
+        Vector<Integer> indices = new Vector<Integer>();
+        String[] subranges = range.split(separator);
+        for (int i = 0; i < subranges.length; i++) {
+            try {
+                int value = Integer.valueOf(subranges[i]);
+                indices.add(value);
+            } catch (Exception e) {
+                continue;
+            }
+        }
+        return indices;
+    }
+
+    protected HashMap<Port, Integer> _portMap;
+    protected HashMap<Process, Integer> _sinkMap;
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+}
diff --git a/dol/src/dol/visitor/rtems/lib/README b/dol/src/dol/visitor/rtems/lib/README
new file mode 100644 (file)
index 0000000..e5d0dc0
--- /dev/null
@@ -0,0 +1,80 @@
+How-to for running code in MPARM environment:
+
+One-to-one mapping:
+- Generate the code: ant -f runexample -Dnumber=? mparm
+- Copy the generated dir 'systemc' to <MPARM>/MPARM/apps
+- Copy the library 'queue_lib' into dir 'systemc'
+- Compile the code: make
+- Link the binary: ln -sf o-optimize/app.exe TargetMem_<?>.mem
+    ? depends on how many processors
+- Run: $SWARMDIR/bin/mpsim.x -c <?> --intc=i  -C -S -D
+    ? is number of processors
+
+
+Multi-to-one mapping:
+- Modify main.c
+    - number_of_processes: each field is number of processes per processor
+    - xxx_PROCESSOR: set to a same number if mapping to common processor
+    - processor_init(): leave  one for each processor (not necessary)
+- system.c
+    - macro CONFIGURE_MAXIMUM_TASKS should be two times larger than the 
+      maximum number of processes mapped to one processor.
+- MAXQUEUE
+    - where should we put this macro ?
+- If using the dol mapping specification, the processor 1 should be reserved
+  in the case of enabling macro QUEUE_BUFF_SHAPER !
+
+MPARM queue_lib spec:
+- Always use interrupt
+- Always use memcpy
+- DMA always enables, the switch is in the Makefile
+- Token size is always 32 bits
+- Default Queue size is 4, can be redefined
+
+
+Segment wide Calibration:
+- Modify Makefile:
+    - enable macro PERFORMANCE_EXTRACT (default disable)
+    - uncomment line: 
+      CXXSRCS += lib/xmlParser.cpp lib/Performance_Extraction.cpp
+- main.c: Map all processes into one processor
+- Run: $SWARMDIR/bin/mpsim.x -c 1 --intc=i  -C -S -D  
+
+
+Communication exploration:
+- Modify Makefile:
+  - enable one of below macro exclusively:
+    - QUEUE_BUFF_IN_PRODUCER (default)
+    - QUEUE_BUFF_IN_PRODUCER_DMA
+    - QUEUE_BUFF_IN_CONSUMER
+    - QUEUE_BUFF_IN_CONSUMER_DMA
+    - QUEUE_BUFF_SHAPER
+
+Running mpeg2 decoder on MPARM:
+- copy dol.h from other case studies
+- add macro _DOL_ETHZ_GEN_ to Makefile
+- change queue size to 4096 in system.h
+- call mpsim.x with option --s-size=19 (scratchpad size=1Mbyts)
+
+Running mjpeg-2000 decoder on MPARM:
+- jpeg.h
+    - disable macro VIEWER
+    - disable macros VERBOSE and INFO
+- scratch_queue.h
+    - macro MAXQUEUE > 24, if mapping all to one processor
+- system.h
+    - macro CONFIGURE_MAXIMUM_TASKS > 9
+
+
+Tricks:
+- CONFIGURE_MAXIMUM_TASKS in system.h
+- MAXQUEUE in scratch_queue.h 
+- Token size should be multiple of 4 bytes
+- W/R operations should be the same size, otherwise token size should be
+  gcd(Write_token, Read_token).
+
+BUGS & TODO:
+- free() in wrapper not correct
+- Iterated port not tested yet
+- Shaper not finished!
+- Timeslice works?  (Yes)
diff --git a/dol/src/dol/visitor/rtems/lib/appsupport.c b/dol/src/dol/visitor/rtems/lib/appsupport.c
new file mode 100644 (file)
index 0000000..7ced4a5
--- /dev/null
@@ -0,0 +1,136 @@
+///////////////////////////////////////////////////////////////////////////////\r
+// Copyright 2003 DEIS - Universita' di Bologna\r
+//\r
+// name         appsupport.c\r
+// author       DEIS - Universita' di Bologna\r
+//              Davide Bertozzi - dbertozzi@deis.unibo.it\r
+//              Mirko Loghi - mloghi@deis.unibo.it\r
+//              Federico Angiolini - fangiolini@deis.unibo.it\r
+//              Francesco Poletti - fpoletti@deis.unibo.it\r
+// portions by  Massimo Scardamaglia - mascard@vizzavi.it\r
+// info         Provides support for testbench compilation\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+#include <bsp.h>\r
+\r
+#include "appsupport.h"\r
+\r
+volatile char *time_low_ptr   = (char *)(SIMSUPPORT_BASE + GET_TIME_ADDRESS_LO);\r
+volatile char *time_high_ptr  = (char *)(SIMSUPPORT_BASE + GET_TIME_ADDRESS_HI);\r
+volatile char *time_stop_ptr  = (char *)(SIMSUPPORT_BASE + STOP_TIME_ADDRESS);\r
+volatile char *time_rel_ptr   = (char *)(SIMSUPPORT_BASE + RELEASE_TIME_ADDRESS);\r
+\r
+volatile char *cycle_low_ptr  = (char *)(SIMSUPPORT_BASE + GET_CYCLE_ADDRESS_LO);\r
+volatile char *cycle_high_ptr = (char *)(SIMSUPPORT_BASE + GET_CYCLE_ADDRESS_HI);\r
+volatile char *cycle_stop_ptr = (char *)(SIMSUPPORT_BASE + STOP_CYCLE_ADDRESS);\r
+volatile char *cycle_rel_ptr  = (char *)(SIMSUPPORT_BASE + RELEASE_CYCLE_ADDRESS);\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// pr - Allows printing debug info even without support from an OS. See\r
+//      user_swi.cpp for printable messages, or to create your own\r
+\r
+void pr(int proc, int msg_num, int num_arg)\r
+{\r
+#ifndef __OPTIMIZE__\r
+    __asm ("ldr r1, %0" : : "g" (proc) : "r1" );\r
+    __asm ("ldr r2, %0" : : "g" (msg_num) : "r2" );\r
+    __asm ("ldr r3, %0" : : "g" (num_arg) : "r3" );\r
+    __asm ("swi " SWI_PRINTstr);\r
+#else\r
+    __asm ("mov r1, %0" : : "g" (proc) : "r1" );\r
+    __asm ("mov r2, %0" : : "g" (msg_num) : "r2" );\r
+    __asm ("mov r3, %0" : : "g" (num_arg) : "r3" );\r
+    __asm ("swi " SWI_PRINTstr);\r
+#endif\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// get_proc_id - Allows getting the processor's ID (from 1 onwards)\r
+unsigned int get_proc_id()\r
+{\r
+  char *ptr = (char *)(SIMSUPPORT_BASE + GET_CPU_ID_ADDRESS);\r
+  return (*(unsigned long int *)ptr);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// get_proc_num - Allows getting the number of processors in the platform\r
+unsigned int get_proc_num()\r
+{\r
+  char *ptr = (char *)(SIMSUPPORT_BASE + GET_CPU_CNT_ADDRESS);\r
+  return (*(unsigned long int *)ptr);\r
+}\r
+\r
+// ---------------------------\r
+// Frequency scaling functions\r
+// ---------------------------\r
+volatile unsigned int *freqdevice      = (unsigned int *)FREQ_BASE;\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// scale_this_core_frequency - Scales the frequency of the core on which\r
+//                             the application is running\r
+void scale_this_core_frequency(unsigned short int divider)\r
+{\r
+  freqdevice[get_proc_id() - 1] = divider;\r
+}\r
+///////////////////////////////////////////////////////////////////////////////\r
+// scale_device_frequency - Scales the frequency of any device in the system\r
+void scale_device_frequency(unsigned short int divider, int ID)\r
+{\r
+  freqdevice[ID] = divider;\r
+}\r
+///////////////////////////////////////////////////////////////////////////////\r
+// get_this_core_frequency - Gets the frequency divider of the core on which\r
+//                           the application is running\r
+unsigned short int get_this_core_frequency()\r
+{\r
+  return (freqdevice[get_proc_id() - 1]);\r
+}\r
+///////////////////////////////////////////////////////////////////////////////\r
+// get_device_frequency - Gets the frequency divider of any device in the system\r
+unsigned short int get_device_frequency(int ID)\r
+{\r
+  return (freqdevice[ID]);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// get_time - Allows getting the current simulation time\r
+unsigned long long int get_time()\r
+{\r
+  unsigned long long int time;\r
+  \r
+  *time_stop_ptr = 1;\r
+  time = (((unsigned long long int)(*(unsigned long int *)time_high_ptr)) << 32) + *(unsigned long int *)time_low_ptr;\r
+  *time_rel_ptr = 1;\r
+  \r
+  return (time);\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+// get_cycle - Allows getting the current simulation cycle\r
+unsigned long long int get_cycle1()\r
+{\r
+  unsigned long long int cycle;\r
+  \r
+  *cycle_stop_ptr = 1;\r
+  cycle = (((unsigned long long int)(*(unsigned long int *)cycle_high_ptr)) << 32) + *(unsigned long int *)cycle_low_ptr;\r
+  *cycle_rel_ptr = 1;\r
+  \r
+  return (cycle);\r
+}\r
+\r
+extern rtems_id timer_sem_id;\r
+unsigned long long int get_cycle()\r
+{\r
+  unsigned long long int cycle;\r
+  rtems_status_code rtems_status;\r
+\r
+  rtems_status = rtems_semaphore_obtain(timer_sem_id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);\r
+  *cycle_stop_ptr = 1;\r
+  cycle = (((unsigned long long int)(*(unsigned long int *)cycle_high_ptr))\r
+           << 32) + *(unsigned long int *)cycle_low_ptr;\r
+  *cycle_rel_ptr = 1;\r
+  rtems_status =  rtems_semaphore_release(timer_sem_id);\r
+\r
+  return (cycle);\r
+}\r
diff --git a/dol/src/dol/visitor/rtems/lib/appsupport.h b/dol/src/dol/visitor/rtems/lib/appsupport.h
new file mode 100644 (file)
index 0000000..6e50558
--- /dev/null
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////////\r
+// Copyright 2003 DEIS - Universita' di Bologna\r
+// \r
+// name         appsupport.h\r
+// author       DEIS - Universita' di Bologna\r
+//              Davide Bertozzi - dbertozzi@deis.unibo.it\r
+//              Mirko Loghi - mloghi@deis.unibo.it\r
+//              Federico Angiolini - fangiolini@deis.unibo.it\r
+//              Francesco Poletti - fpoletti@deis.unibo.it\r
+// portions by  Massimo Scardamaglia - mascard@vizzavi.it\r
+// info         Provides support for testbench compilation\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+#ifndef __APPSUPPORT_H__\r
+#define __APPSUPPORT_H__\r
+\r
+#include "swi_calls.h"\r
+#include "config.h"\r
+#include "sim_support_flags.h"\r
+\r
+#define start_metric()       __asm ("swi " SWI_METRIC_STARTstr)\r
+#define stop_metric()        __asm ("swi " SWI_METRIC_STOPstr)\r
+#define dump_metric()        __asm ("swi " SWI_METRIC_DUMPstr)\r
+#define clear_metric()       __asm ("swi " SWI_METRIC_CLEARstr)\r
+#define stop_simulation()    __asm ("swi " SWI_EXITstr)\r
+void pr(int proc, int msg_num, int num_arg);\r
+unsigned int get_proc_id();\r
+\r
+#undef get_id\r
+#define get_id() get_proc_id()\r
+\r
+unsigned int get_proc_num();\r
+\r
+// ---------------------------\r
+// Frequency scaling functions\r
+// ---------------------------\r
+void scale_this_core_frequency(unsigned short int divider);\r
+void scale_device_frequency(unsigned short int divider, int ID);\r
+unsigned short int get_this_core_frequency();\r
+unsigned short int get_device_frequency(int ID);\r
+\r
+#define RTEMS_TRACE_MAIN_APP\r
+\r
+#ifdef RTEMS_TRACE_MAIN_APP\r
+//It print out the processor id, the parameter "a" and the actual clock cycles\r
+//Eg. Processor 0  -  0x3e740 start_cycle:353089\r
+#define SHOW_TIME_START(a)    pr(0x11111, 0x10020, (int)a)\r
+//Eg. Processor 0  -  0x3e740 stop_cycle:353143\r
+#define SHOW_TIME_STOP(a)     pr(0x11111, 0x10030, (int)a)\r
+//It print out the string a \r
+#define SHOW_DEBUG(a)         pr(0x11111, 0x10000, (int)a)\r
+#define SHOW_DEBUG_NON(a)     pr(0x11111, 0x10001, (int)a)\r
+#define SHOW_DEBUG_NOP(a)     pr(0x11111, 0x10002, (int)a)\r
+#define SHOW_DEBUG_NON_NOP(a) pr(0x11111, 0x10003, (int)a)\r
+//It print out the integer a\r
+#define SHOW_DEBUG_INT(a)         pr(0x11111, 0x10010, (int)a)\r
+#define SHOW_DEBUG_INT_NON(a)     pr(0x11111, 0x10011, (int)a)\r
+#define SHOW_DEBUG_INT_NOP(a)     pr(0x11111, 0x10012, (int)a)\r
+#define SHOW_DEBUG_INT_NON_NOP(a) pr(0x11111, 0x10013, (int)a)\r
+#else\r
+//empty definitions\r
+#define SHOW_TIME_START(a)\r
+#define SHOW_TIME_STOP(a)\r
+#define SHOW_DEBUG(a)\r
+#define SHOW_DEBUG_NON(a)\r
+#define SHOW_DEBUG_INT_NOP(a)\r
+#define SHOW_DEBUG_INT_NON_NOP(a)\r
+#define SHOW_DEBUG_INT(a)\r
+#define SHOW_DEBUG_INT_NON(a)\r
+#define SHOW_DEBUG_INT_NOP(a)\r
+#define SHOW_DEBUG_INT_NON_NOP(a)\r
+#endif\r
+\r
+unsigned long long int get_time();\r
+unsigned long long int get_cycle();\r
+unsigned long long int get_cycle1();\r
+\r
+#endif // __APPSUPPORT_H__\r
diff --git a/dol/src/dol/visitor/rtems/lib/buffer_test_io.h b/dol/src/dol/visitor/rtems/lib/buffer_test_io.h
new file mode 100644 (file)
index 0000000..605a608
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  Support for running the test output through a buffer
+ * 
+ *  buffer_test_io.h,v 1.1 2002/08/02 00:51:52 joel Exp
+ */
+
+#ifndef __BUFFER_TEST_IO_h
+#define __BUFFER_TEST_IO_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+
+/*
+ *  Uncomment this to get buffered test output.  When commented out,
+ *  test output behaves as it always has and is printed ASAP.
+ */
+
+/* #define TESTS_BUFFER_OUTPUT */
+
+#if !defined(TESTS_BUFFER_OUTPUT)
+
+#define rtems_test_exit(_s) \
+  do { \
+    exit(_s); \
+  } while (0)
+
+#define FLUSH_OUTPUT() \
+  do { \
+    fflush(stdout); \
+  } while (0)
+
+#else  /* buffer test output */
+
+#define _TEST_OUTPUT_BUFFER_SIZE 2048
+extern char _test_output_buffer[_TEST_OUTPUT_BUFFER_SIZE];
+void _test_output_append(char *);
+void _test_output_flush(void);
+
+#define rtems_test_exit(_s) \
+  do { \
+    _test_output_flush(); \
+    exit(_s); \
+  } while (0)
+
+#undef printf
+#define printf(...) \
+  do { \
+     char _buffer[128]; \
+     sprintf( _buffer, __VA_ARGS__); \
+     _test_output_append( _buffer ); \
+  } while (0)
+
+#undef puts
+#define puts(_string) \
+  do { \
+     char _buffer[128]; \
+     sprintf( _buffer, "%s\n", _string ); \
+     _test_output_append( _buffer ); \
+  } while (0)
+
+#undef putchar
+#define putchar(_c) \
+  do { \
+     char _buffer[2]; \
+     _buffer[0] = _c; \
+     _buffer[1] = '\0'; \
+     _test_output_append( _buffer ); \
+  } while (0)
+
+/* we write to stderr when there is a pause() */
+#define FLUSH_OUTPUT() _test_output_flush()
+
+#if defined(TEST_INIT) || defined(CONFIGURE_INIT)
+
+char _test_output_buffer[_TEST_OUTPUT_BUFFER_SIZE];
+int _test_output_buffer_index = 0;
+
+void _test_output_append(char *_buffer)
+{
+  char *p;
+  
+  for ( p=_buffer ; *p ; p++ ) {
+    _test_output_buffer[_test_output_buffer_index++] = *p;
+    _test_output_buffer[_test_output_buffer_index]   = '\0';
+#if 0
+    if ( *p == '\n' ) {
+      fprintf( stderr, "BUFFER -- %s", _test_output_buffer );
+      _test_output_buffer_index = 0;
+     _test_output_buffer[0]   = '\0';
+    }
+#endif
+    if ( _test_output_buffer_index >= (_TEST_OUTPUT_BUFFER_SIZE - 80) ) 
+      _test_output_flush();
+  }
+}
+
+#include <termios.h>
+#include <unistd.h>
+
+void _test_output_flush(void)
+{
+  fprintf( stderr, "%s", _test_output_buffer );
+  _test_output_buffer_index = 0;
+  tcdrain( 2 );
+}
+
+#endif  /* TEST_INIT */
+#endif /* TESTS_BUFFER_OUTPUT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/dol/src/dol/visitor/rtems/lib/dol.h b/dol/src/dol/visitor/rtems/lib/dol.h
new file mode 100644 (file)
index 0000000..f07b246
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __DOL_H__
+#define __DOL_H__
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//structure for process
+struct _process;
+
+//
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr;
+} DOLProcess;
+
+void DOL_read(void *port, void *buf, int len, DOLProcess *process);
+void DOL_write(void *port, void *buf, int len, DOLProcess *process);
+void DOL_detach(DOLProcess *process);
+
+#endif
diff --git a/dol/src/dol/visitor/rtems/lib/process_wrapper_template.c b/dol/src/dol/visitor/rtems/lib/process_wrapper_template.c
new file mode 100644 (file)
index 0000000..15c262b
--- /dev/null
@@ -0,0 +1,116 @@
+#include <bsp.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "rtems_process_wrapper.h"
+
+#ifdef WORKLOAD_EXTRACT
+#define DOL_read(port, buf, len, process) \
+{ ((RtemsProcessWrapper*)process->wptr)->end_line = __LINE__; \
+  DOL_read(port, buf, len, process); \
+  ((RtemsProcessWrapper*)process->wptr)->start_line = __LINE__; }
+
+#define DOL_write(port, buf, len, process) \
+{ ((RtemsProcessWrapper*)process->wptr)->end_line = __LINE__; \
+  DOL_write(port, buf, len, process); \
+  ((RtemsProcessWrapper*)process->wptr)->start_line = __LINE__; }
+#endif
+
+#ifdef PRINTF_TO_DEBUG
+#undef printf
+#define printf(...) \
+    do {            \
+        char _buffer[128];                     \
+        sprintf(_buffer, __VA_ARGS__);         \
+        SHOW_DEBUG((int)_buffer);              \
+    } while (0)
+#endif
+
+//#include "@PROCESSNAME@.c"
+
+//DOL-specific implementation
+rtems_task @PROCESSNAME@_task(rtems_task_argument argument) {
+    RtemsProcessWrapper* wrapper = (RtemsProcessWrapper*)argument;
+    DOLProcess* process;
+    LocalState state;
+    int number_of_activations = 0;
+    int i;
+    rtems_task_priority old_priority;
+
+    process = (DOLProcess *)malloc(sizeof(DOLProcess));
+    state = (LocalState)malloc(sizeof(@Processname@_State));
+    process->init = @PROCESSNAME@_init;
+    process->fire = @PROCESSNAME@_fire;
+    process->local = state;
+    process->wptr = wrapper;
+
+    //initialize the index array
+    wrapper->index = (int *)malloc(4 * sizeof(int));
+    for (i = 0; i < 4; i++) {
+        wrapper->index[i] = getIndex(wrapper->name, "_", i);
+    }
+
+    printf("Start process %s.\n", wrapper->name);
+    process->init(process);
+
+    //yield process such that other processes can be initialized
+#ifdef MPARM
+    do {
+        rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
+    } while((int)get_cycle() < 1511576);
+#endif
+    rtems_task_set_priority(RTEMS_SELF, wrapper->priority, &old_priority);
+
+    while (!wrapper->is_detached) {
+
+        //placeholder for periodic trigger
+
+#ifdef WORKLOAD_EXTRACT
+        wrapper->start_line = 0;
+        SHOW_DEBUG("log start_fire");
+        SHOW_DEBUG_INT((int)get_cycle());
+#endif
+
+        process->fire(process);
+
+#ifdef WORKLOAD_EXTRACT
+        SHOW_DEBUG("log end_fire");
+        SHOW_DEBUG_INT((int)get_cycle());
+        wrapper->end_line = 0;
+#endif
+        number_of_activations++;
+    }
+
+#ifdef MPARM_SCRATCHPAD_QUEUE
+    #ifdef QUEUE_BUFF_SHAPER
+    @ENDING_SHAPER@
+    #endif
+#else // pc386
+    //below is not necessary if no dynamic switching
+    //printf("Detached @PROCESSNAME@. Cleanup... ");
+    if (wrapper->index) {
+        free(wrapper->index);
+    } else {
+        printf("Could not free memory for index of @PROCESSNAME@.\n");
+    }
+
+    if (wrapper->port_id) {
+        free(wrapper->port_id);
+    } else {
+        printf("Could not free memory for port_id of @PROCESSNAME@.\n");
+    }
+
+    if (wrapper->port_queue_id) {
+    } else {
+        printf("Could not free memory for port_queue_id of @PROCESSNAME@.\n");
+    }
+#endif // MPARM_SCRATCHPAD_QUEUE
+    //printf("Done.\n");
+
+    printf("Detach process %s.\n", wrapper->name);
+#ifdef MPARM
+    Cleanup();
+#endif
+
+    rtems_task_delete(RTEMS_SELF);
+}
diff --git a/dol/src/dol/visitor/rtems/lib/rtems_process_wrapper.c b/dol/src/dol/visitor/rtems/lib/rtems_process_wrapper.c
new file mode 100644 (file)
index 0000000..387818e
--- /dev/null
@@ -0,0 +1,253 @@
+#include <string.h>
+#include "rtems_process_wrapper.h"
+
+/**
+ *
+ */
+void DOL_read(void *port, void *buf, int len, DOLProcess *process) {
+    RtemsProcessWrapper* process_wrapper = (RtemsProcessWrapper*)process->wptr;
+    int i;
+
+#ifdef WORKLOAD_EXTRACT
+    SHOW_DEBUG("log start_read");
+    SHOW_DEBUG_INT((int)get_cycle());
+    SHOW_DEBUG_INT((int)port);
+    SHOW_DEBUG_INT((int)(process_wrapper->start_line));
+    SHOW_DEBUG_INT((int)(process_wrapper->end_line));
+    SHOW_DEBUG_INT((int)len);
+#endif
+
+#ifdef MPARM_SCRATCHPAD_QUEUE
+    for (i = 0; i < process_wrapper->number_of_in_ports; i++) {
+        // len not taken into account yet !!!!!!!
+        if (process_wrapper->in_port_id[i] == (int)port) {
+            SCRATCH_QUEUE_CONSUMER* queue_id =
+                (SCRATCH_QUEUE_CONSUMER*)process_wrapper->in_queue_id[i];
+
+#if defined (QUEUE_BUFF_IN_PRODUCER)
+            scratch_queue_read(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_IN_PRODUCER_DMA)
+            scratch_queue_read_dma(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_IN_CONSUMER)
+            scratch_queue_read(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_IN_CONSUMER_DMA)
+            scratch_queue_read(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_IN_SHARDMEM)
+            scratch_queue_read(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_SHAPER)
+            scratch_queue_read_2(queue_id, (char *)buf, len);
+#endif
+            break;
+        }
+    }
+#else // pc386
+    for (i = 0; i < process_wrapper->number_of_ports; i++) {
+        if (process_wrapper->port_id[i] == (int)port) {
+            int queue_id = process_wrapper->port_queue_id[i];
+            int j;
+
+            //receive message byte-per-byte
+            for (j = 0; j < len; j++) {
+                size_t size = 1;
+                rtems_message_queue_receive(
+                    queue_id,
+                    buf + j,
+                    &size,
+                    RTEMS_DEFAULT_ATTRIBUTES,
+                    RTEMS_NO_TIMEOUT);
+            }
+            break;
+        }
+    }
+#endif // end MPARM_SCRATCHPAD_QUEUE
+
+    //SHOW_DEBUG("read from app");
+    //SHOW_DEBUG_INT(*(int *)buf);
+
+#ifdef WORKLOAD_EXTRACT
+    SHOW_DEBUG("log end_read");
+    SHOW_DEBUG_INT((int)get_cycle());
+    SHOW_DEBUG_INT((int)port);
+#endif
+}
+
+/**
+ *
+ */
+void DOL_write(void *port, void *buf, int len, DOLProcess *process) {
+    RtemsProcessWrapper* process_wrapper = (RtemsProcessWrapper*)process->wptr;
+    int i;
+
+#ifdef WORKLOAD_EXTRACT
+    SHOW_DEBUG("log start_write");
+    SHOW_DEBUG_INT((int)get_cycle());
+    SHOW_DEBUG_INT((int)port);
+    SHOW_DEBUG_INT((int)(process_wrapper->start_line));
+    SHOW_DEBUG_INT((int)(process_wrapper->end_line));
+    SHOW_DEBUG_INT((int)len);
+#endif
+
+#if defined MPARM_SCRATCHPAD_QUEUE
+    for (i = 0; i < process_wrapper->number_of_out_ports; i++) {
+        if (process_wrapper->out_port_id[i] == (int)port) {
+            SCRATCH_QUEUE_PRODUCER* queue_id =
+                (SCRATCH_QUEUE_PRODUCER*)process_wrapper->out_queue_id[i];
+
+
+#if defined (QUEUE_BUFF_IN_PRODUCER) || (QUEUE_BUFF_IN_CONSUMER)
+            scratch_queue_write(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_IN_PRODUCER_DMA) || (QUEUE_BUFF_IN_CONSUMER_DMA)
+            scratch_queue_write_dma(queue_id, (char *)buf, len);
+#elif defined (QUEUE_BUFF_IN_SHARDMEM)
+            scratch_queue_write(queue_id, (char *)buf, len);
+#elif defined(QUEUE_BUFF_SHAPER)
+            scratch_queue_write_2(queue_id, (char *)buf, len); // (2) shaper
+#endif
+
+            break;
+        }
+    }
+#else // pc386
+    for (i = 0; i < process_wrapper->number_of_ports; i++) {
+        if (process_wrapper->port_id[i] == (int)port) {
+            int queue_id = process_wrapper->port_queue_id[i];
+            rtems_status_code status;
+            int j;
+
+            //send message byte-per-byte
+            for (j = 0; j < len; j++) {
+                do {
+                    status = rtems_message_queue_send(queue_id, buf + j, 1);
+                    if (status != RTEMS_SUCCESSFUL) {
+                        rtems_task_wake_after(0);
+                    }
+                } while (status != RTEMS_SUCCESSFUL);
+            }
+
+            break;
+        }
+    }
+#endif // end MPARM_SCRATCHPAD_QUEUE
+
+#ifdef WORKLOAD_EXTRACT
+    SHOW_DEBUG("log end_write");
+    SHOW_DEBUG_INT((int)get_cycle());
+    SHOW_DEBUG_INT((int)port);
+#endif
+}
+
+/**
+ *
+ */
+void DOL_detach(DOLProcess *process) {
+    //printf("[%s] DOL_detach.\n", (char*)(process->local));
+    ((RtemsProcessWrapper*)process->wptr)->is_detached = 1;
+}
+
+/**
+ * Gets an index of a string, where the index must be separated by
+ * a character specified in tokens.
+ * Returns -1, when an error occurs.
+ *
+ * Example:
+ * getIndex("name_1_2", "_", 0) will return 1.
+ * getIndex("name_1_2", "_", 1) will return 2.
+ *
+ * @param string string to parse
+ * @param tokens delimiter of indices
+ * @param indexNumber position of index (starting at 0)
+ */
+int getIndex(const char* string, char* tokens, int indexNumber) {
+    char* string_copy;
+    char* token_pointer;
+    int index = 0;
+
+    string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));
+    if (!string_copy) {
+        fprintf(stderr, "getIndex(): could not allocate memory.\n");
+        return -1;
+    }
+
+    strcpy(string_copy, string);
+
+    token_pointer = strtok(string_copy, tokens);
+    do {
+        token_pointer = strtok(NULL, tokens);
+        index++;
+    } while (index <= indexNumber && token_pointer != 0);
+
+    if (token_pointer) {
+        index = atoi(token_pointer);
+        free(string_copy);
+        return index;
+    }
+
+    free(string_copy);
+    return -1;
+}
+
+/**
+ * Create the port name of an iterated port based on its basename and the
+ * given indices.
+ *
+ * @param port buffer where the result is stored (created using
+ *             CREATEPORTVAR)
+ * @param base basename of the port
+ * @param number_of_indices number of dimensions of the port
+ * @param index_range_pairs index and range values for each dimension
+ */
+int *createPort(int *port, int base, int number_of_indices,
+                int index_range_pairs, ...) {
+    int index[4];
+    int range[4];
+    int i;
+    int value;
+
+    va_list marker;
+    va_start(marker, index_range_pairs);
+
+    value = index_range_pairs;
+    for (i = 0; i < number_of_indices; i++) {
+        index[i] = value;
+        value = va_arg(marker, int);
+        range[i] = value;
+        if (i < number_of_indices - 1) {
+            value = va_arg(marker, int);
+        }
+    }
+
+    *port = base;
+    for (i = 0; i < number_of_indices; i++) {
+        int j;
+        int weight = 1;
+        for (j = 1; j < number_of_indices - i; j ++) {
+            weight *= range[j];
+        }
+        *port += index[i] * weight;
+    }
+
+    /*
+    switch (number_of_indices) {
+        case 1:
+            *port = base + index[0];
+            break;
+        case 2:
+            *port = base + index[0] * range[1]
+                         + index[1];
+            break;
+        case 3:
+            *port = base + index[0] * range[1] * range[2]
+                         + index[1] * range[0]
+                         + index[2];
+            break;
+        case 4:
+            *port = base + index[0] * range[1] * range[2] * range[3]
+                         + index[1] * range[2] * range[3]
+                         + index[2] * range[3]
+                         + index[3];
+        break;
+    }
+    */
+
+    return port;
+}
diff --git a/dol/src/dol/visitor/rtems/lib/rtems_process_wrapper.h b/dol/src/dol/visitor/rtems/lib/rtems_process_wrapper.h
new file mode 100644 (file)
index 0000000..c72022b
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef __RTEMS_PROCESS_WRAPPER_H__
+#define __RTEMS_PROCESS_WRAPPER_H__
+
+#include <bsp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include "dol.h"
+
+#ifdef MPARM_SCRATCHPAD_QUEUE
+#include "scratch_queue.h"
+#endif
+
+#ifdef MPARM
+#define printf(format ...) { char stringBuffer[80]; sprintf(stringBuffer, format); SHOW_DEBUG(stringBuffer); }
+#endif
+
+typedef struct _process_wrapper {
+    DOLProcess               *dol_process;
+    char*                    name;
+    int*                     index;
+    int                      is_detached;
+    int                      priority;
+#ifdef WORKLOAD_EXTRACT
+    int                      start_line;
+    int                      end_line;
+#endif
+#ifdef MPARM_SCRATCHPAD_QUEUE
+    int*                     in_port_id;
+    int*                     out_port_id;
+    SCRATCH_QUEUE_PRODUCER** out_queue_id;
+    SCRATCH_QUEUE_CONSUMER** in_queue_id;
+    int                      number_of_in_ports;
+    int                      number_of_out_ports;
+#else  // for pc396
+    int*                     port_id;
+    int*                     port_queue_id;
+    int                      number_of_ports;
+#endif
+} RtemsProcessWrapper;
+
+// define queue memory in consumer scratchpad
+//#define QUEUE_IN_CONSUMER
+
+/**
+ * Gets an index of a string, where the index must be separated by
+ * a character specified in tokens.
+ * Returns -1, when an error occurs.
+ *
+ * Example:
+ * getIndex("name_1_2", "_", 0) will return 1.
+ * getIndex("name_1_2", "_", 1) will return 2.
+ *
+ * @param string string to parse
+ * @param tokens delimiter of indices
+ * @param indexNumber position of index (starting at 0)
+ */
+int getIndex(const char* string, char* tokens, int indexNumber);
+
+/**
+ * Create the port name of an iterated port based on its basename and the
+ * given indices.
+ *
+ * @param port buffer where the result is stored (created using
+ *             CREATEPORTVAR)
+ * @param base basename of the port
+ * @param number_of_indices number of dimensions of the port
+ * @param index_range_pairs index and range values for each dimension
+ */
+int *createPort(int *port, int base, int number_of_indices, int index_range_pairs, ...);
+
+//DOL macros
+#define GETINDEX(dimension) \
+    ((RtemsProcessWrapper*)(p->wptr))->index[dimension]
+
+#define CREATEPORTVAR(name) \
+    int name
+
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \
+    createPort(&port, base, number_of_indices, index_range_pairs)
+
+#ifdef PERFORMANCE_EXTRACT
+#include "Performance_Extraction.h"
+#endif
+
+#ifdef MPARM
+extern unsigned int active_processes;
+inline void Cleanup() {
+    register rtems_interrupt_level level;
+    rtems_interrupt_disable(level);
+    active_processes--;
+
+    if(active_processes==0) {
+#ifdef PERFORMANCE_EXTRACT
+        performance_extraction.write_to_xml_file("calibration");
+#endif
+        printf("All processes detached.");
+        rtems_interrupt_enable(level);
+        exit(0);
+    }
+    rtems_interrupt_enable(level);
+}
+#endif
+
+#endif
diff --git a/dol/src/dol/visitor/rtems/lib/system.h b/dol/src/dol/visitor/rtems/lib/system.h
new file mode 100644 (file)
index 0000000..147d79f
--- /dev/null
@@ -0,0 +1,64 @@
+/*  system.h
+ *
+ *  This include file contains information that is included in every
+ *  function in the test set.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  system.h,v 1.12 2000/06/12 15:00:11 joel Exp
+ */
+
+#include "tmacros.h"
+#include "appsupport.h"
+
+// Functions
+rtems_task Init(rtems_task_argument argument);
+rtems_task Test_task(rtems_task_argument argument);
+
+// Configuration information
+#define CONFIGURE_TEST_NEEDS_CONSOLE_DRIVER
+
+#define MAXIMUM_REGIONS 2
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES      4
+
+// Tells confdefs.h to build the init task configuration
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+// ??????
+#define CONFIGURE_TICKS_PER_TIMESLICE  100 // ???
+
+#define CONFIGURE_MAXIMUM_TASKS 32
+
+// Tells confdefs.h to build the default configuration table
+#ifdef TEST_INIT
+#define CONFIGURE_INIT
+#endif
+
+#define CONFIGURE_MP_APPLICATION
+//These are just to allow the OS to be able to compile. 
+//Then this value is overwritten during the boot of the OS, 
+//using the call to coprocessor functions
+#define CONFIGURE_MP_MAXIMUM_NODES 1
+#define NODE_NUMBER 1
+
+
+/////////////////////////////////
+#define SCRATCHPAD_QUEUE // enable scratchpad queue
+
+#define DEFAULT_BUFFER_SIZE 100  //scratchpad queue size
+#define TOKEN_BYTES 4096
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+//#define MAXQUEUE 10
+//#define SCRATCH_SIZE_PLATFORM (1024*512)
+
+
+
+#include <confdefs.h>
+
diff --git a/dol/src/dol/visitor/rtems/lib/tmacros.h b/dol/src/dol/visitor/rtems/lib/tmacros.h
new file mode 100644 (file)
index 0000000..76308ad
--- /dev/null
@@ -0,0 +1,247 @@
+/*  tmacros.h
+ *
+ *  This include file contains macros which are useful in the RTEMS
+ *  test suites.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.OARcorp.com/rtems/license.html.
+ *
+ *  tmacros.h,v 1.25 2002/08/02 00:51:52 joel Exp
+ */
+
+#ifndef __TMACROS_h
+#define __TMACROS_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bsp.h>    /* includes <rtems.h> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <rtems/error.h>
+
+#define FOREVER 1                  /* infinite loop */
+
+#ifdef TEST_INIT
+#define TEST_EXTERN 
+#else
+#define TEST_EXTERN extern
+#endif
+
+#include "buffer_test_io.h"
+
+/*
+ *  Check that that the dispatch disable level is proper for the
+ *  mode/state of the test.  Normally it should be 0 when in task space.
+ */
+
+#define check_dispatch_disable_level( _expect ) \
+  do { \
+    extern volatile rtems_unsigned32 _Thread_Dispatch_disable_level; \
+    if ( (_expect) != -1 && _Thread_Dispatch_disable_level != (_expect) ) { \
+      printf( "\n_Thread_Dispatch_disable_level is (%d) not %d\n", \
+              _Thread_Dispatch_disable_level, (_expect) ); \
+      FLUSH_OUTPUT(); \
+      rtems_test_exit( 1 ); \
+    } \
+  } while ( 0 ) 
+
+/*
+ *  These macros properly report errors within the Classic API
+ */
+
+#define directive_failed( _dirstat, _failmsg )  \
+ fatal_directive_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
+
+#define directive_failed_with_level( _dirstat, _failmsg, _level )  \
+ fatal_directive_status_with_level( \
+      _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
+
+#define fatal_directive_status( _stat, _desired, _msg ) \
+  fatal_directive_status_with_level( _stat, _desired, _msg, 0 )
+
+#define fatal_directive_check_status_only( _stat, _desired, _msg ) \
+  do { \
+    if ( (_stat) != (_desired) ) { \
+      printf( "\n%s FAILED -- expected (%s) got (%s)\n", \
+              (_msg), rtems_status_text(_desired), rtems_status_text(_stat) ); \
+      FLUSH_OUTPUT(); \
+      rtems_test_exit( _stat ); \
+    } \
+  } while ( 0 )
+
+#define fatal_directive_status_with_level( _stat, _desired, _msg, _level ) \
+  do { \
+    check_dispatch_disable_level( _level ); \
+    fatal_directive_check_status_only( _stat, _desired, _msg ); \
+  } while ( 0 ) 
+
+/*
+ *  These macros properly report errors from the POSIX API
+ */
+
+#define posix_service_failed( _dirstat, _failmsg )  \
+ fatal_posix_service_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
+
+#define posix_service_failed_with_level( _dirstat, _failmsg, _level )  \
+ fatal_posix_service_status_with_level( \
+      _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
+
+#define fatal_posix_service_status( _stat, _desired, _msg ) \
+  fatal_posix_service_status_with_level( _stat, _desired, _msg, 0 )
+
+#define fatal_posix_service_status_with_level( _stat, _desired, _msg, _level ) \
+  do { \
+    check_dispatch_disable_level( _level ); \
+    if ( (_stat) != (_desired) ) { \
+      printf( "\n%s FAILED -- expected (%d - %s) got (%d - %s)\n", \
+              (_msg), _desired, strerror(_desired), _stat, strerror(_stat) ); \
+      printf( "\n FAILED -- errno (%d - %s)\n", \
+              errno, strerror(errno) ); \
+      FLUSH_OUTPUT(); \
+      rtems_test_exit( _stat ); \
+    } \
+  } while ( 0 )
+
+/*
+ *  Generic integer version of the error reporting
+ */
+
+#define int_service_failed( _dirstat, _failmsg )  \
+ fatal_int_service_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
+
+#define int_service_failed_with_level( _dirstat, _failmsg, _level )  \
+ fatal_int_service_status_with_level( \
+      _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
+
+#define fatal_int_service_status( _stat, _desired, _msg ) \
+  fatal_int_service_status_with_level( _stat, _desired, _msg, 0 )
+
+#define fatal_int_service_status_with_level( _stat, _desired, _msg, _level ) \
+  do { \
+    check_dispatch_disable_level( _level ); \
+    if ( (_stat) != (_desired) ) { \
+      printf( "\n%s FAILED -- expected (%d) got (%d)\n", \
+              (_msg), (_desired), (_stat) ); \
+      FLUSH_OUTPUT(); \
+      rtems_test_exit( _stat ); \
+    } \
+  } while ( 0 )
+
+/*
+ *  Print the time: modificata per swarm da Poletti Francesco per risolvere il
+ *  problema di stampa degli interi
+ */
+
+#define print_time(_s1, _tb, _s2) \
+  do { \
+    myprint( "%s%02d:%02d:%02d   %02d/%02d/%0d%s", \
+       _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
+       (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
+    fflush(stdout); \
+  } while ( 0 )
+
+
+#define sprint_time(_str, _s1, _tb, _s2) \
+  do { \
+    sprintf( (str), "%s%02d:%02d:%02d   %02d/%02d/%04d%s", \
+       _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
+       (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
+  } while ( 0 )
+
+#define put_dot( _c ) \
+  do { \
+    putchar( _c ); \
+    FLUSH_OUTPUT(); \
+  } while ( 0 )
+
+#define new_line  puts( "" )
+
+#define puts_nocr printf
+
+#ifdef RTEMS_TEST_NO_PAUSE
+#define rtems_test_pause() \
+    do { \
+      printf( "<pause>\n" ); \
+      FLUSH_OUTPUT(); \
+  } while ( 0 )
+
+#define rtems_test_pause_and_screen_number( _screen ) \
+  do { \
+    printf( "<pause - screen %d>\n", (_screen) ); \
+    FLUSH_OUTPUT(); \
+  } while ( 0 )
+#else
+#define rtems_test_pause() \
+  do { \
+    char buffer[ 80 ]; \
+    printf( "<pause>" ); \
+    FLUSH_OUTPUT(); \
+    gets( buffer ); \
+    puts( "" ); \
+  } while ( 0 )
+
+#define rtems_test_pause_and_screen_number( _screen ) \
+  do { \
+    char buffer[ 80 ]; \
+    printf( "<pause - screen %d>", (_screen) ); \
+    FLUSH_OUTPUT(); \
+    gets( buffer ); \
+    puts( "" ); \
+  } while ( 0 )
+#endif
+
+#define put_name( _name, _crlf ) \
+  do { char buf[6];int i=1;\
+    rtems_unsigned32 c0, c1, c2, c3; \
+    \
+    c0 = ((_name) >> 24) & 0xff; \
+    c1 = ((_name) >> 16) & 0xff; \
+    c2 = ((_name) >> 8) & 0xff; \
+    c3 = (_name) & 0xff; \
+    buf[0]=c0; \
+    if ( c1 ) {buf[i]=(char)c1; i++;} ; \
+    if ( c2 ) {buf[i]=(char)c2; i++;}; \
+    if ( c3 ) {buf[i]=(char)c3; i++;}; \
+    if ( (_crlf) ) {buf[i]='\n'; i++;}\
+    buf[i]=0;\
+    printf(buf);\
+    } while (0)
+
+#ifndef build_time
+#define build_time( TB, MON, DAY, YR, HR, MIN, SEC, TK ) \
+  { (TB)->year   = YR;  \
+    (TB)->month  = MON; \
+    (TB)->day    = DAY; \
+    (TB)->hour   = HR;  \
+    (TB)->minute = MIN; \
+    (TB)->second = SEC; \
+    (TB)->ticks  = TK; }
+#endif
+
+#define task_number( tid ) \
+  ( rtems_get_index( tid ) - \
+     rtems_configuration_get_rtems_api_configuration()->number_of_initialization_tasks )
+
+static inline rtems_unsigned32 get_ticks_per_second( void )
+{
+  rtems_interval ticks_per_second;
+  (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second );
+  return ticks_per_second;
+}
+
+#define TICKS_PER_SECOND get_ticks_per_second()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/dol/src/dol/visitor/rtems/lib/traffic_shaping.c b/dol/src/dol/visitor/rtems/lib/traffic_shaping.c
new file mode 100644 (file)
index 0000000..d47d2f5
--- /dev/null
@@ -0,0 +1,189 @@
+#include <bsp.h>
+#include <stdio.h>
+
+#include "appsupport.h"
+#include "rtems_process_wrapper.h"
+#include "traffic_shaping.h"
+
+unsigned int sink_processes;
+void sink_end_process(rtems_task_argument argument);
+void queue_status_process(rtems_task_argument argument);
+void shaping_process(rtems_task_argument argument);
+rtems_task shaping_init(rtems_task_argument argument) {
+    rtems_id task_id;
+    rtems_status_code status;
+    QUEUE_WRAPPER *queue_wrap, *sink_wrap;
+    rtems_name name;
+    int i;
+
+    // instatiate daemons for data transfer notices
+    queue_wrap = (QUEUE_WRAPPER *)malloc(NUMBER_OF_QUEUES *
+                                          sizeof(QUEUE_WRAPPER));
+    for (i=0; i < NUMBER_OF_QUEUES; i++) {
+        queue_wrap[i].q = scratch_queue_autoinit_shaper(i+1, 0, 0, 0);
+        queue_wrap[i].hasData = 0;
+    }
+
+    for (i=0; i< NUMBER_OF_QUEUES; i++) {
+        name = rtems_build_name('q', 's', i+1, 'c');
+        status = rtems_task_create(name,
+                                   127,
+                                   RTEMS_MINIMUM_STACK_SIZE,
+                                   RTEMS_DEFAULT_MODES,
+                                   RTEMS_LOCAL,
+                                   &task_id, -1);
+        if (status != RTEMS_SUCCESSFUL) {
+            printf("[init    ] Create queue process failed (status %d).\n",
+                   status);
+            rtems_shutdown_executive(0);
+        }
+        status = rtems_task_start(task_id, queue_status_process,
+                                  (rtems_task_argument)&queue_wrap[i]);
+        if (status != RTEMS_SUCCESSFUL) {
+            printf("[init    ] Start queue process failed (status %d).\n",
+                   status);
+            rtems_shutdown_executive(0);
+        }
+    }
+
+    // instatiate daemons to wait for sinks finishing
+    sink_processes = NUMBER_OF_SINKS;
+    sink_wrap = (QUEUE_WRAPPER *)malloc(NUMBER_OF_SINKS *
+                                        sizeof(QUEUE_WRAPPER));
+    for (i=0; i<NUMBER_OF_SINKS; i++) {
+        sink_wrap[i].sem_terminate = get_sem_terminate(i+1);
+    }
+    for (i=0; i<NUMBER_OF_SINKS; i++) {
+        name = rtems_build_name('s', 't', i+1, 'c');
+        status = rtems_task_create(name,
+                                   127,
+                                   RTEMS_MINIMUM_STACK_SIZE,
+                                   RTEMS_DEFAULT_MODES,
+                                   RTEMS_LOCAL,
+                                   &task_id, -1);
+        if (status != RTEMS_SUCCESSFUL) {
+            printf("[init    ] Create sink process failed (status %d).\n",
+                   status);
+            rtems_shutdown_executive(0);
+        }
+        status = rtems_task_start(task_id, sink_end_process,
+                                  (rtems_task_argument)&sink_wrap[i]);
+        if (status != RTEMS_SUCCESSFUL) {
+            printf("[init    ] Start sink process failed (status %d).\n",
+                   status);
+            rtems_shutdown_executive(0);
+        }
+    }
+
+    
+    // intatiate daemon for data transfer
+    name = rtems_build_name('t', 's', NUMBER_OF_QUEUES, 'c');
+    status = rtems_task_create(name,
+                               128,
+                               RTEMS_MINIMUM_STACK_SIZE,
+                               RTEMS_DEFAULT_MODES,
+                               RTEMS_LOCAL,
+                               &task_id, -1);
+    if (status != RTEMS_SUCCESSFUL) {
+        printf("[init    ] Create shaping process failed (status %d).\n",
+               status);
+        rtems_shutdown_executive(0);
+    }
+    status = rtems_task_start(task_id, shaping_process,
+                              (rtems_task_argument)queue_wrap);
+    if (status != RTEMS_SUCCESSFUL) {
+        printf("[init    ] Start shaping process failed (status %d).\n",
+               status);
+        rtems_shutdown_executive(0);
+    }
+
+    rtems_task_delete(RTEMS_SELF);
+}
+
+
+void queue_status_process(rtems_task_argument argument) 
+{
+    QUEUE_WRAPPER *wrap = (QUEUE_WRAPPER *) argument;
+    SCRATCH_QUEUE_SHAPER *queue = wrap->q;
+
+/*    printf("queue:%x, traffice_shaping: "
+           "\n\t sem_shaper_used:%x, "
+           "\n\t sem_shaper_left:%x, "
+           "\n\t semaphore_left:%x, "
+           "\n\t semaphore_used:%x",
+           wrap->q,
+           queue->sem_shaper_used,
+           queue->sem_shaper_left,
+           queue->semaphore_left,
+           queue->semaphore_used
+           ); */
+    
+    while (1) {
+        // always USEINTERRUPT
+        ss_sem_wait(queue->sem_shaper_used);
+        ss_sem_wait(queue->sem_shaper_left);
+
+        wrap->hasData ++;
+    }
+}
+
+void sink_end_process(rtems_task_argument argument)
+{
+    QUEUE_WRAPPER *queue_wrap = (QUEUE_WRAPPER *) argument;
+
+    // wait for terminating signal from sink
+    ss_sem_wait(queue_wrap->sem_terminate);
+
+    sink_processes--;
+    if (sink_processes == 0) {
+        SHOW_DEBUG("END!!!");
+        exit(0);
+    }
+}
+
+static int cur_queue; // current queue
+QUEUE_WRAPPER * get_next_queue(QUEUE_WRAPPER * queue_wrap);
+int canSend(QUEUE_WRAPPER * queue);
+void shaping_process(rtems_task_argument argument) 
+{
+    QUEUE_WRAPPER *queue_wrap = (QUEUE_WRAPPER *) argument;
+    cur_queue = 0;
+
+    while (1) {
+        QUEUE_WRAPPER *q_w;
+        q_w = get_next_queue(queue_wrap);
+
+        if (canSend(q_w)) {
+            if (q_w->hasData) {
+                scratch_queue_shaperRW(q_w->q);
+                q_w->hasData--;
+            }
+        }
+    }
+    
+}
+
+#define PULL_MODE
+// queue scheduling
+QUEUE_WRAPPER * get_next_queue(QUEUE_WRAPPER * queue_wrap) 
+{
+    // round robin
+#ifdef PULL_MODE
+    cur_queue = (cur_queue == 0) ? NUMBER_OF_QUEUES : cur_queue;
+    cur_queue --;
+#else // PUSH MODE
+    cur_queue++;
+    cur_queue = (cur_queue == NUMBER_OF_QUEUES) ? 0 : cur_queue;
+#endif
+    return &queue_wrap[cur_queue];
+}
+
+
+// shaping
+int canSend(QUEUE_WRAPPER * queue)
+{
+    return 1;
+}
+
+
+
diff --git a/dol/src/dol/visitor/rtems/lib/traffic_shaping.h b/dol/src/dol/visitor/rtems/lib/traffic_shaping.h
new file mode 100644 (file)
index 0000000..2ff49b8
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef TRAFFIC_SHAPING_H
+#define TRAFFIC_SHAPING_H
+
+#include "scratch_queue.h"
+
+typedef struct _queue_wrapper {
+    SCRATCH_QUEUE_SHAPER *q;
+    int hasData;
+    QUEUE_SEMAPHORE sem_terminate;
+} QUEUE_WRAPPER;
+
+#define @NUMBER_OF_QUEUES@ // generated
+#define @NUMBER_OF_SINKS@  // generated
+
+rtems_task shaping_init(rtems_task_argument argument);
+
+#endif
diff --git a/dol/src/dol/visitor/systemC/MakefileVisitor.java b/dol/src/dol/visitor/systemC/MakefileVisitor.java
new file mode 100644 (file)
index 0000000..c53f585
--- /dev/null
@@ -0,0 +1,72 @@
+/* $Id: MakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.systemC;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a SystemC package Makefile.
+ */
+public class MakefileVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of the Makefile
+     */
+    public MakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * Create a Makefile for the given process network.
+     *
+     * @param x process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+
+            ps.println("CXX = g++");
+            ps.println("CC = g++");
+            ps.println();
+            ps.println("SYSTEMC_INC = -I" + _ui.getSystemCINC());
+            ps.println("SYSTEMC_LIB = " + _ui.getSystemCLIB());
+            ps.println("MY_LIB_INC = -Ilib -Isc_wrappers -Iprocesses");
+            ps.println("VPATH = lib:sc_wrappers:processes");
+            ps.println();
+            ps.println("CXXFLAGS = -g -O0 -D__DOL_ETHZ_GEN__ $(SYSTEMC_INC) $(MY_LIB_INC)");
+            ps.println("CFLAGS = $(CXXFLAGS)");
+            ps.println();
+
+            ps.print("PROCESS_OBJS = dol.o ");
+            for (String basename : x.getProcessBasenames()) {
+                ps.print(basename + "_wrapper.o ");
+            }
+            ps.println();
+            ps.println();
+            ps.println("all:" + _name);
+            ps.println();
+            ps.println(_name + ": " + _name + ".o $(PROCESS_OBJS)");
+            ps.println("\t$(CXX) $(CXXFLAGS) -o $@ $^ $(SYSTEMC_LIB)");
+            ps.println("clean:");
+            ps.println("\t-rm -f *.o core core.* *.core " + _name);
+
+        } catch (Exception e) {
+            System.out.println(" SystemC Makefile Visitor: exception " +
+                    "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
+
+    protected String _dir = null;
+    protected String _name = "sc_application";
+}
diff --git a/dol/src/dol/visitor/systemC/PNSystemCVisitor.java b/dol/src/dol/visitor/systemC/PNSystemCVisitor.java
new file mode 100644 (file)
index 0000000..e043782
--- /dev/null
@@ -0,0 +1,101 @@
+/* $Id: PNSystemCVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.systemC;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a SystemC package.
+ */
+public class PNSystemCVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param packageName Name of the SystemC directory
+     */
+    public PNSystemCVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            //_packageName = x.getName() + "SystemCPackage";
+            _generateDirHierarchy();
+
+            x.accept(new MakefileVisitor(_srcDir));
+            x.accept(new SCModuleVisitor(_srcDir));
+            x.accept(new ProcessVisitor(_wrapperDir));
+
+        }
+        catch (Exception e) {
+            System.out.println(" SystemC PN Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _generateDirHierarchy()
+        throws IOException, FileNotFoundException {
+        File dir = new File(_packageName);
+        dir.mkdirs();
+
+        _srcDir = _packageName + _delimiter + _srcDirName;
+        dir = new File(_srcDir);
+        dir.mkdirs();
+
+        _libDir = _srcDir + _delimiter + _libDirName;
+        dir = new File(_libDir);
+        dir.mkdirs();
+
+        _processDir = _srcDir + _delimiter + _processDirName;
+        dir = new File(_processDir);
+        dir.mkdirs();
+
+        _wrapperDir = _srcDir + _delimiter + _wrapperDirName;
+        dir = new File(_wrapperDir);
+        dir.mkdirs();
+
+        //copy library files
+        File source = new File(_ui.getMySystemCLib());
+        File destination = new File(_libDir);
+        new Copier().copy(source, destination);
+
+        //copy process source code
+        source = new File(_srcDirName);
+        destination = new File(_processDir);
+        new Copier().copy(source, destination);
+    }
+
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+
+    protected String _libDir = "";
+    protected static String _libDirName = "lib";
+
+    protected String _processDir = "";
+    protected static String _processDirName = "processes";
+
+    protected String _wrapperDir = "";
+    protected static String _wrapperDirName = "sc_wrappers";
+
+    protected String _threadPostfix = "_thread";
+
+    protected CodePrintStream _mainPS = null;
+}
diff --git a/dol/src/dol/visitor/systemC/ProcessVisitor.java b/dol/src/dol/visitor/systemC/ProcessVisitor.java
new file mode 100644 (file)
index 0000000..f87545b
--- /dev/null
@@ -0,0 +1,351 @@
+/* $Id: ProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.systemC;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a SystemC wrapper for a process: process_wrapper.[h/cpp].
+ */
+public class ProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir target directory
+     */
+    public ProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            Vector<String> pList = new Vector<String>();
+
+            for (Process p : x.getProcessList()) {
+                String basename = p.getBasename();
+                if (!pList.contains(basename)) {
+                    pList.add(basename);
+                    p.accept(this);
+                }
+            }
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     * @param p process that needs to be rendered
+     */
+    public void visitComponent(Process p) {
+        try {
+            _createCppFile(p);
+            _createHeaderFile(p);
+            _adaptSources(p);
+        }
+        catch (Exception e) {
+            System.out.println("Process Visitor: exception "
+                    + "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    protected void _createCppFile(Process p) throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.cpp";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#include \"" + p.getBasename()
+                + "_wrapper.h\"");
+        ps.printPrefixln();
+
+        if (p.hasOutPorts()) {
+            //DOL_write()
+            ps.printPrefixln("static inline int DOL_write(void *port, "
+                    + "void *buf, int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("char *str = (char *)buf;");
+            ps.printPrefixln("while (len-- > 0) ");
+            ps.printLeftBracket();
+
+            int j = 0;
+            for (Port ip : p.getPortList()) {
+                if (ip.isOutPort()) {
+                    String s = (j++ == 0) ? "if " : " else if ";
+                    ps.printPrefixln(s + "(strstr(\" OUTPORT_"
+                            + ip.getName() + "\", (const char*)port)) ");
+                    ps.printLeftBracket();
+                    ps.printPrefixln("(static_cast<" + p.getBasename()
+                            + "_wrapper *>(process->wptr))->OUTPORT_"
+                            + ip.getName() + "->write(*(str++));");
+                    ps.printRightBracket();
+                }
+            }
+            ps.printRightBracket();
+            ps.printRightBracket();
+
+            //DOL_wtest()
+            ps.printPrefixln("static inline int DOL_wtest(void *port, "
+                    + "int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            j = 0;
+            for (Port ip : p.getPortList()) {
+                if (ip.isOutPort()) {
+                    String s = (j++ == 0) ? "if " : "else if ";
+                    ps.printPrefixln(s + "(strstr(\" OUTPORT_"
+                            + ip.getName() + "\", (const char*)port)) ");
+                    ps.printLeftBracket();
+                    ps.printPrefixln("return (static_cast<" + p.getBasename()
+                            + "_wrapper *>(process->wptr))->OUTPORT_"
+                            + ip.getName() + "->wtest(len);");
+                    ps.printRightBracket();
+                }
+            }
+            ps.printRightBracket();
+        }
+
+        ps.printPrefixln();
+        if (p.hasInPorts()) {
+            //DOL_read()
+            ps.printPrefixln("static inline int DOL_read(void *port, "
+                    + "void *buf, int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            ps.printPrefixln("char *str = (char *)buf;");
+            ps.printPrefixln("while (len-- > 0)");
+            ps.printLeftBracket();
+
+            int j = 0;
+            for (Port ip : p.getPortList()) {
+                if (ip.isInPort()) {
+                    String s = (j++ == 0) ? "if " : "else if ";
+                    ps.printPrefixln(s + "(strstr(\" INPORT_"
+                            + ip.getName() + "\", (const char*)port))");
+                    ps.printLeftBracket();
+                    ps.printPrefixln("(static_cast<" + p.getBasename()
+                            + "_wrapper *>(process->wptr))->INPORT_"
+                            + ip.getName() + "->read(*(str++));");
+                    ps.printRightBracket();
+                }
+            }
+            ps.printRightBracket();
+            ps.printRightBracket();
+
+            //DOL_rtest()
+            ps.printPrefixln("static inline int DOL_rtest(void *port, "
+                    + "int len, DOLProcess *process)");
+            ps.printLeftBracket();
+            j = 0;
+            for (Port ip : p.getPortList()) {
+                if (ip.isInPort()) {
+                    String s = (j++ == 0) ? "if " : " else if ";
+                    ps.printPrefixln(s + "(strstr(\" INPORT_"
+                            + ip.getName() + "\", (const char*)port))");
+                    ps.printLeftBracket();
+                    ps.printPrefixln("return (static_cast<" + p.getBasename()
+                            + "_wrapper *>(process->wptr))->INPORT_"
+                            + ip.getName() + "->rtest(len);");
+                    ps.printRightBracket();
+                }
+            }
+            ps.printRightBracket();
+
+        }
+
+        ps.printPrefixln();
+        ps.printPrefixln("static inline int DOL_detach(DOLProcess *p)");
+        ps.printLeftBracket();
+        ps.printPrefixln("(static_cast<" + p.getBasename()
+                + "_wrapper *>(p->wptr))" + "->setDetached();");
+        ps.printRightBracket();
+        ps.printPrefixln();
+
+        ps.printPrefixln("#define GETINDEX(dimension) \\");
+        ps.printPrefixln("(static_cast<" + p.getBasename()
+                + "_wrapper *>(p->wptr))->_processIndex[dimension]");
+        ps.printPrefixln();
+
+        //include c file
+        for (SourceCode sr : p.getSrcList()) {
+            ps.printPrefixln("#include \"" + sr.getLocality() + "\"");
+        }
+        ps.printPrefixln();
+
+
+        ps.printPrefixln("void " + p.getBasename()
+                + "_wrapper::setDetached() { _detached = 1; }");
+        ps.printPrefixln("int " + p.getBasename()
+                + "_wrapper::isDetached() { return _detached; }");
+        ps.printPrefixln();
+
+        //constructor
+        ps.printPrefixln(p.getBasename() + "_wrapper::" + p.getBasename()
+                + "_wrapper(sc_module_name name=sc_gen_unique_name(\""
+                + p.getBasename() + "\" ))  : sc_module(name), "
+                // + "_process(" + p.getBasename() +  "), "
+                + "_detached(0)");
+        ps.printLeftBracket();
+        ps.printPrefixln("_state = (LocalState)new "
+                + p.getBasename().substring(0, 1).toUpperCase()
+                + p.getBasename().substring(1) + "_State;");
+        //ps.printPrefixln("struct _local_states *_state = "
+        //        + "new struct _local_states;");
+        //ps.printPrefixln("memcpy(_state, " + p.getBasename()
+        //        + ".local, sizeof(struct _local_states));");
+        ps.printPrefixln("_process.local = _state;");
+        //ps.printPrefixln("sprintf(_process.local->id, name);");
+        ps.printPrefixln("_process.init = " + p.getBasename() + "_init;");
+        ps.printPrefixln("_process.fire = " + p.getBasename() + "_fire;");
+        ps.printPrefixln("_process.wptr = this;");
+        ps.printPrefixln();
+        ps.printPrefixln("char buffer[255];");
+        ps.printPrefixln("sprintf(buffer, name);");
+        ps.printPrefixln("for (int i = 0; i < 4; i++)");
+        ps.printPrefixln("    _processIndex[i] = "
+                + "getIndex(buffer, \"_\", i);");
+
+        ps.printPrefixln();
+        ps.printRightBracket();
+
+        ps.printPrefixln();
+        ps.printPrefixln("void " + p.getBasename()
+                + "_wrapper::initialize()");
+        ps.printLeftBracket();
+        ps.printPrefixln("_process.init(&_process);");
+        ps.printRightBracket();
+        ps.printPrefixln();
+        ps.printPrefixln("int " + p.getBasename() + "_wrapper::fire()");
+        ps.printLeftBracket();
+        ps.printPrefixln("return _process.fire(&_process);");
+        ps.printRightBracket();
+        ps.printPrefixln();
+        ps.printPrefixln(p.getBasename() + "_wrapper::~" + p.getBasename()
+                + "_wrapper()");
+        ps.printLeftBracket();
+        ps.printPrefixln("if (_state)");
+        ps.printLeftBracket();
+        ps.printPrefixln("delete ("
+                + p.getBasename().substring(0, 1).toUpperCase()
+                + p.getBasename().substring(1) + "_State*)_state;");
+        ps.printRightBracket();
+        ps.printRightBracket();
+    }
+
+    protected void _createHeaderFile(Process p)
+        throws IOException {
+        String filename = _dir + _delimiter + p.getBasename()
+                + "_wrapper.h";
+        OutputStream file = new FileOutputStream(filename);
+        CodePrintStream ps = new CodePrintStream(file);
+
+        ps.printPrefixln("#ifndef " + p.getBasename() + "_WRAPPER_H");
+        ps.printPrefixln("#define " + p.getBasename() + "_WRAPPER_H");
+        ps.printPrefixln();
+        ps.printPrefixln("#include \"systemc.h\"");
+        ps.printPrefixln();
+        ps.printPrefixln("#include \"dol_sched_if.h\"");
+        ps.printPrefixln("#include \"dol_fifo_if.h\"");
+        ps.printPrefixln("#include \"simple_fifo.h\"");
+        ps.printPrefixln();
+        ps.printPrefixln("#include <dol.h>");
+        ps.printPrefixln();
+        ps.printPrefixln("class " + p.getBasename() +
+                         "_wrapper : virtual public dol_sched_if, " +
+                         "public sc_module");
+        ps.printLeftBracket();
+        ps.printPrefixln("public:");
+
+        for (Port pr : p.getPortList()) {
+            if (pr.isOutPort()) {
+                ps.printPrefixln("sc_port<write_if> OUTPORT_" +
+                                 pr.getName() + ";");
+            }
+            else if (pr.isInPort()) {
+                ps.printPrefixln("sc_port<read_if> INPORT_" +
+                                 pr.getName() + ";");
+            }
+        }
+        ps.printPrefixln("int _processIndex[4];");
+
+        ps.printPrefixln();
+        ps.printPrefixln("" + p.getBasename()
+                + "_wrapper(sc_module_name name);");
+        ps.printPrefixln();
+        ps.printPrefixln("virtual ~" + p.getBasename() + "_wrapper();");
+        ps.printPrefixln();
+        ps.printPrefixln("// DOL scheduler interface");
+        ps.printPrefixln("void initialize();");
+        ps.printPrefixln("int fire();");
+        ps.printPrefixln("void setDetached();");
+        ps.printPrefixln("int isDetached();");
+        ps.printPrefixln();
+        ps.printPrefixln();
+        ps.printPrefixln("protected:");
+        ps.printPrefixln("LocalState _state;");
+
+        ps.printPrefixln();
+        ps.printPrefixln("private:");
+        ps.printPrefixln("" + p.getBasename() + "_wrapper( const "
+                + p.getBasename() + "_wrapper& );");
+        ps.printPrefixln("" + p.getBasename() + "_wrapper& operator = "
+                + "( const " + p.getBasename() + "_wrapper& );");
+        ps.printPrefixln("DOLProcess _process;");
+        ps.printPrefixln("int _detached;");
+        ps.printRightBracket();
+        ps.printPrefixln(";");
+        ps.printPrefixln("#endif");
+    }
+
+    /**
+     * Make modifications to source files of a process.
+     * Port names need to be strings for the SystemC code generation.
+     * Therefore, in the header files integer port names are put into
+     * quotation marks.
+     * 
+     * @param p process whose sources should be adapted
+     * @throws IOException
+     */
+    protected void _adaptSources(Process p) throws IOException {
+        Sed sed = new Sed();
+        for (Port port : p.getPortList()) {
+            String processHeaderFile;
+
+            for (SourceCode sr : p.getSrcList()) {
+                processHeaderFile = _dir + _delimiter + ".."
+                        + _delimiter + "processes" + _delimiter
+                        + sr.getLocality().
+                        replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+                sed.sed(processHeaderFile,
+                        "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                        + port.getBasename() + "\"?[ ]*$",
+                        "$1 " + "\"" + port.getBasename() + "\"");
+            }
+        }
+    }
+
+    
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/systemC/SCModuleVisitor.java b/dol/src/dol/visitor/systemC/SCModuleVisitor.java
new file mode 100644 (file)
index 0000000..006a08c
--- /dev/null
@@ -0,0 +1,232 @@
+/* $Id: SCModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.systemC;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the top sc module: sc_applicaion.cpp.
+ */
+public class SCModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param dir path of this file
+     */
+    public SCModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered
+     */
+    public void visitComponent(ProcessNetwork x) {
+        try {
+            String filename = _dir + _delimiter + "sc_application.cpp";
+            OutputStream file = new FileOutputStream(filename);
+            _mainPS = new CodePrintStream(file);
+
+            _mainPS.printPrefixln("#include <systemc>");
+            _mainPS.printPrefixln("#include <list>");
+            _mainPS.printPrefixln("#include \"dol_fifo.h\"");
+            _mainPS.printPrefixln("#include \"dol_sched_if.h\"");
+            _mainPS.println();
+
+            for (String basename : x.getProcessBasenames()) {
+                _mainPS.printPrefixln("#include \"" + basename
+                        + "_wrapper.h\"");
+            }
+            _mainPS.println();
+            _mainPS.printPrefixln("using namespace std;");
+
+            _mainPS.println();
+            _mainPS.printPrefixln("class sc_application : public sc_module ");
+            _mainPS.printLeftBracket();
+
+            _mainPS.printPrefixln("public:");
+            _mainPS.printPrefixln("SC_HAS_PROCESS(sc_application);");
+
+            //declare processes
+            _mainPS.println();
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln(p.getBasename() + "_wrapper "
+                        + p.getName() + "_ins"+ ";");
+                _mainPS.printPrefixln("sc_event " + p.getName()
+                        + "_event;");
+            }
+            _mainPS.println();
+
+            //define the scheduler
+            _mainPS.printPrefixln("sc_event sched_event;");
+            _mainPS.printPrefixln("list<sc_event* > eventList;");
+            _mainPS.printPrefixln("list<sc_event* >::iterator iter;");
+            _mainPS.println();
+
+            //declare channels
+            _mainPS.println();
+            for (Channel p : x.getChannelList()) {
+                _mainPS.printPrefixln("fifo " + p.getName() + "_ins;");
+            }
+            _mainPS.println();
+
+            //model constructor
+            _mainPS.printPrefixln("sc_application(sc_module_name name)");
+
+            //parameter of constructor
+            _mainPS.printPrefix(":       sc_module(name)");
+            for (Process p : x.getProcessList()) {
+                _mainPS.println(",");
+                _mainPS.printPrefix(p.getName() + "_ins(\""
+                        + p.getName() +"\")");
+            }
+
+            if (x.getChannelList().size() > 0) {
+                for (Channel c : x.getChannelList()) {
+                    _mainPS.println(",");
+                    _mainPS.printPrefix(c.getName() + "_ins("
+                                        + "\"" + c.getName() + "\", "
+                                        + c.getSize() * c.getTokenSize()
+                                        + ")");
+                }
+            }
+            _mainPS.println("");
+            _mainPS.printLeftBracket();
+            
+            //construtor content
+            //build the network
+            for (Channel p : x.getChannelList()) {
+                p.accept(this);
+            }
+            _mainPS.println("");
+
+            _mainPS.println("");
+
+            _mainPS.printPrefixln("SC_THREAD(thread_init);");
+            //init thread
+            _mainPS.printPrefixln("SC_THREAD(thread_sched);");
+
+            //declare concurrent non-terminating threads
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln("SC_THREAD(thread_" +
+                                      p.getName() + ");");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define scheduler thread
+            _mainPS.printPrefixln("void thread_init()");
+            _mainPS.printLeftBracket();
+            //init
+            for (Process p : x.getProcessList()) {
+                _mainPS.printPrefixln(p.getName() + "_ins.initialize();");
+            }
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+
+            //different scheduling algorithm can be put here
+            _mainPS.printPrefixln("void thread_sched()");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("while (1)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("for (iter=eventList.begin(); iter != "
+                    + "eventList.end(); ++iter)");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_event* e = (*iter);");
+            _mainPS.printPrefixln("notify(*e);");
+            _mainPS.printRightBracket();
+            _mainPS.printPrefixln("eventList.clear();");
+            _mainPS.printPrefixln("wait(sched_event);");
+            _mainPS.printRightBracket();
+            _mainPS.printRightBracket();
+            _mainPS.println();
+
+            //define threads
+            for (Process p : x.getProcessList()) {
+                p.accept(this);
+            }
+
+            _mainPS.printRightBracket(); // end of class
+            _mainPS.println(";");
+
+            //create and run the simulator
+            _mainPS.printPrefixln("int sc_main (int argc, char *argv[])");
+            _mainPS.printLeftBracket();
+            _mainPS.printPrefixln("sc_report_handler::set_actions(\""
+                    + "/IEEE_Std_1666/deprecated\", SC_DO_NOTHING);");
+            _mainPS.printPrefixln("sc_report::register_id("
+                    + "RP_ID_PARAMETER_PROBLEM, "
+                    + "\"parameter problem\" );");
+
+            //create an instance of the application model
+            //remove potential whitespaces before using the process
+            //network name as a systemc identifier
+            _mainPS.printPrefixln("sc_application my_app_mdl(\""
+                    + x.getName().replaceAll(" ", "")  + "\");");
+            _mainPS.printPrefixln("sc_start(-1,SC_NS);");
+            _mainPS.printPrefixln("return 0;");
+
+            _mainPS.printRightBracket();
+
+        }
+        catch (Exception e) {
+            System.out.println(" SystemC module visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Print a line for the process in the correct format for DOTTY.
+     *
+     * @param x process that needs to be rendered
+     */
+    public void visitComponent(Process x) {
+        _mainPS.printPrefixln("void thread_" + x.getName() + "()");
+        _mainPS.printLeftBracket();
+        _mainPS.printPrefixln("while (!" + x.getName()
+                + "_ins.isDetached())");
+        _mainPS.printLeftBracket();
+        _mainPS.printPrefixln(x.getName() + "_ins.fire();");
+        _mainPS.printPrefixln("eventList.push_back(&" + x.getName()
+                              + "_event);");
+        _mainPS.printPrefixln("sched_event.notify();");
+        _mainPS.printPrefixln("wait(" + x.getName() + "_event);");
+
+        _mainPS.printRightBracket();
+        _mainPS.printRightBracket();
+    }
+
+    /**
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        for (Port p : x.getPortList()) {
+            if (p.isOutPort()) {
+                //we get port name from channel
+                //channel.out == process.in
+                _mainPS.printPrefixln(p.getPeerResource().getName()
+                        + "_ins.INPORT_" + p.getPeerPort().getName()
+                        + "(" + x.getName() + "_ins);");
+            } else if (p.isInPort()) {
+                _mainPS.printPrefixln(p.getPeerResource().getName()
+                        + "_ins.OUTPORT_" + p.getPeerPort().getName()
+                        + "(" + x.getName() + "_ins);");
+            }
+        }
+    }
+
+    protected CodePrintStream _mainPS = null;
+    protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/systemC/lib/dol.c b/dol/src/dol/visitor/systemC/lib/dol.c
new file mode 100644 (file)
index 0000000..d852cf5
--- /dev/null
@@ -0,0 +1,81 @@
+#include "dol.h"\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ * Example: createPort(xxx, "port", 2, 1, N1, 3, N2) will result in xxx\r
+ * having the value "port_1_3". The range definitions N1, N2 will be ignored\r
+ * in this implementation\r
+ *\r
+ * @param port buffer where the result is stored\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+char* createPort(char* port, char* base,\r
+        int number_of_indices, int indices, ...) {\r
+    char next_index_string[10];\r
+    strcpy(port, base);\r
+\r
+    if (number_of_indices > 4) {\r
+        printf("Error: iterated ports must not have more than ");\r
+        printf("4 dimensions.\n");\r
+        exit(-1);\r
+    }\r
+\r
+    va_list argumentlist;\r
+    va_start(argumentlist, indices);\r
+\r
+    if (number_of_indices > 0) {\r
+      sprintf(next_index_string, "_%d", indices);\r
+      strcat(port, next_index_string);\r
+\r
+      for (int k = 1; k < number_of_indices; k++) {\r
+          va_arg(argumentlist, int); //skip the range value\r
+          sprintf(next_index_string, "_%d", va_arg(argumentlist, int));\r
+          strcat(port, next_index_string);\r
+      }\r
+    }\r
+    return port;\r
+}\r
+\r
+/**\r
+ * Gets an index of a string, where the index must be separated by\r
+ * a character specified in tokens.\r
+ * Returns -1, when an error occurs.\r
+ *\r
+ * Example:\r
+ * getIndex("name_1_2", "_", 0) will return 1.\r
+ * getIndex("name_1_2", "_", 1) will return 2.\r
+ *\r
+ * @param string string to parse\r
+ * @param tokens delimiter of indices\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int getIndex(const char* string, char* tokens, int indexNumber) {\r
+  char* string_copy;\r
+  char* token_pointer;\r
+  int index = 0;\r
+\r
+  string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));\r
+  if (!string_copy) {\r
+    fprintf(stderr, "getIndex(): could not allocate memory.\n");\r
+    return -1;\r
+  }\r
+\r
+  strcpy(string_copy, string);\r
+\r
+  token_pointer = strtok(string_copy, tokens);\r
+  do {\r
+    token_pointer = strtok(NULL, tokens);\r
+    index++;\r
+  } while (index <= indexNumber && token_pointer != 0);\r
+\r
+  if (token_pointer) {\r
+    index = atoi(token_pointer);\r
+    free(string_copy);\r
+    return index;\r
+  }\r
+\r
+  return -1;\r
+}\r
diff --git a/dol/src/dol/visitor/systemC/lib/dol.h b/dol/src/dol/visitor/systemC/lib/dol.h
new file mode 100644 (file)
index 0000000..282bc4d
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef DOL_H
+#define DOL_H
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/************************************************************************
+ * do not add code to this header
+ ************************************************************************/
+
+/**
+ *  - Local variables for each process can be defined in the structure
+ *    LocalState. For each process, a new instance of LocalState  is
+ *    instantiated.
+ *  - The ProcessInit function pointer points to the function which is
+ *    called to initialize a process.
+ *  - The ProcessFire function pointer points to the function which is
+ *    called repeatedly by the scheduler.
+ *  - The wptr is a placeholder for callback. A pointer to the wrapper
+ *    class instance of the process can be assigned. This is done in the
+ *    code generated by the code generation, so one can just leave it
+ *    blank.
+ */
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//additional behavioral functions could be declared here
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+//process handler
+struct _process;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr; //placeholder for wrapper instance
+} DOLProcess;
+
+
+//macros to deal with iterated ports
+
+/**
+ * macro to create a variable to store a port name
+ *
+ * @param name name of the variable
+ */
+#define MAX_PORT_NAME_LENGTH 255
+#define CREATEPORTVAR(name) char name[MAX_PORT_NAME_LENGTH]
+
+
+/**
+ * Create the port name of an iterated port based on its basename and the
+ * given indices.
+ *
+ * @param port buffer where the result is stored (created using
+ *             CREATEPORTVAR)
+ * @param base basename of the port
+ * @param number_of_indices number of dimensions of the port
+ * @param index_range_pairs index and range values for each dimension
+ */
+#define CREATEPORT(port, base, number_of_indices, indices...) \
+  createPort(port, base, number_of_indices, indices)
+
+char* createPort(char* port,
+                 char* base,
+                 int number_of_indices,
+                 int indices, ...);
+
+int getIndex(const char* string, char* tokens, int indexNumber);
+
+#endif
diff --git a/dol/src/dol/visitor/systemC/lib/dol_fifo.h b/dol/src/dol/visitor/systemC/lib/dol_fifo.h
new file mode 100644 (file)
index 0000000..5646682
--- /dev/null
@@ -0,0 +1,432 @@
+/**************************************************************************
+       dol_fifo.h
+       DOL FIFO channel:   
+       relative bloking (RB) and relative non-bloking (RN) 
+       task transaction level (TTL) fifo channel 
+
+       (c) 2006 by Alexander Maxiaguine <maxiagui@tik.ee.ethz.ch>
+
+       Computer Engineering and Networks Laboratory, TIK
+       Swiss Federal Institute of Technology, ETHZ Zurich 
+       Switzerland
+
+**************************************************************************/
+
+/**************************************************************************
+       Change Log:
+
+       14.03.06 -- creation
+
+**************************************************************************/
+
+#ifndef DOL_FIFO_H
+#define DOL_FIFO_H
+
+#include <typeinfo>
+#include "systemc.h"
+
+#include "dol_rp_ids.h"
+#include "dol_fifo_if.h"
+
+
+template <class T>
+class dol_fifo
+: public dol_fifo_write_if<T>,
+  public dol_fifo_read_if<T>,
+  public sc_prim_channel
+{
+public:
+
+    // constructors
+    explicit dol_fifo( int size ) : sc_prim_channel( sc_gen_unique_name( "dol_fifo" ) )
+       { init( size ); }
+    
+    explicit dol_fifo( const char* name, int size) : sc_prim_channel( name)
+       { init( size ); }
+
+    // destructor
+    virtual ~dol_fifo()
+       { delete [] m_buf; }
+
+    virtual void register_port( sc_port_base&, const char* );
+
+    // ********* WRITE interface methods **************
+    // bloking (re)acquire free room in the channel
+    virtual void reAcquireRoom(int count);
+    
+    // non-bloking (re)acquire free room in the channel
+    virtual bool tryReAcquireRoom(int count);
+    
+    // store data into the acquired free room
+    virtual void store(int offset, T* data, int count);
+    
+    // release the stored data to the channel (commit write)
+    virtual void releaseData(int count);
+
+    // ********* READ interface methods **************
+    // bloking (re)acquire data in the channel
+    virtual void reAcquireData(int count);
+    
+    // non-bloking (re)acquire data in the channel
+    virtual bool tryReAcquireData(int count);
+    
+    // load the acquired data into a vector
+    virtual void load(int offset, T* vector, int count);
+    
+    // free up the room in the channel (commit read)
+    virtual void releaseRoom(int count);
+    
+    
+    // ***************************************
+    // helper methods (for debug, etc.)
+    
+    bool in_deadlock()         {
+        return reader_is_blocked && writer_is_blocked;
+    }
+    
+    void trace( sc_trace_file* tf ) const;
+    virtual void print( ::std::ostream& = ::std::cout ) const;
+    virtual void dump( ::std::ostream& = ::std::cout ) const;
+    
+    
+    virtual const char* kind() const
+        { return "dol_fifo"; }
+
+    
+protected:
+    
+    virtual void update();
+    void init( int );
+
+    
+protected:
+
+    int m_size;                        // buffer size
+    T*  m_buf;                 // the buffer
+
+    // channel state variables
+    int m_rwin_head;    // index of read window head (oldest full token)
+    int m_wwin_head;    // index of write window head (oldest empty token)
+    
+    int m_readable;      // number of readable tokens (number of full tokens)
+    int m_acquired_room; // size of acquired room (write window)
+    int m_acquired_data; // size of acquired data (read window)
+    
+    int m_released_data;  // size of data (filled tokens) released during this delta cycle
+    int m_released_room;  // size of room (emptied tokens) released during this delta cycle
+    
+
+    // SC specific properties
+    sc_event m_data_released_event;
+    sc_event m_room_released_event;
+    
+    sc_port_base* m_reader;    // used for static design rule checking
+    sc_port_base* m_writer;    // used for static design rule checking
+
+    // used to detect deadlocks
+    bool reader_is_blocked;
+    bool writer_is_blocked;
+    
+private:
+    
+    // disabled
+    dol_fifo( const dol_fifo<T>& );
+    dol_fifo& operator = ( const dol_fifo<T>& );
+};
+
+
+
+
+// ************ Implementation ************************************
+
+// *** WRITE interface methods ****
+
+// blocking (re)acquire free room of size COUNT in the channel
+template <class T>
+inline void dol_fifo<T>::reAcquireRoom( int count )
+{
+    while( m_size - m_readable < count   ) {
+        if( m_size < count) {
+            SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Requested room is larger than total available buffer space \n  --> This is a deadlock\n\n");
+        }
+        
+        writer_is_blocked = true;
+        sc_core::wait( m_room_released_event );
+        writer_is_blocked = false;
+    }
+    m_acquired_room = count;
+}
+
+// non-bloking (re)acquire free room in the channel
+template <class T>
+inline bool dol_fifo<T>::tryReAcquireRoom( int count )
+{
+    if( m_size - m_readable < count   ) {
+        if( m_size < count) {
+            SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Requested room is larger than the total available buffer space \n\n");
+        }
+        return false;
+    }
+    m_acquired_room = count;
+    return true;
+}
+
+// write COUNT data into the acquired free room starting from the position indicated by OFFSET
+template <class T>
+inline void dol_fifo<T>::store( int offset, T* data, int count )
+{
+    // sanity checks
+    if( m_acquired_room <= 0) {
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to write without acquiring the room\n  --> I ignore this action\n\n");
+        return;
+    }
+    if( offset >  m_acquired_room - 1 ) {
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to write beyond the acquired room: offset value may be too large\n  --> I ignore this action\n\n");
+        return;
+    }
+    if( count >  m_acquired_room - offset ) {
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to write beyound the acquired room: data size may be too large\n  --> I'm decreasing the data size\n\n");
+        count =  m_acquired_room - offset;
+    }
+    
+    int wi = ( m_wwin_head + offset ) % m_size;
+    for(int i=0; i<count; i++ ) {
+        m_buf[wi] = data[i];
+        wi = ( wi + 1 ) % m_size;
+    }
+}
+
+// release COUNT stored data to the channel (commit write)
+template <class T>
+inline void dol_fifo<T>::releaseData( int count )
+{
+    // sanity check
+    if( count > m_acquired_room ) {
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to release more room than was acquired\n  --> I'm decreasing the size of released room\n\n");
+        count = m_acquired_room;
+    }
+       
+    m_readable += count;
+    m_released_data += count;
+    
+    m_acquired_room -= count;
+    m_wwin_head = ( m_wwin_head + count ) % m_size;
+
+    request_update();
+}
+
+
+// *** READ interface methods ****
+
+// bloking (re)acquire COUNT data in the channel
+template <class T>
+inline void dol_fifo<T>::reAcquireData( int count )
+{
+    while( m_readable < count  ) {
+        if( m_size < count) {
+            SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Acquired data size is larger than total available buffer space\n  --> This is a deadlock\n\n");
+        }
+        
+        reader_is_blocked = true;
+        sc_core::wait( m_data_released_event );
+        reader_is_blocked = false;
+    }
+    
+    m_acquired_data = count;
+}
+
+// non-bloking (re)acquire COUNT data in the channel
+template <class T>
+inline
+bool
+dol_fifo<T>::tryReAcquireData( int count ) {
+    if( m_readable < count  ) {
+        
+        if( m_size < count) {
+            SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Acquired data size is larger than total available buffer space \n\n");
+        }
+        return false;
+    }
+
+    m_acquired_data = count;
+    return true;
+}
+
+// load COUNT acquired data into a vector
+// from the read window starting at the position indicated by OFFSET
+template <class T>
+inline void dol_fifo<T>::load( int offset, T* vector, int count )
+{
+    // sanity checks
+    if( m_acquired_data <= 0) {
+        
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to load without acquiring the data\n  --> I ignore this action\n\n");
+        return;
+    }
+    
+    if( offset >  m_acquired_data - 1 ) {
+        
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to read beyond the acquired data: offset value may be too large\n  --> I ignore this action\n\n");
+        return;
+    }
+    
+    if( count >  m_acquired_data - offset ) {
+        
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to read beyound the acquired data: data size may be too large\n  --> I'm decreasing the data size\n\n");
+        count =  m_acquired_data - offset;
+       }
+    
+    
+    int ri = ( m_rwin_head + offset ) % m_size;
+    
+    for(int i=0; i<count; i++ ) {
+        vector[i] = m_buf[ri];
+        ri = ( ri + 1 ) % m_size;
+    }
+}
+
+// free up COUNT room in the channel (commit read)
+template <class T>
+inline void dol_fifo<T>::releaseRoom( int count ) 
+{
+    // sanity check
+    if( count > m_acquired_data ) {
+        SC_REPORT_WARNING(RP_ID_PARAMETER_PROBLEM, "Attempt to free up more room than was acquired\n  --> I'm decreasing the size of released room\n\n");
+        count = m_acquired_data;
+    }
+       
+    m_readable -= count;
+    m_released_room += count;
+    
+    m_acquired_data -= count;
+    m_rwin_head = ( m_rwin_head + count ) % m_size;
+
+    request_update();
+}
+
+
+
+
+// *** Other methods *** 
+
+
+template <class T>
+inline void dol_fifo<T>::update()
+{
+    if( m_released_room > 0 ) {
+        m_room_released_event.notify_delayed();
+    }
+    
+    if( m_released_data > 0 ) {
+        m_data_released_event.notify_delayed();
+    }
+
+    m_released_room = 0;
+    m_released_data = 0;
+}
+
+
+template <class T>
+inline void dol_fifo<T>::init( int size )
+{
+    if( size <= 0 ) {
+        SC_REPORT_ERROR( SC_ID_INVALID_FIFO_SIZE_, 0 );
+    }
+
+    m_size = size;
+    m_buf = new T[m_size];
+
+    m_readable = 0;
+       
+    m_acquired_room = 0;
+    m_acquired_data = 0;
+    
+    m_rwin_head = 0;
+    m_wwin_head = 0;
+    
+    m_released_data = 0;
+    m_released_room = 0;
+
+    m_reader = 0;
+    m_writer = 0;
+
+    reader_is_blocked = false;
+    writer_is_blocked = false;
+}
+
+
+template <class T>
+inline void dol_fifo<T>::register_port( sc_port_base& port_,
+                                        const char* if_typename_ )
+{
+    std::string nm( if_typename_ );
+    if( nm == typeid( dol_fifo_read_if<T> ).name() ) {
+       // only one reader can be connected
+       if( m_reader != 0 ) {
+           SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_READER_, 0 );
+       }
+       m_reader = &port_;
+    } else {  // nm == typeid( dol_fifo_write_if<T> ).name()
+       // only one writer can be connected
+       if( m_writer != 0 ) {
+           SC_REPORT_ERROR( SC_ID_MORE_THAN_ONE_FIFO_WRITER_, 0 );
+       }
+       m_writer = &port_;
+    }
+}
+
+
+
+template <class T>
+inline void dol_fifo<T>::trace( sc_trace_file* tf ) const
+{
+#ifdef DEBUG_SYSTEMC
+    char buf[32];
+    std::string nm = name();
+    for( int i = 0; i < m_size; ++ i ) {
+        sprintf( buf, "_%d", i );
+        sc_trace( tf, m_buf[i], nm + buf );
+    }
+#endif
+}
+
+
+template <class T>
+inline void dol_fifo<T>::print( ::std::ostream& os ) const
+{
+    if( m_readable ) {
+        for(int j=0, i = m_rwin_head; j<m_readable; j++) {
+//            os << m_buf[i] << ::std::endl;
+            os << m_buf[i];
+            i = ( i + 1 ) % m_size;
+        }
+    }
+    os << ::std::endl;
+}
+
+template <class T>
+inline void dol_fifo<T>::dump( ::std::ostream& os ) const
+{
+    os << "name = " << name() << ::std::endl;
+    if( m_readable ) {
+        for(int j=0, i = m_rwin_head; j<m_readable; j++) {
+            os << "value[" << j << "] = " << m_buf[i] << ::std::endl;
+            i = ( i + 1 ) % m_size;
+            
+        }
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+
+template <class T>
+inline ::std::ostream& operator << ( ::std::ostream& os, const dol_fifo<T>& a )
+{
+    a.print( os );
+    return os;
+}
+
+
+#endif
diff --git a/dol/src/dol/visitor/systemC/lib/dol_fifo_if.h b/dol/src/dol/visitor/systemC/lib/dol_fifo_if.h
new file mode 100644 (file)
index 0000000..04c6f4a
--- /dev/null
@@ -0,0 +1,90 @@
+/**************************************************************************\r
+       dol_fifo_if.h\r
\r
+       DOL FIFO channel interfaces   \r
+\r
+       (c) 2006 by Alexander Maxiaguine <maxiagui@tik.ee.ethz.ch>\r
+\r
+       Computer Engineering and Networks Laboratory, TIK\r
+       Swiss Federal Institute of Technology, ETHZ Zurich \r
+       Switzerland\r
+\r
+**************************************************************************/\r
+\r
+/**************************************************************************\r
+       Change Log:\r
+\r
+       14.03.06 -- creation\r
+\r
+**************************************************************************/\r
+\r
+#ifndef DOL_FIFO_IF_H\r
+#define DOL_FIFO_IF_H\r
+\r
+#include "systemc.h"\r
+\r
+\r
+template <class T>\r
+class dol_fifo_write_if : virtual public sc_interface\r
+{\r
+public:\r
+    \r
+    // bloking (re)acquire free room in the channel\r
+    virtual void reAcquireRoom(int count) = 0;\r
+    \r
+    // non-bloking (re)acquire free room in the channel\r
+    virtual bool tryReAcquireRoom(int count) = 0;\r
+    \r
+    // store data into the acquired free room\r
+    virtual void store(int offset, T* data, int count) = 0;\r
+    \r
+    // release the stored data to the channel (commit write)\r
+    virtual void releaseData(int count) = 0;\r
+\r
+    \r
+protected:\r
+    \r
+    // constructor\r
+    dol_fifo_write_if()        {}\r
+\r
+    \r
+private:\r
+\r
+    // disabled\r
+    dol_fifo_write_if( const dol_fifo_write_if<T>& );\r
+    dol_fifo_write_if<T>& operator = ( const dol_fifo_write_if<T>& );\r
+};\r
+\r
+template <class T>\r
+class dol_fifo_read_if : virtual public sc_interface\r
+{\r
+public:\r
+\r
+    // bloking (re)acquire data in the channel\r
+    virtual void reAcquireData(int count) = 0;\r
+\r
+    // non-bloking (re)acquire data in the channel\r
+    virtual bool tryReAcquireData(int count) = 0;\r
+    \r
+    // load the acquired data into a vector\r
+    virtual void load(int offset, T* vector, int count) = 0;\r
+    \r
+    // free up the room in the channel (commit read)\r
+    virtual void releaseRoom(int count) = 0;\r
+    \r
+    \r
+protected:\r
+    \r
+    // constructor\r
+    dol_fifo_read_if() {}\r
+\r
+    \r
+private:\r
+\r
+    // disabled\r
+    dol_fifo_read_if( const dol_fifo_read_if<T>& );\r
+    dol_fifo_read_if<T>& operator = ( const dol_fifo_read_if<T>& );\r
+};\r
+\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/systemC/lib/dol_rp_ids.h b/dol/src/dol/visitor/systemC/lib/dol_rp_ids.h
new file mode 100644 (file)
index 0000000..1bd44c5
--- /dev/null
@@ -0,0 +1,28 @@
+/**************************************************************************\r
+       dol_rp_ids.h\r
\r
+       Report IDs\r
+\r
+       (c) 2006 by Alexander Maxiaguine <maxiagui@tik.ee.ethz.ch>\r
+\r
+       Computer Engineering and Networks Laboratory, TIK\r
+       Swiss Federal Institute of Technology, ETHZ Zurich \r
+       Switzerland\r
+\r
+**************************************************************************/\r
+\r
+/**************************************************************************\r
+       Change Log:\r
+\r
+       14.03.06 -- creation\r
+\r
+**************************************************************************/\r
+\r
+#ifndef DOL_RP_IDS_H\r
+#define DOL_RP_IDS_H\r
+\r
+//----------------- REPORT IDs --------------------------      \r
+const int RP_ID_PARAMETER_PROBLEM      = 5000;\r
+\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/systemC/lib/dol_sched_if.h b/dol/src/dol/visitor/systemC/lib/dol_sched_if.h
new file mode 100644 (file)
index 0000000..1856731
--- /dev/null
@@ -0,0 +1,46 @@
+/**************************************************************************\r
+       dol_sched_if.h\r
\r
+       Scheduler interface for a DOL process    \r
+\r
+       (c) 2006 by Alexander Maxiaguine <maxiagui@tik.ee.ethz.ch>\r
+\r
+       Computer Engineering and Networks Laboratory, TIK\r
+       Swiss Federal Institute of Technology, ETHZ Zurich \r
+       Switzerland\r
+\r
+**************************************************************************/\r
+\r
+/**************************************************************************\r
+       Change Log:\r
+\r
+       14.03.06 -- creation\r
+\r
+**************************************************************************/\r
+\r
+#ifndef DOL_SCHED_IF_H\r
+#define DOL_SCHED_IF_H\r
+\r
+#include "systemc.h"\r
+\r
+\r
+class dol_sched_if \r
+{\r
+\r
+public:\r
+       virtual void initialize() = 0;\r
+       virtual int fire() = 0;\r
+\r
+\r
+protected:\r
+       dol_sched_if()  {}\r
+\r
+\r
+private:\r
+\r
+    // disabled\r
+    dol_sched_if( const dol_sched_if& );\r
+    dol_sched_if& operator = ( const dol_sched_if& );\r
+};\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/systemC/lib/simple_fifo.h b/dol/src/dol/visitor/systemC/lib/simple_fifo.h
new file mode 100644 (file)
index 0000000..d11aecf
--- /dev/null
@@ -0,0 +1,182 @@
+/*****************************************************************************
+
+  The following code is derived, directly or indirectly, from the SystemC
+  source code Copyright (c) 1996-2004 by all Contributors.
+  All Rights reserved.
+
+  The contents of this file are subject to the restrictions and limitations
+  set forth in the SystemC Open Source License Version 2.4 (the "License");
+  You may not use this file except in compliance with such restrictions and
+  limitations. You may obtain instructions on how to receive a copy of the
+  License at http://www.systemc.org/. Software distributed by Contributors
+  under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
+  ANY KIND, either express or implied. See the License for the specific
+  language governing rights and limitations under the License.
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  simple_fifo.cpp -- Simple SystemC 2.0 producer/consumer example.
+
+                     From "An Introduction to System Level Modeling in
+                     SystemC 2.0". By Stuart Swan, Cadence Design Systems.
+                     Available at www.systemc.org
+
+  Original Author: Stuart Swan, Cadence Design Systems, 2001-06-18
+
+ *****************************************************************************/
+
+/*****************************************************************************
+
+  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
+  changes you are making here.
+
+      Name, Affiliation, Date:
+  Description of Modification:
+
+ *****************************************************************************/
+
+#ifndef _SIMPLE_FIFO_H_
+#define _SIMPLE_FIFO_H_
+
+#include <systemc.h>
+
+class write_if : virtual public sc_interface
+{
+   public:
+     virtual void write(char) = 0;
+     virtual void reset() = 0;
+     virtual int wtest(int) = 0;
+};
+
+class read_if : virtual public sc_interface
+{
+   public:
+     virtual void read(char &) = 0;
+     virtual int num_available() = 0;
+     virtual int rtest(int) = 0;
+};
+
+class fifo : public sc_channel, public write_if, public read_if
+{
+   public:
+     fifo(sc_module_name name, int size)
+         : sc_channel(name), num_elements(0), first(0), max(size) {
+         data = new char[size];
+     }
+
+     void write(char c) {
+       if (num_elements == max)
+         wait(read_event);
+
+       data[(first + num_elements) % max] = c;
+       ++ num_elements;
+       write_event.notify();
+     }
+
+     void read(char &c){
+       if (num_elements == 0)
+         wait(write_event);
+
+       c = data[first];
+       -- num_elements;
+       first = (first + 1) % max;
+       read_event.notify();
+     }
+
+     int rtest(int size) { return (size <= num_elements) ? 1 : 0; }
+     int wtest(int size) { return (size <= max - num_elements) ? 1 : 0; }
+
+    
+     void reset() { num_elements = first = 0; }
+
+     int num_available() { return num_elements;}
+
+   private:
+     int max;
+     char *data;
+     int num_elements, first;
+     sc_event write_event, read_event;
+};
+
+
+#endif
+
+/*
+class producer : public sc_module
+{
+   public:
+     sc_port<write_if> out;
+
+     SC_HAS_PROCESS(producer);
+
+     producer(sc_module_name name) : sc_module(name)
+     {
+       SC_THREAD(main);
+     }
+
+     void main()
+     {
+       const char *str =
+         "Visit www.systemc.org and see what SystemC can do for you today!\n";
+
+       while (*str)
+         out->write(*str++);
+     }
+};
+
+class consumer : public sc_module
+{
+   public:
+     sc_port<read_if> in;
+
+     SC_HAS_PROCESS(consumer);
+
+     consumer(sc_module_name name) : sc_module(name)
+     {
+       SC_THREAD(main);
+     }
+
+     void main()
+     {
+       char c;
+       cout << endl << endl;
+
+       while (true) {
+         in->read(c);
+         cout << c << flush;
+
+         if (in->num_available() == 1)
+          cout << "<1>" << flush;
+         if (in->num_available() == 9)
+          cout << "<9>" << flush;
+       }
+     }
+};
+
+class top : public sc_module
+{
+   public:
+     fifo *fifo_inst;
+     producer *prod_inst;
+     consumer *cons_inst;
+
+     top(sc_module_name name) : sc_module(name)
+     {
+       fifo_inst = new fifo("Fifo1");
+
+       prod_inst = new producer("Producer1");
+       prod_inst->out(*fifo_inst);
+
+       cons_inst = new consumer("Consumer1");
+       cons_inst->in(*fifo_inst);
+     }
+};
+
+int sc_main (int argc , char *argv[]) {
+   top top1("Top1");
+   sc_start(-1);
+   return 0;
+}
+*/
diff --git a/dol/src/dol/visitor/systemC/package.html b/dol/src/dol/visitor/systemC/package.html
new file mode 100644 (file)
index 0000000..10fe852
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Code generator for SystemC functional simulation.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/visitor/xml/MapXmlVisitor.java b/dol/src/dol/visitor/xml/MapXmlVisitor.java
new file mode 100644 (file)
index 0000000..564715a
--- /dev/null
@@ -0,0 +1,193 @@
+/* $Id: MapXmlVisitor.java 1 2010-02-24 13:03:05Z haidw $ */\r
+package dol.visitor.xml;\r
+\r
+import dol.datamodel.XmlTag;\r
+import dol.datamodel.mapping.CommunicationBinding;\r
+import dol.datamodel.mapping.ComputationBinding;\r
+import dol.datamodel.mapping.Configuration;\r
+import dol.datamodel.mapping.Mapping;\r
+import dol.datamodel.mapping.Schedule;\r
+import dol.datamodel.mapping.ScheduleEntry;\r
+import dol.datamodel.mapping.SchedulingPolicy;\r
+import dol.datamodel.mapping.Variable;\r
+import dol.util.CodePrintString;\r
+import dol.visitor.MapVisitor;\r
+\r
+public class MapXmlVisitor extends MapVisitor {\r
+\r
+    /**\r
+     * Constructor.\r
+     *\r
+     * @param stringBuffer buffer where the result is stored\r
+     */\r
+    public MapXmlVisitor(StringBuffer stringBuffer) {\r
+        _ps = new CodePrintString(stringBuffer);\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @param x mapping that needs to be rendered.\r
+     */\r
+    public void visitComponent(Mapping x) {\r
+        String xmlns = dol.util.SchemaLocation.\r
+                getMappingNamespace();\r
+        String xsiLocation = dol.util.SchemaLocation.\r
+                getMappingSchemaLocation();\r
+\r
+        _ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");\r
+        _ps.printOpeningTag(_xt.getMappingTag());\r
+        _ps.println(" xmlns=\"" + xmlns\r
+                    + "\" xmlns:xsi=\"http://www.w3.org/2001/"\r
+                    + "XMLSchema-instance\""\r
+                    + System.getProperty("line.separator")\r
+                    + "  xsi:schemaLocation=\""\r
+                    + xmlns + " " + xsiLocation + "\" name=\""\r
+                    + x.getName() + "\">");\r
+\r
+        // Visit variables\r
+        for(Variable v : x.getVarList()) {\r
+            v.accept(this);\r
+        }\r
+\r
+        // Visit computation bindings\r
+        for(ComputationBinding b : x.getCompBindList()) {\r
+            b.accept(this);\r
+        }\r
+\r
+        // Visit communication bindings\r
+        for(CommunicationBinding b : x.getCommBindList()) {\r
+            b.accept(this);\r
+        }\r
+\r
+        // Visit schedules\r
+        for(Schedule s : x.getScheduleList()) {\r
+            s.accept(this);\r
+        }\r
+\r
+        _ps.printClosingTag(_xt.getMappingTag());\r
+    }\r
+\r
+    /**\r
+     * \r
+     */\r
+    public void visitComponent(ComputationBinding x) {\r
+        _ps.printOpeningTag(_xt.getBindingTag());\r
+        _ps.println(" name=\"" + x.getName()\r
+                + "\" xsi:type=\"computation\">");\r
+\r
+        // Process\r
+        _ps.printPrefix();\r
+        String s = "<" + _xt.getProcessTag()\r
+                + " name=\"" + x.getProcess().getName() + "\"/>";\r
+        _ps.println(s);\r
+\r
+        // Processor\r
+        _ps.printPrefix();\r
+        s = "<" + _xt.getProcessorTag()\r
+            + " name=\"" + x.getProcessor().getName() + "\"/>";\r
+        _ps.println(s);\r
+        _ps.printClosingTag(_xt.getBindingTag());\r
+    }\r
+\r
+    /**\r
+     * \r
+     */\r
+    public void visitComponent(CommunicationBinding x) {\r
+        _ps.printOpeningTag(_xt.getBindingTag());\r
+        _ps.println(" name=\"" + x.getName()\r
+                + "\" xsi:type=\"communication\">");\r
+\r
+        // SW channel\r
+        _ps.printPrefix();\r
+        String s = "<" + _xt.getSWChannelTag()\r
+                + " name=\"" + x.getChannel().getName() + "\"/>";\r
+        _ps.println(s);\r
+\r
+        // Write path\r
+        _ps.printPrefix();\r
+        s = "<" + _xt.getWritePathTag()\r
+                + " name=\"" + x.getWritePath().getName() + "\"/>";\r
+        _ps.println(s);\r
+\r
+        // Read path\r
+        _ps.printPrefix();\r
+        s = "<" + _xt.getReadPathTag()\r
+            + " name=\"" + x.getReadPath().getName() + "\"/>";\r
+        _ps.println(s);\r
+\r
+        _ps.printClosingTag(_xt.getBindingTag());\r
+    }\r
+\r
+    /**\r
+     * \r
+     */\r
+    public void visitComponent(Schedule x) {\r
+        _ps.printOpeningTag(_xt.getScheduleTag());\r
+        _ps.println(" name=\"" + x.getName()\r
+                + "\" type=\""\r
+                + SchedulingPolicy.toString(x.getSchedPolicy()) + "\">");\r
+\r
+        // Resource\r
+        _ps.printPrefix();\r
+        String s = "<" + _xt.getResourceTag()\r
+                + " name=\"" + x.getResource().getName() + "\"/>";\r
+        _ps.println(s);\r
+\r
+        // Scheduler table entries\r
+        for (ScheduleEntry p : x.getEntryList()) {\r
+            p.accept(this);\r
+        }\r
+\r
+        // Configuration of schedule\r
+        for (Configuration c : x.getCfgList()) {\r
+            c.accept(this);\r
+        }\r
+\r
+        _ps.printClosingTag(_xt.getScheduleTag());\r
+    }\r
+\r
+    /**\r
+     * \r
+     */\r
+    public void visitComponent(ScheduleEntry x) {\r
+        if (x.getCfgList().size() == 0) {\r
+            _ps.printPrefixln("<" + _xt.getOriginTag() + " name=\""\r
+                    + x.getName() + "\"/>");\r
+        } else {\r
+            _ps.printOpeningTag(_xt.getOriginTag());\r
+            _ps.println(" name=\"" + x.getName() + "\">");\r
+    \r
+            // Configuration of the scheduler entry\r
+            for (Configuration c : x.getCfgList()) {\r
+                c.accept(this);\r
+            }\r
+\r
+           _ps.printClosingTag(_xt.getOriginTag());\r
+        }\r
+    }\r
+\r
+    /**\r
+     * \r
+     */\r
+    public void visitComponent(Variable x) {\r
+        _ps.printPrefix();\r
+        String s = "<" + _xt.getVariableTag()\r
+                + " name=\"" + x.getName() + "\""\r
+                + " value=\"" + Integer.toString(x.getValue()) + "\"/>";\r
+        _ps.println(s);\r
+    }\r
+\r
+    /**\r
+     * \r
+     */\r
+    public void visitComponent(Configuration x) {\r
+        _ps.printPrefix();\r
+        String s = "<" + _xt.getConfigurationTag()\r
+                + " name=\"" + x.getName() + "\""\r
+                + " value=\"" + x.getValue() + "\"/>";\r
+        _ps.println(s);\r
+    }\r
+\r
+    protected CodePrintString _ps = null;\r
+    protected XmlTag _xt = XmlTag.getInstance();\r
+}\r
diff --git a/dol/src/dol/visitor/xml/PNXmlVisitor.java b/dol/src/dol/visitor/xml/PNXmlVisitor.java
new file mode 100644 (file)
index 0000000..19666e0
--- /dev/null
@@ -0,0 +1,217 @@
+/* $Id: PNXmlVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.xml;
+
+import dol.datamodel.XmlTag;
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Configuration;
+import dol.datamodel.pn.Connection;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.ProfilingConfiguration;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintString;
+import dol.visitor.PNVisitor;
+
+/**
+ * This is a class for a visitor that is used to generate
+ * a schema compatible XML for process network.
+ */
+public class PNXmlVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     *
+     * @param stringBuffer buffer where the result is stored
+     */
+    public PNXmlVisitor(StringBuffer stringBuffer) {
+        _ps = new CodePrintString(stringBuffer);
+    }
+
+    /**
+     *
+     * @param x process network that needs to be rendered.
+     */
+    public void visitComponent(ProcessNetwork x) {
+        String xmlns = dol.util.SchemaLocation.
+                getProcessNetworkNamespace();
+        String xsiLocation = dol.util.SchemaLocation.
+                getProcessNetworkSchemaLocation();
+
+
+        _ps.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        _ps.printOpeningTag(_xt.getPNTag());
+        _ps.println(" xmlns=\"" + xmlns
+                    + "\" xmlns:xsi=\"http://www.w3.org/2001/"
+                    + "XMLSchema-instance\""
+                    + System.getProperty("line.separator")
+                    + "  xsi:schemaLocation=\""
+                    + xmlns + " " + xsiLocation + "\" name=\""
+                    + x.getName() + "_annotated" + "\">");
+
+        //visit all processes
+        for (Process p : x.getProcessList()) {
+            p.accept(this);
+        }
+        _ps.println();
+
+        //visit all channels
+        for (Channel c : x.getChannelList()) {
+            c.accept(this);
+        }
+        _ps.println();
+
+        //visit all connections
+        for (Connection n : x.getConnectionList()) {
+            n.accept(this);
+        }
+
+        _ps.printClosingTag(_xt.getPNTag());
+    }
+
+    /**
+     * Print a line for the process in the correct format for XML.
+     *
+     * @param x process that needs to be rendered
+     */
+    public void visitComponent(Process x) {
+        _ps.printOpeningTag(_xt.getProcessTag());
+        _ps.println(" name=\"" + x.getName()
+                    + "\" basename=\"" + x.getBasename()
+                    + "\" range=\"" + x.getRange()
+                    + "\">");
+
+        for (Port p : x.getPortList()) {
+            p.accept(this);
+        }
+
+        for (SourceCode s : x.getSrcList()) {
+            s.accept(this);
+        }
+
+        for (Configuration c : x.getCfgList()) {
+            c.accept(this);
+        }
+
+        for (ProfilingConfiguration c : x.getProfilingList()) {
+            c.accept(this);
+        }
+
+        _ps.printClosingTag(_xt.getProcessTag());
+    }
+
+    /**
+     * Print a line for the channel in the correct format for XML.
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Channel x) {
+        _ps.printOpeningTag(_xt.getSWChannelTag());
+        _ps.println(" name=\"" + x.getName()
+                    + "\" basename=\"" + x.getBasename()
+                    + "\" type=\"" + x.getType()
+                    + "\" size=\"" + x.getSize()
+                    + "\">");
+
+        for (Port p : x.getPortList()) {
+            p.accept(this);
+        }
+
+        for (Configuration c : x.getCfgList()) {
+            c.accept(this);
+        }
+
+        for (ProfilingConfiguration c : x.getProfilingList()) {
+            c.accept(this);
+        }
+
+        _ps.printClosingTag(_xt.getSWChannelTag());
+    }
+
+    /**
+     * Print a line for the connection in the correct format for XML.
+     *
+     * @param x channel that needs to be rendered
+     */
+    public void visitComponent(Connection x) {
+        _ps.printOpeningTag(_xt.getConnectionTag());
+        _ps.println(" name=\"" + x.getName() + "\">");
+
+        //origin
+        _ps.printOpeningTag("origin");
+        _ps.println(" name=\"" + x.getOrigin().getName() + "\">");
+        _ps.println("          <port name=\""
+                + x.getOriginPort().getName() + "\"/>");
+        _ps.printClosingTag("origin");
+
+        //target
+        _ps.printOpeningTag("target");
+        _ps.println(" name=\"" + x.getTarget().getName() + "\">");
+        _ps.println("          <port name=\""
+                + x.getTargetPort().getName() + "\"/>");
+        _ps.printClosingTag("target");
+        _ps.printClosingTag("connection");
+    }
+
+    /**
+     * Print a line for the port in the correct format for XML.
+     *
+     * @param x port that needs to be rendered
+     */
+    public void visitComponent(Port x) {
+        _ps.printPrefix();
+        String s = "<" + _xt.getPortTag() 
+            + " name=\"" + x.getName()
+            + "\" basename=\"" + x.getBasename()
+            + "\" range=\"" + x.getRange()
+            + "\"";
+        if (!x.getType().equals(""))
+            s += " type=\"" + x.getType() + "\"";
+        s +=  " />";
+
+        _ps.println(s);
+    }
+
+    /**
+     * Print a line for the source code in the correct format for XML.
+     *
+     * @param x source that needs to be rendered
+     */
+    public void visitComponent(SourceCode x) {
+        _ps.printPrefix();
+        _ps.println("<" + _xt.getSourceTag()
+                    + " type=\"" + x.getType()
+                    + "\" location=\"" + x.getLocality()
+                    + "\" />");
+    }
+
+    /**
+     * Print a line for the configuration in the correct format for XML.
+     *
+     * @param x configuration that needs to be rendered
+     */
+    public void visitComponent(Configuration x) {
+        _ps.printPrefix();
+        _ps.println("<" + _xt.getConfigurationTag()
+                    + " name=\"" + x.getName()
+                    + "\" value=\"" + x.getValue()
+                    + "\" />");
+    }
+    
+    /**
+     * Print a line for the profiling configuration in the correct format for XML.
+     *
+     * @param x configuration that needs to be rendered
+     */
+    public void visitComponent(ProfilingConfiguration x) {
+        _ps.printPrefix();
+        _ps.println("<" + _xt.getProfilingTag()
+                    + " name=\"" + x.getName()
+                    + "\" value=\"" + x.getValue()
+                    + "\" />");
+    }
+
+    protected CodePrintString _ps = null;
+    
+    protected XmlTag _xt = XmlTag.getInstance();
+}
diff --git a/dol/src/dol/visitor/xml/package.html b/dol/src/dol/visitor/xml/package.html
new file mode 100644 (file)
index 0000000..a476417
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Schema compatible XML generator for process network.
+
+Maybe for architecture and mapping in the future.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol/visitor/yapi/YapiMakefileVisitor.java b/dol/src/dol/visitor/yapi/YapiMakefileVisitor.java
new file mode 100644 (file)
index 0000000..5103ec9
--- /dev/null
@@ -0,0 +1,76 @@
+/* $Id: YapiMakefileVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.yapi;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class YapiMakefileVisitor extends PNVisitor {
+
+    /**
+     *
+     */
+    public YapiMakefileVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            String filename = _dir + _delimiter + "Makefile";
+            OutputStream file = new FileOutputStream(filename);
+            PrintStream ps = new PrintStream(file);
+            ps.println("YAPI = /lib/yapi");
+            ps.println("INCLUDES = -I$(YAPI)/include -Iwrappers -Ilib -Iprocesses -I.");
+            ps.println("LIBS = $(YAPI)/lib/libyapi.a");
+            ps.println("CXX = g++");
+            ps.println("CXXFLAGS = -g -Wall -O $(INCLUDES)");
+            ps.println("OBJS = application.o  \\");
+            Vector<String> processList = new Vector<String>();
+            for (Process p : pn.getProcessList()) {
+                String basename = p.getBasename();
+                if (!processList.contains(basename)) {
+                    processList.add(basename);
+                    ps.println("       wrappers/" + p.getBasename()
+                            + "_wrapper.o \\");
+                }
+            }
+            ps.println("       lib/dolSupport.o \\");
+            ps.println("       lib/ProcessWrapper.o \\");
+            ps.println("       lib/main.o");
+            ps.println();
+            ps.println("EXE = ./sc_application");
+            ps.println();
+            ps.println("all : $(EXE)");
+            ps.println();
+            ps.println("test : $(EXE)");
+            ps.println("\t@$(EXE)");
+            ps.println();
+            ps.println("$(EXE) : $(OBJS)");
+            ps.println("\t$(CXX) $(LDFLAGS) $(OBJS) $(LIBS) -o $(EXE)");
+            ps.println();
+            ps.println("clean : ;");
+            ps.println("\trm -rf $(OBJS) $(EXE)");
+        }
+        catch (IOException e) {
+            System.out.println(" Yapi Makefile Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected String _dir = null;
+    protected String _name = "sc_application";
+}
+
diff --git a/dol/src/dol/visitor/yapi/YapiModuleVisitor.java b/dol/src/dol/visitor/yapi/YapiModuleVisitor.java
new file mode 100644 (file)
index 0000000..bf2f699
--- /dev/null
@@ -0,0 +1,126 @@
+/* $Id: YapiModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.yapi;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.CodePrintStream;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * the main program.
+ */
+public class YapiModuleVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public YapiModuleVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+     * 
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            //create header file
+            String filename = _dir + _delimiter + "application.h";
+            OutputStream file = new FileOutputStream(filename);
+            _code = new CodePrintStream(file);
+
+            _code.println("#include \"yapi.h\"");
+            _code.println();
+
+            Vector<String> processList = new Vector<String>();
+            for (Process p : pn.getProcessList()) {
+                String basename = p.getBasename();
+                if (!processList.contains(basename)) {
+                    processList.add(basename);
+                    _code.println("#include \""
+                            + p.getBasename() + "_wrapper.h\"");
+                }
+            }
+            _code.println();
+            _code.println("class Application : public ProcessNetwork");
+            _code.println("{");
+            _code.println("public:");
+            _code.println("  Application(const Id& n);");
+            _code.println("  const char* type() const;");
+            _code.println();
+            _code.println("private:");
+
+            for (Channel c : pn.getChannelList()) {
+                if (c.getType().equals("fifo")) {
+                    _code.println("  Fifo<char> " + c.getName()
+                        + ";");
+                } else if (c.getType().equals("wfifo")) {
+                    System.out.println("Warning: YAPI visitor does not "
+                        + "support windowed FIFOs.");
+                }
+            }
+            _code.println();
+
+            for (Process p : pn.getProcessList()) {
+                _code.println("  " + p.getBasename() + "_wrapper "
+                        + p.getName() + ";");
+            }
+            _code.println("};");
+            file.close();
+
+
+            //create cpp file
+            filename = _dir + _delimiter + "application.cpp";
+            file = new FileOutputStream(filename);
+            _code = new CodePrintStream(file);
+
+            _code.println("#include \"application.h\"");
+            _code.println();
+            _code.println("Application::Application(const Id& n) :");
+            _code.print("  ProcessNetwork(n)");
+            for (Channel c : pn.getChannelList()) {
+                if (c.getType().equals("fifo")) {
+                    _code.print(",\n  " + c.getName() + "(id(\""
+                        + c.getName() + "\"))");
+                } else if (c.getType().equals("wfifo")) {
+                    System.out.println("Warning: YAPI visitor does not "
+                        + "support windowed FIFOs.");
+                }
+            }
+            for (Process p : pn.getProcessList()) {
+                _code.print(",\n  " + p.getName() + "(\""
+                        + p.getName() + "\", id(\"" + p.getName()
+                        + "\")");
+
+                for (Port port : p.getPortList()) {
+                    _code.print(", " + port.getPeerResource().getName());
+                }
+                _code.print(")");
+            }
+            _code.println();
+            _code.println("{ }");
+            _code.println();
+            _code.println("const char* Application::type() const");
+            _code.println("{");
+            _code.println("  return \"Application\";");
+            _code.println("}");
+        }
+        catch (Exception e) {
+            System.out.println("YapiModuleVisitor: "
+                    + "exception occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    protected CodePrintStream _code = null;
+    protected String _dir = null;
+    protected OutputStream _file;
+    protected CodePrintStream _pn;
+}
+
diff --git a/dol/src/dol/visitor/yapi/YapiProcessVisitor.java b/dol/src/dol/visitor/yapi/YapiProcessVisitor.java
new file mode 100644 (file)
index 0000000..660f540
--- /dev/null
@@ -0,0 +1,309 @@
+/* $Id: YapiProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.yapi;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class YapiProcessVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public YapiProcessVisitor(String dir) {
+        _dir = dir;
+    }
+
+    /**
+    *
+    * @param x process network that needs to be rendered
+    */
+   public void visitComponent(ProcessNetwork x) {
+       try {
+           Vector<String> pList = new Vector<String>();
+
+           for (Process p : x.getProcessList()) {
+               String basename = p.getBasename();
+               if (!pList.contains(basename)) {
+                   pList.add(basename);
+                   p.accept(this);
+               }
+           }
+       }
+       catch (Exception e) {
+           System.out.println("Process Visitor: exception "
+                   + "occured: " + e.getMessage());
+           e.printStackTrace();
+       }
+   }
+
+   /**
+    *
+    * @param p process that needs to be rendered
+    */
+   public void visitComponent(Process p) {
+       try {
+           _createCppFile(p);
+           _createHeaderFile(p);
+           _adaptSources(p);
+       }
+       catch (Exception e) {
+           System.out.println("Process Visitor: exception "
+                   + "occured: " + e.getMessage());
+           e.printStackTrace();
+       }
+   }
+
+   /**
+    *
+    */
+   protected void _adaptSources(Process p) throws IOException {
+       Sed sed = new Sed();
+       for (Port port : p.getPortList()) {
+           String processHeaderFile;
+
+           for (SourceCode sr : p.getSrcList()) {
+               processHeaderFile = _dir + _delimiter + ".."
+                       + _delimiter + "processes" + _delimiter
+                       + sr.getLocality().
+                       replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+               if (port.isOutPort()) {
+                   sed.sed(processHeaderFile,
+                           "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                           + port.getBasename() + "\"?",
+                           "$1 " + "(const_cast<void *>((const void*)"
+                           +"(((static_cast<" + p.getBasename()
+                           + "_wrapper *>(p->wptr))->OUTPORT_"
+                           + port.getBasename() + "))))");
+               }
+               else if (port.isInPort()) {
+                   sed.sed(processHeaderFile,
+                           "(#define[ ]*PORT_\\w*[ ]*)\"?"
+                           + port.getBasename() + "\"?",
+                           "$1 " + "(const_cast<void *>((const void*)"
+                           +"(((static_cast<" + p.getBasename()
+                           + "_wrapper *>(p->wptr))->INPORT_"
+                           + port.getBasename() + "))))");
+               }
+           }
+       }
+   }
+   
+   /**
+    *
+    */
+   protected void _createCppFile(Process p) throws IOException {
+       String filename = _dir + _delimiter + p.getBasename()
+               + "_wrapper.cpp";
+       OutputStream file = new FileOutputStream(filename);
+       CodePrintStream ps = new CodePrintStream(file);
+
+       String newline = System.getProperty("line.separator");
+       String code = "#include \"" + p.getBasename() + "_wrapper.h\""
+               + newline;
+       code += "#include \"dolSupport.h\"" + newline;
+       for (SourceCode sr : p.getSrcList()) {
+           code += "#include \"" + sr.getLocality() + "\"" + newline;
+       }
+       
+       code += newline;
+
+       code += p.getBasename() + "_wrapper::" + p.getBasename()
+               + "_wrapper(const char* name, const Id& n";
+       for (Port port : p.getPortList()) {
+           if (port.isInPort()) {
+               code += ", In<char>& inport_" + port.getName();
+           } else {
+               code += ", Out<char>& outport_" + port.getName();
+           }
+       }
+       code += ")" + newline;
+
+       code += " : ProcessWrapper(name, n)" + newline;
+       code += " {" + newline;
+       code += "    _state = (LocalState)new "
+               + p.getBasename().substring(0, 1).toUpperCase()
+               + p.getBasename().substring(1) + "_State;"
+               + newline;
+       code += "    _process.local = _state;"  + newline; 
+       code += "    _process.init = " + p.getBasename() + "_init;"
+               + newline;
+       code += "    _process.fire = " + p.getBasename() + "_fire;"
+               + newline;
+       code += "    _process.wptr = this;" + newline;
+       for (Port port : p.getPortList()) {
+           if (!port.getRange().equals("")) {
+               String portName =
+                   port.getName().replaceAll("_([0-9])", "][$1");
+               portName += "]";
+               portName = portName.replaceFirst("]", "");
+               if (port.isOutPort()) {
+                   code += "    OUTPORT_" + portName
+                           + " = new OutPort<char>(id(\"" + port.getName()
+                           + "\"), outport_" + port.getName() + ");"
+                           + newline;
+               }
+               else if (port.isInPort()) {
+                   code += "    INPORT_" + portName
+                           + " = new InPort<char>(id(\"" + port.getName()
+                           + "\"), inport_" + port.getName() + ");"
+                           + newline;
+               }
+           } else {
+               if (port.isInPort()) {
+                   code += "    INPORT_" + port.getName()
+                           + " = new InPort<char>(id(\"" + port.getName()
+                           + "\"), inport_" + port.getName() + ");"
+                           + newline;
+               } else {
+                   code += "    OUTPORT_" + port.getName()
+                           + " = new OutPort<char>(id(\"" + port.getName()
+                           + "\"), outport_" + port.getName() + ");"
+                           + newline;
+               }
+           }
+       }
+       code += "}" + newline + newline;
+
+       code += p.getBasename() + "_wrapper::~" + p.getBasename()
+               + "_wrapper() {" + newline;
+       code += "    if (_state)" + newline;
+       code += "        delete ("
+               + p.getBasename().substring(0, 1).toUpperCase()
+               + p.getBasename().substring(1) + "_State*)_state;"
+               + newline;
+       for (Port port : p.getPortList()) {
+           if (!port.getRange().equals("")) {
+               String portName =
+                   port.getName().replaceAll("_([0-9])", "][$1");
+               portName += "]";
+               portName = portName.replaceFirst("]", "");
+               if (port.isOutPort()) {
+                   code += "    if (OUTPORT_" + portName + ")" + newline;
+                   code += "        delete OUTPORT_" + portName + ";"
+                           + newline;
+               }
+               else if (port.isInPort()) {
+                   code += "    if (INPORT_" + portName + ")" + newline;
+                   code += "        delete INPORT_" + portName + ";"
+                           + newline;
+               }
+           } else {
+               if (port.isInPort()) {
+                   code += "    if(INPORT_" + port.getName() + ")"
+                           + newline;
+                   code += "        delete INPORT_" + port.getName() + ";"
+                           + newline;
+               } else {
+                   code += "    if(OUTPORT_" + port.getName() + ")"
+                           + newline;
+                   code += "        delete OUTPORT_" + port.getName() + ";"
+                           + newline;
+               }
+           }
+       }
+       code += "}" + newline + newline;
+       
+       code += "const char* "
+               + p.getBasename() + "_wrapper::type() const {" + newline;
+       code += "    return \"" + p.getName() + "\";" + newline;
+       code += "}" + newline + newline;
+
+       code += "void " + p.getBasename() + "_wrapper::main() {" + newline;
+       code += "    _process.init(&_process);" + newline;
+       code += "    while(!isDetached()) {" + newline;
+       code += "        _process.fire(&_process);" + newline;
+       code += "    }" + newline;
+       code += "}" + newline;
+       ps.printPrefixln(code);
+   }
+
+   protected void _createHeaderFile(Process p)
+       throws IOException {
+       String filename = _dir + _delimiter + p.getBasename()
+               + "_wrapper.h";
+       OutputStream file = new FileOutputStream(filename);
+       CodePrintStream ps = new CodePrintStream(file);
+
+       String newline = System.getProperty("line.separator");
+       String code = "#ifndef " + p.getBasename() + "_WRAPPER_H"
+               + newline;
+       code += "#define " + p.getBasename() + "_WRAPPER_H" + newline
+               + newline;
+       code += "#include \"ProcessWrapper.h\"" + newline; 
+       code += newline;
+
+       code += "class " + p.getBasename() + "_wrapper : "
+               + "public ProcessWrapper {" + newline;
+       code += "    public:" + newline;
+       code += "        " + p.getBasename()
+               + "_wrapper(const char* name, const Id& n";
+       for (Port port : p.getPortList()) {
+           if (port.isInPort()) {
+               code += ", In<char>& inport_" + port.getName();
+           } else {
+               code += ", Out<char>& outport_" + port.getName();
+           }
+       }
+       code += ");" + newline;
+       code += "        virtual ~" + p.getBasename() + "_wrapper();"
+               + newline;
+       code += "        const char* type() const;" + newline;
+       code += "        void main();" + newline + newline;
+
+       Vector<String> portList = new Vector<String>();
+       for (Port port : p.getPortList()) {
+           String basename = port.getBasename();
+
+           if (!portList.contains(basename)) {
+               portList.add(basename);
+
+               if (!port.getRange().equals("")) {
+                   if (port.isOutPort()) {
+                       code += "        OutPort<char> *OUTPORT_"
+                               + port.getBasename() + "["
+                               + port.getRange().replaceAll(
+                               ";", "\\]\\[") + "];" + newline;
+                   }
+                   else if (port.isInPort()) {
+                       code += "        InPort<char> *INPORT_"
+                               + port.getBasename() + "["
+                               + port.getRange().replaceAll(
+                               ";", "\\]\\[") + "];" + newline;
+                   }
+               }
+               else {
+                   if (port.isOutPort()) {
+                       code += "        OutPort<char> *OUTPORT_"
+                               + port.getName() + ";" + newline;
+                   }
+                   else if (port.isInPort()) {
+                       code += "        InPort<char> *INPORT_"
+                               + port.getName() + ";" + newline;
+                   }
+               }
+           }
+       }
+       code += newline;
+       code += "    protected:" + newline;
+       code += "        LocalState _state;" + newline;
+       code += "};" + newline + newline;
+       code += "#endif";
+       ps.printPrefixln(code);
+   }
+
+   protected String _dir = null;
+}
diff --git a/dol/src/dol/visitor/yapi/YapiVisitor.java b/dol/src/dol/visitor/yapi/YapiVisitor.java
new file mode 100644 (file)
index 0000000..3815727
--- /dev/null
@@ -0,0 +1,95 @@
+/* $Id: YapiVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.yapi;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class YapiVisitor extends PNVisitor {
+
+    /**
+     * Constructor.
+     */
+    public YapiVisitor(String packageName) {
+        _packageName = packageName;
+    }
+
+    /**
+     *
+     */
+    public void visitComponent(ProcessNetwork pn) {
+        try {
+            _generateDirHierarchy();
+
+            pn.accept(new YapiMakefileVisitor(_srcDir));
+            pn.accept(new YapiModuleVisitor(_srcDir));
+            pn.accept(new YapiProcessVisitor(_wrapperDir));
+
+        } catch (Exception e) {
+            System.out.println(" SystemC PN Visitor: exception " +
+                               "occured: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     *
+     */
+    private void _generateDirHierarchy()
+        throws IOException, FileNotFoundException {
+
+        File dir = new File(_packageName);
+        dir.mkdirs();
+
+        _srcDir = _packageName + _delimiter + _srcDirName;
+        dir = new File(_srcDir);
+        dir.mkdirs();
+
+        _libDir = _srcDir + _delimiter + _libDirName;
+        dir = new File(_libDir);
+        dir.mkdirs();
+
+        _processDir = _srcDir + _delimiter + _processDirName;
+        dir = new File(_processDir);
+        dir.mkdirs();
+
+        _wrapperDir = _srcDir + _delimiter + _wrapperDirName;
+        dir = new File(_wrapperDir);
+        dir.mkdirs();
+
+        // copy library
+        String libraryPath = _ui.getMySystemCLib();
+        libraryPath = libraryPath.replaceAll("systemC",
+                "yapi");
+        File source = new File(libraryPath);
+        File destination = new File(_libDir);
+        new Copier().copy(source, destination);
+
+        //copy process src code
+        source = new File(_srcDirName);
+        destination = new File(_processDir);
+        new Copier().copy(source, destination);
+    }
+
+    protected String _packageName = null;
+
+    protected String _srcDir = "";
+    protected static String _srcDirName = "src";
+
+    protected String _libDir = "";
+    protected static String _libDirName = "lib";
+
+    protected String _processDir = "";
+    protected static String _processDirName = "processes";
+
+    protected String _wrapperDir = "";
+    protected static String _wrapperDirName = "wrappers";
+}
+
diff --git a/dol/src/dol/visitor/yapi/lib/ProcessWrapper.cpp b/dol/src/dol/visitor/yapi/lib/ProcessWrapper.cpp
new file mode 100644 (file)
index 0000000..de28efe
--- /dev/null
@@ -0,0 +1,107 @@
+#include "ProcessWrapper.h"\r
+#include "dolSupport.h"\r
+\r
+/**\r
+ *\r
+ */\r
+ProcessWrapper::ProcessWrapper(const char* name, const Id& n) : Process(n) {\r
+    _name = new char[strlen(name) + 1];\r
+    strcpy(_name, name);\r
+\r
+    _isDetached = false;\r
+    for (int i = 0; i < 4; i++) {\r
+        _iteratorIndex[i] = getIndex(_name, "_", i);\r
+    }\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+ProcessWrapper::~ProcessWrapper() {\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void ProcessWrapper::initialize() {\r
+    _process.init(&_process);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+int ProcessWrapper::fire()\r
+{\r
+    return _process.fire(&_process);\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void ProcessWrapper::detach() {\r
+    _isDetached = true;\r
+}\r
+\r
+\r
+/**\r
+ * Gets an index of a string, where the index must be separated by\r
+ * a character specified in tokens.\r
+ * Returns -1, when an error occurs.\r
+ *\r
+ * Example:\r
+ * getIndex("name_1_2", "_", 0) will return 1.\r
+ * getIndex("name_1_2", "_", 1) will return 2.\r
+ *\r
+ * @param string string to parse\r
+ * @param tokens delimiter of indices\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int ProcessWrapper::getIndex(const char* string, char* tokens,\r
+        int indexNumber) const {\r
+    char* string_copy;\r
+    char* token_pointer;\r
+    int index = 0;\r
+\r
+    string_copy = (char*) malloc(sizeof(char) * (strlen(string) + 1));\r
+    if (!string_copy) {\r
+        fprintf(stderr, "getIndex(): could not allocate memory.\n");\r
+        return -1;\r
+    }\r
+\r
+    strcpy(string_copy, string);\r
+\r
+    token_pointer = strtok(string_copy, tokens);\r
+    do {\r
+        token_pointer = strtok(NULL, tokens);\r
+        index++;\r
+    } while (index <= indexNumber && token_pointer != 0);\r
+\r
+    if (token_pointer) {\r
+        index = atoi(token_pointer);\r
+        free(string_copy);\r
+        return index;\r
+    }\r
+\r
+    return -1;\r
+}\r
+\r
+\r
+/**\r
+ * Get the name of this process.\r
+ */\r
+char* ProcessWrapper::getName() const {\r
+    return _name;\r
+}\r
+\r
+\r
+/**\r
+ * Get the index of this process.\r
+ * @param indexNumber position of index (starting at 0)\r
+ */\r
+int ProcessWrapper::getIndex(unsigned indexNumber) const {\r
+    if (indexNumber < 4) {\r
+        return _iteratorIndex[indexNumber];\r
+    }\r
+    return -1;\r
+}\r
diff --git a/dol/src/dol/visitor/yapi/lib/ProcessWrapper.h b/dol/src/dol/visitor/yapi/lib/ProcessWrapper.h
new file mode 100644 (file)
index 0000000..bdecd34
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _PROCESSWRAPPER_H_\r
+#define _PROCESSWRAPPER_H_\r
+\r
+#include "dol.h"\r
+#include "yapi.h"\r
+\r
+class ProcessWrapper : public Process\r
+{\r
+    public:\r
+        ProcessWrapper(const char* name, const Id& n);\r
+        virtual ~ProcessWrapper();\r
+        virtual void initialize();\r
+        virtual int fire();\r
+        virtual bool isDetached() const { return _isDetached; }\r
+        virtual void detach();\r
+        virtual int getIndex(unsigned indexNumber) const;\r
+        virtual char* getName() const;\r
+\r
+    protected:\r
+        char* _name;\r
+        DOLProcess _process;\r
+        bool _isDetached;\r
+        int _iteratorIndex[4];\r
+        virtual int getIndex(const char* string, char* tokens,\r
+                int indexNumber) const;\r
+};\r
+\r
+#endif\r
+\r
diff --git a/dol/src/dol/visitor/yapi/lib/dol.h b/dol/src/dol/visitor/yapi/lib/dol.h
new file mode 100644 (file)
index 0000000..8fbefe4
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef DOL_H
+#define DOL_H
+
+/************************************************************************
+ * do not add code to this header
+ ************************************************************************/
+
+/**
+ *  Define the DOL process handler scheme.
+ *  - Local variables are defined in structure LocalState. Local
+ *    variables may vary from different processes.
+ *  - The ProcessInit function pointer points to a function which
+ *    initializes a process.
+ *  - The ProcessFire function pointer points to a function which
+ *    performs the actual computation. The communication between
+ *    processes is inside the ProcessFire function.
+ *  - The WPTR is a placeholder for callback. One can just
+ *    leave it blank.
+ */
+
+//structure for local memory of process
+typedef struct _local_states *LocalState;
+
+//additional behavioral functions could be declared here
+typedef void (*ProcessInit)(struct _process*);
+typedef int (*ProcessFire)(struct _process*);
+typedef void *WPTR;
+
+//process handler
+struct _process;
+
+typedef struct _process {
+    LocalState     local;
+    ProcessInit    init;
+    ProcessFire    fire;
+    WPTR           wptr; //placeholder for wrapper instance
+} DOLProcess;
+
+#endif
diff --git a/dol/src/dol/visitor/yapi/lib/dolSupport.cpp b/dol/src/dol/visitor/yapi/lib/dolSupport.cpp
new file mode 100644 (file)
index 0000000..164e1a6
--- /dev/null
@@ -0,0 +1,81 @@
+#include "dolSupport.h"\r
+#include "ProcessWrapper.h"\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned dolwrite(OutPort<char> *out, const void *buf, unsigned len, const DOLProcess *process)\r
+{\r
+    write(*out, (char*)buf, len);\r
+    return len;\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned dolread(InPort<char> *in, const void *buf, unsigned len, const DOLProcess *process) {\r
+    read(*in, (char*)buf, len);\r
+    return len;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+void DOL_detach(DOLProcess* p) {\r
+    static_cast<ProcessWrapper *>(p->wptr)->detach();\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0) {\r
+    *port = (void**)((void**)base)[index0];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1) {\r
+    *port = (void**)((void**)base)[index0 * range1 + index1];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2\r
+                       + index1 * range2 + index2];\r
+}\r
+\r
+\r
+/**\r
+ *\r
+ */\r
+void createPort(void** port,\r
+                void* base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3) {\r
+    *port = (void**)((void**)base)[index0 * range1 * range2 * range3\r
+                       + index1 * range2 * range3\r
+                       + index2 * range3\r
+                       + index3];\r
+}\r
diff --git a/dol/src/dol/visitor/yapi/lib/dolSupport.h b/dol/src/dol/visitor/yapi/lib/dolSupport.h
new file mode 100644 (file)
index 0000000..897516f
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef DOLSUPPORT_H\r
+#define DOLSUPPORT_H\r
+\r
+#include "dol.h"\r
+#include "yapi.h"\r
+\r
+#define DOL_write(port, buf, len, process) \\r
+    dolwrite(static_cast<OutPort<char> *>(port), buf, len, process)\r
+#define DOL_read(port, buf, len, process) \\r
+    dolread(static_cast<InPort<char> *>(port), buf, len, process)\r
+\r
+void DOL_detach(DOLProcess* p);\r
+\r
+//fifo access functions\r
+unsigned dolwrite(OutPort<char> *out, const void *buf, unsigned len, const DOLProcess *process);\r
+unsigned dolread(InPort<char> *in, const void *buf, unsigned len, const DOLProcess *process);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2);\r
+\r
+void createPort(void **port,\r
+                void *base,\r
+                int number_of_indices,\r
+                int index0, int range0,\r
+                int index1, int range1,\r
+                int index2, int range2,\r
+                int index3, int range3);\r
+\r
+#define GETINDEX(dimension) \\r
+  static_cast<ProcessWrapper *>(p->wptr)->getIndex(dimension)\r
+\r
+/**\r
+ * macro to create a variable to store a port name\r
+ *\r
+ * @param name name of the variable\r
+ */\r
+#define CREATEPORTVAR(name) void *name\r
+\r
+/**\r
+ * Create the port name of an iterated port based on its basename and the\r
+ * given indices.\r
+ *\r
+ * @param port buffer where the result is stored (created using\r
+ *             CREATEPORTVAR)\r
+ * @param base basename of the port\r
+ * @param number_of_indices number of dimensions of the port\r
+ * @param index_range_pairs index and range values for each dimension\r
+ */\r
+#define CREATEPORT(port, base, number_of_indices, index_range_pairs...) \\r
+  createPort((void**)(&port), base, number_of_indices, index_range_pairs)\r
+\r
+#endif\r
diff --git a/dol/src/dol/visitor/yapi/lib/main.cpp b/dol/src/dol/visitor/yapi/lib/main.cpp
new file mode 100644 (file)
index 0000000..2879eb3
--- /dev/null
@@ -0,0 +1,41 @@
+#include "yapi.h"
+#include "application.h"
+#include <fstream>
+
+using namespace std;
+
+int main()
+{
+  // create yapi run-time environment
+  RTE rte;
+
+  // redirect standard output
+  ofstream f("./app.out");
+  rte.setOutStream(f);
+
+  // redirect standard error
+  ofstream g("./app.err");
+  rte.setErrorStream(g);
+
+  // create toplevel process network
+  Application app(id("app"));
+
+  // start the process network and
+  // wait for processes to finish
+  rte.start(app);
+
+  // print workload
+  ofstream h("./appworkload.txt");
+  printWorkload(app, h);
+
+  // generate dotty file
+  ofstream i("./app.dot");
+  printDotty(app, i);
+
+  f.close();
+  g.close();
+  h.close();
+  i.close();
+
+  return 0;
+}
diff --git a/dol/src/dol/visitor/yapi/package.html b/dol/src/dol/visitor/yapi/package.html
new file mode 100644 (file)
index 0000000..813bcf2
--- /dev/null
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+</head>
+<body bgcolor="white">
+
+Code generator for YAPI functional simulation.
+
+<h2>Package Specification</h2>
+
+<!-- use ordinary html here -->
+
+<h2>Related Documentation</h2>
+
+<!-- use ordinary html here -->
+
+<!-- Put @see and @since tags down here. -->
+
+</body>
+</html>
diff --git a/dol/src/dol_template.properties b/dol/src/dol_template.properties
new file mode 100644 (file)
index 0000000..85d8e36
--- /dev/null
@@ -0,0 +1,23 @@
+# template for dol.properties file
+# use ant config to fill in the values
+
+# DOL path: 
+# path to local directory of DOL
+#
+# example:
+# DOL_PATH = /home/shapes/dol
+
+DOL_path = @dol_path@
+
+# SystemC library path:
+# SYSTEMC_INC and SYSTEMC_LIB are the paths to SystemC header and library,
+# respectively. These two path will be used in the generated
+# Makefile to build the SystemC executable binary file.
+# They have to point to local SystemC directory.
+#
+# example:
+# SYSTEMC_INC = /home/shapes/base/resources/lib/systemC/systemc-2.1.v1/include
+# SYSTEMC_LIB = /home/shapes/base/resources/lib/systemC/systemc-2.1.v1/lib-linux/libsystemc.a
+
+SYSTEMC_INC = @systemc_inc@
+SYSTEMC_LIB = @systemc_lib@
diff --git a/dol/test/dolziptest.xml b/dol/test/dolziptest.xml
new file mode 100644 (file)
index 0000000..2c6d3e7
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<project name="runtest" default="runtest" basedir=".">\r
+\r
+  <description>\r
+    Ant build file for automated testing of DOL.\r
+  </description>\r
+\r
+  <property name="test.dir"           location="dolzip"/>\r
+  <property name="test.resource.dir"  location="${test.dir}/test"/>\r
+  <property name="test.src.dir"       location="${test.resource.dir}/src"/>\r
+  <property name="test.reference.dir" location="${test.resource.dir}/reference"/>\r
+  <property name="build.main.dir"     location="${test.dir}/build/bin/main"/>\r
+  <property name="jars.dir"           location="${test.dir}/bin"/>\r
+  <property name="jars"               value=".:${jars.dir}/jdom.jar:${jars.dir}/xercesImpl.jar"/>\r
+  <property name="systemc.inc"        value="/home/shapes/base/resources/lib/systemC/include"/>\r
+  <property name="systemc.lib"        value="/home/shapes/base/resources/lib/systemC/lib-linux/libsystemc.a"/>\r
+  \r
+  <target name="clean">\r
+    <delete dir="${test.dir}"/>\r
+  </target>\r
+\r
+  <!-- copy dol_ethz.zip to test and unzip -->\r
+  <target name="unzipandcompiledol">\r
+    <mkdir dir="${test.dir}"/>\r
+    <unzip src="dol_ethz.zip" dest="${test.dir}"/>\r
+    <copy file="${test.dir}/build_zip.xml" tofile="${test.dir}/build_zip_temp.xml">\r
+      <filterchain>\r
+        <tokenfilter>\r
+          <replaceregex pattern="/home/shapes/base/resources/lib/systemC/include"\r
+                        replace="${systemc.inc}"\r
+                        flags="g"/>\r
+        </tokenfilter>\r
+        <tokenfilter>\r
+          <replaceregex pattern="/home/shapes/base/resources/lib/systemC/lib-linux/libsystemc.a"\r
+                        replace="${systemc.lib}"\r
+                        flags="g"/>\r
+        </tokenfilter>\r
+      </filterchain>\r
+    </copy>\r
+    <move file="${test.dir}/build_zip_temp.xml" tofile="${test.dir}/build_zip.xml"/>\r
+    <ant antfile="build_zip.xml"\r
+         dir="${test.dir}"\r
+         target="all"\r
+         inheritAll="false"/>\r
+  </target>\r
+  \r
+  <!-- get resources required for testing -->\r
+  <target name="preparetest">\r
+    <exec executable="svn">\r
+      <arg line="export --no-auth-cache --username tec file:///home/shapes/base/SVNTree/dolPrototype/trunk/test ${test.resource.dir}"/>\r
+    </exec>\r
+\r
+    <javac destdir="${build.main.dir}" debug="true" classpath="${jars}">\r
+      <src path="${test.src.dir}"/>\r
+    </javac>\r
+    <copy todir="${build.main.dir}" file="${test.resource.dir}/runtests.xml"/>\r
+    <copy todir="${build.main.dir}" file="${test.resource.dir}/test.properties">\r
+      <filterchain>\r
+         <replacetokens>\r
+            <token key="schema_path" value="${test.dir}/schema"/>\r
+         </replacetokens>\r
+      </filterchain>\r
+    </copy>\r
+  </target>\r
+\r
+  <!-- run tests (uses runtests.xml and runexample.xml in ${build.main.dir}) -->\r
+  <target name="runtest" depends="unzipandcompiledol, preparetest">\r
+    <ant antfile="runtests.xml"\r
+         dir="${build.main.dir}"\r
+         target="xml"\r
+         inheritAll="false"/>\r
+    <ant antfile="runtests.xml"\r
+         dir="${build.main.dir}"\r
+         target="checkexamples"\r
+         inheritAll="false"/>\r
+  </target>\r
+</project>\r
diff --git a/dol/test/reference/example1_Linux.txt b/dol/test/reference/example1_Linux.txt
new file mode 100644 (file)
index 0000000..28e844f
--- /dev/null
@@ -0,0 +1,20 @@
+consumer: 0.000000
+consumer: 1.000000
+consumer: 4.000000
+consumer: 9.000000
+consumer: 16.000000
+consumer: 25.000000
+consumer: 36.000000
+consumer: 49.000000
+consumer: 64.000000
+consumer: 81.000000
+consumer: 100.000000
+consumer: 121.000000
+consumer: 144.000000
+consumer: 169.000000
+consumer: 196.000000
+consumer: 225.000000
+consumer: 256.000000
+consumer: 289.000000
+consumer: 324.000000
+consumer: 361.000000
diff --git a/dol/test/reference/example1_Windows XP.txt b/dol/test/reference/example1_Windows XP.txt
new file mode 100644 (file)
index 0000000..28e844f
--- /dev/null
@@ -0,0 +1,20 @@
+consumer: 0.000000
+consumer: 1.000000
+consumer: 4.000000
+consumer: 9.000000
+consumer: 16.000000
+consumer: 25.000000
+consumer: 36.000000
+consumer: 49.000000
+consumer: 64.000000
+consumer: 81.000000
+consumer: 100.000000
+consumer: 121.000000
+consumer: 144.000000
+consumer: 169.000000
+consumer: 196.000000
+consumer: 225.000000
+consumer: 256.000000
+consumer: 289.000000
+consumer: 324.000000
+consumer: 361.000000
diff --git a/dol/test/reference/example2_Linux.txt b/dol/test/reference/example2_Linux.txt
new file mode 100644 (file)
index 0000000..6db8b1c
--- /dev/null
@@ -0,0 +1,20 @@
+consumer: 0.000000
+consumer: 1.000000
+consumer: 256.000000
+consumer: 6561.000000
+consumer: 65536.000000
+consumer: 390625.000000
+consumer: 1679616.000000
+consumer: 5764801.000000
+consumer: 16777216.000000
+consumer: 43046720.000000
+consumer: 100000000.000000
+consumer: 214358880.000000
+consumer: 429981696.000000
+consumer: 815730752.000000
+consumer: 1475789056.000000
+consumer: 2562890752.000000
+consumer: 4294967296.000000
+consumer: 6975757312.000000
+consumer: 11019960320.000000
+consumer: 16983563264.000000
diff --git a/dol/test/reference/example2_Windows XP.txt b/dol/test/reference/example2_Windows XP.txt
new file mode 100644 (file)
index 0000000..6db8b1c
--- /dev/null
@@ -0,0 +1,20 @@
+consumer: 0.000000
+consumer: 1.000000
+consumer: 256.000000
+consumer: 6561.000000
+consumer: 65536.000000
+consumer: 390625.000000
+consumer: 1679616.000000
+consumer: 5764801.000000
+consumer: 16777216.000000
+consumer: 43046720.000000
+consumer: 100000000.000000
+consumer: 214358880.000000
+consumer: 429981696.000000
+consumer: 815730752.000000
+consumer: 1475789056.000000
+consumer: 2562890752.000000
+consumer: 4294967296.000000
+consumer: 6975757312.000000
+consumer: 11019960320.000000
+consumer: 16983563264.000000
diff --git a/dol/test/reference/example3_Linux.txt b/dol/test/reference/example3_Linux.txt
new file mode 100644 (file)
index 0000000..975ef62
--- /dev/null
@@ -0,0 +1,78 @@
+v_consumer: a
+v_consumer: a
+h_consumer: n
+h_consumer: n
+h_consumer: n
+v_consumer: a
+v_consumer: b
+v_consumer: b
+h_consumer: o
+h_consumer: o
+h_consumer: o
+v_consumer: b
+v_consumer: c
+v_consumer: c
+h_consumer: p
+h_consumer: p
+h_consumer: p
+v_consumer: c
+v_consumer: d
+v_consumer: d
+h_consumer: q
+h_consumer: q
+h_consumer: q
+v_consumer: d
+v_consumer: e
+v_consumer: e
+h_consumer: r
+h_consumer: r
+h_consumer: r
+v_consumer: e
+v_consumer: f
+v_consumer: f
+h_consumer: s
+h_consumer: s
+h_consumer: s
+v_consumer: f
+v_consumer: g
+v_consumer: g
+h_consumer: t
+h_consumer: t
+h_consumer: t
+v_consumer: g
+v_consumer: h
+v_consumer: h
+h_consumer: u
+h_consumer: u
+h_consumer: u
+v_consumer: h
+v_consumer: i
+v_consumer: i
+h_consumer: v
+h_consumer: v
+h_consumer: v
+v_consumer: i
+v_consumer: j
+v_consumer: j
+h_consumer: w
+h_consumer: w
+h_consumer: w
+v_consumer: j
+v_consumer: k
+v_consumer: k
+h_consumer: x
+h_consumer: x
+h_consumer: x
+v_consumer: k
+v_consumer: l
+v_consumer: l
+h_consumer: y
+h_consumer: y
+h_consumer: y
+v_consumer: l
+v_consumer: m
+v_consumer: m
+h_consumer: z
+h_consumer: z
+h_consumer: z
+v_consumer: m
diff --git a/dol/test/reference/example3_Windows XP.txt b/dol/test/reference/example3_Windows XP.txt
new file mode 100644 (file)
index 0000000..975ef62
--- /dev/null
@@ -0,0 +1,78 @@
+v_consumer: a
+v_consumer: a
+h_consumer: n
+h_consumer: n
+h_consumer: n
+v_consumer: a
+v_consumer: b
+v_consumer: b
+h_consumer: o
+h_consumer: o
+h_consumer: o
+v_consumer: b
+v_consumer: c
+v_consumer: c
+h_consumer: p
+h_consumer: p
+h_consumer: p
+v_consumer: c
+v_consumer: d
+v_consumer: d
+h_consumer: q
+h_consumer: q
+h_consumer: q
+v_consumer: d
+v_consumer: e
+v_consumer: e
+h_consumer: r
+h_consumer: r
+h_consumer: r
+v_consumer: e
+v_consumer: f
+v_consumer: f
+h_consumer: s
+h_consumer: s
+h_consumer: s
+v_consumer: f
+v_consumer: g
+v_consumer: g
+h_consumer: t
+h_consumer: t
+h_consumer: t
+v_consumer: g
+v_consumer: h
+v_consumer: h
+h_consumer: u
+h_consumer: u
+h_consumer: u
+v_consumer: h
+v_consumer: i
+v_consumer: i
+h_consumer: v
+h_consumer: v
+h_consumer: v
+v_consumer: i
+v_consumer: j
+v_consumer: j
+h_consumer: w
+h_consumer: w
+h_consumer: w
+v_consumer: j
+v_consumer: k
+v_consumer: k
+h_consumer: x
+h_consumer: x
+h_consumer: x
+v_consumer: k
+v_consumer: l
+v_consumer: l
+h_consumer: y
+h_consumer: y
+h_consumer: y
+v_consumer: l
+v_consumer: m
+v_consumer: m
+h_consumer: z
+h_consumer: z
+h_consumer: z
+v_consumer: m
diff --git a/dol/test/reference/example4_Linux.txt b/dol/test/reference/example4_Linux.txt
new file mode 100644 (file)
index 0000000..3a7079b
--- /dev/null
@@ -0,0 +1,32 @@
+input_generator: Write to zeroinput_0: 0.000000\r
+input_generator: Write to matrixA_0_0_0: 1.000000\r
+input_generator: Write to matrixB_0_0_0: 0.000000\r
+input_generator: Write to matrixA_1_0_0: 1.000000\r
+input_generator: Write to matrixB_1_0_0: 0.000000\r
+input_generator: Write to zeroinput_1: 0.000000\r
+input_generator: Write to matrixA_0_0_1: 2.000000\r
+input_generator: Write to matrixB_0_0_1: -1.000000\r
+input_generator: Write to matrixA_1_0_1: 2.000000\r
+input_generator: Write to matrixB_1_0_1: -1.000000\r
+input_generator: Write to zeroinput_2: 0.000000\r
+input_generator: Write to matrixA_0_1_0: 3.000000\r
+input_generator: Write to matrixB_0_1_0: -2.000000\r
+input_generator: Write to matrixA_1_1_0: 3.000000\r
+input_generator: Write to matrixB_1_1_0: -2.000000\r
+input_generator: Write to zeroinput_3: 0.000000\r
+input_generator: Write to matrixA_0_1_1: 4.000000\r
+input_generator: Write to matrixB_0_1_1: -3.000000\r
+input_generator: Write to matrixA_1_1_1: 4.000000\r
+input_generator: Write to matrixB_1_1_1: -3.000000\r
+  addmult_0_0_0: 1.000000 * 0.000000 + 0.000000 = 0.000000\r
+  addmult_0_0_1: 2.000000 * -2.000000 + 0.000000 = -4.000000\r
+  addmult_0_1_0: 3.000000 * 0.000000 + 0.000000 = 0.000000\r
+  addmult_0_1_1: 4.000000 * -2.000000 + 0.000000 = -8.000000\r
+  addmult_1_0_0: 1.000000 * -1.000000 + 0.000000 = -1.000000\r
+  addmult_1_0_1: 2.000000 * -3.000000 + -1.000000 = -7.000000\r
+  addmult_1_1_0: 3.000000 * -1.000000 + 0.000000 = -3.000000\r
+  addmult_1_1_1: 4.000000 * -3.000000 + -3.000000 = -15.000000\r
+output_consumer: matrixC[0][0]: -4.000000\r
+output_consumer: matrixC[0][1]: -7.000000\r
+output_consumer: matrixC[1][0]: -8.000000\r
+output_consumer: matrixC[1][1]: -15.000000\r
diff --git a/dol/test/reference/example4_Windows XP.txt b/dol/test/reference/example4_Windows XP.txt
new file mode 100644 (file)
index 0000000..3a7079b
--- /dev/null
@@ -0,0 +1,32 @@
+input_generator: Write to zeroinput_0: 0.000000\r
+input_generator: Write to matrixA_0_0_0: 1.000000\r
+input_generator: Write to matrixB_0_0_0: 0.000000\r
+input_generator: Write to matrixA_1_0_0: 1.000000\r
+input_generator: Write to matrixB_1_0_0: 0.000000\r
+input_generator: Write to zeroinput_1: 0.000000\r
+input_generator: Write to matrixA_0_0_1: 2.000000\r
+input_generator: Write to matrixB_0_0_1: -1.000000\r
+input_generator: Write to matrixA_1_0_1: 2.000000\r
+input_generator: Write to matrixB_1_0_1: -1.000000\r
+input_generator: Write to zeroinput_2: 0.000000\r
+input_generator: Write to matrixA_0_1_0: 3.000000\r
+input_generator: Write to matrixB_0_1_0: -2.000000\r
+input_generator: Write to matrixA_1_1_0: 3.000000\r
+input_generator: Write to matrixB_1_1_0: -2.000000\r
+input_generator: Write to zeroinput_3: 0.000000\r
+input_generator: Write to matrixA_0_1_1: 4.000000\r
+input_generator: Write to matrixB_0_1_1: -3.000000\r
+input_generator: Write to matrixA_1_1_1: 4.000000\r
+input_generator: Write to matrixB_1_1_1: -3.000000\r
+  addmult_0_0_0: 1.000000 * 0.000000 + 0.000000 = 0.000000\r
+  addmult_0_0_1: 2.000000 * -2.000000 + 0.000000 = -4.000000\r
+  addmult_0_1_0: 3.000000 * 0.000000 + 0.000000 = 0.000000\r
+  addmult_0_1_1: 4.000000 * -2.000000 + 0.000000 = -8.000000\r
+  addmult_1_0_0: 1.000000 * -1.000000 + 0.000000 = -1.000000\r
+  addmult_1_0_1: 2.000000 * -3.000000 + -1.000000 = -7.000000\r
+  addmult_1_1_0: 3.000000 * -1.000000 + 0.000000 = -3.000000\r
+  addmult_1_1_1: 4.000000 * -3.000000 + -3.000000 = -15.000000\r
+output_consumer: matrixC[0][0]: -4.000000\r
+output_consumer: matrixC[0][1]: -7.000000\r
+output_consumer: matrixC[1][0]: -8.000000\r
+output_consumer: matrixC[1][1]: -15.000000\r
diff --git a/dol/test/reference/example5_Linux.txt b/dol/test/reference/example5_Linux.txt
new file mode 100644 (file)
index 0000000..3e36a91
--- /dev/null
@@ -0,0 +1,64 @@
+       FFT2_0_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_1: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_2: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_3: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_4: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_5: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_6: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_7: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_1: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_1_2: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_3: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_1_4: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_5: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_1_6: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_7: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_2_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_2_1: twiddle_factor  0.707107 + j * -0.707107
+       FFT2_2_2: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_2_3: twiddle_factor -0.707107 + j * -0.707107
+       FFT2_2_4: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_2_5: twiddle_factor  0.707107 + j * -0.707107
+       FFT2_2_6: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_2_7: twiddle_factor -0.707107 + j * -0.707107
+       FFT2_3_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_3_1: twiddle_factor  0.923880 + j * -0.382683
+       FFT2_3_2: twiddle_factor  0.707107 + j * -0.707107
+       FFT2_3_3: twiddle_factor  0.382683 + j * -0.923880
+       FFT2_3_4: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_3_5: twiddle_factor -0.382684 + j * -0.923880
+       FFT2_3_6: twiddle_factor -0.707107 + j * -0.707107
+       FFT2_3_7: twiddle_factor -0.923880 + j * -0.382683
+input_generator: Write to input_coefficients_0: -7.000000 + j *  6.000000
+input_generator: Write to input_coefficients_1: -6.000000 + j * -6.000000
+input_generator: Write to input_coefficients_2:  1.000000 + j * -1.000000
+input_generator: Write to input_coefficients_3:  1.000000 + j *  2.000000
+input_generator: Write to input_coefficients_4: -7.000000 + j * -2.000000
+input_generator: Write to input_coefficients_5: -8.000000 + j *  0.000000
+input_generator: Write to input_coefficients_6: -8.000000 + j *  1.000000
+input_generator: Write to input_coefficients_7: -8.000000 + j *  1.000000
+input_generator: Write to input_coefficients_8: -2.000000 + j *  8.000000
+input_generator: Write to input_coefficients_9: -4.000000 + j *  0.000000
+input_generator: Write to input_coefficients_10:  1.000000 + j *  6.000000
+input_generator: Write to input_coefficients_11: -1.000000 + j *  3.000000
+input_generator: Write to input_coefficients_12: -2.000000 + j *  3.000000
+input_generator: Write to input_coefficients_13: -3.000000 + j * -2.000000
+input_generator: Write to input_coefficients_14: -4.000000 + j * -8.000000
+input_generator: Write to input_coefficients_15: -3.000000 + j * -5.000000
+output_consumer: coeff[0]: -60.000000 + j *  6.000000
+output_consumer: coeff[1]:  0.616942 + j * -12.269464
+output_consumer: coeff[2]:  8.464464 + j * -18.677670
+output_consumer: coeff[3]: -7.116004 + j * 10.640678
+output_consumer: coeff[4]: -17.000000 + j * 27.000000
+output_consumer: coeff[5]: -9.306217 + j * 18.624950
+output_consumer: coeff[6]: -1.393398 + j * 27.707106
+output_consumer: coeff[7]: -3.112326 + j * -3.457108
+output_consumer: coeff[8]:  4.000000 + j * 20.000000
+output_consumer: coeff[9]: -12.131660 + j *  1.298900
+output_consumer: coeff[10]: 15.535534 + j * 16.677666
+output_consumer: coeff[11]:  4.287576 + j *  3.643592
+output_consumer: coeff[12]:  1.000000 + j *  7.000000
+output_consumer: coeff[13]: -19.179064 + j *  4.345614
+output_consumer: coeff[14]: -22.606600 + j * 26.292894
+output_consumer: coeff[15]:  5.940753 + j * -38.827164
diff --git a/dol/test/reference/example5_Windows XP.txt b/dol/test/reference/example5_Windows XP.txt
new file mode 100644 (file)
index 0000000..dfe7b6f
--- /dev/null
@@ -0,0 +1,64 @@
+       FFT2_0_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_1: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_2: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_3: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_4: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_5: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_6: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_0_7: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_1: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_1_2: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_3: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_1_4: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_5: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_1_6: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_1_7: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_2_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_2_1: twiddle_factor  0.707107 + j * -0.707107
+       FFT2_2_2: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_2_3: twiddle_factor -0.707107 + j * -0.707107
+       FFT2_2_4: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_2_5: twiddle_factor  0.707107 + j * -0.707107
+       FFT2_2_6: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_2_7: twiddle_factor -0.707107 + j * -0.707107
+       FFT2_3_0: twiddle_factor  1.000000 + j * -0.000000
+       FFT2_3_1: twiddle_factor  0.923880 + j * -0.382683
+       FFT2_3_2: twiddle_factor  0.707107 + j * -0.707107
+       FFT2_3_3: twiddle_factor  0.382683 + j * -0.923880
+       FFT2_3_4: twiddle_factor -0.000000 + j * -1.000000
+       FFT2_3_5: twiddle_factor -0.382683 + j * -0.923880
+       FFT2_3_6: twiddle_factor -0.707107 + j * -0.707107
+       FFT2_3_7: twiddle_factor -0.923880 + j * -0.382683
+input_generator: Write to input_coefficients_0: -9.000000 + j *  4.000000
+input_generator: Write to input_coefficients_1: -2.000000 + j *  0.000000
+input_generator: Write to input_coefficients_2: -3.000000 + j *  0.000000
+input_generator: Write to input_coefficients_3:  8.000000 + j *  3.000000
+input_generator: Write to input_coefficients_4:  6.000000 + j *  0.000000
+input_generator: Write to input_coefficients_5: -7.000000 + j * -9.000000
+input_generator: Write to input_coefficients_6: -5.000000 + j *  2.000000
+input_generator: Write to input_coefficients_7:  1.000000 + j *  2.000000
+input_generator: Write to input_coefficients_8:  8.000000 + j * -4.000000
+input_generator: Write to input_coefficients_9: -6.000000 + j * -4.000000
+input_generator: Write to input_coefficients_10:  9.000000 + j * -2.000000
+input_generator: Write to input_coefficients_11: -8.000000 + j * -4.000000
+input_generator: Write to input_coefficients_12: -3.000000 + j *  1.000000
+input_generator: Write to input_coefficients_13: -9.000000 + j *  7.000000
+input_generator: Write to input_coefficients_14: -9.000000 + j * -9.000000
+input_generator: Write to input_coefficients_15: -7.000000 + j *  7.000000
+output_consumer: coeff[0]: -36.000000 + j * -6.000000
+output_consumer: coeff[1]: -27.156870 + j * -5.812504
+output_consumer: coeff[2]: -6.071069 + j * -25.242640
+output_consumer: coeff[3]: -7.438680 + j *  7.017483
+output_consumer: coeff[4]: -3.999999 + j * 28.000000
+output_consumer: coeff[5]:  1.106642 + j * 13.313931
+output_consumer: coeff[6]: -18.899494 + j *  3.443651
+output_consumer: coeff[7]: -46.865753 + j * -33.359482
+output_consumer: coeff[8]: 24.000000 + j * -10.000000
+output_consumer: coeff[9]: -13.085772 + j *  2.398290
+output_consumer: coeff[10]:  8.071067 + j * -16.757360
+output_consumer: coeff[11]: 16.450871 + j * 51.024147
+output_consumer: coeff[12]: 24.000000 + j * -8.000000
+output_consumer: coeff[13]: -32.863998 + j * -13.899717
+output_consumer: coeff[14]:  0.899496 + j * 34.556351
+output_consumer: coeff[15]: -26.146439 + j * 43.317848
diff --git a/dol/test/reference/example6_Linux.txt b/dol/test/reference/example6_Linux.txt
new file mode 100644 (file)
index 0000000..aef2f51
--- /dev/null
@@ -0,0 +1,21 @@
+producer: samples = { -7.0, +6.0, -6.0, -6.0, +1.0, -1.0, +1.0, +2.0, -7.0, -2.0 }
+producer: Write sample[00]: -7.0000
+producer: Write sample[01]: +6.0000
+producer: Write sample[02]: -6.0000
+consumer:                             Read sample[00]: -7.0000
+producer: Write sample[03]: -6.0000
+consumer:                             Read sample[01]: +2.5000
+producer: Write sample[04]: +1.0000
+consumer:                             Read sample[02]: -4.7500
+producer: Write sample[05]: -1.0000
+consumer:                             Read sample[03]: -8.3750
+producer: Write sample[06]: +1.0000
+consumer:                             Read sample[04]: -3.1875
+producer: Write sample[07]: +2.0000
+consumer:                             Read sample[05]: -2.5938
+producer: Write sample[08]: -7.0000
+consumer:                             Read sample[06]: -0.2969
+producer: Write sample[09]: -2.0000
+consumer:                             Read sample[07]: +1.8516
+consumer:                             Read sample[08]: -6.0742
+consumer:                             Read sample[09]: -5.0371
diff --git a/dol/test/reference/example6_Windows XP.txt b/dol/test/reference/example6_Windows XP.txt
new file mode 100644 (file)
index 0000000..d266e3c
--- /dev/null
@@ -0,0 +1,21 @@
+producer: samples = { -9.0, +4.0, -2.0, +0.0, -3.0, +0.0, +8.0, +3.0, +6.0, +0.0 }
+producer: Write sample[00]: -9.0000
+producer: Write sample[01]: +4.0000
+producer: Write sample[02]: -2.0000
+consumer:                             Read sample[00]: -9.0000
+producer: Write sample[03]: +0.0000
+consumer:                             Read sample[01]: -0.5000
+producer: Write sample[04]: -3.0000
+consumer:                             Read sample[02]: -2.2500
+producer: Write sample[05]: +0.0000
+consumer:                             Read sample[03]: -1.1250
+producer: Write sample[06]: +8.0000
+consumer:                             Read sample[04]: -3.5625
+producer: Write sample[07]: +3.0000
+consumer:                             Read sample[05]: -1.7812
+producer: Write sample[08]: +6.0000
+consumer:                             Read sample[06]: +7.1094
+producer: Write sample[09]: +0.0000
+consumer:                             Read sample[07]: +6.5547
+consumer:                             Read sample[08]: +9.2773
+consumer:                             Read sample[09]: +4.6387
diff --git a/dol/test/reference/example7_Linux.txt b/dol/test/reference/example7_Linux.txt
new file mode 100644 (file)
index 0000000..3639ade
--- /dev/null
@@ -0,0 +1,31 @@
+init producer.
+init consumer.
+init filter_0: filter coefficient = -0.9
+init filter_1: filter coefficient = -0.6
+init filter_2: filter coefficient = -0.1
+producer: samples = { -7.0, +6.0, -6.0, -6.0, +1.0 }
+producer: Write sample[00]: -7.0000
+producer: Write sample[01]: +6.0000
+filter_0: inA: -7.0000, inB: 0.0000, outA = outB: -7.0000
+filter_1: inA: -7.0000, inB: 0.0000, outA: -7.0000, outB: 4.2000
+filter_2: inA: -7.0000, inB: 0.0000, outA: -7.0000, outB: 0.7000
+producer: Write sample[02]: -6.0000
+consumer:                             Read sample[00]: -7.0000
+filter_0: inA: 6.0000, inB: 4.2000, outA = outB: 10.2000
+filter_1: inA: 10.2000, inB: 0.7000, outA: 10.2000, outB: -5.4200
+filter_2: inA: 10.2000, inB: 0.0000, outA: 10.2000, outB: -1.0200
+producer: Write sample[03]: -6.0000
+consumer:                             Read sample[01]: +10.2000
+filter_0: inA: -6.0000, inB: -5.4200, outA = outB: -11.4200
+filter_1: inA: -11.4200, inB: -1.0200, outA: -11.4200, outB: 5.8320
+filter_2: inA: -11.4200, inB: 0.0000, outA: -11.4200, outB: 1.1420
+producer: Write sample[04]: +1.0000
+consumer:                             Read sample[02]: -11.4200
+filter_0: inA: -6.0000, inB: 5.8320, outA = outB: -0.1680
+filter_1: inA: -0.1680, inB: 1.1420, outA: -0.1680, outB: 1.2428
+filter_2: inA: -0.1680, inB: 0.0000, outA: -0.1680, outB: 0.0168
+consumer:                             Read sample[03]: -0.1680
+filter_0: inA: 1.0000, inB: 1.2428, outA = outB: 2.2428
+filter_1: inA: 2.2428, inB: 0.0168, outA: 2.2428, outB: -1.3289
+filter_2: inA: 2.2428, inB: 0.0000, outA: 2.2428, outB: -0.2243
+consumer:                             Read sample[04]: +2.2428
diff --git a/dol/test/reference/example7_Windows XP.txt b/dol/test/reference/example7_Windows XP.txt
new file mode 100644 (file)
index 0000000..9305352
--- /dev/null
@@ -0,0 +1,31 @@
+init producer.
+init consumer.
+init filter_0: filter coefficient = -1.0
+init filter_1: filter coefficient = +0.1
+init filter_2: filter coefficient = -0.1
+producer: samples = { -9.0, +4.0, -2.0, +0.0, -3.0 }
+producer: Write sample[00]: -9.0000
+producer: Write sample[01]: +4.0000
+filter_0: inA: -9.0000, inB: 0.0000, outA = outB: -9.0000
+filter_1: inA: -9.0000, inB: 0.0000, outA: -9.0000, outB: -0.9000
+filter_2: inA: -9.0000, inB: 0.0000, outA: -9.0000, outB: 0.9000
+producer: Write sample[02]: -2.0000
+consumer:                             Read sample[00]: -9.0000
+filter_0: inA: 4.0000, inB: -0.9000, outA = outB: 3.1000
+filter_1: inA: 3.1000, inB: 0.9000, outA: 3.1000, outB: 1.2100
+filter_2: inA: 3.1000, inB: 0.0000, outA: 3.1000, outB: -0.3100
+producer: Write sample[03]: +0.0000
+consumer:                             Read sample[01]: +3.1000
+filter_0: inA: -2.0000, inB: 1.2100, outA = outB: -0.7900
+filter_1: inA: -0.7900, inB: -0.3100, outA: -0.7900, outB: -0.3890
+filter_2: inA: -0.7900, inB: 0.0000, outA: -0.7900, outB: 0.0790
+producer: Write sample[04]: -3.0000
+consumer:                             Read sample[02]: -0.7900
+filter_0: inA: 0.0000, inB: -0.3890, outA = outB: -0.3890
+filter_1: inA: -0.3890, inB: 0.0790, outA: -0.3890, outB: 0.0401
+filter_2: inA: -0.3890, inB: 0.0000, outA: -0.3890, outB: 0.0389
+consumer:                             Read sample[03]: -0.3890
+filter_0: inA: -3.0000, inB: 0.0401, outA = outB: -2.9599
+filter_1: inA: -2.9599, inB: 0.0389, outA: -2.9599, outB: -0.2571
+filter_2: inA: -2.9599, inB: 0.0000, outA: -2.9599, outB: 0.2960
+consumer:                             Read sample[04]: -2.9599
diff --git a/dol/test/reference/examplesingleprocess_Linux.txt b/dol/test/reference/examplesingleprocess_Linux.txt
new file mode 100644 (file)
index 0000000..1cbbe87
--- /dev/null
@@ -0,0 +1,30 @@
+task_0: 0
+task_1: 0
+task_2: 0
+task_0: 1
+task_1: 1
+task_2: 1
+task_0: 2
+task_1: 2
+task_2: 2
+task_0: 3
+task_1: 3
+task_2: 3
+task_0: 4
+task_1: 4
+task_2: 4
+task_0: 5
+task_1: 5
+task_2: 5
+task_0: 6
+task_1: 6
+task_2: 6
+task_0: 7
+task_1: 7
+task_2: 7
+task_0: 8
+task_1: 8
+task_2: 8
+task_0: 9
+task_1: 9
+task_2: 9
diff --git a/dol/test/reference/examplesingleprocess_Windows XP.txt b/dol/test/reference/examplesingleprocess_Windows XP.txt
new file mode 100644 (file)
index 0000000..1cbbe87
--- /dev/null
@@ -0,0 +1,30 @@
+task_0: 0
+task_1: 0
+task_2: 0
+task_0: 1
+task_1: 1
+task_2: 1
+task_0: 2
+task_1: 2
+task_2: 2
+task_0: 3
+task_1: 3
+task_2: 3
+task_0: 4
+task_1: 4
+task_2: 4
+task_0: 5
+task_1: 5
+task_2: 5
+task_0: 6
+task_1: 6
+task_2: 6
+task_0: 7
+task_1: 7
+task_2: 7
+task_0: 8
+task_1: 8
+task_2: 8
+task_0: 9
+task_1: 9
+task_2: 9
diff --git a/dol/test/runtests.xml b/dol/test/runtests.xml
new file mode 100644 (file)
index 0000000..f6578e9
--- /dev/null
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project name="dol" default="all" basedir=".">
+
+  <description>
+    Ant build file to run tests.
+  </description>
+
+  <!-- directory paths -->
+  <property name="lib.dir"     location="./../../../jars"/>
+  <property name="bin.dir"     location="./../../../bin"/>
+  <property name="jars"        value=".:./..:${lib.dir}/dol.jar:${lib.dir}/xercesImpl.jar:${lib.dir}/jdom.jar:${bin.dir}/dol.jar:${bin.dir}/xercesImpl.jar:${bin.dir}/jdom.jar"/>
+  <property name="example.dir" location="./../../../examples"/>
+  <property name="test.dir"    location="./../../../test"/>
+
+  <property name="generator" value="HdS"/> <!-- HdS, protothread, systemC, PaF -->
+
+  <target name="all" depends="xml, checkexamples"/>
+
+  <!-- check validity of XML documents -->
+  <target name="xml">
+    <echo message="Check XML documents."/>
+    <java classname="test.test.TreeValidator"
+          dir="."
+          fork="true"
+          failonerror="true">
+      <classpath path="${jars}"/>
+      <arg line="${example.dir}/schema
+                 ${example.dir}/exampleproducerconsumer
+                 ${example.dir}/example1
+                 ${example.dir}/example2
+                 ${example.dir}/example3
+                 ${example.dir}/example4 
+                 ${example.dir}/example5 
+                 ${example.dir}/example6 
+                 ${example.dir}/example7
+                 ${example.dir}/examplesingleprocess
+                 ${example.dir}/arch"/>
+    </java>
+  </target>
+
+  <!-- compile and run examples and check agains reference output --> 
+  <macrodef name="runandcheck">
+    <attribute name="number"/>
+    <sequential>
+      <ant antfile="runexample.xml"
+           target="runexample"
+           inheritAll="false">
+        <property name="number" value="@{number}"/>
+        <property name="generator" value="${generator}"/>
+      </ant>
+
+      <copy file="example@{number}/${generator}/src/log.txt"
+            tofile="test/example@{number}log.txt"
+            overwrite="true">
+      </copy>
+
+      <copy file="${test.dir}/reference/example@{number}_${os.name}.txt"
+            tofile="test/example@{number}ref.txt"
+            overwrite="true">
+      </copy>
+
+      <java classname="test.util.Diff"
+            dir="."
+            fork="true"
+            failonerror="true">
+        <classpath path="${jars}"/>
+        <arg line="test/example@{number}ref.txt test/example@{number}log.txt "/>
+      </java>
+
+      <java classname="dol.main.Main"
+            dir="."
+            fork="true"
+            classpath="${jars}"
+            failonerror="true">
+        <arg line=" -T profile.txt -P example@{number}/example@{number}_flattened.xml -G example@{number}/example@{number}_flattened_annotated.xml"/>
+      </java>
+
+      <echo message="Successfully tested example @{number}."/>
+    </sequential>
+  </macrodef>
+
+  <!-- check all examples -->
+  <target name="checkexamples">
+    <echo message="Check examples."/>
+    <mkdir dir="test"/>
+    <runandcheck number="1"/>
+    <runandcheck number="2"/>
+    <runandcheck number="4"/>
+    <runandcheck number="6"/>
+    <runandcheck number="7"/>
+    <runandcheck number="singleprocess"/>
+    <runandcheck number="3"/>
+  </target>
+
+</project>
diff --git a/dol/test/src/test/test/TreeValidator.java b/dol/test/src/test/test/TreeValidator.java
new file mode 100644 (file)
index 0000000..4deede8
--- /dev/null
@@ -0,0 +1,78 @@
+package test.test;
+
+import java.io.File;
+
+import test.util.XMLValidator;
+
+/**
+ * Class to check well-formedness and validity of XML documents.
+ */
+public class TreeValidator {
+
+    /**
+     * Check the well-formedness and validity of XML files.
+     *
+     * @param args Specifies the XML file to be checked or the
+     *             directory (including subdirectories) where XML
+     *             and XSD files are checked. Multiple files or
+     *             directories can be specified.
+     */
+    public static void main(String args[]) throws Exception {
+        System.out.println("Run TreeValidator.");
+        if (args.length == 0)
+            browseDirectoryTree("./");
+        else {
+            for (int k = 0; k < args.length; k++)
+                browseDirectoryTree(args[k]);
+        }
+        System.out.println("Finished.");
+    }
+
+    /**
+     * Method which defines what is done for each file found in the
+     * directory tree: When the file is an XML or XSD file, it is
+     * validated using
+     * {@link test.util.XMLValidator#isValid(java.lang.String)}.
+     *
+     * @param filename file to process
+     */
+    protected static void processFile(String filename) throws Exception {
+        if (filename.endsWith("xml") || filename.endsWith("xsd")) {
+            System.out.println("Checking " + filename + "...");
+            if (!XMLValidator.isValid(filename))
+              throw new Exception("File not valid.");
+        }
+    }
+
+    /**
+     * Iterate through the given directory tree. For each file found in
+     * the file, the method {@link #processFile(java.lang.String)} is
+     * called.
+     *
+     * @param path the path of the directory to be browsed
+     */
+    protected static void browseDirectoryTree(String path) throws Exception {
+        File file = new File(path);
+
+        if (!file.exists()) return;
+        if (!file.isDirectory()) return;
+
+        String filepath = file.getPath();
+        String filename = file.getName();
+
+        //loop through files in directory
+        String[] files = file.list();
+
+        for (int k = 0; k < files.length; k++) {
+            File newfile = new File(file.getPath(), files[k]);
+            if (newfile.isFile())
+                processFile(path + System.getProperty("file.separator")
+                        + files[k]);
+            else if (newfile.isDirectory()) {
+                browseDirectoryTree(file.getPath()
+                        + System.getProperty("file.separator")
+                        + files[k]);
+            }
+        }
+    }
+}
diff --git a/dol/test/src/test/util/Diff.java b/dol/test/src/test/util/Diff.java
new file mode 100644 (file)
index 0000000..dd0f73e
--- /dev/null
@@ -0,0 +1,46 @@
+package test.util;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.FileReader;\r
+\r
+/**\r
+ * Class to diff two files\r
+ */\r
+public class Diff {\r
+\r
+    /**\r
+     * Main.\r
+     *\r
+     * @param args names of the two files to compare\r
+     */\r
+    public static void main(String[] args) throws Exception {\r
+        if (args.length != 2) {\r
+            //System.out.println("Usage: java Diff file1 file2");\r
+            throw new Exception("Usage: java Diff file1 file2");\r
+        }\r
+\r
+        try {\r
+          BufferedReader fileOneReader = new BufferedReader(new FileReader(args[0]));\r
+          BufferedReader fileTwoReader = new BufferedReader(new FileReader(args[1]));\r
+\r
+          String lineOne, lineTwo;\r
+          while ((lineOne = fileOneReader.readLine()) != null) {\r
+              lineTwo = fileTwoReader.readLine();\r
+              if (lineTwo == null)\r
+                  throw new Exception("Files are not equal: "\r
+                          + args[1] + " is shorter.");\r
+              else if (!lineOne.equals(lineTwo))\r
+                  throw new Exception("Files do not match.");\r
+          }\r
+\r
+          if ((lineTwo = fileTwoReader.readLine()) != null)\r
+              throw new Exception("Files are not equal: "\r
+                      + args[0]  + " is shorter.");\r
+        }\r
+        catch (Exception e) {\r
+          throw e;\r
+        }\r
+\r
+        //System.out.println("Files are equal.");\r
+    }\r
+}\r
diff --git a/dol/test/src/test/util/XMLValidator.java b/dol/test/src/test/util/XMLValidator.java
new file mode 100644 (file)
index 0000000..eba16cd
--- /dev/null
@@ -0,0 +1,56 @@
+package test.util;
+
+import java.util.ResourceBundle;
+import java.io.IOException;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+/**
+ * Class to check well-formedness and validity of XML documents.
+ */
+public class XMLValidator {
+
+    /**
+     * Check the well-formedness and validity of an XML document.
+     * The file is checked against the schema which is referenced from
+     * within the file. When the document is an XML schema, it is checked
+     * against <a href="http://www.w3.org/2001/XMLSchema.xsd"
+     * target="_blank">http://www.w3.org/2001/XMLSchema.xsd</a>.
+     *
+     * @param filename filename of the file to be checked
+     */
+    public static boolean isValid(String filename) {
+        ResourceBundle resourceBundle = ResourceBundle.getBundle("test");
+
+        SAXBuilder builder = new SAXBuilder(true);
+        builder.setFeature("http://xml.org/sax/features/validation",
+                true);
+        builder.setFeature("http://apache.org/xml/features/validation/"
+                + "schema", true);
+        builder.setFeature("http://apache.org/xml/features/validation/"
+                + "schema-full-checking", true);
+        builder.setProperty("http://apache.org/xml/properties/schema/"
+                + "external-schemaLocation",
+                "http://www.w3.org/2001/XMLSchema "
+                + "http://www.w3.org/2001/XMLSchema.xsd "
+                + resourceBundle.getString("LOCAL_SCHEMAS"));
+
+        try {
+            builder.build(filename);
+        }
+        catch (JDOMException e) {
+            System.out.println("Found an error in " + filename + ".");
+            System.out.println(e.getMessage());
+            System.out.println("");
+            return false;
+        }
+        catch (IOException e) {
+            System.out.println("Found an error in " + filename + ".");
+            System.out.println(e.getMessage());
+            System.out.println("");
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/dol/test/test.properties b/dol/test/test.properties
new file mode 100644 (file)
index 0000000..0a6c222
--- /dev/null
@@ -0,0 +1,9 @@
+#local schemas for validation of XML files
+LOCAL_SCHEMAS = \
+  http://www.tik.ee.ethz.ch/~shapes/schema/PROCESSNETWORK \
+    file:///@schema_path@/processnetwork.xsd \
+  http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE \
+    file:///@schema_path@/architecture.xsd \
+  http://www.tik.ee.ethz.ch/~shapes/schema/MAPPING \
+    file:///@schema_path@/mapping.xsd
+