X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fvisitor%2Fprotothread%2FProtothreadProcessVisitor.java;fp=dol%2Fsrc%2Fdol%2Fvisitor%2Fprotothread%2FProtothreadProcessVisitor.java;h=e67ac18ab66c4ef75dccdb9708ebe8c9f64f20ea;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/visitor/protothread/ProtothreadProcessVisitor.java b/dol/src/dol/visitor/protothread/ProtothreadProcessVisitor.java new file mode 100644 index 0000000..e67ac18 --- /dev/null +++ b/dol/src/dol/visitor/protothread/ProtothreadProcessVisitor.java @@ -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 processList = new Vector(); + 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 "); + 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 basenames = new Vector(); + 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; +}