private HashMap<File, ArrayList<CodeAddition>> codeAdditions;
+ private ArrayList<String> globalContent;
+
public CodeGenerator(File[] srcFiles) {
this.srcFiles = srcFiles;
this.contents = new HashMap<File, ArrayList<String>>();
+ this.globalContent = null;
readSrcFiles();
this.codeAdditions = new HashMap<File, ArrayList<CodeAddition>>();
* </p>
*/
private void globalConstruct2Code(SpecConstruct inst) {
- int lineNum = inst.endLineNum + 1;
GlobalConstruct construct = (GlobalConstruct) inst.construct;
- ArrayList<String> newCode = new ArrayList<String>();
-
- // Generate all sequential variables into a struct
- newCode.add("struct " + CodeVariables.SPEC_SEQUENTIAL_STRUCT + " {\n");
-
- // Generate the code in global construct first
- SequentialDefineSubConstruct globalCode = construct.code;
- breakCodeLines(newCode, globalCode.declareVar);
-
- // Generate code from the DefineVar, __COND_SAT__ and __ID__
- // The hashtable in the contract can only contains pointers or integers
- // __COND_SAT__
- newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_CONDITION
- + ";");
- // __ID__
- newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_ID + ";");
- // DefineVars
- for (String interfaceName : _semantics.interfaceName2Construct.keySet()) {
- InterfaceConstruct iConstruct = (InterfaceConstruct) _semantics.interfaceName2Construct
- .get(interfaceName).construct;
- ArrayList<DefineVar> defineVars = iConstruct.action.defineVars;
- for (int i = 0; i < defineVars.size(); i++) {
- DefineVar var = defineVars.get(i);
- newCode.add(CodeVariables.SPEC_HASHTABLE + var.getNewVarName()
- + ";");
- }
- }
- // __interface
- newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_INTERFACE
- + ";");
- // __interface_call_sequence
- newCode.add(CodeVariables.SPEC_HASHTABLE
- + CodeVariables.SPEC_INTERFACE_CALL_SEQUENCE + ";");
- // Interface call sequence varaiable
- newCode.add(CodeVariables.SPEC_TAG + " "
- + CodeVariables.INTERFACE_CALL_SEQUENCE + ";");
- // End of the struct
- newCode.add("}");
-
- // FIXME: Constructor should be modified and put in the right place
- // Generate constructor (the place to initialize everything!)
- breakCodeLines(newCode, globalCode.initVar);
- // __COND_SAT__
- newCode.add("init_table(&" + CodeVariables.SPEC_CONDITION + ");");
- // __ID__
- newCode.add("init_table(&" + CodeVariables.SPEC_ID + ");");
- // DefineVars
- for (String interfaceName : _semantics.interfaceName2Construct.keySet()) {
- InterfaceConstruct iConstruct = (InterfaceConstruct) _semantics.interfaceName2Construct
- .get(interfaceName).construct;
- ArrayList<DefineVar> defineVars = iConstruct.action.defineVars;
- for (int i = 0; i < defineVars.size(); i++) {
- DefineVar var = defineVars.get(i);
- newCode.add("init_table(&" + var.getNewVarName() + ");");
- }
- }
- // __interface
- newCode.add("init_table(&" + CodeVariables.SPEC_INTERFACE + ");");
- // __interface_call_sequence
- newCode.add("init_table(&" + CodeVariables.SPEC_INTERFACE_CALL_SEQUENCE + ");");
-
- // Pass the happens-before relationship check here
- newCode.addAll(CodeVariables.generateHBInitAnnotation(_semantics));
-
- newCode.add("\n");
-
- // Generate the sequential functions
- breakCodeLines(newCode, globalCode.defineFunc);
-
- printCode(newCode);
-
- CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(inst.file)) {
- codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(inst.file).add(addition);
- }
-
- // Break the code (String) into multiple lines and add it to newCode
- private void breakCodeLines(ArrayList<String> newCode, String code) {
- int begin = 0, end = 0;
- while (end < code.length()) {
- if (code.charAt(end) == '\n') {
- String line = code.substring(begin, end);
- newCode.add(line);
- begin = end + 1;
- }
- end++;
- }
- }
-
- private void printCode(ArrayList<String> code) {
- for (int i = 0; i < code.size(); i++) {
- System.out.println(code.get(i));
- }
+ ArrayList<String> newCode = CodeVariables.generateGlobalVarDeclaration(
+ _semantics, construct);
+ // Record the global content array to generate the new file
+ globalContent = newCode;
}
// Mainly rename and wrap the interface
throws InterfaceWrongFormatException {
int lineNum = inst.endLineNum + 1;
InterfaceConstruct construct = (InterfaceConstruct) inst.construct;
- ArrayList<String> newCode = new ArrayList<String>();
-
+
// Rename the interface name
File file = inst.file;
String funcDecl = inst.interfaceDeclBody;
}
// Generate new wrapper
- /**
- *
- *
- */
-
- breakCodeLines(newCode, funcDecl);
- newCode.add("{");
- // Generate interface sequence call
- newCode.add(CodeVariables.UINT64 + " call_sequence_num = current(&"
- + CodeVariables.INTERFACE_CALL_SEQUENCE + ");");
- // FIXME: Add Happens-before check here
- newCode.add("}");
-
+ ArrayList<String> newCode = CodeVariables.generateInterfaceWrapper(_semantics, inst);
+ // Add it to the codeAdditions
CodeAddition addition = new CodeAddition(lineNum, newCode);
if (!codeAdditions.containsKey(inst.file)) {
codeAdditions.put(inst.file, new ArrayList<CodeAddition>());
// Depending on "(" to find the function name, so it doesn't matter if
// there's any template
- int begin = 0, end = funcDecl.indexOf('(');
- if (end == -1) {
+ int beginIdx = funcDecl.indexOf('(');
+ if (beginIdx == -1) {
throw new InterfaceWrongFormatException(funcDecl
+ "\n has wrong format!");
}
- end--;
- while (end > 0) {
- char ch = funcDecl.charAt(end);
- if (ch == '_' || (ch >= 'a' && ch <= 'z')
- || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
- break;
- }
- end--;
- }
- begin = end;
- while (begin > 0) {
- char ch = funcDecl.charAt(begin);
- if (ch == '_' || (ch >= 'a' && ch <= 'z')
- || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
- begin--;
- continue;
- }
- break;
- }
- String funcName = funcDecl.substring(begin + 1, end + 1), newLine;
- int lineBreakIdx = funcDecl.indexOf('\n');
- int firstLineBreak = lineBreakIdx == -1 ? funcDecl.length()
- : lineBreakIdx;
- newLine = funcDecl.substring(0, begin + 1)
+ IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx);
+ String funcName = idExtractor.getPrevID();
+ int idBeginIdx = idExtractor.getIDBeginIdx(),
+ idEndIdx = idExtractor.getIDEndIdx(),
+ idLineBeginIdx = idExtractor.lineBeginIdxOfID(),
+ idLineEndIdx = idExtractor.lineEndIdxOfID();
+ String newLine = funcDecl.substring(idLineBeginIdx, idBeginIdx)
+ CodeVariables.SPEC_INTERFACE_WRAPPER + funcName
- + funcDecl.substring(end + 1, firstLineBreak);
+ + funcDecl.substring(idEndIdx + 1, idLineEndIdx + 1);
+
+ int lineNumOfID = idExtractor.lineNumOfID();
// Be careful: lineNum - 1 -> index of content array
- content.set(inst.endLineNum, newLine);
+ content.set(inst.endLineNum + lineNumOfID, newLine);
return funcName;
}
public static void main(String[] argvs) {
String homeDir = Environment.HOME_DIRECTORY;
File[] srcFiles = {
- // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c"),
- // new File(homeDir
- // +
- // "/benchmark/cliffc-hashtable/simplified_cliffc_hashtable.h"),
- new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
- new File(homeDir + "/benchmark/ms-queue/my_queue.h") };
+ // new File(homeDir + "/benchmark/linuxrwlocks/linuxrwlocks.c"),
+ new File(homeDir
+ + "/benchmark/cliffc-hashtable/simplified_cliffc_hashtable.h"), };
+ // new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
+ // new File(homeDir + "/benchmark/ms-queue/my_queue.h") };
CodeGenerator gen = new CodeGenerator(srcFiles);
gen.generateCode();
}
import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
+import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
+import edu.uci.eecs.specCompiler.specExtraction.SpecConstruct;
public class CodeVariables {
// C++ code or library
- public static final String HEADER_threads = "threads.h";
+ public static final String HEADER_THREADS = "threads.h";
public static final String ThreadIDType = "thrd_t";
public static final String GET_THREAD_ID = "thrd_current";
public static final String BOOLEAN = "bool";
public static final String UINT64 = "uint64_t";
// Model checker code
- public static final String HEADER_CDSAnnotate = "cdsannotate.h";
+ public static final String HEADER_CDSANNOTATE = "cdsannotate.h";
public static final String HEADER_SPECANNOTATION = "specannotation.h";
+ public static final String HEADER_CDSTRACE = "cdstrace.h";
public static final String CDSAnnotate = "cdsannotate";
public static final String CDSAnnotateType = "SPEC_ANALYSIS";
- // It's a SPEC_TAG type, it has current() and next() function
- public static final String INTERFACE_CALL_SEQUENCE = "__interface_call_sequence";
+ public static final String GET_PREV_ATOMIC_VAL = "get_prev_value";
- public static final String SPEC_ANNOTATION_TYPE = "spec_anno_type";
+ public static final String SPEC_ANNO_TYPE = "spec_anno_type";
+ public static final String SPEC_ANNO_TYPE_HB_INIT = "HB_INIT";
+ public static final String SPEC_ANNO_TYPE_INTERFACE_BEGIN = "INTERFACE_BEGIN";
+ public static final String SPEC_ANNO_TYPE_POST_CHECK = "POST_CHECK";
+ public static final String SPEC_ANNO_TYPE_HB_CONDITION = "HB_CONDITION";
+ public static final String SPEC_ANNO_TYPE_INTERFACE_END = "INTERFACE_END";
+ public static final String SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE = "POTENTIAL_CP_DEFINE";
public static final String SPEC_ANNOTATION = "spec_annotation";
+ public static final String SPEC_ANNOTATION_FIELD_TYPE = "type";
+ public static final String SPEC_ANNOTATION_FIELD_ANNO = "annotation";
public static final String ANNO_HB_INIT = "anno_hb_init";
public static final String ANNO_INTERFACE_BOUNDARY = "anno_interface_boundary";
public static final String ANNO_POST_CHECK = "anno_post_check";
// Specification variables
- public static final String SPEC_SEQUENTIAL_HEADER = "_spec_sequential.h";
- public static final String SPEC_SEQUENTIAL_HEADER_MACRO = SPEC_SEQUENTIAL_HEADER
+ public static final String HEADER_SPEC_SEQUENTIAL = "_spec_sequential.h";
+ public static final String SPEC_SEQUENTIAL_HEADER_MACRO = HEADER_SPEC_SEQUENTIAL
.replace('.', '_').toUpperCase();
public static final String SPEC_SEQUENTIAL_STRUCT = "Sequential";
public static final String SPEC_SEQUENTIAL_INSTANCE = "__sequential";
public static final String SPEC_ID = "id";
public static final String SPEC_INTERFACE = "interface";
public static final String SPEC_INTERFACE_CALL_SEQUENCE = "interface_call_sequence";
+ public static final String SPEC_GLOBAL_CALL_SEQUENCE = "global_call_sequence";
public static final String SPEC_INTERFACE_WRAPPER = "__wrapper_";
+ public static final String VAR_ThreadID = "tid";
+ public static final String VAR_CALL_SEQUENCE_NUM = "call_sequence_num";
+
// Specification library
public static final String SPEC_QUEUE = "spec_queue";
public static final String SPEC_STACK = "spec_stack";
+ public static final String SPEC_DEQUE = "spec_deque";
public static final String SPEC_HASHTABLE = "spec_hashtable";
- public static final String SPEC_PRIVATE_HASHTABLE_HEADER = "spec_private_hashtable.h";
+ public static final String HEADER_SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable.h";
public static final String SPEC_PRIVATE_HASHTABLE = "spec_private_hashtable";
+ public static final String HEADER_SPEC_TAG = "spec_tag.h";
public static final String SPEC_TAG = "spec_tag";
+ public static final String SPEC_TAG_CURRENT = "current";
+ public static final String SPEC_TAG_NEXT = "next";
// Macro
public static final String MACRO_ID = "__ID__";
public static final String MACRO_COND = "__COND_SAT__";
public static final String MACRO_RETURN = "__RET__";
+ public static final String MACRO_ATOMIC_RETURN = "__ATOMIC_RET__";
// Break the code (String) into multiple lines and add it to newCode
private static void breakCodeLines(ArrayList<String> newCode, String code) {
}
}
- private static void printCode(ArrayList<String> code) {
+ public static void printCode(ArrayList<String> code) {
for (int i = 0; i < code.size(); i++) {
System.out.println(code.get(i));
}
}
-
+
+ public static String getFuncName(String funcDecl) {
+ int beginIdx = funcDecl.indexOf('(');
+ IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx);
+ return idExtractor.getPrevID();
+ }
+
+ public static String getFuncReturnType(String funcDecl) {
+ int beginIdx = funcDecl.indexOf('(');
+ IDExtractor idExtractor = new IDExtractor(funcDecl, beginIdx);
+ idExtractor.getPrevID();
+ int idLineBegin = idExtractor.lineBeginIdxOfID(), idBegin = idExtractor
+ .getIDBeginIdx();
+ String type = funcDecl.substring(idLineBegin, idBegin);
+ return SpecExtractor.trimSpace(type);
+ }
+
+ public static ArrayList<String> getFuncArgs(String funcDecl) {
+ ArrayList<String> args = new ArrayList<String>();
+ int beginIdx = funcDecl.indexOf('('), endIdx = funcDecl.indexOf(')');
+ IDExtractor idExtractor = new IDExtractor(funcDecl, endIdx);
+ String arg = idExtractor.getPrevID();
+ // Void argument
+ if (arg == null || idExtractor.getIDBeginIdx() < beginIdx) {
+ return args;
+ } else {
+ args.add(arg);
+ }
+
+ do {
+ endIdx = funcDecl.lastIndexOf(',', endIdx);
+ if (endIdx == -1) {
+ return args;
+ }
+ idExtractor.reset(endIdx);
+ args.add(idExtractor.getPrevID());
+ } while (true);
+ }
+
+ private static String COMMENT(String comment) {
+ return "/* " + comment + " */";
+ }
+
+ private static String GET(String var) {
+ return "get(&" + VAR(var) + ", " + VAR_ThreadID + ")";
+ }
+
+ private static String PUT(String var, String tid, String val) {
+ return "put(&" + VAR(var) + ", " + tid + ", " + val + ");";
+ }
+
+ private static String INIT(String var) {
+ return "init(&" + VAR(var) + ");";
+ }
+
+ private static String INCLUDE(String header) {
+ return "#include <" + header + ">";
+ }
+
+ private static String DEFINE(String left, String right) {
+ return "#define " + left + " " + right;
+ }
+
+ private static String UNDEFINE(String macro) {
+ return "#undef " + macro;
+ }
+
+ private static String VAR(String var) {
+ return SPEC_SEQUENTIAL_INSTANCE + "." + var;
+ }
+
+ private static String BRACE(String val) {
+ return "(" + val + ")";
+ }
+
+ private static String VAR_PTR(String var) {
+ return "&" + SPEC_SEQUENTIAL_INSTANCE + "." + var;
+ }
+
+ private static String ASSIGN(String structName, String field, String val) {
+ return structName + "." + field + " = " + val + ";";
+ }
+
+ private static String ASSIGN_PTR(String structName, String field, String val) {
+ return structName + "." + field + " = &" + val + ";";
+ }
+
+ private static String DECLARE(String structType, String structName) {
+ return structType + " " + structName + ";";
+ }
+
+ private static String DECLARE_DEFINE(String type, String var, String val) {
+ return type + " " + var + " = " + val + ";";
+ }
+
+ private static String ANNOTATE(String structName) {
+ return CDSAnnotate + "(" + CDSAnnotateType + ", &" + structName + ");";
+ }
+
public static ArrayList<String> generateGlobalVarDeclaration(
SemanticsChecker semantics, GlobalConstruct construct) {
ArrayList<String> newCode = new ArrayList<String>();
// Header conflicting avoidance macro & headers
- newCode.add("/** @file " + SPEC_SEQUENTIAL_HEADER);
+ newCode.add("/** @file " + HEADER_SPEC_SEQUENTIAL);
newCode.add(" * @brief Automatically generated header file for sequential variables");
newCode.add(" */");
newCode.add("#ifndef " + SPEC_SEQUENTIAL_HEADER_MACRO);
newCode.add("#define " + SPEC_SEQUENTIAL_HEADER_MACRO);
- newCode.add("#include " + "<" + SPEC_PRIVATE_HASHTABLE_HEADER + ">");
- newCode.add("#include " + "<" + HEADER_SPECANNOTATION + ">");
+ newCode.add("");
+ newCode.add(INCLUDE(HEADER_SPEC_PRIVATE_HASHTABLE));
+ newCode.add(INCLUDE(HEADER_SPECANNOTATION));
+ newCode.add(INCLUDE(HEADER_SPEC_TAG));
+ newCode.add("");
// Generate all sequential variables into a struct
- newCode.add("/* Beginning of struct " + SPEC_SEQUENTIAL_STRUCT + " */");
+ newCode.add(COMMENT("Beginning of struct " + SPEC_SEQUENTIAL_STRUCT));
newCode.add("typedef struct " + SPEC_SEQUENTIAL_STRUCT + " {");
- newCode.add("/* Condition of interface */");
- newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_CONDITION + ";");
- newCode.add("/* ID of interface */");
- newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_ID + ";");
- newCode.add("/* Current interface call */");
- newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_INTERFACE + ";");
- newCode.add("/* Current interface call sequence */");
- newCode.add(SPEC_PRIVATE_HASHTABLE + " " + SPEC_INTERFACE_CALL_SEQUENCE
- + ";");
+ newCode.add(COMMENT("Condition"));
+ newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, SPEC_CONDITION));
+ newCode.add(COMMENT("ID"));
+ newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, SPEC_ID));
+ newCode.add(COMMENT("Current interface call"));
+ newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE, SPEC_INTERFACE));
+ newCode.add(COMMENT("Current interface call sequence"));
+ newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE,
+ SPEC_INTERFACE_CALL_SEQUENCE));
+ newCode.add(COMMENT("Global interface call sequence number"));
+ newCode.add(DECLARE(SPEC_TAG, SPEC_GLOBAL_CALL_SEQUENCE));
newCode.add("");
// DefineVar declaration
for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct
.get(interfaceName).construct;
ArrayList<DefineVar> defineVars = iConstruct.action.defineVars;
- newCode.add("/* DefineVar in " + interfaceName + " */");
- for (int i = 0; i < defineVars.size(); i++) {
- DefineVar var = defineVars.get(i);
- newCode.add(SPEC_PRIVATE_HASHTABLE + " " + var.getNewVarName()
- + ";");
+ if (defineVars.size() > 0) {
+ newCode.add(COMMENT("DefineVar in " + interfaceName));
+ for (int i = 0; i < defineVars.size(); i++) {
+ DefineVar var = defineVars.get(i);
+ newCode.add(DECLARE(SPEC_PRIVATE_HASHTABLE,
+ var.getNewVarName()));
+ }
}
newCode.add("");
}
// Generate user-defined variable declaration
- newCode.add("/* Beginnint of other user-defined variables */");
+ newCode.add(COMMENT("Beginnint of other user-defined variables"));
SequentialDefineSubConstruct globalCode = construct.code;
breakCodeLines(newCode, globalCode.declareVar);
- newCode.add("/* End of other user-defined variables */");
+ newCode.add(COMMENT("End of other user-defined variables"));
// End of struct Sequential
- newCode.add("} " + SPEC_SEQUENTIAL_STRUCT + "; /* End of struct "
- + SPEC_SEQUENTIAL_STRUCT + " */");
-
- // Generate
-
- // Generate code from the DefineVar, __COND_SAT__ and __ID__
- // The hashtable in the contract can only contains pointers or integers
- // __COND_SAT__
- newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_CONDITION
- + ";");
- // __ID__
- newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_ID + ";");
- // DefineVars
+ newCode.add("} " + SPEC_SEQUENTIAL_STRUCT + "; "
+ + COMMENT("End of struct " + SPEC_SEQUENTIAL_STRUCT));
+
+ // Generate definition of the sequential struct
+ newCode.add("");
+ newCode.add(COMMENT("Instance of the struct"));
+ newCode.add(DECLARE(SPEC_SEQUENTIAL_STRUCT, SPEC_SEQUENTIAL_INSTANCE));
+
+ newCode.add("");
+ newCode.add(COMMENT("Define function for sequential code initialization"));
+ newCode.add("void " + SPEC_SEQUENTIAL_INSTANCE + "_init() {");
+ // Internal variables
+ newCode.add(COMMENT("Init internal variables"));
+ newCode.add(INIT(SPEC_CONDITION));
+ newCode.add(INIT(SPEC_ID));
+ newCode.add(INIT(SPEC_INTERFACE));
+ newCode.add(INIT(SPEC_INTERFACE_CALL_SEQUENCE));
+ newCode.add(INIT(SPEC_GLOBAL_CALL_SEQUENCE));
+ // Init DefineVars
+ newCode.add(COMMENT("Init DefineVars"));
for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct
.get(interfaceName).construct;
ArrayList<DefineVar> defineVars = iConstruct.action.defineVars;
- for (int i = 0; i < defineVars.size(); i++) {
- DefineVar var = defineVars.get(i);
- newCode.add(CodeVariables.SPEC_HASHTABLE + var.getNewVarName()
- + ";");
+ if (defineVars.size() > 0) {
+ newCode.add(COMMENT("DefineVar in " + interfaceName));
+ for (int i = 0; i < defineVars.size(); i++) {
+ DefineVar var = defineVars.get(i);
+ newCode.add(INIT(var.getNewVarName()));
+ }
}
}
- // __interface
- newCode.add(CodeVariables.SPEC_HASHTABLE + CodeVariables.SPEC_INTERFACE
- + ";");
- // __interface_call_sequence
- newCode.add(CodeVariables.SPEC_HASHTABLE
- + CodeVariables.SPEC_INTERFACE_CALL_SEQUENCE + ";");
- // Interface call sequence varaiable
- newCode.add(CodeVariables.SPEC_TAG + " "
- + CodeVariables.INTERFACE_CALL_SEQUENCE + ";");
- // End of the struct
- newCode.add("}");
-
- // FIXME: Constructor should be modified and put in the right place
- // Generate constructor (the place to initialize everything!)
+ // Init user-defined variables
+ newCode.add(COMMENT("Init user-defined variables"));
breakCodeLines(newCode, globalCode.initVar);
- // __COND_SAT__
- newCode.add("init_table(&" + CodeVariables.SPEC_CONDITION + ");");
- // __ID__
- newCode.add("init_table(&" + CodeVariables.SPEC_ID + ");");
- // DefineVars
- for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
- InterfaceConstruct iConstruct = (InterfaceConstruct) semantics.interfaceName2Construct
- .get(interfaceName).construct;
- ArrayList<DefineVar> defineVars = iConstruct.action.defineVars;
- for (int i = 0; i < defineVars.size(); i++) {
- DefineVar var = defineVars.get(i);
- newCode.add("init_table(&" + var.getNewVarName() + ");");
- }
- }
- // __interface
- newCode.add("init_table(&" + CodeVariables.SPEC_INTERFACE + ");");
- // __interface_call_sequence
- newCode.add("init_table(&" + CodeVariables.SPEC_INTERFACE_CALL_SEQUENCE
- + ");");
-
- // Pass the happens-before relationship check here
+ // Pass the HB initialization
+ newCode.add(COMMENT("Pass the happens-before initialization here"));
newCode.addAll(CodeVariables.generateHBInitAnnotation(semantics));
+ // End of init the function
+ newCode.add("} " + COMMENT("End of init function"));
- newCode.add("\n");
-
- // Generate the sequential functions
+ // Generate the user-defined sequential functions
+ newCode.add("");
+ newCode.add(COMMENT("All other user-defined functions"));
breakCodeLines(newCode, globalCode.defineFunc);
// The end
- newCode.add("#endif " + SPEC_SEQUENTIAL_HEADER_MACRO + "\t/* End of "
- + SPEC_SEQUENTIAL_HEADER + " */");
+ newCode.add("");
+ newCode.add("#endif " + SPEC_SEQUENTIAL_HEADER_MACRO + "\t"
+ + COMMENT("End of " + HEADER_SPEC_SEQUENTIAL));
- printCode(newCode);
+ // printCode(newCode);
return newCode;
}
- public static ArrayList<String> generateHBInitAnnotation(
+ private static ArrayList<String> generateHBInitAnnotation(
SemanticsChecker semantics) {
ArrayList<String> newCode = new ArrayList<String>();
int hbConditionInitIdx = 0;
for (ConditionalInterface right : semantics.getHBConditions().get(
left)) {
String structVarName = "hbConditionInit" + hbConditionInitIdx;
+ String annotationVarName = "hb_init" + hbConditionInitIdx;
hbConditionInitIdx++;
- int interfaceNumBefore = semantics.interface2Num
- .get(left.interfaceName), hbLabelNumBefore = semantics.hbLabel2Num
- .get(left.hbConditionLabel), interfaceNumAfter = semantics.interface2Num
- .get(right.interfaceName), hbLabelNumAfter = semantics.hbLabel2Num
- .get(right.hbConditionLabel);
+ String interfaceNumBefore = Integer
+ .toString(semantics.interface2Num
+ .get(left.interfaceName)), hbLabelNumBefore = Integer
+ .toString(semantics.hbLabel2Num
+ .get(left.hbConditionLabel)), interfaceNumAfter = Integer
+ .toString(semantics.interface2Num
+ .get(right.interfaceName)), hbLabelNumAfter = Integer
+ .toString(semantics.hbLabel2Num
+ .get(right.hbConditionLabel));
+ newCode.add(COMMENT(left + " -> " + right));
+
newCode.add(ANNO_HB_INIT + " " + structVarName + ";");
+ newCode.add(ASSIGN(structVarName, "interface_num_before",
+ interfaceNumBefore));
+ newCode.add(ASSIGN(structVarName, "hb_condition_num_before",
+ hbLabelNumBefore));
+ newCode.add(ASSIGN(structVarName, "interface_num_after",
+ interfaceNumAfter));
+ newCode.add(ASSIGN(structVarName, "hb_condition_num_after",
+ hbLabelNumAfter));
- newCode.add(structVarName + "." + "interface_num_before"
- + " = " + interfaceNumBefore + ";");
- newCode.add(structVarName + "." + "hb_condition_num_before"
- + " = " + hbLabelNumBefore + ";");
- newCode.add(structVarName + "." + "interface_num_after" + " = "
- + interfaceNumAfter + ";");
- newCode.add(structVarName + "." + "hb_condition_num_after"
- + " = " + hbLabelNumAfter + ";");
-
- newCode.add(CDSAnnotate + "(" + CDSAnnotateType + ", &"
- + structVarName + ");");
+ newCode.add(DECLARE(SPEC_ANNOTATION, annotationVarName));
+ newCode.add(ASSIGN(annotationVarName,
+ SPEC_ANNOTATION_FIELD_TYPE, SPEC_ANNO_TYPE_HB_INIT));
+ newCode.add(ASSIGN_PTR(annotationVarName,
+ SPEC_ANNOTATION_FIELD_ANNO, structVarName));
+ newCode.add(ANNOTATE(annotationVarName));
}
}
return newCode;
}
+
+ public static ArrayList<String> generateInterfaceWrapper(
+ SemanticsChecker semantics, SpecConstruct inst) {
+ InterfaceConstruct construct = (InterfaceConstruct) inst.construct;
+ ArrayList<String> newCode = new ArrayList<String>();
+ String funcDecl = inst.interfaceDeclBody.substring(0,
+ inst.interfaceDeclBody.indexOf(')') + 1);
+ String returnType = getFuncReturnType(funcDecl), funcName = getFuncName(funcDecl), renamedFuncName = SPEC_INTERFACE_WRAPPER
+ + funcName;
+ ArrayList<String> args = getFuncArgs(funcDecl);
+
+ // Generate necessary header file (might be redundant but never mind)
+ newCode.add(COMMENT("Automatically generated code for interface: "
+ + construct.name));
+ newCode.add(COMMENT("Include redundant headers"));
+ newCode.add(INCLUDE(HEADER_THREADS));
+ newCode.add(INCLUDE(HEADER_CDSANNOTATE));
+ newCode.add(INCLUDE(HEADER_SPECANNOTATION));
+ newCode.add(INCLUDE(HEADER_SPEC_TAG));
+ newCode.add(INCLUDE(HEADER_SPEC_PRIVATE_HASHTABLE));
+ newCode.add("");
+
+ // Generate wrapper header
+ newCode.add(COMMENT("Wrapper for " + SPEC_INTERFACE_WRAPPER + funcName));
+ breakCodeLines(newCode, funcDecl);
+ newCode.add("{");
+
+ // Wrapper function body
+ newCode.add(DECLARE_DEFINE(ThreadIDType, VAR_ThreadID, GET_THREAD_ID
+ + BRACE("")));
+ newCode.add(DECLARE_DEFINE(UINT64, VAR_CALL_SEQUENCE_NUM,
+ SPEC_TAG_CURRENT + BRACE(VAR_PTR(SPEC_GLOBAL_CALL_SEQUENCE))));
+ newCode.add(SPEC_TAG_NEXT + BRACE(VAR_PTR(SPEC_GLOBAL_CALL_SEQUENCE)));
+ newCode.add(PUT(SPEC_INTERFACE_CALL_SEQUENCE, VAR_ThreadID,
+ VAR_CALL_SEQUENCE_NUM));
+ // Interface begin
+ newCode.add("");
+ newCode.add(COMMENT("Interface begin"));
+ String interfaceName = construct.name;
+ String annoStruct = "interface_boundary", interfaceNum = Integer
+ .toString(semantics.interface2Num.get(interfaceName));
+ newCode.add(DECLARE(ANNO_INTERFACE_BOUNDARY, annoStruct));
+ newCode.add(ASSIGN(annoStruct, "interface_num", interfaceNum));
+ newCode.add(ASSIGN(annoStruct, "call_sequence_num",
+ VAR_CALL_SEQUENCE_NUM));
+ String anno = "annotation_interface_begin";
+ newCode.add(DECLARE(SPEC_ANNOTATION, anno));
+ newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE,
+ SPEC_ANNO_TYPE_INTERFACE_BEGIN));
+ newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct));
+ newCode.add(ANNOTATE(anno));
+ // Call original renamed function
+ String funcCall = renamedFuncName + "(";
+ if (args.size() == 0) {
+ funcCall = funcCall + ")";
+ } else {
+ funcCall = funcCall + args.get(0);
+ for (int i = 1; i < args.size(); i++) {
+ funcCall = funcCall + ", " + args.get(i);
+ }
+ funcCall = funcCall + ")";
+ }
+ newCode.add(DECLARE_DEFINE(returnType, MACRO_RETURN, funcCall));
+ newCode.add(DECLARE_DEFINE("int", MACRO_COND, GET(SPEC_CONDITION)));
+ newCode.add(DECLARE_DEFINE(UINT64, MACRO_ID, GET(SPEC_ID)));
+ // Post check & action
+ newCode.add("");
+ newCode.add(COMMENT("Post_check action, define macros for all DefineVars"));
+ // Define all DefineVar macro
+ ArrayList<DefineVar> defineVars = construct.action.defineVars;
+ for (int i = 0; i < defineVars.size(); i++) {
+ DefineVar var = defineVars.get(i);
+ newCode.add(DEFINE(var.varName, BRACE(GET(interfaceName + "_"
+ + var.varName))));
+ }
+ // Post check
+ newCode.add(DECLARE_DEFINE("bool", "post_check_passed",
+ construct.postCheck));
+ annoStruct = "post_check";
+ newCode.add(DECLARE(ANNO_POST_CHECK, annoStruct));
+ newCode.add(ASSIGN(annoStruct, "check_passed", "post_check_passed"));
+ newCode.add(ASSIGN(annoStruct, "interface_num", interfaceNum));
+ newCode.add(ASSIGN(annoStruct, "call_sequence_num",
+ VAR_CALL_SEQUENCE_NUM));
+ anno = "annotation_post_check";
+ newCode.add(DECLARE(SPEC_ANNOTATION, anno));
+ newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE,
+ SPEC_ANNO_TYPE_POST_CHECK));
+ newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct));
+ newCode.add(ANNOTATE(anno));
+ // Post action if any
+ breakCodeLines(newCode, construct.postAction);
+ // Undefine all DefineVar macro
+ for (int i = 0; i < defineVars.size(); i++) {
+ DefineVar var = defineVars.get(i);
+ newCode.add(UNDEFINE(var.varName));
+ }
+ // HB conditions
+ newCode.add("");
+ for (String label : construct.hbConditions.keySet()) {
+ String hbCondition = construct.hbConditions.get(label);
+ newCode.add(COMMENT("Happens-before condition for " + label
+ + " ::= " + hbCondition));
+ newCode.add("if " + BRACE(hbCondition) + " {");
+ String hbNum = Integer.toString(semantics.hbLabel2Num.get(label));
+ annoStruct = "hb_condition" + hbNum;
+ newCode.add(DECLARE(ANNO_HB_CONDITION, annoStruct));
+ newCode.add(ASSIGN(annoStruct, "interface_num", interfaceNum));
+ newCode.add(ASSIGN(annoStruct, "hb_condition_num", hbNum));
+ newCode.add(ASSIGN(annoStruct, "id", MACRO_ID));
+ newCode.add(ASSIGN(annoStruct, "call_sequence_num",
+ VAR_CALL_SEQUENCE_NUM));
+ anno = "annotation_hb_condition";
+ newCode.add(DECLARE(SPEC_ANNOTATION, anno));
+ newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE,
+ SPEC_ANNO_TYPE_HB_CONDITION));
+ newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct));
+ ANNOTATE(anno);
+ newCode.add("} " + COMMENT("End of HB condition " + label));
+ newCode.add("");
+ }
+ // Interface end
+ annoStruct = "interface_boundary";
+ anno = "annotation_interface_end";
+ newCode.add(DECLARE(SPEC_ANNOTATION, anno));
+ newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE,
+ SPEC_ANNO_TYPE_INTERFACE_END));
+ newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct));
+ newCode.add(ANNOTATE(anno));
+
+ // End of the wrapper function
+ newCode.add("} "
+ + COMMENT("End of automatically generated code for interface wrapper"));
+
+ printCode(newCode);
+ return newCode;
+ }
+
+ public static ArrayList<String> generatePotentialCPDefine(
+ SemanticsChecker semantics, SpecConstruct inst) {
+ PotentialCPDefineConstruct construct = (PotentialCPDefineConstruct) inst.construct;
+ ArrayList<String> newCode = new ArrayList<String>();
+
+ // Generate redundant header files
+ newCode.add(COMMENT("Automatically generated code for potential commit point: "
+ + construct.label));
+ newCode.add(COMMENT("Include redundant headers"));
+ newCode.add(INCLUDE(HEADER_THREADS));
+ newCode.add(INCLUDE(HEADER_CDSTRACE));
+ newCode.add(INCLUDE(HEADER_SPEC_PRIVATE_HASHTABLE));
+ newCode.add(INCLUDE(HEADER_SPEC_SEQUENTIAL));
+ newCode.add("");
+ // Some necessary function calls
+ newCode.add(DECLARE_DEFINE(ThreadIDType, VAR_ThreadID, GET_THREAD_ID
+ + BRACE("")));
+ newCode.add(DECLARE_DEFINE(UINT64, MACRO_ATOMIC_RETURN,
+ GET_PREV_ATOMIC_VAL + BRACE(VAR_ThreadID)));
+ newCode.add("if " + BRACE(construct.condition) + " {");
+ newCode.add(DECLARE_DEFINE(UINT64, VAR_CALL_SEQUENCE_NUM,
+ GET(SPEC_INTERFACE_CALL_SEQUENCE)));
+ String annoStruct = "potential_cp_define";
+ newCode.add(DECLARE(ANNO_POTENTIAL_CP_DEFINE, annoStruct));
+ newCode.add(ASSIGN(annoStruct, "interface_num", GET(SPEC_INTERFACE)));
+ String labelNum = Integer.toString(semantics.commitPointLabel2Num
+ .get(construct.label));
+ newCode.add(ASSIGN(annoStruct, "label_num", labelNum));
+ newCode.add(ASSIGN(annoStruct, "call_sequence_num",
+ VAR_CALL_SEQUENCE_NUM));
+ String anno = "annotation_potential_cp_define";
+ newCode.add(DECLARE(SPEC_ANNOTATION, anno));
+ newCode.add(ASSIGN(anno, SPEC_ANNOTATION_FIELD_TYPE,
+ SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE));
+ newCode.add(ASSIGN_PTR(anno, SPEC_ANNOTATION_FIELD_ANNO, annoStruct));
+ ANNOTATE(anno);
+
+ newCode.add("} "
+ + COMMENT("End of automatically generated code for potential commit point"));
+
+ return newCode;
+ }
}