#include <stdlib.h>
#include <stdio.h>
+inline bool fail(int ret) {
+ return ret == ABORT || ret == EMPTY;
+}
+
Deque * create() {
Deque * q = (Deque *) calloc(1, sizeof(Deque));
Array * a = (Array *) calloc(1, sizeof(Array)+2*sizeof(atomic_int));
#define EMPTY 0xffffffff
#define ABORT 0xfffffffe
+inline bool fail(int ret);
/**
@Begin
@Options:
Push -> Steal
@Commutativity: Push <-> Steal: true
@Commutativity: Take <-> Steal: true
- @Commutativity: Steal <-> Steal: _Method1.__RET__ == ABORT || _Method2.__RET__ == ABORT
+ @Commutativity: Steal <-> Steal: fail(_Method1.__RET__) || fail(_Method2.__RET__)
@End
*/
+++ /dev/null
-"preScanner.jj" is used to process the backslash sign at the end of a line
-(basically splice broken lines before really processing the specifications).
-
-"util.jj" is used to process some specific strings, such as the declaration of a
-function with templated types. It is designed to be used as a library funcions.
-
-"spec_compiler.jj" is the file to parse the extracted specifications.
+++ /dev/null
-/* spec-compiler.jj Grammer definition for the specification */
-
-
-/*
- SPEC constructs:
- Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation.
- Within there, any line beginning with a "#" is a comment of the annotation.
- Each constrcut should begin with @Begin and end with @End. Otherwise, the
- annotation would be considered as normal comments of the source.
-
- a) Global construct
- @Begin
- @Options:
- # If LANG is not define, it's C++ by default. C does not support class
- # and template, so if it's defined as C, we should also have a explicit
- # entry point.
- LANG = C;
- @Global_define:
- @DeclareVar:
- @InitVar:
- @DefineFunc:
- ...
- @Interface_cluster:
- ...
- @Happens-before:
- ...
- @End
-
- b) Interface construct
- @Begin
- @Interface: ...
- @Commit_point_set:
- IDENTIFIER | IDENTIFIER ...
- @Condition: ... (Optional)
- @HB_Condition:
- IDENTIFIER :: <C_CPP_Condition>
- @HB_Condition: ...
- @ID: ... (Optional, use default ID)
- @Check: (Optional)
- ...
- @Action: (Optional)
- # Type here must be a pointer
- @DefineVar: Type var1 = SomeExpression (Optional)
- @Code (Optional)
- ...
- @Post_action: (Optional)
- @Post_check: (Optional)
- @End
-
- c) Potential commit construct
- @Begin
- @Potential_commit_point_define: ...
- @Label: ...
- @End
-
- d) Commit point define construct
- @Begin
- @Commit_point_define_check: ...
- @Label: ...
- @End
-
- OR
-
- @Begin
- @Commit_point_define: ...
- @Potential_commit_point_label: ...
- @Label: ...
- @End
-
- e) Entry point construct
- @Begin
- @Entry_point
- @End
-
- f) Interface define construct
- @Begin
- @Interface_define: <Interface_Name>
- @End
-*/
-
-
-
-options {
- STATIC = false;
- JAVA_UNICODE_ESCAPE = true;
-}
-
-PARSER_BEGIN(SpecParser)
-package edu.uci.eecs.specCompiler.grammerParser;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import edu.uci.eecs.specCompiler.specExtraction.Construct;
-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.CPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
-import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ActionSubConstruct.DefineVar;
-import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
-
- public class SpecParser {
- public static void main(String[] argvs)
- throws ParseException, TokenMgrError {
- try {
- FileInputStream fis = new FileInputStream("./grammer/spec.txt");
- SpecParser parser = new SpecParser(fis);
- //parser.Parse();
- System.out.println("Parsing finished!");
- ArrayList<String> typeParams = parser.FormalParamList();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- public static Construct parseSpec(String text)
- throws ParseException, TokenMgrError {
- InputStream input = new ByteArrayInputStream(text.getBytes());
- SpecParser parser = new SpecParser(input);
- return parser.Parse();
- }
-
-
- }
-PARSER_END(SpecParser)
-
- "/*"}
-
-< IN_COMMENT > SKIP : { < ~[] > }
-
-< IN_COMMENT > SKIP : {
- "*/": DEFAULT
-}
-
-<IN_COMMENT> TOKEN : {
- <A: "@A"> |
- <B: "@B">
-}
-
-SKIP :
-{
- " "
-|
- "\n"
-|
- "\r"
-|
- "\r\n"
-|
- "\t"
-|
- // "#" comment for the specification
- <"#" (~["\n", "\r"])* (["\n", "\r"])>
-|
- // "//" comment for the specification
- <"//" (~["\n", "\r"])* (["\n", "\r"])>
-}
-
-<IN_COMMENT, DEFAULT> TOKEN :
-{
-/* Above are specification-only tokens */
- <HEAD: "/**" : IN_COMMENT>
-|
- <TAIL: "*/" : DEFAULT>
-|
- <BEGIN: "@Begin">
-|
- <END: "@End">
-|
- <OPTIONS: "@Options:">
-|
- <GLOBAL_DEFINE: "@Global_define:">
-|
- <DECLARE_VAR: "@DeclareVar:">
-|
- <INIT_VAR: "@InitVar:">
-|
- <DEFINE_FUNC: "@DefineFunc:">
-|
- <INTERFACE_CLUSTER: "@Interface_cluster:">
-|
- <HAPPENS_BEFORE: "@Happens_before:">
-|
- <INTERFACE: "@Interface:">
-|
- <COMMIT_POINT_SET: "@Commit_point_set:">
-|
- <ENTRY_POINT: "@Entry_point">
-|
- <INTERFACE_DEFINE: "@Interface_define:">
-|
- <CONDITION: "@Condition:">
-|
- <HB_CONDITION: "@HB_condition:">
-|
- <ID: "@ID:">
-|
- <CHECK: "@Check:">
-|
- <ACTION: "@Action:">
-|
- <DEFINEVAR: "@DefineVar:">
-|
- <CODE: "@Code:">
-|
- <POST_ACTION: "@Post_action:">
-|
- <POST_CHECK: "@Post_check:">
-|
- <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
-|
- <LABEL: "@Label:">
-|
- <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
-|
- <COMMIT_POINT_DEFINE: "@Commit_point_define:">
-|
- <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
-
-
-/* Specification & C/C++ shared tokens */
-
-// Reserved keywords
-|
- <CONST: "const">
-|
- <STRUCT: "struct">
-|
- <TYPENAME: "typename">
-
-
-|
- <#DIGIT: ["0"-"9"]>
-|
- <#LETTER: ["a"-"z", "A"-"Z"]>
-|
- <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
-|
- <EQUALS: "=">
-|
- <OPEN_PAREN: "{">
-|
- <CLOSE_PAREN: "}">
-|
- <OPEN_BRACKET: "(">
-|
- <CLOSE_BRACKET: ")">
-|
- <HB_SYMBOL: "->">
-|
- <COMMA: ",">
-
-|
-/* C/C++ only token*/
- <DOT: ".">
-|
- <STAR: "*">
-|
- <NEGATE: "~">
-|
- <EXCLAMATION: "!">
-|
- <AND: "&">
-|
- <OR: "|">
-|
- <MOD: "%">
-|
- <PLUS: "+">
-|
- <PLUSPLUS: "++">
-|
- <MINUS: "-">
-|
- <MINUSMINUS: "--">
-|
- <DIVIDE: "/">
-|
- <BACKSLASH: "\\">
-|
- <LESS_THAN: "<">
-|
- <GREATER_THAN: ">">
-|
- <GREATER_EQUALS: ">=">
-|
- <LESS_EQUALS: "<=">
-|
- <LOGICAL_EQUALS: "==">
-|
- <NOT_EQUALS: "!=">
-|
- <LOGICAL_AND: "&&">
-|
- <LOGICAL_OR: "||">
-|
- <XOR: "^">
-|
- <QUESTION_MARK: "?">
-|
- <COLON: ":">
-|
- <DOUBLECOLON: "::">
-|
- <SEMI_COLON: ";">
-|
- <STRING_LITERAL:
- "\""
- ((~["\"","\\","\n","\r"])
- | ("\\"
- ( ["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"]
- ["0"-"7"]
- )
- )
- )*
- "\"">
-|
- <CHARACTER_LITERAL:
- "'"
- ((~["'","\\","\n","\r"])
- | ("\\"
- (["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"]
- ["0"-"7"]
- )
- )
- )
- "'">
-|
- < INTEGER_LITERAL:
- <DECIMAL_LITERAL> (["l","L"])?
- | <HEX_LITERAL> (["l","L"])?
- | <OCTAL_LITERAL> (["l","L"])?>
-|
- < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
-|
- < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
-|
- < #OCTAL_LITERAL: "0" (["0"-"7"])* >
-|
- < FLOATING_POINT_LITERAL:
- <DECIMAL_FLOATING_POINT_LITERAL>
- | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
-|
- < #DECIMAL_FLOATING_POINT_LITERAL:
- (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
- | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
- | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
- | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
-|
- < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
-|
- < #HEXADECIMAL_FLOATING_POINT_LITERAL:
- "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
- | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
-|
- < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
-}
-
-String Type() :
-{
- String type;
- String str;
-}
-{
- { type = ""; }
- ("const"
- { type = "const"; }
- )?
- (("struct" { type = type + " struct"; })?
- (str = <IDENTIFIER>.image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- }))
- ((str = "const".image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- }) |
- (str = <STAR>.image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- }) |
- (str = <AND>.image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- })
- )*
- {
- return type;
- }
-}
-
-ArrayList<String> FormalParamList() :
-{
- ArrayList<String> typeParams;
-}
-{
- {
- typeParams = new ArrayList<String>();
- }
- (TypeParam(typeParams) (<COMMA> TypeParam(typeParams))*)?
- {
- System.out.println(typeParams);
- return typeParams;
- }
-}
-
-void TypeParam(ArrayList<String> typeParams) :
-{
- String type, param;
-}
-{
- (type = Type()) (param = <IDENTIFIER>.image)
- {
- typeParams.add(type);
- typeParams.add(param);
- }
-}
-
-Construct Parse() :
-{
- Construct res;
-}
-{
- (
- LOOKAHEAD(3) res = Global_construct() |
- LOOKAHEAD(3) res = Interface() |
- LOOKAHEAD(3) res = Potential_commit_point_define() |
- LOOKAHEAD(3) res = Commit_point_define() |
- LOOKAHEAD(3) res = Commit_point_define_check() |
- LOOKAHEAD(3) res = Entry_point() |
- LOOKAHEAD(3) res = Interface_define()
- )
- <EOF>
- {
- //System.out.println(res);
- return res;
- }
-}
-
-GlobalConstruct Global_construct() :
-{
- GlobalConstruct res;
- SequentialDefineSubConstruct code;
- HashMap<String, String> options;
- String key, value;
-}
-{
- {
- res = null;
- options = new HashMap<String, String>();
- }
- <HEAD>
- <BEGIN>
- (<OPTIONS>
- ((key = <IDENTIFIER>.image)
- <EQUALS>
- (value = <IDENTIFIER>.image)
- {
- if (options.containsKey(key)) {
- throw new ParseException("Duplicate options!");
- }
- options.put(key, value);
- }
- <SEMI_COLON>
- )*
- )?
- (code = Global_define())
- { res = new GlobalConstruct(code, options); }
- (Interface_clusters(res))?
- (Happens_before(res))?
- <END>
- <TAIL>
- {
- res.unfoldInterfaceCluster();
- return res;
- }
-}
-
-String C_CPP_CODE() :
-{
- StringBuilder text;
- Token t;
-}
-{
- {
- text = new StringBuilder();
- t = new Token();
- }
- (
- //LOOKAHEAD(2)
- (
- t = <CONST> | t = <STRUCT> |
- t = <IDENTIFIER> | t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
- t = <OPEN_BRACKET> | t = <CLOSE_BRACKET> | t = <HB_SYMBOL> | t = <COMMA> |
- t = <DOT> | t = <STAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
- t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
- t = <LESS_THAN> | t = <GREATER_THAN> | t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
- t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
- t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
- t = <SEMI_COLON> | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
- t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL>
- )
- {
- text.append(t.image);
- if (t.image.equals(";") || t.image.equals("\\")
- || t.image.equals("{") || t.image.equals("}"))
- text.append("\n");
- else
- text.append(" ");
- }
- )+
- {
- //System.out.println(text);
- return text.toString();
- }
-}
-
-SequentialDefineSubConstruct Global_define() :
-{
- String declareVar, initVar, defineFunc;
-}
-{
- {
- declareVar = "";
- initVar = "";
- defineFunc = "";
- }
- <GLOBAL_DEFINE>
- (<DECLARE_VAR> (declareVar = C_CPP_CODE()))?
- (<INIT_VAR> (initVar = C_CPP_CODE()))?
- (<DEFINE_FUNC> (defineFunc = C_CPP_CODE()))?
- {
- SequentialDefineSubConstruct res = new SequentialDefineSubConstruct(declareVar, initVar, defineFunc);
- //System.out.println(res);
- return res;
- }
-}
-
-ConditionalInterface Conditional_interface() :
-{
- String interfaceName, hbConditionLabel;
-}
-{
- {
- hbConditionLabel = "";
- }
- interfaceName = <IDENTIFIER>.image (<OPEN_BRACKET> hbConditionLabel =
- <IDENTIFIER>.image <CLOSE_BRACKET>)?
- {
- return new ConditionalInterface(interfaceName, hbConditionLabel);
- }
-}
-
-void Interface_cluster(GlobalConstruct inst) :
-{
- String clusterName;
- ConditionalInterface condInterface;
-}
-{
- (clusterName= <IDENTIFIER>.image)
- <EQUALS> <OPEN_PAREN>
- (condInterface = Conditional_interface()
- { inst.addInterface2Cluster(clusterName, condInterface); }
- )
- (<COMMA> condInterface = Conditional_interface()
- { inst.addInterface2Cluster(clusterName, condInterface); }
- )*
- <CLOSE_PAREN>
-}
-
-void Interface_clusters(GlobalConstruct inst) :
-{}
-{
- <INTERFACE_CLUSTER> (Interface_cluster(inst))+
-}
-
-void Happens_before(GlobalConstruct inst) :
-{
- ConditionalInterface left, right;
-}
-{
- <HAPPENS_BEFORE>
- (
- left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
- { inst.addHBCondition(left, right); }
- )+
-}
-
-InterfaceConstruct Interface() :
-{
- InterfaceConstruct res;
- String interfaceName, condition, idCode, check, postAction,
- postCheck, commitPoint, hbLabel, hbCondition;
- ActionSubConstruct action;
- ArrayList<String> commitPointSet;
- HashMap<String, String> hbConditions;
-}
-{
- {
- res = null;
- action = null;
- condition = "";
- idCode = "";
- check = "";
- postAction = "";
- postCheck = "";
- commitPointSet = new ArrayList<String>();
- hbConditions = new HashMap<String, String>();
- }
- <HEAD>
- <BEGIN>
- <INTERFACE> (interfaceName = <IDENTIFIER>.image)
- <COMMIT_POINT_SET>
- (commitPoint = <IDENTIFIER>.image
- { commitPointSet.add(commitPoint); }
- )
- (<OR>
- (commitPoint = <IDENTIFIER>.image)
- {
- if (commitPointSet.contains(commitPoint)) {
- throw new ParseException(interfaceName + " has" +
- "duplicate commit point labels");
- }
- commitPointSet.add(commitPoint);
- }
- )*
-
- (<CONDITION> (condition = C_CPP_CODE()))?
- (
- <HB_CONDITION>
- (hbLabel = <IDENTIFIER>.image)
- (hbCondition = C_CPP_CODE())
- {
- if (hbConditions.containsKey(hbLabel)) {
- throw new ParseException(interfaceName + " has" +
- "duplicate happens-before condtion labels");
- }
- hbConditions.put(hbLabel, hbCondition);
- }
- )*
- (<ID> (idCode = C_CPP_CODE()))?
- (<CHECK> (check = C_CPP_CODE()))?
- (action = Action())?
- (<POST_ACTION> (postAction = C_CPP_CODE()))?
- (<POST_CHECK> (postCheck = C_CPP_CODE()))?
- <END>
- <TAIL>
- {
- res = new InterfaceConstruct(interfaceName, commitPointSet, condition,
- hbConditions, idCode, check, action, postAction, postCheck);
- return res;
- }
-}
-
-ActionSubConstruct Action() :
-{
- String type, name, expr, defineVarStr, code;
- ArrayList<DefineVar> defineVars;
-}
-{
- {
- defineVars = new ArrayList<DefineVar>();
- code = "";
- }
- <ACTION>
- (
- (
- (<DEFINEVAR> (defineVarStr = C_CPP_CODE())
- {
- int eqIdx = defineVarStr.indexOf('=');
- int typeEnd = defineVarStr.lastIndexOf(' ', eqIdx - 2);
- type = defineVarStr.substring(0, typeEnd);
- name = defineVarStr.substring(typeEnd + 1, eqIdx - 1);
- expr = defineVarStr.substring(eqIdx + 2);
- DefineVar defineVar = new DefineVar(type, name, expr);
- defineVars.add(defineVar);
- })* (<CODE> (code = C_CPP_CODE()))? )
- )
-
- {
- ActionSubConstruct res = new ActionSubConstruct(defineVars, code);
- return res;
- }
-}
-
-PotentialCPDefineConstruct Potential_commit_point_define() :
-{
- PotentialCPDefineConstruct res;
- String label, condition;
-}
-{
-
- { res = null; }
- <HEAD>
- <BEGIN>
- <POTENTIAL_COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- <TAIL>
- {
- res = new PotentialCPDefineConstruct(label, condition);
- return res;
- }
-}
-
-
-CPDefineConstruct Commit_point_define() :
-{
- CPDefineConstruct res;
- String label, potentialCPLabel, condition;
-}
-{
-
- { res = null; }
- <HEAD>
- <BEGIN>
- <COMMIT_POINT_DEFINE> (condition = C_CPP_CODE())
- <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- <TAIL>
- {
- res = new CPDefineConstruct(label, potentialCPLabel, condition);
- return res;
- }
-}
-
-
-CPDefineCheckConstruct Commit_point_define_check() :
-{
- CPDefineCheckConstruct res;
- String label, condition;
-}
-{
-
- { res = null; }
- <HEAD>
- <BEGIN>
- <COMMIT_POINT_DEFINE_CHECK> (condition = C_CPP_CODE())
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- <TAIL>
- {
- res = new CPDefineCheckConstruct(label, condition);
- return res;
- }
-}
-
-EntryPointConstruct Entry_point() :
-{}
-{
-
- <HEAD>
- <BEGIN>
- <ENTRY_POINT>
- <END>
- <TAIL>
- {
- return new EntryPointConstruct();
- }
-}
-
-InterfaceDefineConstruct Interface_define() :
-{
- String name;
-}
-{
- <HEAD>
- <BEGIN>
- <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
- <END>
- <TAIL>
- {
- return new InterfaceDefineConstruct(name);
- }
-}
-
-
+++ /dev/null
-/* pre_scan.jj Process the backslash at the end of line */
-
-options {
- STATIC = false;
- JAVA_UNICODE_ESCAPE = true;
-}
-
-PARSER_BEGIN(PreScanner)
-package edu.uci.eecs.specCompiler.grammerParser.preScanner;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
-import java.util.ArrayList;
-
- public class PreScanner {
- public static void main(String[] argvs)
- throws ParseException, TokenMgrError {
- try {
- FileInputStream fis = new FileInputStream("./grammer/spec.txt");
- PreScanner preScanner = new PreScanner(fis);
- String code = preScanner.ProcessEndBackslash();
- System.out.println(code);
- System.out.println("Finished!");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- }
-PARSER_END(PreScanner)
-
-SKIP : {
- <"\\\n">
-}
-
-TOKEN : {
- <ANY: ~[]>
-}
-
-String ProcessEndBackslash() :
-{
- StringBuilder sb;
- String str;
-}
-{
- { sb = new StringBuilder(); }
- (str = <ANY>.image { sb.append(str); } )* <EOF>
- {
- return sb.toString();
- }
-}
+++ /dev/null
-/**
-@Begin
- @Options:
- LANG = C;
- CLASS = cliffc_hashtable;
- @Global_define:
- @DeclareVar:
- spec_hashtable<TypeK, TypeV*> map;
- spec_hashtable<TypeK, Tag> id_map;
- Tag tag;
- @InitVar:
- map = spec_hashtable<TypeK, TypeV*>();
- id_map = spec_hashtable<TypeK, TypeV*>();
- tag = Tag();
- @DefineFunc:
- static bool equals_val(TypeV *ptr1, TypeV *ptr2) {
- // ...
- }
-
- # Update the tag for the current key slot if the corresponding tag
- # is NULL, otherwise just return that tag. It will update the next
- # available tag too if it requires a new tag for that key slot.
- static Tag getKeyTag(TypeK &key) {
- if (id_map.get(key) == NULL) {
- Tag cur_tag = tag.current();
- id_map.put(key, cur_tag);
- tag.next();
- return cur_tag;
- } else {
- return id_map.get(key);
- }
- }
-
- @Interface_cluster:
- Read_interface = {
- Get,
- PutIfAbsent,
- RemoveAny,
- RemoveIfMatch,
- ReplaceAny,
- ReplaceIfMatch
- }
-
- Write_interface = {
- Put,
- PutIfAbsent(COND_PutIfAbsentSucc),
- RemoveAny,
- RemoveIfMatch(COND_RemoveIfMatchSucc),
- ReplaceAny,
- ReplaceIfMatch(COND_ReplaceIfMatchSucc)
- }
- @Happens_before:
- Write_interface -> Read_interface
- @End
- */
+++ /dev/null
-/* spec-compiler.jj Grammer definition for the specification */
-
-
-/*
- SPEC constructs:
- Each construct should be embraced by /DOUBLE_STAR ... STAR/ annotation.
- Within there, any line beginning with a "#" is a comment of the annotation.
- Each constrcut should begin with @Begin and end with @End. Otherwise, the
- annotation would be considered as normal comments of the source.
-
- a) Global construct
- @DeclareState: C/C++ variable declaration; // Declare the state structure
- @InitState: C/C++ statements; // Specify how to initialize the state
- @CopyState: // A function on how to copy an existing state (Not sure if we
- // need this because we might be able to auto this
- @Commutativity: Method1 <-> Method2 (Guard) // Admissibility condition.
- // Allow specify 0-many rules
-
- b) Interface construct
- @Interface: InterfaceName // Required; a label to represent the interface
- @LocalState: // Optional; to calculate the accumulative local state before this
- // method call in a customized fashion. If not specified here, the
- // local state would be default, which is the result of the
- // execution on the subset of method calls in the sequential order
- @PreCondition: // Optional; checking code
- @LocalSideEffect: // Optional; to calculate the side effect this method call
- // have on the local state in a customized fashion. If this
- // field is not stated, it means we don't care about it.
- @SideEffect: // Optional; to calculate the side effect on the global state. When
- // the "@LocalSideEffect" specification is ommitted, we also impose the
- // same side effect on the set of method calls that happen before this
- // method call in the sequential order.
- @PostCondition: // Optional; checking code
-
-
- c) Ordering point construct
- @OPDefine: condition // If the specified condition satisfied, the atomic
- // operation right before is an ordering point
-
- @PotentialOP(Label): condition // If the specified condition satisfied, the
- // atomic operation right before is a potential
- // ordering point, and we label it with a tag
-
- @OPCheck(Label): condition // If the specified condition satisfied, the
- // potential ordering point defined earlier with the
- // same tag becomes an ordering point
-
- @OPClear: condition // If the specified condition satisfied, all the
- // ordering points and potential ordering points will be
- // cleared
-
- @OPClearDefine: condition // If the specified condition satisfied, all the
- // ordering points and potential ordering points will
- // be cleared, and the atomic operation right before
- // becomes an ordering point. This is a syntax sugar
- // as the combination of an "OPClear" and "OPDefine"
- // statement
-
-*/
-
-
-
-options {
- STATIC = false;
- JAVA_UNICODE_ESCAPE = true;
-}
-
-PARSER_BEGIN(SpecParser)
-package edu.uci.eecs.specCompiler.grammerParser;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Arrays;
-
-import edu.uci.eecs.specCompiler.specExtraction.Construct;
-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.CommutativityRule;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
-import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
-import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
-import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
-import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
-
- public class SpecParser {
- private static ArrayList<String> _content;
- private static File _file;
- private static ArrayList<Construct> _constructs;
-
-
- public static void main(String[] argvs)
- throws ParseException, TokenMgrError {
- try {
- File f = new File("./grammer/spec1.txt");
- FileInputStream fis = new FileInputStream(f);
- SpecParser parser = new SpecParser(fis);
-
- ArrayList<String> content = new ArrayList<String>();
- ArrayList<Construct> constructs = new ArrayList<Construct>();
- ArrayList<String> headers = new ArrayList<String>();
- parser.Parse(f, content, constructs, headers);
- for (int i = 0; i < content.size(); i++) {
- System.out.println(content.get(i));
- }
-
- for (int i = 0; i < constructs.size(); i++) {
- System.out.println(constructs.get(i));
- }
-
-
- //parser.Test();
- System.out.println("Parsing finished!");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- public static SourceFileInfo ParseFile(File f)
- throws ParseException, TokenMgrError {
- try {
- InputStream input = new FileInputStream(f);
- SpecParser parser = new SpecParser(input);
- ArrayList<String> content = new ArrayList<String>(),
- headers = new ArrayList<String>();
- ArrayList<Construct> constructs = new ArrayList<Construct>();
- parser.Parse(f, content, constructs, headers);
- return new SourceFileInfo(f, content, headers, constructs);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
-
- private static ArrayList<String> breakLines(String all) {
- String lines[] = all.split("[\\r\\n]+");
- return new ArrayList<String>(Arrays.asList(lines));
- }
-
-
- public static ArrayList<VariableDeclaration> getTemplateArg(String line)
- throws ParseException {
- InputStream input = new ByteArrayInputStream(line.getBytes());
- SpecParser parser = new SpecParser(input);
- return parser.TemplateParamList();
- }
-
- public static FunctionHeader parseFuncHeader(String line)
- throws ParseException {
- InputStream input = new ByteArrayInputStream(line.getBytes());
- SpecParser parser = new SpecParser(input);
- return parser.FuncDecl();
- }
-
-
- public static String stringArray2String(ArrayList<String> content) {
- StringBuilder sb = new StringBuilder();
- if (content.size() == 1)
- return content.get(0);
- for (int i = 0; i < content.size(); i++) {
- sb.append(content.get(i) + "\n");
- }
- return sb.toString();
- }
-
- /**
- boolean spaceSeparator(Token t) {
- switch (t.image) {
- case "[":
- case "]":
- case "=":
- case "(":
- case ")":
- case ",":
- case ".":
- case "*":
- case "~":
- case "!":
- case "&":
- case "|":
- case "%":
- case "+":
- case "-":
- case "/":
- case "<":
- case ">":
- case "<=":
- case ">=":
- case "==":
- case "!=":
- case "&&":
- case "||":
- case "^":
- case "?":
- case ":":
- case "::":
- case "<<":
- case ">>":
- case ">>>":
- case "+=":
- case "-=":
- case "*=":
- case "/=":
- case "%=":
- case "^=":
- case "&=":
- case ";":
- return false;
- default:
- return true;
- }
- }
- */
-
- }
-PARSER_END(SpecParser)
-
-
-
-<IN_POTENTIAL_SPEC, IN_SPEC> SKIP :
-{
- " "
-|
- "\n"
-|
- "\r"
-|
- "\r\n"
-|
- "\t"
-}
-
-SKIP : {
- "/**" : IN_POTENTIAL_SPEC
-}
-
-<IN_POTENTIAL_SPEC> TOKEN : {
- <BEGIN: "@Begin"> : IN_SPEC
-}
-
-<IN_SPEC> SKIP : {
- "*/" : DEFAULT
-}
-
-SKIP : {
- "/*": IN_COMMENT
-}
-
-<DEFAULT> TOKEN: {
- <ANY: ~[]>
-}
-
-<*> SKIP : {
- // "//" comment for the specification
- <"//" (~["\n", "\r"])* (["\n", "\r"])>
-}
-
-<IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : {
- "*/": DEFAULT
-}
-
-<IN_COMMENT, IN_POTENTIAL_SPEC> SKIP : { < ~[] > }
-
-<IN_SPEC> SKIP :
-{
- // "#" comment for the specification
- <"#" (~["\n", "\r"])* (["\n", "\r"])>
-}
-
-
-<IN_SPEC> TOKEN : {
- <END: "@End">
-|
- <OPTIONS: "@Options:">
-|
- <GLOBAL_DEFINE: "@Global_define:">
-|
- <DECLARE_STRUCT: "@DeclareStruct:">
-|
- <DECLARE_VAR: "@DeclareVar:">
-|
- <INIT_VAR: "@InitVar:">
-|
- <CLEANUP: "@Finalize:">
-|
- <DEFINE_FUNC: "@DefineFunc:">
-|
- <INTERFACE_CLUSTER: "@Interface_cluster:">
-|
- <HAPPENS_BEFORE: "@Happens_before:">
-|
- <COMMUTATIVITY: "@Commutativity:">
-|
- <INTERFACE: "@Interface:">
-|
- <COMMIT_POINT_SET: "@Commit_point_set:">
-|
- <ENTRY_POINT: "@Entry_point">
-|
- <CLASS_BEGIN: "@Class_begin">
-|
- <CLASS_END: "@Class_end">
-|
- <INTERFACE_DEFINE: "@Interface_define:">
-|
- <CONDITION: "@Condition:">
-|
- <HB_CONDITION: "@HB_condition:">
-|
- <ID: "@ID:">
-|
- <CHECK: "@Check:">
-|
- <ACTION: "@Action:">
-|
- <CODE: "@Code:">
-|
- <POST_ACTION: "@Post_action:">
-|
- <POST_CHECK: "@Post_check:">
-|
- <POTENTIAL_COMMIT_POINT_DEFINE: "@Potential_commit_point_define:">
-|
- <POTENTIAL_ADDITIONAL_ORDERING_POINT_DEFINE: "@Potential_additional_ordering_point_define:">
-|
- <LABEL: "@Label:">
-|
- <COMMIT_POINT_DEFINE_CHECK: "@Commit_point_define_check:">
-|
- <ADDITIONAL_ORDERING_POINT_DEFINE_CHECK: "@Additional_ordering_point_define_check:">
-|
- <COMMIT_POINT_DEFINE: "@Commit_point_define:">
-|
- <ADDITIONAL_ORDERING_POINT_DEFINE: "@Additional_ordering_point_define:">
-|
- <COMMIT_POINT_CLEAR: "@Commit_point_clear:">
-|
- <POTENTIAL_COMMIT_POINT_LABEL: "@Potential_commit_point_label:">
-|
- <POTENTIAL_ADDITIONAL_ORDERING_POINT_LABEL: "@Potential_additional_ordering_point_label:">
-}
-
-
-<IN_SPEC> TOKEN :
-{
-/* Specification & C/C++ shared tokens */
-// Reserved keywords
- <CONST: "const">
-|
- <STRUCT: "struct">
-|
- <CLASS: "class">
-|
- <UNSIGNED: "unsigned">
-|
- <TEMPLATE: "template">
-|
- <INLINE: "inline">
-|
- <STATIC: "static">
-|
- <FOR: "for">
-|
- <#DIGIT: ["0"-"9"]>
-|
- <#LETTER: ["a"-"z", "A"-"Z"]>
-|
- <IDENTIFIER: (<LETTER> | "_") (<LETTER> | <DIGIT> | "_")*>
-|
- <POUND: "#">
-|
- <OPEN_BRACKET: "[">
-|
- <CLOSE_BRACKET: "]">
-|
- <EQUALS: "=">
-|
- <OPEN_PAREN: "(">
-|
- <CLOSE_PAREN: ")">
-|
- <OPEN_BRACE: "{">
-|
- <CLOSE_BRACE: "}">
-|
- <HB_SYMBOL: "->">
-|
- <COMMUTATIVITY_SYMBOL: "<->">
-|
- <COMMA: ",">
-|
-/* C/C++ only token*/
- <DOT: ".">
-|
- <DOLLAR: "$">
-|
- <STAR: "*">
-|
- <NEGATE: "~">
-|
- <EXCLAMATION: "!">
-|
- <AND: "&">
-|
- <OR: "|">
-|
- <MOD: "%">
-|
- <PLUS: "+">
-|
- <PLUSPLUS: "++">
-|
- <MINUS: "-">
-|
- <MINUSMINUS: "--">
-|
- <DIVIDE: "/">
-|
- <BACKSLASH: "\\">
-|
- <LESS_THAN: "<">
-|
- <GREATER_THAN: ">">
-|
- <GREATER_EQUALS: ">=">
-|
- <LESS_EQUALS: "<=">
-|
- <LOGICAL_EQUALS: "==">
-|
- <NOT_EQUALS: "!=">
-|
- <LOGICAL_AND: "&&">
-|
- <LOGICAL_OR: "||">
-|
- <XOR: "^">
-|
- <QUESTION_MARK: "?">
-|
- <COLON: ":">
-|
- <DOUBLECOLON: "::">
-|
- <DOUBLELESSTHAN: "<<">
-|
- <DOUBLEGREATERTHAN: ">>">
-|
- <TRIPLEGREATERTHAN: ">>>">
-|
- <PLUS_EQUALS: "+=">
-|
- <MINUS_EQUALS: "-=">
-|
- <TIMES_EQUALS: "*=">
-|
- <DIVIDE_EQUALS: "/=">
-|
- <MOD_EQUALS: "%=">
-|
- <XOR_EQUALS: "^=">
-|
- <OR_EQUALS: "|=">
-|
- <AND_EQUALS: "&=">
-|
- <SEMI_COLON: ";">
-|
- <STRING_LITERAL:
- "\""
- ((~["\"","\\","\n","\r"])
- | ("\\"
- ( ["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"]
- ["0"-"7"]
- )
- )
- )*
- "\"">
-|
- <CHARACTER_LITERAL:
- "'"
- ((~["'","\\","\n","\r"])
- | ("\\"
- (["n","t","b","r","f","\\","'","\""]
- | ["0"-"7"] ( ["0"-"7"] )?
- | ["0"-"3"] ["0"-"7"]
- ["0"-"7"]
- )
- )
- )
- "'">
-|
- < INTEGER_LITERAL:
- <DECIMAL_LITERAL> (["l","L"])?
- | <HEX_LITERAL> (["l","L"])?
- | <OCTAL_LITERAL> (["l","L"])?>
-|
- < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
-|
- < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
-|
- < #OCTAL_LITERAL: "0" (["0"-"7"])* >
-|
- < FLOATING_POINT_LITERAL:
- <DECIMAL_FLOATING_POINT_LITERAL>
- | <HEXADECIMAL_FLOATING_POINT_LITERAL> >
-|
- < #DECIMAL_FLOATING_POINT_LITERAL:
- (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
- | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
- | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])?
- | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"]>
-|
- < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
-|
- < #HEXADECIMAL_FLOATING_POINT_LITERAL:
- "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
- | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?>
-|
- < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ >
-|
- < #SPACE: (" " | "\t")+>
-|
- < #TO_END_OF_LINE: (~["\n"])+>
-|
- /* Macro token */
- <INCLUDE: "#" (<SPACE>)? "include" <SPACE> (<STRING_LITERAL> | "<" (<LETTER> | <DOT>)+ ">")>
-|
- <DEFINE: "#" (<SPACE>)? <TO_END_OF_LINE>>
-}
-
-String Type() :
-{
- String type;
- String str;
- QualifiedName name;
-}
-{
- { type = ""; }
- (<CONST>
- { type = "const"; }
- )?
- (((str = <STRUCT>.image | str = <CLASS>.image | str = <UNSIGNED>.image) { type = type + " " + str; })?
- (
- name = ParseQualifiedName() {
- if (!type.equals(""))
- type = type + " " + name.fullName;
- else
- type = name.fullName;
- })
- )
- ((str = <CONST>.image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- }) |
- (str = <STAR>.image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- }) |
- (str = <AND>.image {
- if (!type.equals(""))
- type = type + " " + str;
- else
- type = str;
- })
- )*
- {
- return type;
- }
-}
-
-
-String ParameterizedName() :
-{
- String res = "";
- String str;
-}
-{
- (str = <IDENTIFIER>.image {res = str;})
- (<OPEN_BRACKET> str = Type() { res = res + "<" + str; }
- (<COMMA> str = Type() { res = res + ", " + str; })* <CLOSE_BRACKET>
- { res = res + ">"; }
- )?
- {
- return res;
- }
-}
-
-FunctionHeader FuncDecl() :
-{
- String ret;
- QualifiedName funcName;
- ArrayList<VariableDeclaration> args;
-}
-{
- (<STATIC> | <INLINE>)*
- ret = Type()
- funcName = ParseQualifiedName()
- args = FormalParamList()
- {
- FunctionHeader res = new FunctionHeader(ret, funcName, args);
- //System.out.println(res);
- return res;
- }
-}
-
-QualifiedName ParseQualifiedName() :
-{
- String qualifiedName, str;
-}
-{
- { qualifiedName = ""; }
- (str = ParameterizedName() { qualifiedName = qualifiedName + str; } )
- ( <DOUBLECOLON> (str = ParameterizedName() { qualifiedName = qualifiedName +
- "::" + str; } ))*
- {
- QualifiedName res = new QualifiedName(qualifiedName);
- //System.out.println(res);
- return res;
- }
-}
-
-ArrayList<VariableDeclaration> TemplateParamList() :
-{
- ArrayList<VariableDeclaration> params;
- String type;
- String name;
-}
-{
- {
- params = new ArrayList<VariableDeclaration>();
- }
- <TEMPLATE>
- <OPEN_BRACKET>
- (type = <IDENTIFIER>.image
- name = <IDENTIFIER>.image
- {
- params.add(new VariableDeclaration(type, name));
- }
- )
-
- (<COMMA> type = <IDENTIFIER>.image
- name = <IDENTIFIER>.image
- {
- params.add(new VariableDeclaration(type, name));
- }
- )*
- <CLOSE_BRACKET>
- {
- //System.out.println(params);
- return params;
- }
-}
-
-ArrayList<VariableDeclaration > FormalParamList() :
-{
- ArrayList<VariableDeclaration > typeParams;
- VariableDeclaration varDecl;
-}
-{
- {
- typeParams = new ArrayList<VariableDeclaration >();
- }
- <OPEN_PAREN>
- ((varDecl = TypeParam() {typeParams.add(varDecl);})
- ((<COMMA> varDecl = TypeParam() {typeParams.add(varDecl);}))*)?
- <CLOSE_PAREN>
- {
- return typeParams;
- }
-}
-
-VariableDeclaration TypeParam() :
-{
- String type, param;
-}
-{
- (type = Type()) (param = <IDENTIFIER>.image)
- {
- return new VariableDeclaration(type, param);
- }
-}
-
-
-
-ArrayList<String> C_CPP_CODE(ArrayList<String> headers) :
-{
- String text;
- Token t;
- boolean newLine = false;
- boolean newSpace = true;
- boolean inTemplate = false;
- boolean inForLoop = false;
- ArrayList<String> content;
- String header;
-}
-{
- {
- text = "";
- t = new Token();
- content = new ArrayList<String>();
- }
- (
- LOOKAHEAD(2)
- (
- t = <CONST> | t = <STRUCT> | t = <CLASS> | t = <UNSIGNED> |
- (t = <TEMPLATE> { inTemplate = true; })|
- t = <STATIC> | t = <INLINE> |
- (t = <FOR> { inForLoop = true; })|
- (t = <INCLUDE>
- {
- header = t.image;
- newLine = true;
- if (headers != null) {
- headers.add(header.substring(header.lastIndexOf(' ') + 1));
- }
- })
- | t = <IDENTIFIER> | t = <POUND> |
- (t = <OPEN_BRACE> { newLine = true; } ) |
- (t = <CLOSE_BRACE> { newLine = true; inForLoop = false;} ) |
- t = <EQUALS> | t = <OPEN_PAREN> | t = <CLOSE_PAREN> |
- t = <OPEN_BRACKET> | t = <CLOSE_BRACKET>
- | t = <HB_SYMBOL> | t = <COMMA> |
- t = <DOT> | t = <STAR> | t = <DOLLAR> | t = <NEGATE> | t = <EXCLAMATION> | t = <AND> | t = <OR> | t = <MOD> | t = <PLUS> |
- t = <PLUSPLUS> | t = <MINUS> | t = <MINUSMINUS> | t = <DIVIDE> | t = <BACKSLASH> |
- t = <LESS_THAN> |
- (t = <GREATER_THAN> { if (inTemplate) newLine = true; }) |
- t = <GREATER_EQUALS> | t = <LESS_EQUALS> |
- t = <LOGICAL_EQUALS> | t = <NOT_EQUALS> | t = <LOGICAL_AND> | t = <LOGICAL_OR> | t = <XOR> |
- t = <QUESTION_MARK> | t = <COLON> | t = <DOUBLECOLON> |
- t = <DOUBLELESSTHAN> |
- t = <DOUBLEGREATERTHAN> |
- t = <TRIPLEGREATERTHAN> |
-
- t = <PLUS_EQUALS> |
- t = <MINUS_EQUALS> |
- t = <TIMES_EQUALS> |
- t = <DIVIDE_EQUALS> |
- t = <MOD_EQUALS> |
- t = <XOR_EQUALS> |
- t = <OR_EQUALS> |
- t = <AND_EQUALS> |
-
- (t = <SEMI_COLON> { if (!inForLoop) newLine = true; } )
- | t = <STRING_LITERAL> | t = <CHARACTER_LITERAL> |
- t = <INTEGER_LITERAL> | t = <FLOATING_POINT_LITERAL> |
- (t = <DEFINE> { newLine = true; } )
- )
- {
- if (text.equals("")) {
- text = t.image;
- newSpace = true;
- } else {
- text = text + " " + t.image;
- /*
- if (newSpace && spaceSeparator(t)) {
- text = text + " " + t.image;
- } else {
- text = text + t.image;
- if (spaceSeparator(t))
- newSpace = true;
- }*/
- }
- if (newLine) {
- content.add(text);
- text = "";
- newLine = false;
- inTemplate = false;
- }
- }
- )+
-
- {
- if (content.size() == 0) {
- content.add(text);
- }
- return content;
- }
-}
-
-
-void Parse(File f, ArrayList<String> content, ArrayList<Construct> constructs, ArrayList<String> headers) :
-{
- Construct inst;
- StringBuilder sb;
- boolean flushSB;
-}
-{
- {
- _file = f;
- _content = content;
- _constructs = constructs;
- sb = new StringBuilder();
- }
- (
- (inst = ParseSpec()
- {
- _constructs.add(inst);
- }
- ) |
- //((code = C_CPP_CODE(headers)) { _content.addAll(code); })
- (
- flushSB = OriginalCode(sb)
- {
- if (flushSB) {
- sb = new StringBuilder();
- }
- }
- )
- )*
- // For the last piece of code
- {
- _content.add(sb.toString());
- }
- <EOF>
-}
-
-// If true, there's a new line and sb should be flushed
-boolean OriginalCode(StringBuilder sb) :
-{
- String str;
-}
-{
- str = <ANY>.image
- {
- if (!str.equals("\n")) {
- sb.append(str);
- return false;
- } else {
- _content.add(sb.toString());
- return true;
- }
- }
-}
-
-Construct ParseSpec() :
-{
- Construct res;
-}
-{
- (
- LOOKAHEAD(2) res = Global_construct() |
- LOOKAHEAD(2) res = Interface() |
- LOOKAHEAD(2) res = Potential_commit_point_define() |
- LOOKAHEAD(2) res = Commit_point_define() |
- LOOKAHEAD(2) res = Commit_point_define_check() |
- LOOKAHEAD(2) res = Potential_additional_ordering_point_define() |
- LOOKAHEAD(2) res = Additional_ordering_point_define() |
- LOOKAHEAD(2) res = Additional_ordering_point_define_check() |
- LOOKAHEAD(2) res = Commit_point_clear() |
- LOOKAHEAD(2) res = Entry_point() |
- LOOKAHEAD(2) res = Class_begin() |
- LOOKAHEAD(2) res = Class_end() |
- LOOKAHEAD(2) res = Interface_define()
- )
- {
- //System.out.println(res);
- return res;
- }
-}
-
-GlobalConstruct Global_construct() :
-{
- GlobalConstruct res;
- SequentialDefineSubConstruct code;
- HashMap<String, String> options;
- String key, value;
-}
-{
- {
- res = null;
- options = new HashMap<String, String>();
- }
- <BEGIN>
- (<OPTIONS>
- ((key = <IDENTIFIER>.image)
- <EQUALS>
- (value = <IDENTIFIER>.image)
- {
- if (options.containsKey(key)) {
- throw new ParseException("Duplicate options!");
- }
- options.put(key, value);
- }
- <SEMI_COLON>
- )*
- )?
- (code = Global_define())
- { res = new GlobalConstruct(_file, _content.size(), code, options); }
- (Interface_clusters(res))?
- (Happens_before(res))?
- (Commutativity(res))?
- <END>
- {
- res.unfoldInterfaceCluster();
- return res;
- }
-}
-
-SequentialDefineSubConstruct Global_define() :
-{
- ArrayList<String> initVar, cleanup, defineFunc, code, declareStruct;
- ArrayList<ArrayList<String>> defineFuncs;
- ArrayList<VariableDeclaration> declareVars;
- ArrayList<ArrayList<String>> declareStructs;
- VariableDeclaration declareVar;
-
-}
-{
- {
- declareVars = new ArrayList<VariableDeclaration>();
- initVar = new ArrayList<String>();
- cleanup = new ArrayList<String>();
- defineFuncs = new ArrayList<ArrayList<String>>();
- declareStructs = new ArrayList<ArrayList<String>>();
- }
- <GLOBAL_DEFINE>
- (<DECLARE_STRUCT> (declareStruct = C_CPP_CODE(null) {
- declareStructs.add(declareStruct); }))*
- (<DECLARE_VAR> ((declareVar = TypeParam() <SEMI_COLON> {
- declareVars.add(declareVar); } )*))?
- (<INIT_VAR> (code = C_CPP_CODE(null) { initVar = code; } ))?
- (<CLEANUP> (code = C_CPP_CODE(null) { cleanup = code; } ))?
- (<DEFINE_FUNC> (defineFunc = C_CPP_CODE(null) { defineFuncs.add(defineFunc); }))*
- {
- SequentialDefineSubConstruct res = new
- SequentialDefineSubConstruct(declareStructs, declareVars, initVar, cleanup, defineFuncs);
- //System.out.println(res);
- return res;
- }
-}
-
-ConditionalInterface Conditional_interface() :
-{
- String interfaceName, hbConditionLabel;
-}
-{
- {
- hbConditionLabel = "";
- }
- interfaceName = <IDENTIFIER>.image (<OPEN_PAREN> hbConditionLabel =
- <IDENTIFIER>.image <CLOSE_PAREN>)?
- {
- return new ConditionalInterface(interfaceName, hbConditionLabel);
- }
-}
-
-void Interface_cluster(GlobalConstruct inst) :
-{
- String clusterName;
- ConditionalInterface condInterface;
-}
-{
- (clusterName= <IDENTIFIER>.image)
- <EQUALS> <OPEN_BRACE>
- (condInterface = Conditional_interface()
- { inst.addInterface2Cluster(clusterName, condInterface); }
- )
- (<COMMA> condInterface = Conditional_interface()
- { inst.addInterface2Cluster(clusterName, condInterface); }
- )*
- <CLOSE_BRACE>
-}
-
-void Interface_clusters(GlobalConstruct inst) :
-{}
-{
- <INTERFACE_CLUSTER> (Interface_cluster(inst))+
-}
-
-void Happens_before(GlobalConstruct inst) :
-{
- ConditionalInterface left, right;
-}
-{
- <HAPPENS_BEFORE>
- (
- left = Conditional_interface() <HB_SYMBOL> right = Conditional_interface()
- { inst.addHBCondition(left, right); }
- )+
-}
-
-void Commutativity(GlobalConstruct inst) :
-{
- String method1, method2, condition;
- ArrayList<String> content;
-}
-{
- {
- content = new ArrayList<String>();
- }
-
- (
- <COMMUTATIVITY>
- method1 = <IDENTIFIER>.image <COMMUTATIVITY_SYMBOL>
- method2 = <IDENTIFIER>.image
- <COLON>
- content = C_CPP_CODE(null)
- { condition = stringArray2String(content); }
- {
- inst.addCommutativityRule(method1, method2, condition);
- }
- )+
-}
-
-InterfaceConstruct Interface() :
-{
- InterfaceConstruct res;
- String interfaceName, condition, idCode, check,
- postCheck, commitPoint, hbLabel, hbCondition;
- ArrayList<String> commitPointSet;
- ArrayList<String> action, postAction;
- HashMap<String, String> hbConditions;
- ArrayList<String> content;
-}
-{
- {
- res = null;
- action = new ArrayList<String>();
- condition = "";
- idCode = "";
- check = "";
- postCheck = "";
- commitPointSet = new ArrayList<String>();
- hbConditions = new HashMap<String, String>();
- postAction = new ArrayList<String>();
- }
- <BEGIN>
- <INTERFACE> (interfaceName = <IDENTIFIER>.image)
- <COMMIT_POINT_SET>
- (commitPoint = <IDENTIFIER>.image
- { commitPointSet.add(commitPoint); }
- )
- (<OR>
- (commitPoint = <IDENTIFIER>.image)
- {
- if (commitPointSet.contains(commitPoint)) {
- throw new ParseException(interfaceName + " has" +
- "duplicate commit point labels");
- }
- commitPointSet.add(commitPoint);
- }
- )*
-
- (<CONDITION> (content = C_CPP_CODE(null) { condition = stringArray2String(content); }))?
- (
- <HB_CONDITION>
- (hbLabel = <IDENTIFIER>.image) <DOUBLECOLON>
- (content = C_CPP_CODE(null) { hbCondition = stringArray2String(content); })
- {
- if (hbConditions.containsKey(hbLabel)) {
- throw new ParseException(interfaceName + " has" +
- "duplicate happens-before condtion labels");
- }
- hbConditions.put(hbLabel, hbCondition);
- }
- )*
- (<ID> (content = C_CPP_CODE(null) { idCode = stringArray2String(content); }))?
- (<CHECK> (content = C_CPP_CODE(null) { check = stringArray2String(content); }))?
- (<ACTION> action = C_CPP_CODE(null))?
- (<POST_ACTION> (postAction = C_CPP_CODE(null) ))?
- (<POST_CHECK> (content = C_CPP_CODE(null) { postCheck = stringArray2String(content); }))?
- <END>
- {
- res = new InterfaceConstruct(_file, _content.size(), interfaceName, commitPointSet, condition,
- hbConditions, idCode, check, action, postAction, postCheck);
- return res;
- }
-}
-
-
-PotentialCPDefineConstruct Potential_commit_point_define() :
-{
- PotentialCPDefineConstruct res;
- String label, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <POTENTIAL_COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- res = new PotentialCPDefineConstruct(_file, _content.size(), label, condition);
- return res;
- }
-}
-
-PotentialCPDefineConstruct Potential_additional_ordering_point_define() :
-{
- PotentialCPDefineConstruct res;
- String label, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <POTENTIAL_ADDITIONAL_ORDERING_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- // Set the boolean flag isAdditionalOrderingPoint to be true
- res = new PotentialCPDefineConstruct(_file, _content.size(), true, label, condition);
- return res;
- }
-}
-
-
-CPDefineConstruct Commit_point_define() :
-{
- CPDefineConstruct res;
- String label, potentialCPLabel, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <COMMIT_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <POTENTIAL_COMMIT_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- res = new CPDefineConstruct(_file, _content.size(), false, label, potentialCPLabel, condition);
- return res;
- }
-}
-
-CPDefineConstruct Additional_ordering_point_define() :
-{
- CPDefineConstruct res;
- String label, potentialCPLabel, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <ADDITIONAL_ORDERING_POINT_DEFINE> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <POTENTIAL_ADDITIONAL_ORDERING_POINT_LABEL> (potentialCPLabel = <IDENTIFIER>.image)
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- // Set the boolean flag isAdditionalOrderingPoint to be true
- res = new CPDefineConstruct(_file, _content.size(), true, label, potentialCPLabel, condition);
- return res;
- }
-}
-
-CPClearConstruct Commit_point_clear() :
-{
- CPClearConstruct res;
- String label, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <COMMIT_POINT_CLEAR> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- res = new CPClearConstruct(_file, _content.size(), label, condition);
- return res;
- }
-}
-
-
-CPDefineCheckConstruct Commit_point_define_check() :
-{
- CPDefineCheckConstruct res;
- String label, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <COMMIT_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- res = new CPDefineCheckConstruct(_file, _content.size(), false, label, condition);
- return res;
- }
-}
-
-CPDefineCheckConstruct Additional_ordering_point_define_check() :
-{
- CPDefineCheckConstruct res;
- String label, condition;
- ArrayList<String> content;
-}
-{
-
- { res = null; }
- <BEGIN>
- <ADDITIONAL_ORDERING_POINT_DEFINE_CHECK> (content = C_CPP_CODE(null) { condition = stringArray2String(content); })
- <LABEL> (label = <IDENTIFIER>.image)
- <END>
- {
- // Set the boolean flag isAdditionalOrderingPoint to be true
- res = new CPDefineCheckConstruct(_file, _content.size(), true, label, condition);
- return res;
- }
-}
-
-EntryPointConstruct Entry_point() :
-{}
-{
-
- <BEGIN>
- <ENTRY_POINT>
- <END>
- {
- return new EntryPointConstruct(_file, _content.size());
- }
-}
-
-ClassBeginConstruct Class_begin() :
-{}
-{
-
- <BEGIN>
- <CLASS_BEGIN>
- <END>
- {
- return new ClassBeginConstruct(_file, _content.size());
- }
-}
-
-ClassEndConstruct Class_end() :
-{}
-{
-
- <BEGIN>
- <CLASS_END>
- <END>
- {
- return new ClassEndConstruct(_file, _content.size());
- }
-}
-
-InterfaceDefineConstruct Interface_define() :
-{
- String name;
-}
-{
- <BEGIN>
- <INTERFACE_DEFINE> (name = <IDENTIFIER>.image)
- <END>
- {
- return new InterfaceDefineConstruct(_file, _content.size(), name);
- }
-}
}
PARSER_BEGIN(UtilParser)
-package edu.uci.eecs.specCompiler.grammerParser.utilParser;
-import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
-import edu.uci.eecs.specCompiler.specExtraction.QualifiedName;
-import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
+package edu.uci.eecs.utilParser;
+import edu.uci.eecs.specExtraction.FunctionHeader;
+import edu.uci.eecs.specExtraction.QualifiedName;
+import edu.uci.eecs.specExtraction.VariableDeclaration;
+//import edu.uci.eecs.specExtraction.WrongAnnotationException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.ArrayList;
+
- public class UtilParser {
- public static void main(String[] argvs)
- throws ParseException, TokenMgrError {
- try {
- File f = new File("./grammer/spec1.txt");
- FileInputStream fis = new FileInputStream(f);
- UtilParser parser = new UtilParser(fis);
-
- //parser.Test();
- System.out.println("Parsing finished!");
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
+public class UtilParser {
+ public static void main(String[] argvs)
+ throws ParseException, TokenMgrError {
+ try {
+ File f = new File("./grammer/spec1.txt");
+ FileInputStream fis = new FileInputStream(f);
+ UtilParser parser = new UtilParser(fis);
+
+ //parser.Test();
+ System.out.println("Parsing finished!");
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
}
+ }
- public static ArrayList<VariableDeclaration> getTemplateArg(String line)
- throws ParseException {
- InputStream input = new ByteArrayInputStream(line.getBytes());
- UtilParser parser = new UtilParser(input);
- return parser.TemplateParamList();
- }
+ public static ArrayList<VariableDeclaration> getTemplateArg(String line)
+ throws ParseException {
+ InputStream input = new ByteArrayInputStream(line.getBytes());
+ UtilParser parser = new UtilParser(input);
+ return parser.TemplateParamList();
+ }
- public static FunctionHeader parseFuncHeader(String line)
- throws ParseException {
- InputStream input = new ByteArrayInputStream(line.getBytes());
- UtilParser parser = new UtilParser(input);
- return parser.FuncDecl();
- }
+ public static FunctionHeader parseFuncHeader(String line)
+ throws ParseException {
+ InputStream input = new ByteArrayInputStream(line.getBytes());
+ UtilParser parser = new UtilParser(input);
+ return parser.FuncDecl();
+ }
- public static String stringArray2String(ArrayList<String> content) {
- StringBuilder sb = new StringBuilder();
- if (content.size() == 1)
- return content.get(0);
- for (int i = 0; i < content.size(); i++) {
- sb.append(content.get(i) + "\n");
- }
- return sb.toString();
+ public static String stringArray2String(ArrayList<String> content) {
+ StringBuilder sb = new StringBuilder();
+ if (content.size() == 1)
+ return content.get(0);
+ for (int i = 0; i < content.size(); i++) {
+ sb.append(content.get(i) + "\n");
}
+ return sb.toString();
}
+}
PARSER_END(UtilParser)
SKIP :
V. Examples
+
+!!!!!!! The register example should be extended to commute if we think of their
+transitional effects as set operations --- a set operation that will only mask
+out side the effects of its own previous behavior (things that are hb/SC before
+it) ---- VERY IMPORTANT note here!!
+
+
1. The register examples: Basically, we can think of registers as the cache on a
memory system. The effect of a load or store basically tells us what the current
value in the cache line is, and a load can read from values that can be
+++ /dev/null
-#DIRS := barrier mcs-lock mpmc-queue spsc-queue spsc-bugfix linuxrwlocks \
- dekker-fences chase-lev-deque ms-queue chase-lev-deque-bugfix \
- concurrent-hashmap seqlock spsc-example spsc-queue-scfence \
- treiber-stack
-
-DIRS := ms-queue concurrent-hashmap linuxrwlocks mcs-lock read-copy-update \
- chase-lev-deque-bugfix spsc-bugfix mpmc-queue seqlock
-
-.PHONY: $(DIRS)
-
-all: $(DIRS)
-
-clean: $(DIRS:%=clean-%)
-
-$(DIRS):
- $(MAKE) -C $@
-
-clean-%:
- -$(MAKE) -C $* clean
+++ /dev/null
-# A few common Makefile items
-
-CC = gcc
-CXX = g++
-
-UNAME = $(shell uname)
-
-LIB_NAME = model
-LIB_SO = lib$(LIB_NAME).so
-
-BASE = $(HOME)/model-checker-priv/model-checker-priv
-INCLUDE = -I$(BASE)/include -I../include -I$(BASE)/spec-analysis -I$(BASE)
-
-# C preprocessor flags
-CPPFLAGS += $(INCLUDE) -O3
-
-# C++ compiler flags
-CXXFLAGS += $(CPPFLAGS)
-
-# C compiler flags
-CFLAGS += $(CPPFLAGS)
-
-# Linker flags
-LDFLAGS += -L$(BASE) -l$(LIB_NAME) -rdynamic
-
-# Mac OSX options
-ifeq ($(UNAME), Darwin)
-MACFLAGS = -D_XOPEN_SOURCE -DMAC
-CPPFLAGS += $(MACFLAGS)
-CXXFLAGS += $(MACFLAGS)
-CFLAGS += $(MACFLAGS)
-LDFLAGS += $(MACFLAGS)
-endif
+++ /dev/null
-include ../benchmarks.mk
-
-TESTNAME = main testcase1 testcase2
-
-HEADERS = deque.h
-OBJECTS = deque.o
-
-all: $(TESTNAME)
-
-$(TESTNAME): % : %.c $(OBJECTS)
- $(CC) -o $@ $^ $(CPPFLAGS) $(LDFLAGS)
-
-%.o: %.c
- $(CC) -c -o $@ $< $(CPPFLAGS)
-
-clean:
- rm -f $(TESTNAME) *.o
+++ /dev/null
-#include <stdatomic.h>
-#include <inttypes.h>
-#include "deque.h"
-#include <stdlib.h>
-#include <stdio.h>
-
-Deque * create() {
- Deque * q = (Deque *) calloc(1, sizeof(Deque));
- Array * a = (Array *) calloc(1, sizeof(Array)+2*sizeof(atomic_int));
- atomic_store_explicit(&q->array, a, memory_order_relaxed);
- atomic_store_explicit(&q->top, 0, memory_order_relaxed);
- atomic_store_explicit(&q->bottom, 0, memory_order_relaxed);
- atomic_store_explicit(&a->size, 2, memory_order_relaxed);
- return q;
-}
-
-
-
-int take(Deque * q) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Take
- interface_begin->interface_name = "Take";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__take(q);
- Take_info* info = (Take_info*) malloc(sizeof(Take_info));
- info->__RET__ = __RET__;
- info->q = q;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Take
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__take(Deque * q) {
- size_t b = atomic_load_explicit(&q->bottom, memory_order_relaxed) - 1;
- /* Automatically generated code for commit point define check: Take_Read_Bottom */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Take_Read_Bottom";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
-
- atomic_store_explicit(&q->bottom, b, memory_order_relaxed);
-
- atomic_thread_fence(memory_order_seq_cst);
- size_t t = atomic_load_explicit(&q->top, memory_order_relaxed);
-
- int x;
- if (t <= b) {
-
- int size = atomic_load_explicit(&a->size,memory_order_relaxed);
- x = atomic_load_explicit(&a->buffer[b % size], memory_order_relaxed);
-
- if (t == b) {
-
- bool succ = atomic_compare_exchange_strong_explicit(&q->top, &t, t +
- 1, memory_order_seq_cst, memory_order_relaxed);
-
-
- /* Automatically generated code for commit point define check: Take_Additional_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Take_Additional_Point";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (!succ) {
-
- x = EMPTY;
- }
- atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed);
- }
- } else {
- x = EMPTY;
- atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed);
- }
- return x;
-}
-
-void resize(Deque *q) {
- Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
- size_t size=atomic_load_explicit(&a->size, memory_order_relaxed);
- size_t new_size=size << 1;
- Array *new_a = (Array *) calloc(1, new_size * sizeof(atomic_int) + sizeof(Array));
- size_t top=atomic_load_explicit(&q->top, memory_order_relaxed);
- size_t bottom=atomic_load_explicit(&q->bottom, memory_order_relaxed);
- atomic_store_explicit(&new_a->size, new_size, memory_order_relaxed);
- size_t i;
- for(i=top; i < bottom; i++) {
- atomic_store_explicit(&new_a->buffer[i % new_size], atomic_load_explicit(&a->buffer[i % size], memory_order_relaxed), memory_order_relaxed);
- }
-
- atomic_store_explicit(&q->array, new_a, memory_order_release);
- }
-
-
-void push(Deque * q, int x) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Push
- interface_begin->interface_name = "Push";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__push(q, x);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Push
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Push_info* info = (Push_info*) malloc(sizeof(Push_info));
- info->q = q;
- info->x = x;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Push
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__push(Deque * q, int x) {
- size_t b = atomic_load_explicit(&q->bottom, memory_order_relaxed);
-
- size_t t = atomic_load_explicit(&q->top, memory_order_acquire);
- Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
- if (b - t > atomic_load_explicit(&a->size, memory_order_relaxed) - 1) {
- resize(q);
- a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
-
- }
- int size = atomic_load_explicit(&a->size, memory_order_relaxed);
-
- atomic_store_explicit(&a->buffer[b % size], x, memory_order_relaxed);
-
-
- atomic_thread_fence(memory_order_release);
- /* Automatically generated code for commit point define check: Push_Update_Bottom */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "Push_Update_Bottom";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed);
-
-}
-
-
-int steal(Deque * q) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 2; // Steal
- interface_begin->interface_name = "Steal";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__steal(q);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 2; // Steal
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Steal_info* info = (Steal_info*) malloc(sizeof(Steal_info));
- info->__RET__ = __RET__;
- info->q = q;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 2; // Steal
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__steal(Deque * q) {
- size_t t = atomic_load_explicit(&q->top, memory_order_acquire);
-
- atomic_thread_fence(memory_order_seq_cst);
-
- size_t b = atomic_load_explicit(&q->bottom, memory_order_acquire);
- /* Automatically generated code for commit point define check: Steal_Read_Bottom */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "Steal_Read_Bottom";
- cp_define_check->interface_num = 2;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
-
- int x = EMPTY;
- if (t < b) {
-
-
- Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_acquire);
-
- int size = atomic_load_explicit(&a->size, memory_order_relaxed);
- x = atomic_load_explicit(&a->buffer[t % size], memory_order_relaxed);
-
-
- bool succ = atomic_compare_exchange_strong_explicit(&q->top, &t, t + 1,
- memory_order_seq_cst, memory_order_relaxed);
-
-
- /* Automatically generated code for commit point define check: Steal_Additional_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 4;
- cp_define_check->label_name = "Steal_Additional_Point";
- cp_define_check->interface_num = 2;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
-
- if (!succ) {
-
- return ABORT;
- }
- }
- return x;
-}
-
+++ /dev/null
-#ifndef DEQUE_H
-#define DEQUE_H
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-typedef struct {
- atomic_size_t size;
- atomic_int buffer[];
-} Array;
-
-typedef struct {
- atomic_size_t top, bottom;
- atomic_uintptr_t array;
-} Deque;
-
-#define EMPTY 0xffffffff
-#define ABORT 0xfffffffe
-
-/* All other user-defined structs */
-static IntegerList * __deque;
-/* All other user-defined functions */
-inline static bool succ ( int res ) {
-return res != EMPTY && res != ABORT ;
-}
-
-/* Definition of interface info struct: Steal */
-typedef struct Steal_info {
-int __RET__;
-Deque * q;
-} Steal_info;
-/* End of info struct definition: Steal */
-
-/* ID function of interface: Steal */
-inline static call_id_t Steal_id(void *info, thread_id_t __TID__) {
- Steal_info* theInfo = (Steal_info*)info;
- int __RET__ = theInfo->__RET__;
- Deque * q = theInfo->q;
-
- call_id_t __ID__ = succ ( __RET__ ) ? __RET__ : DEFAULT_CALL_ID;
- return __ID__;
-}
-/* End of ID function: Steal */
-
-/* Check action function of interface: Steal */
-inline static bool Steal_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Steal_info* theInfo = (Steal_info*)info;
- int __RET__ = theInfo->__RET__;
- Deque * q = theInfo->q;
-
- int elem = 0 ;
- if ( succ ( __RET__ ) ) {
- elem = front ( __deque ) ;
- pop_front ( __deque ) ;
- }
- check_passed = succ ( __RET__ ) ? __RET__ == elem : true;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Steal */
-
-/* Definition of interface info struct: Take */
-typedef struct Take_info {
-int __RET__;
-Deque * q;
-} Take_info;
-/* End of info struct definition: Take */
-
-/* ID function of interface: Take */
-inline static call_id_t Take_id(void *info, thread_id_t __TID__) {
- Take_info* theInfo = (Take_info*)info;
- int __RET__ = theInfo->__RET__;
- Deque * q = theInfo->q;
-
- call_id_t __ID__ = succ ( __RET__ ) ? __RET__ : DEFAULT_CALL_ID;
- return __ID__;
-}
-/* End of ID function: Take */
-
-/* Check action function of interface: Take */
-inline static bool Take_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Take_info* theInfo = (Take_info*)info;
- int __RET__ = theInfo->__RET__;
- Deque * q = theInfo->q;
-
- int elem = 0 ;
- if ( succ ( __RET__ ) ) {
- elem = back ( __deque ) ;
- pop_back ( __deque ) ;
- }
- check_passed = succ ( __RET__ ) ? __RET__ == elem : true;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Take */
-
-/* Definition of interface info struct: Push */
-typedef struct Push_info {
-Deque * q;
-int x;
-} Push_info;
-/* End of info struct definition: Push */
-
-/* ID function of interface: Push */
-inline static call_id_t Push_id(void *info, thread_id_t __TID__) {
- Push_info* theInfo = (Push_info*)info;
- Deque * q = theInfo->q;
- int x = theInfo->x;
-
- call_id_t __ID__ = x;
- return __ID__;
-}
-/* End of ID function: Push */
-
-/* Check action function of interface: Push */
-inline static bool Push_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Push_info* theInfo = (Push_info*)info;
- Deque * q = theInfo->q;
- int x = theInfo->x;
-
- push_back ( __deque , x ) ;
- return true;
-}
-/* End of check action function: Push */
-
-#define INTERFACE_SIZE 3
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Push_info *_info1 = (Push_info*) info1;
- Steal_info *_info2 = (Steal_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Take_info *_info1 = (Take_info*) info1;
- Steal_info *_info2 = (Steal_info*) info2;
- return true;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- __deque = createIntegerList ( ) ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- if ( __deque ) destroyIntegerList ( __deque ) ;
- return true ;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 3 * 2);
- func_ptr_table[2 * 2] = (void*) &Steal_id;
- func_ptr_table[2 * 2 + 1] = (void*) &Steal_check_action;
- func_ptr_table[2 * 0] = (void*) &Take_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Take_check_action;
- func_ptr_table[2 * 1] = (void*) &Push_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Push_check_action;
- /* Push(true) -> Steal(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 1; // Push
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 2; // Steal
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
- #define HB_RULE_TABLE_SIZE 1
- hb_rule_table[0] = hbConditionInit0;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 2);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 2;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-
-Deque * create();
-void resize(Deque *q);
-
-int __wrapper__take(Deque * q);
-
-int __wrapper__take(Deque * q) ;
-
-void __wrapper__push(Deque * q, int x);
-
-void __wrapper__push(Deque * q, int x) ;
-
-int __wrapper__steal(Deque * q);
-
-int __wrapper__steal(Deque * q) ;
-
-#endif
-
+++ /dev/null
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include "model-assert.h"
-
-#include "deque.h"
-
-Deque *q;
-int a;
-int b;
-int c;
-
-static void task(void * param) {
- a=steal(q);
- if (a == ABORT) {
- printf("Steal NULL\n");
- } else {
- printf("Steal %d\n", a);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t;
- q=create();
- thrd_create(&t, task, 0);
- push(q, 1);
- printf("Push 1\n");
- push(q, 2);
- printf("Push 2\n");
- push(q, 4);
- printf("Push 4\n");
- b=take(q);
- if (b == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", b);
- }
- c=take(q);
- if (c == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", c);
- }
- thrd_join(t);
-
-
- return 0;
-}
-
+++ /dev/null
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include "model-assert.h"
-
-#include "deque.h"
-
-Deque *q;
-int a;
-int b;
-int c;
-int x;
-
-static void task(void * param) {
- a=steal(q);
- if (a == ABORT) {
- printf("Steal NULL\n");
- } else {
- printf("Steal %d\n", a);
- }
- x=steal(q);
- if (x == ABORT) {
- printf("Steal NULL\n");
- } else {
- printf("Steal %d\n", x);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t;
- q=create();
- thrd_create(&t, task, 0);
- push(q, 1);
- printf("Push 1\n");
- push(q, 2);
- printf("Push 2\n");
- push(q, 4);
- printf("Push 4\n");
- b=take(q);
- if (b == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", b);
- }
- c=take(q);
- if (c == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", c);
- }
- thrd_join(t);
-
-
- return 0;
-}
-
+++ /dev/null
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include "model-assert.h"
-
-#include "deque.h"
-
-Deque *q;
-int a;
-int b;
-int c;
-int x;
-
-static void task(void * param) {
- a=steal(q);
- if (a == ABORT) {
- printf("Steal NULL\n");
- } else {
- printf("Steal %d\n", a);
- }
-
- x=steal(q);
- if (x == ABORT) {
- printf("Steal NULL\n");
- } else {
- printf("Steal %d\n", x);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t;
- q=create();
- thrd_create(&t, task, 0);
- push(q, 1);
- printf("Push 1\n");
- push(q, 2);
- printf("Push 2\n");
- push(q, 4);
- printf("Push 4\n");
- b=take(q);
- if (b == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", b);
- }
- c=take(q);
- if (c == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", c);
- }
- thrd_join(t);
-
-
- return 0;
-}
-
+++ /dev/null
-#include <stdlib.h>
-#include <assert.h>
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include "model-assert.h"
-
-#include "deque.h"
-
-Deque *q;
-int a;
-int b;
-int c;
-int x;
-
-static void task(void * param) {
- a=steal(q);
- if (a == ABORT) {
- printf("Steal NULL\n");
- } else {
- printf("Steal %d\n", a);
- }
-
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t;
- q=create();
- push(q, 1);
- printf("Push 1\n");
- push(q, 2);
- printf("Push 2\n");
- push(q, 4);
- printf("Push 4\n");
- push(q, 5);
- printf("Push 5\n");
- thrd_create(&t, task, 0);
-
- b=take(q);
- if (b == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", b);
- }
- c=take(q);
- if (c == EMPTY) {
- printf("Take NULL\n");
- } else {
- printf("Take %d\n", c);
- }
- thrd_join(t);
-
-
- return 0;
-}
-
+++ /dev/null
-#ifndef CLIFFC_HASHTABLE_H
-#define CLIFFC_HASHTABLE_H
-
-#include <iostream>
-#include <atomic>
-#include "stdio.h"
-#ifdef STANDALONE
-#include <assert.h>
-#define MODEL_ASSERT assert
-#else
-#include <model-assert.h>
-#endif
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-using namespace std;
-
-
-
-template<typename TypeK, typename TypeV>
-class cliffc_hashtable;
-
-
-struct kvs_data {
- int _size;
- atomic<void*> *_data;
-
- kvs_data(int sz) {
- _size = sz;
- int real_size = sz * 2 + 2;
- _data = new atomic<void*>[real_size];
- int *hashes = new int[_size];
- int i;
- for (i = 0; i < _size; i++) {
- hashes[i] = 0;
- }
- for (i = 2; i < real_size; i++) {
- _data[i].store(NULL, memory_order_relaxed);
- }
- _data[1].store(hashes, memory_order_relaxed);
- }
-
- ~kvs_data() {
- int *hashes = (int*) _data[1].load(memory_order_relaxed);
- delete hashes;
- delete[] _data;
- }
-};
-
-struct slot {
- bool _prime;
- void *_ptr;
-
- slot(bool prime, void *ptr) {
- _prime = prime;
- _ptr = ptr;
- }
-};
-
-
-
-
-template<typename TypeK, typename TypeV>
-class cliffc_hashtable {
-/* All other user-defined structs */
-static spec_table * map;
-static spec_table * id_map;
-static id_tag_t * tag;
-/* All other user-defined functions */
-inline static bool equals_key ( void * ptr1 , void * ptr2 ) {
-TypeK * key1 = ( TypeK * ) ptr1 , * key2 = ( TypeK * ) ptr2 ;
-if ( key1 == NULL || key2 == NULL ) return false ;
-return key1 -> equals ( key2 ) ;
-}
-
-inline static bool equals_val ( void * ptr1 , void * ptr2 ) {
-if ( ptr1 == ptr2 ) return true ;
-TypeV * val1 = ( TypeV * ) ptr1 , * val2 = ( TypeV * ) ptr2 ;
-if ( val1 == NULL || val2 == NULL ) return false ;
-return val1 -> equals ( val2 ) ;
-}
-
-inline static bool equals_id ( void * ptr1 , void * ptr2 ) {
-id_tag_t * id1 = ( id_tag_t * ) ptr1 , * id2 = ( id_tag_t * ) ptr2 ;
-if ( id1 == NULL || id2 == NULL ) return false ;
-return ( * id1 ) . tag == ( * id2 ) . tag ;
-}
-
-inline static call_id_t getKeyTag ( TypeK * key ) {
-if ( ! spec_table_contains ( id_map , key ) ) {
-call_id_t cur_id = current ( tag ) ;
-spec_table_put ( id_map , key , ( void * ) cur_id ) ;
-next ( tag ) ;
-return cur_id ;
-}
-else {
-call_id_t res = ( call_id_t ) spec_table_get ( id_map , key ) ;
-return res ;
-}
-}
-
-/* Definition of interface info struct: Put */
-typedef struct Put_info {
-TypeV * __RET__;
-TypeK * key;
-TypeV * val;
-} Put_info;
-/* End of info struct definition: Put */
-
-/* ID function of interface: Put */
-inline static call_id_t Put_id(void *info, thread_id_t __TID__) {
- Put_info* theInfo = (Put_info*)info;
- TypeV * __RET__ = theInfo->__RET__;
- TypeK * key = theInfo->key;
- TypeV * val = theInfo->val;
-
- call_id_t __ID__ = getKeyTag ( key );
- return __ID__;
-}
-/* End of ID function: Put */
-
-/* Check action function of interface: Put */
-inline static bool Put_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Put_info* theInfo = (Put_info*)info;
- TypeV * __RET__ = theInfo->__RET__;
- TypeK * key = theInfo->key;
- TypeV * val = theInfo->val;
-
- TypeV * _Old_Val = ( TypeV * ) spec_table_get ( map , key ) ;
- spec_table_put ( map , key , val ) ;
- bool passed = false ;
- if ( ! passed ) {
- int old = _Old_Val == NULL ? 0 : _Old_Val -> _val ;
- int ret = __RET__ == NULL ? 0 : __RET__ -> _val ;
- }
- check_passed = equals_val ( __RET__ , _Old_Val );
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Put */
-
-/* Definition of interface info struct: Get */
-typedef struct Get_info {
-TypeV * __RET__;
-TypeK * key;
-} Get_info;
-/* End of info struct definition: Get */
-
-/* ID function of interface: Get */
-inline static call_id_t Get_id(void *info, thread_id_t __TID__) {
- Get_info* theInfo = (Get_info*)info;
- TypeV * __RET__ = theInfo->__RET__;
- TypeK * key = theInfo->key;
-
- call_id_t __ID__ = getKeyTag ( key );
- return __ID__;
-}
-/* End of ID function: Get */
-
-/* Check action function of interface: Get */
-inline static bool Get_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Get_info* theInfo = (Get_info*)info;
- TypeV * __RET__ = theInfo->__RET__;
- TypeK * key = theInfo->key;
-
- TypeV * _Old_Val = ( TypeV * ) spec_table_get ( map , key ) ;
- bool passed = false ;
- if ( ! passed ) {
- int old = _Old_Val == NULL ? 0 : _Old_Val -> _val ;
- int ret = __RET__ == NULL ? 0 : __RET__ -> _val ;
- }
- check_passed = equals_val ( _Old_Val , __RET__ );
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Get */
-
-#define INTERFACE_SIZE 2
-static void** func_ptr_table;
-static anno_hb_init** hb_init_table;
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- map = new_spec_table_default ( equals_key ) ;
- id_map = new_spec_table_default ( equals_id ) ;
- tag = new_id_tag ( ) ;
-}
-
-/* Cleanup routine of sequential variables */
-static void __SPEC_CLEANUP__() {
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
- func_ptr_table[2 * 1] = (void*) &Put_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Put_check_action;
- func_ptr_table[2 * 0] = (void*) &Get_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Get_check_action;
- /* Put(true) -> Put(true) */
- struct anno_hb_init *hbConditionInit0 = (struct anno_hb_init*) malloc(sizeof(struct anno_hb_init));
- hbConditionInit0->interface_num_before = 1; // Put
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 1; // Put
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Put(true) -> Get(true) */
- struct anno_hb_init *hbConditionInit1 = (struct anno_hb_init*) malloc(sizeof(struct anno_hb_init));
- hbConditionInit1->interface_num_before = 1; // Put
- hbConditionInit1->hb_condition_num_before = 0; //
- hbConditionInit1->interface_num_after = 0; // Get
- hbConditionInit1->hb_condition_num_after = 0; //
- /* Init hb_init_table */
- hb_init_table = (anno_hb_init**) malloc(sizeof(anno_hb_init*) * 2);
- #define HB_INIT_TABLE_SIZE 2
- hb_init_table[0] = hbConditionInit0;
- hb_init_table[1] = hbConditionInit1;
- /* Pass init info, including function table info & HB rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void*) __SPEC_INIT__;
- anno_init->cleanup_func = (void*) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_init_table = hb_init_table;
- anno_init->hb_init_table_size = HB_INIT_TABLE_SIZE;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-friend class CHM;
-
- private:
- class CHM {
- friend class cliffc_hashtable;
- private:
- atomic<kvs_data*> _newkvs;
-
- atomic_int _size;
-
- atomic_int _slots;
-
- atomic_int _copy_idx;
-
- atomic_int _copy_done;
-
- public:
- CHM(int size) {
- _newkvs.store(NULL, memory_order_relaxed);
- _size.store(size, memory_order_relaxed);
- _slots.store(0, memory_order_relaxed);
-
- _copy_idx.store(0, memory_order_relaxed);
- _copy_done.store(0, memory_order_relaxed);
- }
-
- ~CHM() {}
-
- private:
-
- bool table_full(int reprobe_cnt, int len) {
- return
- reprobe_cnt >= REPROBE_LIMIT &&
- _slots.load(memory_order_relaxed) >= reprobe_limit(len);
- }
-
- kvs_data* resize(cliffc_hashtable *topmap, kvs_data *kvs) {
-
- kvs_data *newkvs = _newkvs.load(memory_order_acquire);
- if (newkvs != NULL)
- return newkvs;
-
- int oldlen = kvs->_size;
- int sz = _size.load(memory_order_relaxed);
- int newsz = sz;
-
- if (sz >= (oldlen >> 2)) { newsz = oldlen << 1; if (sz >= (oldlen >> 1))
- newsz = oldlen << 2; }
-
- if (newsz <= oldlen) newsz = oldlen << 1;
- if (newsz < oldlen) newsz = oldlen;
-
-
- newkvs = _newkvs.load(memory_order_acquire);
- if (newkvs != NULL) return newkvs;
-
- newkvs = new kvs_data(newsz);
- void *chm = (void*) new CHM(sz);
- newkvs->_data[0].store(chm, memory_order_relaxed);
-
- kvs_data *cur_newkvs;
-
- if ((cur_newkvs = _newkvs.load(memory_order_acquire)) != NULL)
- return cur_newkvs;
- kvs_data *desired = (kvs_data*) NULL;
- kvs_data *expected = (kvs_data*) newkvs;
-
- if (!_newkvs.compare_exchange_strong(desired, expected, memory_order_release,
- memory_order_relaxed)) {
- delete newkvs;
-
- newkvs = _newkvs.load(memory_order_acquire);
- }
- return newkvs;
- }
-
- void help_copy_impl(cliffc_hashtable *topmap, kvs_data *oldkvs,
- bool copy_all) {
- MODEL_ASSERT (get_chm(oldkvs) == this);
-
- kvs_data *newkvs = _newkvs.load(memory_order_acquire);
- int oldlen = oldkvs->_size;
- int min_copy_work = oldlen > 1024 ? 1024 : oldlen;
-
- int panic_start = -1;
- int copyidx;
- while (_copy_done.load(memory_order_relaxed) < oldlen) {
- copyidx = _copy_idx.load(memory_order_relaxed);
- if (panic_start == -1) { copyidx = _copy_idx.load(memory_order_relaxed);
- while (copyidx < (oldlen << 1) &&
- !_copy_idx.compare_exchange_strong(copyidx, copyidx +
- min_copy_work, memory_order_relaxed, memory_order_relaxed))
- copyidx = _copy_idx.load(memory_order_relaxed);
- if (!(copyidx < (oldlen << 1)))
- panic_start = copyidx;
- }
-
- int workdone = 0;
- for (int i = 0; i < min_copy_work; i++)
- if (copy_slot(topmap, (copyidx + i) & (oldlen - 1), oldkvs,
- newkvs))
- workdone++;
- if (workdone > 0)
- copy_check_and_promote(topmap, oldkvs, workdone);
-
- copyidx += min_copy_work;
- if (!copy_all && panic_start == -1)
- return; }
- copy_check_and_promote(topmap, oldkvs, 0); }
-
- kvs_data* copy_slot_and_check(cliffc_hashtable *topmap, kvs_data
- *oldkvs, int idx, void *should_help) {
-
- kvs_data *newkvs = _newkvs.load(memory_order_acquire);
- if (copy_slot(topmap, idx, oldkvs, newkvs))
- copy_check_and_promote(topmap, oldkvs, 1); return (should_help == NULL) ? newkvs : topmap->help_copy(newkvs);
- }
-
- void copy_check_and_promote(cliffc_hashtable *topmap, kvs_data*
- oldkvs, int workdone) {
- int oldlen = oldkvs->_size;
- int copyDone = _copy_done.load(memory_order_relaxed);
- if (workdone > 0) {
- while (true) {
- copyDone = _copy_done.load(memory_order_relaxed);
- if (_copy_done.compare_exchange_weak(copyDone, copyDone +
- workdone, memory_order_relaxed, memory_order_relaxed))
- break;
- }
- }
-
- if (copyDone + workdone == oldlen &&
- topmap->_kvs.load(memory_order_relaxed) == oldkvs) {
-
- kvs_data *newkvs = _newkvs.load(memory_order_acquire);
-
- topmap->_kvs.compare_exchange_strong(oldkvs, newkvs, memory_order_release,
- memory_order_relaxed);
- }
- }
-
- bool copy_slot(cliffc_hashtable *topmap, int idx, kvs_data *oldkvs,
- kvs_data *newkvs) {
- slot *key_slot;
- while ((key_slot = key(oldkvs, idx)) == NULL)
- CAS_key(oldkvs, idx, NULL, TOMBSTONE);
-
- slot *oldval = val(oldkvs, idx);
- while (!is_prime(oldval)) {
- slot *box = (oldval == NULL || oldval == TOMBSTONE)
- ? TOMBPRIME : new slot(true, oldval->_ptr);
- if (CAS_val(oldkvs, idx, oldval, box)) {
- if (box == TOMBPRIME)
- return 1; oldval = box; break;
- }
- oldval = val(oldkvs, idx); }
-
- if (oldval == TOMBPRIME) return false;
- slot *old_unboxed = new slot(false, oldval->_ptr);
- int copied_into_new = (putIfMatch(topmap, newkvs, key_slot, old_unboxed,
- NULL) == NULL);
-
- while (!CAS_val(oldkvs, idx, oldval, TOMBPRIME))
- oldval = val(oldkvs, idx);
-
- return copied_into_new;
- }
- };
-
-
-
- private:
- static const int Default_Init_Size = 4;
- static slot* const MATCH_ANY;
- static slot* const NO_MATCH_OLD;
-
- static slot* const TOMBPRIME;
- static slot* const TOMBSTONE;
-
- static const int REPROBE_LIMIT = 10;
- atomic<kvs_data*> _kvs;
-
- public:
- cliffc_hashtable() {
- __sequential_init();
-
- kvs_data *kvs = new kvs_data(Default_Init_Size);
- void *chm = (void*) new CHM(0);
- kvs->_data[0].store(chm, memory_order_relaxed);
- _kvs.store(kvs, memory_order_relaxed);
- }
-
- cliffc_hashtable(int init_size) {
-
- __sequential_init();
-
- kvs_data *kvs = new kvs_data(init_size);
- void *chm = (void*) new CHM(0);
- kvs->_data[0].store(chm, memory_order_relaxed);
- _kvs.store(kvs, memory_order_relaxed);
- }
-
-
-TypeV * get(TypeK * key) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Get
- interface_begin->interface_name = "Get";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- TypeV * __RET__ = __wrapper__get(key);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Get
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Get_info* info = (Get_info*) malloc(sizeof(Get_info));
- info->__RET__ = __RET__;
- info->key = key;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Get
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-TypeV * __wrapper__get(TypeK * key) {
- slot *key_slot = new slot(false, key);
- int fullhash = hash(key_slot);
-
- kvs_data *kvs = _kvs.load(memory_order_acquire);
-
- slot *V = get_impl(this, kvs, key_slot, fullhash);
- if (V == NULL) return NULL;
- MODEL_ASSERT (!is_prime(V));
- return (TypeV*) V->_ptr;
- }
-
-
-TypeV * put(TypeK * key, TypeV * val) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Put
- interface_begin->interface_name = "Put";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- TypeV * __RET__ = __wrapper__put(key, val);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Put
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Put_info* info = (Put_info*) malloc(sizeof(Put_info));
- info->__RET__ = __RET__;
- info->key = key;
- info->val = val;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Put
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-TypeV * __wrapper__put(TypeK * key, TypeV * val) {
- return putIfMatch(key, val, NO_MATCH_OLD);
- }
-
-
- TypeV* putIfAbsent(TypeK *key, TypeV *value) {
- return putIfMatch(key, val, TOMBSTONE);
- }
-
-
- TypeV* remove(TypeK *key) {
- return putIfMatch(key, TOMBSTONE, NO_MATCH_OLD);
- }
-
-
- bool remove(TypeK *key, TypeV *val) {
- slot *val_slot = val == NULL ? NULL : new slot(false, val);
- return putIfMatch(key, TOMBSTONE, val) == val;
-
- }
-
-
- TypeV* replace(TypeK *key, TypeV *val) {
- return putIfMatch(key, val, MATCH_ANY);
- }
-
-
- bool replace(TypeK *key, TypeV *oldval, TypeV *newval) {
- return putIfMatch(key, newval, oldval) == oldval;
- }
-
- private:
- static CHM* get_chm(kvs_data* kvs) {
- CHM *res = (CHM*) kvs->_data[0].load(memory_order_relaxed);
- return res;
- }
-
- static int* get_hashes(kvs_data *kvs) {
- return (int *) kvs->_data[1].load(memory_order_relaxed);
- }
-
- static inline slot* key(kvs_data *kvs, int idx) {
- MODEL_ASSERT (idx >= 0 && idx < kvs->_size);
- slot *res = (slot*) kvs->_data[idx * 2 + 2].load(memory_order_relaxed);
- /* Automatically generated code for potential commit point: Read_Key_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 0;
- potential_cp_define->label_name = "Read_Key_Point";
- potential_cp_define->is_additional_point = false;
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- return res;
- }
-
-
- static inline slot* val(kvs_data *kvs, int idx) {
- MODEL_ASSERT (idx >= 0 && idx < kvs->_size);
-
- slot *res = (slot*) kvs->_data[idx * 2 + 3].load(memory_order_acquire);
- /* Automatically generated code for potential commit point: Read_Val_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 1;
- potential_cp_define->label_name = "Read_Val_Point";
- potential_cp_define->is_additional_point = false;
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- return res;
-
-
- }
-
- static int hash(slot *key_slot) {
- MODEL_ASSERT(key_slot != NULL && key_slot->_ptr != NULL);
- TypeK* key = (TypeK*) key_slot->_ptr;
- int h = key->hashCode();
- h += (h << 15) ^ 0xffffcd7d;
- h ^= (h >> 10);
- h += (h << 3);
- h ^= (h >> 6);
- h += (h << 2) + (h << 14);
- return h ^ (h >> 16);
- }
-
- static int reprobe_limit(int len) {
- return REPROBE_LIMIT + (len >> 2);
- }
-
- static inline bool is_prime(slot *val) {
- return (val != NULL) && val->_prime;
- }
-
- static bool keyeq(slot *K, slot *key_slot, int *hashes, int hash,
- int fullhash) {
- MODEL_ASSERT (K != NULL);
- TypeK* key_ptr = (TypeK*) key_slot->_ptr;
- return
- K == key_slot ||
- ((hashes[hash] == 0 || hashes[hash] == fullhash) &&
- K != TOMBSTONE &&
- key_ptr->equals(K->_ptr));
- }
-
- static bool valeq(slot *val_slot1, slot *val_slot2) {
- MODEL_ASSERT (val_slot1 != NULL);
- TypeK* ptr1 = (TypeV*) val_slot1->_ptr;
- if (val_slot2 == NULL || ptr1 == NULL) return false;
- return ptr1->equals(val_slot2->_ptr);
- }
-
- static inline bool CAS_key(kvs_data *kvs, int idx, void *expected, void *desired) {
- bool res = kvs->_data[2 * idx + 2].compare_exchange_strong(expected,
- desired, memory_order_relaxed, memory_order_relaxed);
- /* Automatically generated code for potential commit point: Write_Key_Point */
-
- if (res) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 2;
- potential_cp_define->label_name = "Write_Key_Point";
- potential_cp_define->is_additional_point = false;
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- return res;
- }
-
-
- static inline bool CAS_val(kvs_data *kvs, int idx, void *expected, void
- *desired) {
-
- bool res = kvs->_data[2 * idx + 3].compare_exchange_strong(expected,
- desired, memory_order_acq_rel, memory_order_relaxed);
- /* Automatically generated code for potential commit point: Write_Val_Point */
-
- if (res) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 3;
- potential_cp_define->label_name = "Write_Val_Point";
- potential_cp_define->is_additional_point = false;
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- return res;
- }
-
- slot* get_impl(cliffc_hashtable *topmap, kvs_data *kvs, slot* key_slot, int
- fullhash) {
- int len = kvs->_size;
- CHM *chm = get_chm(kvs);
- int *hashes = get_hashes(kvs);
-
- int idx = fullhash & (len - 1);
- int reprobe_cnt = 0;
- while (true) {
- slot *K = key(kvs, idx);
- /* Automatically generated code for commit point define: Get_Point1 */
-
- if (K == NULL) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 4;
- cp_define->label_name = "Get_Point1";
- cp_define->potential_cp_label_num = 0;
- cp_define->potential_label_name = "Read_Key_Point";
- cp_define->interface_num = 0;
- cp_define->is_additional_point = false;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- slot *V = val(kvs, idx);
-
- if (K == NULL) {
- return NULL; }
-
- if (keyeq(K, key_slot, hashes, idx, fullhash)) {
- if (!is_prime(V)) {
- /* Automatically generated code for commit point clear: Get_Clear */
-
- if (true) {
- struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
- struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_clear->type = CP_CLEAR;
- annotation_cp_clear->annotation = cp_clear;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
- }
-
-
- /* Automatically generated code for commit point define: Get_Point2 */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 6;
- cp_define->label_name = "Get_Point2";
- cp_define->potential_cp_label_num = 1;
- cp_define->potential_label_name = "Read_Val_Point";
- cp_define->interface_num = 0;
- cp_define->is_additional_point = false;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return (V == TOMBSTONE) ? NULL : V; }
- return get_impl(topmap, chm->copy_slot_and_check(topmap, kvs,
- idx, key_slot), key_slot, fullhash);
- }
-
- if (++reprobe_cnt >= REPROBE_LIMIT ||
- key_slot == TOMBSTONE) {
-
- kvs_data *newkvs = chm->_newkvs.load(memory_order_acquire);
-
- return newkvs == NULL ? NULL : get_impl(topmap,
- topmap->help_copy(newkvs), key_slot, fullhash);
- }
-
- idx = (idx + 1) & (len - 1); }
- }
-
- TypeV* putIfMatch(TypeK *key, TypeV *value, slot *old_val) {
- if (old_val == NULL) {
- return NULL;
- }
- slot *key_slot = new slot(false, key);
-
- slot *value_slot = new slot(false, value);
-
- kvs_data *kvs = _kvs.load(memory_order_acquire);
-
- slot *res = putIfMatch(this, kvs, key_slot, value_slot, old_val);
- MODEL_ASSERT (res != NULL);
- MODEL_ASSERT (!is_prime(res));
- return res == TOMBSTONE ? NULL : (TypeV*) res->_ptr;
- }
-
-
- static slot* putIfMatch(cliffc_hashtable *topmap, kvs_data *kvs, slot
- *key_slot, slot *val_slot, slot *expVal) {
- MODEL_ASSERT (val_slot != NULL);
- MODEL_ASSERT (!is_prime(val_slot));
- MODEL_ASSERT (!is_prime(expVal));
-
- int fullhash = hash(key_slot);
- int len = kvs->_size;
- CHM *chm = get_chm(kvs);
- int *hashes = get_hashes(kvs);
- int idx = fullhash & (len - 1);
-
- int reprobe_cnt = 0;
- slot *K;
- slot *V;
- kvs_data *newkvs;
-
- while (true) { K = key(kvs, idx);
- V = val(kvs, idx);
- if (K == NULL) { if (val_slot == TOMBSTONE) return val_slot;
- if (CAS_key(kvs, idx, NULL, key_slot)) {
- /* Automatically generated code for commit point define: Put_WriteKey */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 7;
- cp_define->label_name = "Put_WriteKey";
- cp_define->potential_cp_label_num = 2;
- cp_define->potential_label_name = "Write_Key_Point";
- cp_define->interface_num = 1;
- cp_define->is_additional_point = false;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- chm->_slots.fetch_add(1, memory_order_relaxed); hashes[idx] = fullhash; break;
- }
- K = key(kvs, idx); MODEL_ASSERT (K != NULL);
- }
-
- if (keyeq(K, key_slot, hashes, idx, fullhash))
- break;
- if (++reprobe_cnt >= reprobe_limit(len) ||
- K == TOMBSTONE) { newkvs = chm->resize(topmap, kvs);
- if (expVal != NULL) topmap->help_copy(newkvs);
- return putIfMatch(topmap, newkvs, key_slot, val_slot, expVal);
- }
-
- idx = (idx + 1) & (len - 1); }
- if (val_slot == V) return V;
-
- newkvs = chm->_newkvs.load(memory_order_acquire);
-
- if (newkvs == NULL &&
- ((V == NULL && chm->table_full(reprobe_cnt, len)) || is_prime(V))) {
- newkvs = chm->resize(topmap, kvs); }
-
- if (newkvs != NULL)
- return putIfMatch(topmap, chm->copy_slot_and_check(topmap, kvs, idx,
- expVal), key_slot, val_slot, expVal);
-
- while (true) {
- MODEL_ASSERT (!is_prime(V));
-
- if (expVal != NO_MATCH_OLD &&
- V != expVal &&
- (expVal != MATCH_ANY || V == TOMBSTONE || V == NULL) &&
- !(V == NULL && expVal == TOMBSTONE) &&
- (expVal == NULL || !valeq(expVal, V))) {
-
-
-
- return V; }
-
- if (CAS_val(kvs, idx, V, val_slot)) {
- /* Automatically generated code for commit point define: Put_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 8;
- cp_define->label_name = "Put_Point";
- cp_define->potential_cp_label_num = 3;
- cp_define->potential_label_name = "Write_Val_Point";
- cp_define->interface_num = 1;
- cp_define->is_additional_point = false;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- if (expVal != NULL) { if ((V == NULL || V == TOMBSTONE) &&
- val_slot != TOMBSTONE)
- chm->_size.fetch_add(1, memory_order_relaxed);
- if (!(V == NULL || V == TOMBSTONE) &&
- val_slot == TOMBSTONE)
- chm->_size.fetch_add(-1, memory_order_relaxed);
- }
- return (V == NULL && expVal != NULL) ? TOMBSTONE : V;
- }
- V = val(kvs, idx);
- if (is_prime(V))
- return putIfMatch(topmap, chm->copy_slot_and_check(topmap, kvs,
- idx, expVal), key_slot, val_slot, expVal);
- }
- }
-
- kvs_data* help_copy(kvs_data *helper) {
-
- kvs_data *topkvs = _kvs.load(memory_order_acquire);
- CHM *topchm = get_chm(topkvs);
- if (topchm->_newkvs.load(memory_order_relaxed) == NULL) return helper;
- topchm->help_copy_impl(this, topkvs, false);
- return helper;
- }
-};
-template<typename TypeK, typename TypeV>
-void** cliffc_hashtable<TypeK, TypeV>::func_ptr_table;
-template<typename TypeK, typename TypeV>
-anno_hb_init** cliffc_hashtable<TypeK, TypeV>::hb_init_table;
-template<typename TypeK, typename TypeV>
-spec_table * cliffc_hashtable<TypeK, TypeV>::map;
-template<typename TypeK, typename TypeV>
-spec_table * cliffc_hashtable<TypeK, TypeV>::id_map;
-template<typename TypeK, typename TypeV>
-id_tag_t * cliffc_hashtable<TypeK, TypeV>::tag;
-
-
-#endif
-
+++ /dev/null
-#include <iostream>
-#include <threads.h>
-#include "cliffc_hashtable.h"
-
-using namespace std;
-
-template<typename TypeK, typename TypeV>
-slot* const cliffc_hashtable<TypeK, TypeV>::MATCH_ANY = new slot(false, NULL);
-
-template<typename TypeK, typename TypeV>
-slot* const cliffc_hashtable<TypeK, TypeV>::NO_MATCH_OLD = new slot(false, NULL);
-
-template<typename TypeK, typename TypeV>
-slot* const cliffc_hashtable<TypeK, TypeV>::TOMBPRIME = new slot(true, NULL);
-
-template<typename TypeK, typename TypeV>
-slot* const cliffc_hashtable<TypeK, TypeV>::TOMBSTONE = new slot(false, NULL);
-
-
-class IntWrapper {
- private:
- public:
- int _val;
-
- IntWrapper(int val) : _val(val) {}
-
- IntWrapper() : _val(0) {}
-
- IntWrapper(IntWrapper& copy) : _val(copy._val) {}
-
- int get() {
- return _val;
- }
-
- int hashCode() {
- return _val;
- }
-
- bool operator==(const IntWrapper& rhs) {
- return false;
- }
-
- bool equals(const void *another) {
- if (another == NULL)
- return false;
- IntWrapper *ptr =
- (IntWrapper*) another;
- return ptr->_val == _val;
- }
-};
-
-cliffc_hashtable<IntWrapper, IntWrapper> *table;
-IntWrapper *val1, *val2;
-IntWrapper *k0, *k1, *k2, *k3, *k4, *k5;
-IntWrapper *v0, *v1, *v2, *v3, *v4, *v5;
-
-void threadA(void *arg) {
- IntWrapper *Res;
- int res;
- Res = table->put(k3, v3);
- res = Res == NULL ? 0 : Res->_val;
- printf("Put1: key_%d, val_%d, res_%d\n", k3->_val, v3->_val, res);
-
- Res = table->get(k2);
- res = Res == NULL ? 0 : Res->_val;
- printf("Get2: key_%d, res_%d\n", k2->_val, res);
-}
-
-void threadB(void *arg) {
- IntWrapper *Res;
- int res;
- Res = table->put(k2, v2);
- res = Res == NULL ? 0 : Res->_val;
- printf("Put3: key_%d, val_%d, res_%d\n", k2->_val, v2->_val, res);
-
- Res = table->get(k3);
- res = Res == NULL ? 0 : Res->_val;
- printf("Get4: key_%d, res_%d\n", k3->_val, res);
-}
-
-void threadC(void *arg) {
-}
-
-int user_main(int argc, char *argv[]) {
- thrd_t t1, t2, t3;
- table = new cliffc_hashtable<IntWrapper, IntWrapper>(32);
- k1 = new IntWrapper(3);
- k2 = new IntWrapper(5);
- k3 = new IntWrapper(11);
- k4 = new IntWrapper(7);
- k5 = new IntWrapper(13);
-
- v0 = new IntWrapper(2048);
- v1 = new IntWrapper(1024);
- v2 = new IntWrapper(47);
- v3 = new IntWrapper(73);
- v4 = new IntWrapper(81);
- v5 = new IntWrapper(99);
-
- thrd_create(&t1, threadA, NULL);
- thrd_create(&t2, threadB, NULL);
- thrd_create(&t3, threadC, NULL);
- thrd_join(t1);
- thrd_join(t2);
- thrd_join(t3);
-
- return 0;
-}
-
-
-
+++ /dev/null
-/*
- File: ConcurrentHashMap
-
- Written by Doug Lea. Adapted and released, under explicit
- permission, from JDK1.2 HashMap.java and Hashtable.java which
- carries the following copyright:
-
- * Copyright 1997 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
-
- History:
- Date Who What
- 26nov2000 dl Created, based on ConcurrentReaderHashMap
- 12jan2001 dl public release
- 17nov2001 dl Minor tunings
- 24oct2003 dl Segment implements Serializable
-*/
-
-package EDU.oswego.cs.dl.util.concurrent;
-
-import java.util.Map;
-import java.util.AbstractMap;
-import java.util.AbstractSet;
-import java.util.AbstractCollection;
-import java.util.Collection;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.Enumeration;
-import java.util.NoSuchElementException;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-
-/**
- * A version of Hashtable supporting
- * concurrency for both retrievals and updates:
- *
- * <dl>
- * <dt> Retrievals
- *
- * <dd> Retrievals may overlap updates. (This is the same policy as
- * ConcurrentReaderHashMap.) Successful retrievals using get(key) and
- * containsKey(key) usually run without locking. Unsuccessful
- * retrievals (i.e., when the key is not present) do involve brief
- * synchronization (locking). Because retrieval operations can
- * ordinarily overlap with update operations (i.e., put, remove, and
- * their derivatives), retrievals can only be guaranteed to return the
- * results of the most recently <em>completed</em> operations holding
- * upon their onset. Retrieval operations may or may not return
- * results reflecting in-progress writing operations. However, the
- * retrieval operations do always return consistent results -- either
- * those holding before any single modification or after it, but never
- * a nonsense result. For aggregate operations such as putAll and
- * clear, concurrent reads may reflect insertion or removal of only
- * some entries.
- * <p>
- *
- * Iterators and Enumerations (i.e., those returned by
- * keySet().iterator(), entrySet().iterator(), values().iterator(),
- * keys(), and elements()) return elements reflecting the state of the
- * hash table at some point at or since the creation of the
- * iterator/enumeration. They will return at most one instance of
- * each element (via next()/nextElement()), but might or might not
- * reflect puts and removes that have been processed since they were
- * created. They do <em>not</em> throw ConcurrentModificationException.
- * However, these iterators are designed to be used by only one
- * thread at a time. Passing an iterator across multiple threads may
- * lead to unpredictable results if the table is being concurrently
- * modified. <p>
- *
- *
- * <dt> Updates
- *
- * <dd> This class supports a hard-wired preset <em>concurrency
- * level</em> of 32. This allows a maximum of 32 put and/or remove
- * operations to proceed concurrently. This level is an upper bound on
- * concurrency, not a guarantee, since it interacts with how
- * well-strewn elements are across bins of the table. (The preset
- * value in part reflects the fact that even on large multiprocessors,
- * factors other than synchronization tend to be bottlenecks when more
- * than 32 threads concurrently attempt updates.)
- * Additionally, operations triggering internal resizing and clearing
- * do not execute concurrently with any operation.
- * <p>
- *
- * There is <em>NOT</em> any support for locking the entire table to
- * prevent updates. This makes it imposssible, for example, to
- * add an element only if it is not already present, since another
- * thread may be in the process of doing the same thing.
- * If you need such capabilities, consider instead using the
- * ConcurrentReaderHashMap class.
- *
- * </dl>
- *
- * Because of how concurrency control is split up, the
- * size() and isEmpty() methods require accumulations across 32
- * control segments, and so might be slightly slower than you expect.
- * <p>
- *
- * This class may be used as a direct replacement for
- * java.util.Hashtable in any application that does not rely
- * on the ability to lock the entire table to prevent updates.
- * As of this writing, it performs much faster than Hashtable in
- * typical multi-threaded applications with multiple readers and writers.
- * Like Hashtable but unlike java.util.HashMap,
- * this class does NOT allow <tt>null</tt> to be used as a key or
- * value.
- * <p>
- *
- * Implementation note: A slightly
- * faster implementation of this class will be possible once planned
- * Java Memory Model revisions are in place.
- *
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
-
- **/
-
-
-public class ConcurrentHashMap
- extends AbstractMap
- implements Map, Cloneable, Serializable {
-
- /*
- The basic strategy is an optimistic-style scheme based on
- the guarantee that the hash table and its lists are always
- kept in a consistent enough state to be read without locking:
-
- * Read operations first proceed without locking, by traversing the
- apparently correct list of the apparently correct bin. If an
- entry is found, but not invalidated (value field null), it is
- returned. If not found, operations must recheck (after a memory
- barrier) to make sure they are using both the right list and
- the right table (which can change under resizes). If
- invalidated, reads must acquire main update lock to wait out
- the update, and then re-traverse.
-
- * All list additions are at the front of each bin, making it easy
- to check changes, and also fast to traverse. Entry next
- pointers are never assigned. Remove() builds new nodes when
- necessary to preserve this.
-
- * Remove() (also clear()) invalidates removed nodes to alert read
- operations that they must wait out the full modifications.
-
- * Locking for puts, removes (and, when necessary gets, etc)
- is controlled by Segments, each covering a portion of the
- table. During operations requiring global exclusivity (mainly
- resize and clear), ALL of these locks are acquired at once.
- Note that these segments are NOT contiguous -- they are based
- on the least 5 bits of hashcodes. This ensures that the same
- segment controls the same slots before and after resizing, which
- is necessary for supporting concurrent retrievals. This
- comes at the price of a mismatch of logical vs physical locality,
- but this seems not to be a performance problem in practice.
-
- */
-
- /**
- * The hash table data.
- */
- protected transient Entry[] table;
-
-
- /**
- * The number of concurrency control segments.
- * The value can be at most 32 since ints are used
- * as bitsets over segments. Emprically, it doesn't
- * seem to pay to decrease it either, so the value should be at least 32.
- * In other words, do not redefine this :-)
- **/
-
- protected static final int CONCURRENCY_LEVEL = 32;
-
- /**
- * Mask value for indexing into segments
- **/
-
- protected static final int SEGMENT_MASK = CONCURRENCY_LEVEL - 1;
-
- /**
- * Bookkeeping for each concurrency control segment.
- * Each segment contains a local count of the number of
- * elements in its region.
- * However, the main use of a Segment is for its lock.
- **/
- protected final static class Segment implements Serializable {
- /**
- * The number of elements in this segment's region.
- * It is always updated within synchronized blocks.
- **/
- protected int count;
-
- /**
- * Get the count under synch.
- **/
- protected synchronized int getCount() { return count; }
-
- /**
- * Force a synchronization
- **/
- protected synchronized void synch() {}
- }
-
- /**
- * The array of concurrency control segments.
- **/
-
- protected final Segment[] segments = new Segment[CONCURRENCY_LEVEL];
-
-
- /**
- * The default initial number of table slots for this table (32).
- * Used when not otherwise specified in constructor.
- **/
- public static int DEFAULT_INITIAL_CAPACITY = 32;
-
-
- /**
- * The minimum capacity, used if a lower value is implicitly specified
- * by either of the constructors with arguments.
- * MUST be a power of two.
- */
- private static final int MINIMUM_CAPACITY = 32;
-
- /**
- * The maximum capacity, used if a higher value is implicitly specified
- * by either of the constructors with arguments.
- * MUST be a power of two <= 1<<30.
- */
- private static final int MAXIMUM_CAPACITY = 1 << 30;
-
- /**
- * The default load factor for this table (0.75)
- * Used when not otherwise specified in constructor.
- **/
-
- public static final float DEFAULT_LOAD_FACTOR = 0.75f;
-
- /**
- * The load factor for the hash table.
- *
- * @serial
- */
- protected final float loadFactor;
-
- /**
- * Per-segment resize threshold.
- *
- * @serial
- */
- protected int threshold;
-
-
- /**
- * Number of segments voting for resize. The table is
- * doubled when 1/4 of the segments reach threshold.
- * Volatile but updated without synch since this is just a heuristic.
- **/
-
- protected transient volatile int votesForResize;
-
-
- /**
- * Return the number of set bits in w.
- * For a derivation of this algorithm, see
- * "Algorithms and data structures with applications to
- * graphics and geometry", by Jurg Nievergelt and Klaus Hinrichs,
- * Prentice Hall, 1993.
- * See also notes by Torsten Sillke at
- * http://www.mathematik.uni-bielefeld.de/~sillke/PROBLEMS/bitcount
- **/
- protected static int bitcount(int w) {
- w -= (0xaaaaaaaa & w) >>> 1;
- w = (w & 0x33333333) + ((w >>> 2) & 0x33333333);
- w = (w + (w >>> 4)) & 0x0f0f0f0f;
- w += w >>> 8;
- w += w >>> 16;
- return w & 0xff;
- }
-
- /**
- * Returns the appropriate capacity (power of two) for the specified
- * initial capacity argument.
- */
- private int p2capacity(int initialCapacity) {
- int cap = initialCapacity;
-
- // Compute the appropriate capacity
- int result;
- if (cap > MAXIMUM_CAPACITY || cap < 0) {
- result = MAXIMUM_CAPACITY;
- } else {
- result = MINIMUM_CAPACITY;
- while (result < cap)
- result <<= 1;
- }
- return result;
- }
-
- /**
- * Return hash code for Object x. Since we are using power-of-two
- * tables, it is worth the effort to improve hashcode via
- * the same multiplicative scheme as used in IdentityHashMap.
- */
- protected static int hash(Object x) {
- int h = x.hashCode();
- // Multiply by 127 (quickly, via shifts), and mix in some high
- // bits to help guard against bunching of codes that are
- // consecutive or equally spaced.
- return ((h << 7) - h + (h >>> 9) + (h >>> 17));
- }
-
-
- /**
- * Check for equality of non-null references x and y.
- **/
- protected boolean eq(Object x, Object y) {
- return x == y || x.equals(y);
- }
-
- /** Create table array and set the per-segment threshold **/
- protected Entry[] newTable(int capacity) {
- threshold = (int)(capacity * loadFactor / CONCURRENCY_LEVEL) + 1;
- return new Entry[capacity];
- }
-
- /**
- * Constructs a new, empty map with the specified initial
- * capacity and the specified load factor.
- *
- * @param initialCapacity the initial capacity.
- * The actual initial capacity is rounded to the nearest power of two.
- * @param loadFactor the load factor threshold, used to control resizing.
- * This value is used in an approximate way: When at least
- * a quarter of the segments of the table reach per-segment threshold, or
- * one of the segments itself exceeds overall threshold,
- * the table is doubled.
- * This will on average cause resizing when the table-wide
- * load factor is slightly less than the threshold. If you'd like
- * to avoid resizing, you can set this to a ridiculously large
- * value.
- * @throws IllegalArgumentException if the load factor is nonpositive.
- */
- public ConcurrentHashMap(int initialCapacity,
- float loadFactor) {
- if (!(loadFactor > 0))
- throw new IllegalArgumentException("Illegal Load factor: "+
- loadFactor);
- this.loadFactor = loadFactor;
- for (int i = 0; i < segments.length; ++i)
- segments[i] = new Segment();
- int cap = p2capacity(initialCapacity);
- table = newTable(cap);
- }
-
- /**
- * Constructs a new, empty map with the specified initial
- * capacity and default load factor.
- *
- * @param initialCapacity the initial capacity of the
- * ConcurrentHashMap.
- * @throws IllegalArgumentException if the initial maximum number
- * of elements is less
- * than zero.
- */
- public ConcurrentHashMap(int initialCapacity) {
- this(initialCapacity, DEFAULT_LOAD_FACTOR);
- }
-
- /**
- * Constructs a new, empty map with a default initial capacity
- * and default load factor.
- */
- public ConcurrentHashMap() {
- this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
- }
-
- /**
- * Constructs a new map with the same mappings as the given map. The
- * map is created with a capacity of twice the number of mappings in
- * the given map or 32 (whichever is greater), and a default load factor.
- */
- public ConcurrentHashMap(Map t) {
- this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1,
- MINIMUM_CAPACITY),
- DEFAULT_LOAD_FACTOR);
- putAll(t);
- }
-
- /**
- * Returns the number of key-value mappings in this map.
- *
- * @return the number of key-value mappings in this map.
- */
- public int size() {
- int c = 0;
- for (int i = 0; i < segments.length; ++i)
- c += segments[i].getCount();
- return c;
- }
-
- /**
- * Returns <tt>true</tt> if this map contains no key-value mappings.
- *
- * @return <tt>true</tt> if this map contains no key-value mappings.
- */
- public boolean isEmpty() {
- for (int i = 0; i < segments.length; ++i)
- if (segments[i].getCount() != 0)
- return false;
- return true;
- }
-
-
- /**
- * Returns the value to which the specified key is mapped in this table.
- *
- * @param key a key in the table.
- * @return the value to which the key is mapped in this table;
- * <code>null</code> if the key is not mapped to any value in
- * this table.
- * @exception NullPointerException if the key is
- * <code>null</code>.
- * @see #put(Object, Object)
- */
- public Object get(Object key) {
- int hash = hash(key); // throws null pointer exception if key null
-
- // Try first without locking...
- Entry[] tab = table;
- int index = hash & (tab.length - 1);
- Entry first = tab[index];
- Entry e;
-
- for (e = first; e != null; e = e.next) {
- if (e.hash == hash && eq(key, e.key)) {
- Object value = e.value;
- if (value != null)
- return value;
- else
- break;
- }
- }
-
- // Recheck under synch if key apparently not there or interference
- Segment seg = segments[hash & SEGMENT_MASK];
- synchronized(seg) {
- tab = table;
- index = hash & (tab.length - 1);
- Entry newFirst = tab[index];
- if (e != null || first != newFirst) {
- for (e = newFirst; e != null; e = e.next) {
- if (e.hash == hash && eq(key, e.key))
- return e.value;
- }
- }
- return null;
- }
- }
-
- /**
- * Tests if the specified object is a key in this table.
- *
- * @param key possible key.
- * @return <code>true</code> if and only if the specified object
- * is a key in this table, as determined by the
- * <tt>equals</tt> method; <code>false</code> otherwise.
- * @exception NullPointerException if the key is
- * <code>null</code>.
- * @see #contains(Object)
- */
-
- public boolean containsKey(Object key) {
- return get(key) != null;
- }
-
-
- /**
- * Maps the specified <code>key</code> to the specified
- * <code>value</code> in this table. Neither the key nor the
- * value can be <code>null</code>. (Note that this policy is
- * the same as for java.util.Hashtable, but unlike java.util.HashMap,
- * which does accept nulls as valid keys and values.)<p>
- *
- * The value can be retrieved by calling the <code>get</code> method
- * with a key that is equal to the original key.
- *
- * @param key the table key.
- * @param value the value.
- * @return the previous value of the specified key in this table,
- * or <code>null</code> if it did not have one.
- * @exception NullPointerException if the key or value is
- * <code>null</code>.
- * @see Object#equals(Object)
- * @see #get(Object)
- */
- public Object put(Object key, Object value) {
- if (value == null)
- throw new NullPointerException();
-
- int hash = hash(key);
- Segment seg = segments[hash & SEGMENT_MASK];
- int segcount;
- Entry[] tab;
- int votes;
-
- synchronized(seg) {
- tab = table;
- int index = hash & (tab.length-1);
- Entry first = tab[index];
-
- for (Entry e = first; e != null; e = e.next) {
- if (e.hash == hash && eq(key, e.key)) {
- Object oldValue = e.value;
- e.value = value;
- return oldValue;
- }
- }
-
- // Add to front of list
- Entry newEntry = new Entry(hash, key, value, first);
- tab[index] = newEntry;
-
- if ((segcount = ++seg.count) < threshold)
- return null;
-
- int bit = (1 << (hash & SEGMENT_MASK));
- votes = votesForResize;
- if ((votes & bit) == 0)
- votes = votesForResize |= bit;
- }
-
- // Attempt resize if 1/4 segs vote,
- // or if this seg itself reaches the overall threshold.
- // (The latter check is just a safeguard to avoid pathological cases.)
- if (bitcount(votes) >= CONCURRENCY_LEVEL / 4 ||
- segcount > (threshold * CONCURRENCY_LEVEL))
- resize(0, tab);
-
- return null;
- }
-
- /**
- * Gather all locks in order to call rehash, by
- * recursing within synch blocks for each segment index.
- * @param index the current segment. initially call value must be 0
- * @param assumedTab the state of table on first call to resize. If
- * this changes on any call, the attempt is aborted because the
- * table has already been resized by another thread.
- */
-
- protected void resize(int index, Entry[] assumedTab) {
- Segment seg = segments[index];
- synchronized(seg) {
- if (assumedTab == table) {
- int next = index+1;
- if (next < segments.length)
- resize(next, assumedTab);
- else
- rehash();
- }
- }
- }
-
- /**
- * Rehashes the contents of this map into a new table
- * with a larger capacity.
- */
- protected void rehash() {
- votesForResize = 0; // reset
-
- Entry[] oldTable = table;
- int oldCapacity = oldTable.length;
-
- if (oldCapacity >= MAXIMUM_CAPACITY) {
- threshold = Integer.MAX_VALUE; // avoid retriggering
- return;
- }
-
- int newCapacity = oldCapacity << 1;
- Entry[] newTable = newTable(newCapacity);
- int mask = newCapacity - 1;
-
- /*
- * Reclassify nodes in each list to new Map. Because we are
- * using power-of-two expansion, the elements from each bin
- * must either stay at same index, or move to
- * oldCapacity+index. We also eliminate unnecessary node
- * creation by catching cases where old nodes can be reused
- * because their next fields won't change. Statistically, at
- * the default threshhold, only about one-sixth of them need
- * cloning. (The nodes they replace will be garbage
- * collectable as soon as they are no longer referenced by any
- * reader thread that may be in the midst of traversing table
- * right now.)
- */
-
- for (int i = 0; i < oldCapacity ; i++) {
- // We need to guarantee that any existing reads of old Map can
- // proceed. So we cannot yet null out each bin.
- Entry e = oldTable[i];
-
- if (e != null) {
- int idx = e.hash & mask;
- Entry next = e.next;
-
- // Single node on list
- if (next == null)
- newTable[idx] = e;
-
- else {
- // Reuse trailing consecutive sequence of all same bit
- Entry lastRun = e;
- int lastIdx = idx;
- for (Entry last = next; last != null; last = last.next) {
- int k = last.hash & mask;
- if (k != lastIdx) {
- lastIdx = k;
- lastRun = last;
- }
- }
- newTable[lastIdx] = lastRun;
-
- // Clone all remaining nodes
- for (Entry p = e; p != lastRun; p = p.next) {
- int k = p.hash & mask;
- newTable[k] = new Entry(p.hash, p.key,
- p.value, newTable[k]);
- }
- }
- }
- }
-
- table = newTable;
- }
-
-
- /**
- * Removes the key (and its corresponding value) from this
- * table. This method does nothing if the key is not in the table.
- *
- * @param key the key that needs to be removed.
- * @return the value to which the key had been mapped in this table,
- * or <code>null</code> if the key did not have a mapping.
- * @exception NullPointerException if the key is
- * <code>null</code>.
- */
- public Object remove(Object key) {
- return remove(key, null);
- }
-
-
- /**
- * Removes the (key, value) pair from this
- * table. This method does nothing if the key is not in the table,
- * or if the key is associated with a different value. This method
- * is needed by EntrySet.
- *
- * @param key the key that needs to be removed.
- * @param value the associated value. If the value is null,
- * it means "any value".
- * @return the value to which the key had been mapped in this table,
- * or <code>null</code> if the key did not have a mapping.
- * @exception NullPointerException if the key is
- * <code>null</code>.
- */
-
- protected Object remove(Object key, Object value) {
- /*
- Find the entry, then
- 1. Set value field to null, to force get() to retry
- 2. Rebuild the list without this entry.
- All entries following removed node can stay in list, but
- all preceeding ones need to be cloned. Traversals rely
- on this strategy to ensure that elements will not be
- repeated during iteration.
- */
-
- int hash = hash(key);
- Segment seg = segments[hash & SEGMENT_MASK];
-
- synchronized(seg) {
- Entry[] tab = table;
- int index = hash & (tab.length-1);
- Entry first = tab[index];
- Entry e = first;
-
- for (;;) {
- if (e == null)
- return null;
- if (e.hash == hash && eq(key, e.key))
- break;
- e = e.next;
- }
-
- Object oldValue = e.value;
- if (value != null && !value.equals(oldValue))
- return null;
-
- e.value = null;
-
- Entry head = e.next;
- for (Entry p = first; p != e; p = p.next)
- head = new Entry(p.hash, p.key, p.value, head);
- tab[index] = head;
- seg.count--;
- return oldValue;
- }
- }
-
-
- /**
- * Returns <tt>true</tt> if this map maps one or more keys to the
- * specified value. Note: This method requires a full internal
- * traversal of the hash table, and so is much slower than
- * method <tt>containsKey</tt>.
- *
- * @param value value whose presence in this map is to be tested.
- * @return <tt>true</tt> if this map maps one or more keys to the
- * specified value.
- * @exception NullPointerException if the value is <code>null</code>.
- */
- public boolean containsValue(Object value) {
-
- if (value == null) throw new NullPointerException();
-
- for (int s = 0; s < segments.length; ++s) {
- Segment seg = segments[s];
- Entry[] tab;
- synchronized(seg) { tab = table; }
- for (int i = s; i < tab.length; i+= segments.length) {
- for (Entry e = tab[i]; e != null; e = e.next)
- if (value.equals(e.value))
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests if some key maps into the specified value in this table.
- * This operation is more expensive than the <code>containsKey</code>
- * method.<p>
- *
- * Note that this method is identical in functionality to containsValue,
- * (which is part of the Map interface in the collections framework).
- *
- * @param value a value to search for.
- * @return <code>true</code> if and only if some key maps to the
- * <code>value</code> argument in this table as
- * determined by the <tt>equals</tt> method;
- * <code>false</code> otherwise.
- * @exception NullPointerException if the value is <code>null</code>.
- * @see #containsKey(Object)
- * @see #containsValue(Object)
- * @see Map
- */
-
- public boolean contains(Object value) {
- return containsValue(value);
- }
-
- /**
- * Copies all of the mappings from the specified map to this one.
- *
- * These mappings replace any mappings that this map had for any of the
- * keys currently in the specified Map.
- *
- * @param t Mappings to be stored in this map.
- */
-
- public void putAll(Map t) {
- int n = t.size();
- if (n == 0)
- return;
-
- // Expand enough to hold at least n elements without resizing.
- // We can only resize table by factor of two at a time.
- // It is faster to rehash with fewer elements, so do it now.
- for(;;) {
- Entry[] tab;
- int max;
- synchronized(segments[0]) { // must synch on some segment. pick 0.
- tab = table;
- max = threshold * CONCURRENCY_LEVEL;
- }
- if (n < max)
- break;
- resize(0, tab);
- }
-
- for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
- Map.Entry entry = (Map.Entry) it.next();
- put(entry.getKey(), entry.getValue());
- }
- }
-
- /**
- * Removes all mappings from this map.
- */
-
- public void clear() {
- // We don't need all locks at once so long as locks
- // are obtained in low to high order
- for (int s = 0; s < segments.length; ++s) {
- Segment seg = segments[s];
- synchronized(seg) {
- Entry[] tab = table;
- for (int i = s; i < tab.length; i+= segments.length) {
- for (Entry e = tab[i]; e != null; e = e.next)
- e.value = null;
- tab[i] = null;
- seg.count = 0;
- }
- }
- }
- }
-
- /**
- * Returns a shallow copy of this
- * <tt>ConcurrentHashMap</tt> instance: the keys and
- * values themselves are not cloned.
- *
- * @return a shallow copy of this map.
- */
-
- public Object clone() {
- // We cannot call super.clone, since it would share final segments array,
- // and there's no way to reassign finals.
- return new ConcurrentHashMap(this);
- }
-
- // Views
-
- protected transient Set keySet = null;
- protected transient Set entrySet = null;
- protected transient Collection values = null;
-
- /**
- * Returns a set view of the keys contained in this map. The set is
- * backed by the map, so changes to the map are reflected in the set, and
- * vice-versa. The set supports element removal, which removes the
- * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
- * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
- * <tt>clear</tt> operations. It does not support the <tt>add</tt> or
- * <tt>addAll</tt> operations.
- *
- * @return a set view of the keys contained in this map.
- */
-
- public Set keySet() {
- Set ks = keySet;
- return (ks != null)? ks : (keySet = new KeySet());
- }
-
- private class KeySet extends AbstractSet {
- public Iterator iterator() {
- return new KeyIterator();
- }
- public int size() {
- return ConcurrentHashMap.this.size();
- }
- public boolean contains(Object o) {
- return ConcurrentHashMap.this.containsKey(o);
- }
- public boolean remove(Object o) {
- return ConcurrentHashMap.this.remove(o) != null;
- }
- public void clear() {
- ConcurrentHashMap.this.clear();
- }
- }
-
- /**
- * Returns a collection view of the values contained in this map. The
- * collection is backed by the map, so changes to the map are reflected in
- * the collection, and vice-versa. The collection supports element
- * removal, which removes the corresponding mapping from this map, via the
- * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
- * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
- * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
- *
- * @return a collection view of the values contained in this map.
- */
-
- public Collection values() {
- Collection vs = values;
- return (vs != null)? vs : (values = new Values());
- }
-
- private class Values extends AbstractCollection {
- public Iterator iterator() {
- return new ValueIterator();
- }
- public int size() {
- return ConcurrentHashMap.this.size();
- }
- public boolean contains(Object o) {
- return ConcurrentHashMap.this.containsValue(o);
- }
- public void clear() {
- ConcurrentHashMap.this.clear();
- }
- }
-
- /**
- * Returns a collection view of the mappings contained in this map. Each
- * element in the returned collection is a <tt>Map.Entry</tt>. The
- * collection is backed by the map, so changes to the map are reflected in
- * the collection, and vice-versa. The collection supports element
- * removal, which removes the corresponding mapping from the map, via the
- * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
- * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
- * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
- *
- * @return a collection view of the mappings contained in this map.
- */
-
- public Set entrySet() {
- Set es = entrySet;
- return (es != null) ? es : (entrySet = new EntrySet());
- }
-
- private class EntrySet extends AbstractSet {
- public Iterator iterator() {
- return new HashIterator();
- }
- public boolean contains(Object o) {
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry entry = (Map.Entry)o;
- Object v = ConcurrentHashMap.this.get(entry.getKey());
- return v != null && v.equals(entry.getValue());
- }
- public boolean remove(Object o) {
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry e = (Map.Entry)o;
- return ConcurrentHashMap.this.remove(e.getKey(), e.getValue()) != null;
- }
- public int size() {
- return ConcurrentHashMap.this.size();
- }
- public void clear() {
- ConcurrentHashMap.this.clear();
- }
- }
-
- /**
- * Returns an enumeration of the keys in this table.
- *
- * @return an enumeration of the keys in this table.
- * @see Enumeration
- * @see #elements()
- * @see #keySet()
- * @see Map
- */
- public Enumeration keys() {
- return new KeyIterator();
- }
-
- /**
- * Returns an enumeration of the values in this table.
- * Use the Enumeration methods on the returned object to fetch the elements
- * sequentially.
- *
- * @return an enumeration of the values in this table.
- * @see java.util.Enumeration
- * @see #keys()
- * @see #values()
- * @see Map
- */
-
- public Enumeration elements() {
- return new ValueIterator();
- }
-
- /**
- * ConcurrentHashMap collision list entry.
- */
-
- protected static class Entry implements Map.Entry {
- /*
- The use of volatile for value field ensures that
- we can detect status changes without synchronization.
- The other fields are never changed, and are
- marked as final.
- */
-
- protected final Object key;
- protected volatile Object value;
- protected final int hash;
- protected final Entry next;
-
- Entry(int hash, Object key, Object value, Entry next) {
- this.value = value;
- this.hash = hash;
- this.key = key;
- this.next = next;
- }
-
- // Map.Entry Ops
-
- public Object getKey() {
- return key;
- }
-
- /**
- * Get the value. Note: In an entrySet or entrySet.iterator,
- * unless you can guarantee lack of concurrent modification,
- * <tt>getValue</tt> <em>might</em> return null, reflecting the
- * fact that the entry has been concurrently removed. However,
- * there are no assurances that concurrent removals will be
- * reflected using this method.
- *
- * @return the current value, or null if the entry has been
- * detectably removed.
- **/
- public Object getValue() {
- return value;
- }
-
- /**
- * Set the value of this entry. Note: In an entrySet or
- * entrySet.iterator), unless you can guarantee lack of concurrent
- * modification, <tt>setValue</tt> is not strictly guaranteed to
- * actually replace the value field obtained via the <tt>get</tt>
- * operation of the underlying hash table in multithreaded
- * applications. If iterator-wide synchronization is not used,
- * and any other concurrent <tt>put</tt> or <tt>remove</tt>
- * operations occur, sometimes even to <em>other</em> entries,
- * then this change is not guaranteed to be reflected in the hash
- * table. (It might, or it might not. There are no assurances
- * either way.)
- *
- * @param value the new value.
- * @return the previous value, or null if entry has been detectably
- * removed.
- * @exception NullPointerException if the value is <code>null</code>.
- *
- **/
-
- public Object setValue(Object value) {
- if (value == null)
- throw new NullPointerException();
- Object oldValue = this.value;
- this.value = value;
- return oldValue;
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof Map.Entry))
- return false;
- Map.Entry e = (Map.Entry)o;
- return (key.equals(e.getKey()) && value.equals(e.getValue()));
- }
-
- public int hashCode() {
- return key.hashCode() ^ value.hashCode();
- }
-
- public String toString() {
- return key + "=" + value;
- }
-
- }
-
- protected class HashIterator implements Iterator, Enumeration {
- protected final Entry[] tab; // snapshot of table
- protected int index; // current slot
- protected Entry entry = null; // current node of slot
- protected Object currentKey; // key for current node
- protected Object currentValue; // value for current node
- protected Entry lastReturned = null; // last node returned by next
-
- protected HashIterator() {
- // force all segments to synch
- synchronized(segments[0]) { tab = table; }
- for (int i = 1; i < segments.length; ++i) segments[i].synch();
- index = tab.length - 1;
- }
-
- public boolean hasMoreElements() { return hasNext(); }
- public Object nextElement() { return next(); }
-
- public boolean hasNext() {
- /*
- currentkey and currentValue are set here to ensure that next()
- returns normally if hasNext() returns true. This avoids
- surprises especially when final element is removed during
- traversal -- instead, we just ignore the removal during
- current traversal.
- */
-
- for (;;) {
- if (entry != null) {
- Object v = entry.value;
- if (v != null) {
- currentKey = entry.key;
- currentValue = v;
- return true;
- }
- else
- entry = entry.next;
- }
-
- while (entry == null && index >= 0)
- entry = tab[index--];
-
- if (entry == null) {
- currentKey = currentValue = null;
- return false;
- }
- }
- }
-
- protected Object returnValueOfNext() { return entry; }
-
- public Object next() {
- if (currentKey == null && !hasNext())
- throw new NoSuchElementException();
-
- Object result = returnValueOfNext();
- lastReturned = entry;
- currentKey = currentValue = null;
- entry = entry.next;
- return result;
- }
-
- public void remove() {
- if (lastReturned == null)
- throw new IllegalStateException();
- ConcurrentHashMap.this.remove(lastReturned.key);
- lastReturned = null;
- }
-
- }
-
- protected class KeyIterator extends HashIterator {
- protected Object returnValueOfNext() { return currentKey; }
- }
-
- protected class ValueIterator extends HashIterator {
- protected Object returnValueOfNext() { return currentValue; }
- }
-
- /**
- * Save the state of the <tt>ConcurrentHashMap</tt>
- * instance to a stream (i.e.,
- * serialize it).
- *
- * @serialData
- * An estimate of the table size, followed by
- * the key (Object) and value (Object)
- * for each key-value mapping, followed by a null pair.
- * The key-value mappings are emitted in no particular order.
- */
-
- private void writeObject(java.io.ObjectOutputStream s)
- throws IOException {
- // Write out the loadfactor, and any hidden stuff
- s.defaultWriteObject();
-
- // Write out capacity estimate. It is OK if this
- // changes during the write, since it is only used by
- // readObject to set initial capacity, to avoid needless resizings.
-
- int cap;
- synchronized(segments[0]) { cap = table.length; }
- s.writeInt(cap);
-
- // Write out keys and values (alternating)
- for (int k = 0; k < segments.length; ++k) {
- Segment seg = segments[k];
- Entry[] tab;
- synchronized(seg) { tab = table; }
- for (int i = k; i < tab.length; i+= segments.length) {
- for (Entry e = tab[i]; e != null; e = e.next) {
- s.writeObject(e.key);
- s.writeObject(e.value);
- }
- }
- }
-
- s.writeObject(null);
- s.writeObject(null);
- }
-
- /**
- * Reconstitute the <tt>ConcurrentHashMap</tt>
- * instance from a stream (i.e.,
- * deserialize it).
- */
- private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- // Read in the threshold, loadfactor, and any hidden stuff
- s.defaultReadObject();
-
- int cap = s.readInt();
- table = newTable(cap);
- for (int i = 0; i < segments.length; ++i)
- segments[i] = new Segment();
-
-
- // Read the keys and values, and put the mappings in the table
- for (;;) {
- Object key = s.readObject();
- Object value = s.readObject();
- if (key == null)
- break;
- put(key, value);
- }
- }
-}
+++ /dev/null
-include ../benchmarks.mk
-
-BENCH := hashmap
-TESTS := main testcase1
-
-all: $(TESTS)
-
-$(BENCH).o : $(BENCH).h
- $(CXX) -o $@ $< $(CXXFLAGS) -c $(LDFLAGS)
-
-$(TESTS): % : %.cc $(BENCH).o
- $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
-
-clean:
- rm -f *.o *.d $(TESTS)
+++ /dev/null
-#ifndef _HASHMAP_H
-#define _HASHMAP_H
-
-#include <iostream>
-#include <atomic>
-#include "stdio.h"
-#include <stdlib.h>
-#include <mutex>
-
-#include <spec_lib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-
-#include "common.h"
-
-#define relaxed memory_order_relaxed
-#define release memory_order_release
-#define acquire memory_order_acquire
-#define acq_rel memory_order_acq_rel
-#define seq_cst memory_order_seq_cst
-
-using namespace std;
-
-
-
-class Entry {
- public:
- int key;
- atomic_int value;
- int hash;
- atomic<Entry*> next;
-
- Entry(int h, int k, int v, Entry *n) {
- this->hash = h;
- this->key = k;
- this->value.store(v, relaxed);
- this->next.store(n, relaxed);
- }
-};
-
-class Segment {
- public:
- int count;
- mutex segMutex;
-
- void lock() {
- segMutex.lock();
- }
-
- void unlock() {
- segMutex.unlock();
- }
-
- Segment() {
- this->count = 0;
- }
-};
-
-
-class HashMap {
- public:
-
-/* All other user-defined structs */
-static IntegerMap * __map;
-/* All other user-defined functions */
-/* Definition of interface info struct: Put */
-typedef struct Put_info {
-int __RET__;
-int key;
-int value;
-} Put_info;
-/* End of info struct definition: Put */
-
-/* ID function of interface: Put */
-inline static call_id_t Put_id(void *info, thread_id_t __TID__) {
- Put_info* theInfo = (Put_info*)info;
- int __RET__ = theInfo->__RET__;
- int key = theInfo->key;
- int value = theInfo->value;
-
- call_id_t __ID__ = value;
- return __ID__;
-}
-/* End of ID function: Put */
-
-/* Check action function of interface: Put */
-inline static bool Put_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Put_info* theInfo = (Put_info*)info;
- int __RET__ = theInfo->__RET__;
- int key = theInfo->key;
- int value = theInfo->value;
-
- putIntegerMap ( __map , key , value ) ;
- return true;
-}
-/* End of check action function: Put */
-
-/* Definition of interface info struct: Get */
-typedef struct Get_info {
-int __RET__;
-int key;
-} Get_info;
-/* End of info struct definition: Get */
-
-/* ID function of interface: Get */
-inline static call_id_t Get_id(void *info, thread_id_t __TID__) {
- Get_info* theInfo = (Get_info*)info;
- int __RET__ = theInfo->__RET__;
- int key = theInfo->key;
-
- call_id_t __ID__ = __RET__;
- return __ID__;
-}
-/* End of ID function: Get */
-
-/* Check action function of interface: Get */
-inline static bool Get_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Get_info* theInfo = (Get_info*)info;
- int __RET__ = theInfo->__RET__;
- int key = theInfo->key;
-
- int res = getIntegerMap ( __map , key ) ;
- check_passed = __RET__ ? res == __RET__ : true;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Get */
-
-#define INTERFACE_SIZE 2
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Put_info *_info1 = (Put_info*) info1;
- Put_info *_info2 = (Put_info*) info2;
- return _info1-> key != _info2-> key;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Put_info *_info1 = (Put_info*) info1;
- Get_info *_info2 = (Get_info*) info2;
- return _info1-> key != _info2-> key;
-}
-inline static bool CommutativityCondition2(void *info1, void *info2) {
- Get_info *_info1 = (Get_info*) info1;
- Get_info *_info2 = (Get_info*) info2;
- return true;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- __map = createIntegerMap ( ) ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- if ( __map ) destroyIntegerMap ( __map ) ;
- return true ;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
- func_ptr_table[2 * 1] = (void*) &Put_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Put_check_action;
- func_ptr_table[2 * 0] = (void*) &Get_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Get_check_action;
- /* Put(true) -> Get(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 1; // Put
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 0; // Get
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
- #define HB_RULE_TABLE_SIZE 1
- hb_rule_table[0] = hbConditionInit0;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 3);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 1;
- rule->rule = "_Method1 . key != _Method2 . key";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 0;
- rule->rule = "_Method1 . key != _Method2 . key";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 0;
- rule->rule = "true";
- rule->condition = CommutativityCondition2;
- commutativity_rule_table[2] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 3;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
- atomic<Entry*> *table;
-
- int capacity;
- int size;
-
- static const int CONCURRENCY_LEVEL = 4;
-
- static const int SEGMENT_MASK = CONCURRENCY_LEVEL - 1;
-
- Segment *segments[CONCURRENCY_LEVEL];
-
- static const int DEFAULT_INITIAL_CAPACITY = 16;
-
-
- HashMap() {
- __sequential_init();
-
- this->size = 0;
- this->capacity = DEFAULT_INITIAL_CAPACITY;
- this->table = new atomic<Entry*>[capacity];
- for (int i = 0; i < capacity; i++) {
- atomic_init(&table[i], NULL);
- }
- for (int i = 0; i < CONCURRENCY_LEVEL; i++) {
- segments[i] = new Segment;
- }
- }
-
- int hashKey(int key) {
- return key;
- }
-
-
-
-int get(int key) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Get
- interface_begin->interface_name = "Get";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__get(key);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Get
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Get_info* info = (Get_info*) malloc(sizeof(Get_info));
- info->__RET__ = __RET__;
- info->key = key;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Get
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__get(int key) {
- ASSERT (key);
- int hash = hashKey(key);
-
- atomic<Entry*> *tab = table;
- int index = hash & (capacity - 1);
- atomic<Entry*> *first = &tab[index];
- Entry *e;
- int res = 0;
-
-
-
- Entry *firstPtr = first->load(acquire);
-
- e = firstPtr;
- while (e != NULL) {
- if (key, e->key) {
-
- res = e->value.load(seq_cst);
- /* Automatically generated code for commit point define check: GetReadValue1 */
-
- if (res != 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "GetReadValue1";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (res != 0)
- return res;
- else
- break;
- }
- e = e->next.load(relaxed);
- }
-
- Segment *seg = segments[hash & SEGMENT_MASK];
- seg->lock();
- Entry *newFirstPtr = first->load(relaxed);
- /* Automatically generated code for commit point define check: GetReadEntry */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "GetReadEntry";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (e != NULL || firstPtr != newFirstPtr) {
- e = newFirstPtr;
- while (e != NULL) {
- if (key == e->key) {
- res = e->value.load(relaxed);
- /* Automatically generated code for commit point define check: GetReadValue2 */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "GetReadValue2";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- seg->unlock(); return res;
- }
- e = e->next.load(relaxed);
- }
- }
- seg->unlock(); return 0;
- }
-
-
-int put(int key, int value) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Put
- interface_begin->interface_name = "Put";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__put(key, value);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Put
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Put_info* info = (Put_info*) malloc(sizeof(Put_info));
- info->__RET__ = __RET__;
- info->key = key;
- info->value = value;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Put
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__put(int key, int value) {
- ASSERT (key && value);
- int hash = hashKey(key);
- Segment *seg = segments[hash & SEGMENT_MASK];
- atomic<Entry*> *tab;
-
- seg->lock(); tab = table;
- int index = hash & (capacity - 1);
-
- atomic<Entry*> *first = &tab[index];
- Entry *e;
- int oldValue = 0;
-
- Entry *firstPtr = first->load(relaxed);
- e = firstPtr;
- while (e != NULL) {
- if (key == e->key) {
- oldValue = e->value.load(relaxed);
-
-
- e->value.store(value, seq_cst);
- /* Automatically generated code for commit point define check: PutUpdateValue */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "PutUpdateValue";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- seg->unlock(); return oldValue;
- }
- e = e->next.load(relaxed);
- }
-
- Entry *newEntry = new Entry(hash, key, value, firstPtr);
-
-
- first->store(newEntry, release);
- /* Automatically generated code for commit point define check: PutInsertValue */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 4;
- cp_define_check->label_name = "PutInsertValue";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- seg->unlock(); return 0;
- }
-};
-void** HashMap::func_ptr_table;
-hb_rule** HashMap::hb_rule_table;
-commutativity_rule** HashMap::commutativity_rule_table;
-IntegerMap * HashMap::__map;
-
-
-#endif
-
+++ /dev/null
-#include <iostream>
-#include <threads.h>
-#include "hashmap.h"
-
-HashMap *table;
-
-void threadA(void *arg) {
- table->put(1, 1);
- printf("Thrd A: Put %d -> %d\n", 1, 1);
- int r1 = table->get(2);
- printf("Thrd A: Get %d\n", r1);
-}
-
-void threadB(void *arg) {
- table->put(2, 2);
- printf("Thrd B: Put %d -> %d\n", 2, 2);
- int r2 = table->get(1);
- printf("Thrd B: Get %d\n", r2);
-}
-
-int user_main(int argc, char *argv[]) {
- thrd_t t1, t2;
-
- table = new HashMap;
-
- thrd_create(&t1, threadA, NULL);
- thrd_create(&t2, threadB, NULL);
- thrd_join(t1);
- thrd_join(t2);
-
- return 0;
-}
-
-
-
+++ /dev/null
-#Non-SC:
-The following case can be non-SC.
-
-Thrd1 Thrd2
-put(k1, v1); // a put(k2, v2); // c
-get(k2); // b get(k1); // d
-
-When b and d both read the old head of the list (and they later grab the lock,
-making it the interface SC), it's non-SC because neither reads the updated
-value.
-
-Run testcase1 to make the store and load of value slot to be seq_cst.
-
-Then run testcase2 with "-o annotation" to get store and load of key slot to be
-release/acquire.
-
-0m0.015s + 0m0.000 = 0m0.015s
+++ /dev/null
-#include <iostream>
-#include <threads.h>
-#include "hashmap.h"
-
-HashMap *table;
-
-void threadA(void *arg) {
- table->put(1, 11);
- printf("Thrd A: Put %d -> %d\n", 1, 11);
- int r1 = table->get(2);
- printf("Thrd A: Get %d\n", r1);
-}
-
-void threadB(void *arg) {
- table->put(2, 22);
- printf("Thrd B: Put %d -> %d\n", 2, 22);
- int r2 = table->get(1);
- printf("Thrd B: Get %d\n", r2);
-}
-
-int user_main(int argc, char *argv[]) {
- thrd_t t1, t2;
-
- table = new HashMap;
- table->put(1, 1);
- table->put(2, 2);
-
- thrd_create(&t1, threadA, NULL);
- thrd_create(&t2, threadB, NULL);
- thrd_join(t1);
- thrd_join(t2);
-
- return 0;
-}
-
-
-
+++ /dev/null
-#ifndef __UNRELACY_H__
-#define __UNRELACY_H__
-
-#include <stdatomic.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <mutex>
-#include <condition_variable>
-
-#include <model-assert.h>
-#include <librace.h>
-
-#define $
-
-#define ASSERT(expr) MODEL_ASSERT(expr)
-#define RL_ASSERT(expr) MODEL_ASSERT(expr)
-
-#define RL_NEW new
-#define RL_DELETE(expr) delete expr
-
-#define mo_seqcst memory_order_relaxed
-#define mo_release memory_order_release
-#define mo_acquire memory_order_acquire
-#define mo_acq_rel memory_order_acq_rel
-#define mo_relaxed memory_order_relaxed
-
-namespace rl {
-
- /* This 'useless' struct is declared just so we can use partial template
- * specialization in our store and load functions. */
- template <typename T, size_t n>
- struct useless {
- static void store(void *addr, T val);
- static T load(const void *addr);
- };
-
- template <typename T>
- struct useless<T, 1> {
- static void store(void *addr, T val) { store_8(addr, (uint8_t)val); }
- static T load(const void *addr) { return (T)load_8(addr); }
- };
-
- template <typename T>
- struct useless<T, 2> {
- static void store(void *addr, T val) { store_16(addr, (uint16_t)val); }
- static T load(const void *addr) { return (T)load_16(addr); }
- };
-
- template <typename T>
- struct useless<T, 4> {
- static void store(void *addr, T val) { store_32(addr, (uint32_t)val); }
- static T load(const void *addr) { return (T)load_32(addr); }
- };
-
- template <typename T>
- struct useless<T, 8> {
- static void store(void *addr, T val) { store_64(addr, (uint64_t)val); }
- static T load(const void *addr) { return (T)load_64(addr); }
- };
-
- template <typename T>
- struct var {
- var() { useless<T, sizeof(T)>::store(&value, 0); }
- var(T v) { useless<T, sizeof(T)>::store(&value, v); }
- var(var const& r) {
- value = r.value;
- }
- ~var() { }
-
- void operator = (T v) { useless<T, sizeof(T)>::store(&value, v); }
- T operator () () { return useless<T, sizeof(T)>::load(&value); }
- void operator += (T v) {
- useless<T, sizeof(T)>::store(&value,
- useless<T, sizeof(T)>::load(&value) + v);
- }
- bool operator == (const struct var<T> v) const { return useless<T, sizeof(T)>::load(&value) == useless<T, sizeof(T)>::load(&v.value); }
-
- T value;
- };
-
- class backoff_t
- {
- public:
- typedef int debug_info_param;
- void yield(debug_info_param info) { }
- void yield() { }
- };
-
-
- typedef backoff_t backoff;
- typedef backoff_t linear_backoff;
- typedef backoff_t exp_backoff;
-
-}
-
-#endif /* __UNRELACY_H__ */
+++ /dev/null
-include ../benchmarks.mk
-
-TESTNAME = linuxrwlocks testcase1 testcase2
-
-all: $(TESTNAME)
-
-$(TESTNAME): % : %.c
- $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
-
-clean:
- rm -f $(TESTNAME) *.o
+++ /dev/null
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-#include "librace.h"
-
-#define RW_LOCK_BIAS 0x00100000
-#define WRITE_LOCK_CMP RW_LOCK_BIAS
-
-typedef union {
- atomic_int lock;
-} rwlock_t;
-
-
-
-
-
-
-
-/* All other user-defined structs */
-static bool writer_lock_acquired;
-static int reader_lock_cnt;
-/* All other user-defined functions */
-/* Definition of interface info struct: Write_Trylock */
-typedef struct Write_Trylock_info {
-int __RET__;
-rwlock_t * rw;
-} Write_Trylock_info;
-/* End of info struct definition: Write_Trylock */
-
-/* ID function of interface: Write_Trylock */
-inline static call_id_t Write_Trylock_id(void *info, thread_id_t __TID__) {
- Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Trylock */
-
-/* Check action function of interface: Write_Trylock */
-inline static bool Write_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- if ( __RET__ == 1 ) writer_lock_acquired = true ;
- return true;
-}
-/* End of check action function: Write_Trylock */
-
-/* Definition of interface info struct: Read_Trylock */
-typedef struct Read_Trylock_info {
-int __RET__;
-rwlock_t * rw;
-} Read_Trylock_info;
-/* End of info struct definition: Read_Trylock */
-
-/* ID function of interface: Read_Trylock */
-inline static call_id_t Read_Trylock_id(void *info, thread_id_t __TID__) {
- Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Trylock */
-
-/* Check action function of interface: Read_Trylock */
-inline static bool Read_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- if ( __RET__ ) reader_lock_cnt ++ ;
- check_passed = __RET__ == ! writer_lock_acquired || ! __RET__;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Read_Trylock */
-
-/* Definition of interface info struct: Write_Lock */
-typedef struct Write_Lock_info {
-rwlock_t * rw;
-} Write_Lock_info;
-/* End of info struct definition: Write_Lock */
-
-/* ID function of interface: Write_Lock */
-inline static call_id_t Write_Lock_id(void *info, thread_id_t __TID__) {
- Write_Lock_info* theInfo = (Write_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Lock */
-
-/* Check action function of interface: Write_Lock */
-inline static bool Write_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Lock_info* theInfo = (Write_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = ! writer_lock_acquired && reader_lock_cnt == 0;
- if (!check_passed)
- return false;
- writer_lock_acquired = true ;
- return true;
-}
-/* End of check action function: Write_Lock */
-
-/* Definition of interface info struct: Write_Unlock */
-typedef struct Write_Unlock_info {
-rwlock_t * rw;
-} Write_Unlock_info;
-/* End of info struct definition: Write_Unlock */
-
-/* ID function of interface: Write_Unlock */
-inline static call_id_t Write_Unlock_id(void *info, thread_id_t __TID__) {
- Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Unlock */
-
-/* Check action function of interface: Write_Unlock */
-inline static bool Write_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = reader_lock_cnt == 0 && writer_lock_acquired;
- if (!check_passed)
- return false;
- writer_lock_acquired = false ;
- return true;
-}
-/* End of check action function: Write_Unlock */
-
-/* Definition of interface info struct: Read_Unlock */
-typedef struct Read_Unlock_info {
-rwlock_t * rw;
-} Read_Unlock_info;
-/* End of info struct definition: Read_Unlock */
-
-/* ID function of interface: Read_Unlock */
-inline static call_id_t Read_Unlock_id(void *info, thread_id_t __TID__) {
- Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Unlock */
-
-/* Check action function of interface: Read_Unlock */
-inline static bool Read_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = reader_lock_cnt > 0 && ! writer_lock_acquired;
- if (!check_passed)
- return false;
- reader_lock_cnt -- ;
- return true;
-}
-/* End of check action function: Read_Unlock */
-
-/* Definition of interface info struct: Read_Lock */
-typedef struct Read_Lock_info {
-rwlock_t * rw;
-} Read_Lock_info;
-/* End of info struct definition: Read_Lock */
-
-/* ID function of interface: Read_Lock */
-inline static call_id_t Read_Lock_id(void *info, thread_id_t __TID__) {
- Read_Lock_info* theInfo = (Read_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Lock */
-
-/* Check action function of interface: Read_Lock */
-inline static bool Read_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Lock_info* theInfo = (Read_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = ! writer_lock_acquired;
- if (!check_passed)
- return false;
- reader_lock_cnt ++ ;
- return true;
-}
-/* End of check action function: Read_Lock */
-
-#define INTERFACE_SIZE 6
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Lock_info *_info2 = (Read_Lock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition2(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition3(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition4(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition5(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition6(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition7(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition8(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition9(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Lock_info *_info2 = (Write_Lock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition10(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition11(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition12(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition13(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Lock_info *_info2 = (Write_Lock_info*) info2;
- return ! _info1-> __RET__;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- writer_lock_acquired = false ;
- reader_lock_cnt = 0 ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- return true;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 6 * 2);
- func_ptr_table[2 * 3] = (void*) &Write_Trylock_id;
- func_ptr_table[2 * 3 + 1] = (void*) &Write_Trylock_check_action;
- func_ptr_table[2 * 2] = (void*) &Read_Trylock_id;
- func_ptr_table[2 * 2 + 1] = (void*) &Read_Trylock_check_action;
- func_ptr_table[2 * 1] = (void*) &Write_Lock_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Write_Lock_check_action;
- func_ptr_table[2 * 5] = (void*) &Write_Unlock_id;
- func_ptr_table[2 * 5 + 1] = (void*) &Write_Unlock_check_action;
- func_ptr_table[2 * 4] = (void*) &Read_Unlock_id;
- func_ptr_table[2 * 4 + 1] = (void*) &Read_Unlock_check_action;
- func_ptr_table[2 * 0] = (void*) &Read_Lock_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Read_Lock_check_action;
- /* Read_Unlock(true) -> Write_Lock(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 4; // Read_Unlock
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 1; // Write_Lock
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Read_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
- struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit1->interface_num_before = 4; // Read_Unlock
- hbConditionInit1->hb_condition_num_before = 0; //
- hbConditionInit1->interface_num_after = 3; // Write_Trylock
- hbConditionInit1->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
- /* Write_Unlock(true) -> Write_Lock(true) */
- struct hb_rule *hbConditionInit2 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit2->interface_num_before = 5; // Write_Unlock
- hbConditionInit2->hb_condition_num_before = 0; //
- hbConditionInit2->interface_num_after = 1; // Write_Lock
- hbConditionInit2->hb_condition_num_after = 0; //
- /* Write_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
- struct hb_rule *hbConditionInit3 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit3->interface_num_before = 5; // Write_Unlock
- hbConditionInit3->hb_condition_num_before = 0; //
- hbConditionInit3->interface_num_after = 3; // Write_Trylock
- hbConditionInit3->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
- /* Write_Unlock(true) -> Read_Lock(true) */
- struct hb_rule *hbConditionInit4 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit4->interface_num_before = 5; // Write_Unlock
- hbConditionInit4->hb_condition_num_before = 0; //
- hbConditionInit4->interface_num_after = 0; // Read_Lock
- hbConditionInit4->hb_condition_num_after = 0; //
- /* Write_Unlock(true) -> Read_Trylock(HB_Read_Trylock_Succ) */
- struct hb_rule *hbConditionInit5 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit5->interface_num_before = 5; // Write_Unlock
- hbConditionInit5->hb_condition_num_before = 0; //
- hbConditionInit5->interface_num_after = 2; // Read_Trylock
- hbConditionInit5->hb_condition_num_after = 2; // HB_Read_Trylock_Succ
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 6);
- #define HB_RULE_TABLE_SIZE 6
- hb_rule_table[0] = hbConditionInit0;
- hb_rule_table[1] = hbConditionInit1;
- hb_rule_table[2] = hbConditionInit2;
- hb_rule_table[3] = hbConditionInit3;
- hb_rule_table[4] = hbConditionInit4;
- hb_rule_table[5] = hbConditionInit5;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 14);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 0;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 4;
- rule->rule = "true";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition2;
- commutativity_rule_table[2] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 3;
- rule->rule = "! _Method2 . __RET__";
- rule->condition = CommutativityCondition3;
- commutativity_rule_table[3] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 4;
- rule->rule = "true";
- rule->condition = CommutativityCondition4;
- commutativity_rule_table[4] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition5;
- commutativity_rule_table[5] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 3;
- rule->rule = "! _Method2 . __RET__";
- rule->condition = CommutativityCondition6;
- commutativity_rule_table[6] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition7;
- commutativity_rule_table[7] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 3;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition8;
- commutativity_rule_table[8] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition9;
- commutativity_rule_table[9] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 5;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition10;
- commutativity_rule_table[10] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 3;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition11;
- commutativity_rule_table[11] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 5;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition12;
- commutativity_rule_table[12] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition13;
- commutativity_rule_table[13] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 14;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-static inline int read_can_lock(rwlock_t *lock)
-{
- return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0;
-}
-
-static inline int write_can_lock(rwlock_t *lock)
-{
- return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS;
-}
-
-
-void __wrapper__read_lock(rwlock_t * rw);
-
-void read_lock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Read_Lock
- interface_begin->interface_name = "Read_Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_lock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Read_Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_Lock_info* info = (Read_Lock_info*) malloc(sizeof(Read_Lock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Read_Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_lock(rwlock_t * rw)
-{
-
-
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Lock_Success_1 */
-
- if (priorvalue > 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Read_Lock_Success_1";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- while (priorvalue <= 0) {
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
- while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
- thrd_yield();
- }
-
- priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Lock_Success_2 */
-
- if (priorvalue > 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Read_Lock_Success_2";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-}
-
-
-void __wrapper__write_lock(rwlock_t * rw);
-
-void write_lock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Write_Lock
- interface_begin->interface_name = "Write_Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_lock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Write_Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_Lock_info* info = (Write_Lock_info*) malloc(sizeof(Write_Lock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Write_Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_lock(rwlock_t * rw)
-{
-
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for commit point define check: Write_Lock_Success_1 */
-
- if (priorvalue == RW_LOCK_BIAS) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "Write_Lock_Success_1";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- while (priorvalue != RW_LOCK_BIAS) {
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
- while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
- thrd_yield();
- }
-
- priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for commit point define check: Write_Lock_Success_2 */
-
- if (priorvalue == RW_LOCK_BIAS) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "Write_Lock_Success_2";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-}
-
-int __wrapper__read_trylock(rwlock_t * rw);
-
-int read_trylock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 2; // Read_Trylock
- interface_begin->interface_name = "Read_Trylock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__read_trylock(rw);
- if (__RET__ == 1) {
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 2; // Read_Trylock
- hb_condition->hb_condition_num = 2;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
- }
-
- Read_Trylock_info* info = (Read_Trylock_info*) malloc(sizeof(Read_Trylock_info));
- info->__RET__ = __RET__;
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 2; // Read_Trylock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__read_trylock(rwlock_t * rw)
-{
-
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for potential commit point: Potential_Read_Trylock_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 4;
- potential_cp_define->label_name = "Potential_Read_Trylock_Point";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (priorvalue > 0) {
- /* Automatically generated code for commit point define: Read_Trylock_Succ_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 5;
- cp_define->label_name = "Read_Trylock_Succ_Point";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "Potential_Read_Trylock_Point";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return 1;
- }
- /* Automatically generated code for commit point define: Read_Trylock_Fail_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 6;
- cp_define->label_name = "Read_Trylock_Fail_Point";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "Potential_Read_Trylock_Point";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
- return 0;
-}
-
-int __wrapper__write_trylock(rwlock_t * rw);
-
-int write_trylock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 3; // Write_Trylock
- interface_begin->interface_name = "Write_Trylock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__write_trylock(rw);
- if (__RET__ == 1) {
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 3; // Write_Trylock
- hb_condition->hb_condition_num = 1;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
- }
-
- Write_Trylock_info* info = (Write_Trylock_info*) malloc(sizeof(Write_Trylock_info));
- info->__RET__ = __RET__;
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 3; // Write_Trylock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__write_trylock(rwlock_t * rw)
-{
-
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for potential commit point: Potential_Write_Trylock_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 7;
- potential_cp_define->label_name = "Potential_Write_Trylock_Point";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (priorvalue == RW_LOCK_BIAS) {
- /* Automatically generated code for commit point define: Write_Trylock_Succ_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 8;
- cp_define->label_name = "Write_Trylock_Succ_Point";
- cp_define->potential_cp_label_num = 7;
- cp_define->potential_label_name = "Potential_Write_Trylock_Point";
- cp_define->interface_num = 3;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return 1;
- }
- /* Automatically generated code for commit point define: Write_Trylock_Fail_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 9;
- cp_define->label_name = "Write_Trylock_Fail_Point";
- cp_define->potential_cp_label_num = 7;
- cp_define->potential_label_name = "Potential_Write_Trylock_Point";
- cp_define->interface_num = 3;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
- return 0;
-}
-
-void __wrapper__read_unlock(rwlock_t * rw);
-
-void read_unlock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 4; // Read_Unlock
- interface_begin->interface_name = "Read_Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_unlock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 4; // Read_Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_Unlock_info* info = (Read_Unlock_info*) malloc(sizeof(Read_Unlock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 4; // Read_Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_unlock(rwlock_t * rw)
-{
-
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
- /* Automatically generated code for commit point define check: Read_Unlock_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 10;
- cp_define_check->label_name = "Read_Unlock_Point";
- cp_define_check->interface_num = 4;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-}
-
-void __wrapper__write_unlock(rwlock_t * rw);
-
-void write_unlock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 5; // Write_Unlock
- interface_begin->interface_name = "Write_Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_unlock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 5; // Write_Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_Unlock_info* info = (Write_Unlock_info*) malloc(sizeof(Write_Unlock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 5; // Write_Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_unlock(rwlock_t * rw)
-{
-
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
- /* Automatically generated code for commit point define check: Write_Unlock_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 11;
- cp_define_check->label_name = "Write_Unlock_Point";
- cp_define_check->interface_num = 5;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
-
-}
-
-rwlock_t mylock;
-int shareddata;
-
-static void a(void *obj)
-{
- read_lock(&mylock);
- read_unlock(&mylock);
-
- write_lock(&mylock);
- shareddata = 47;
- write_unlock(&mylock);
-}
-
-static void b(void *obj)
-{
- if (read_trylock(&mylock) == 1) {
- read_unlock(&mylock);
- }
-
- if (write_trylock(&mylock) == 1) {
- write_unlock(&mylock);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t1, t2;
- atomic_init(&mylock.lock, RW_LOCK_BIAS);
-
- thrd_create(&t1, (thrd_start_t)&a, NULL);
- thrd_create(&t2, (thrd_start_t)&b, NULL);
-
- thrd_join(t1);
- thrd_join(t2);
-
- return 0;
-}
-
+++ /dev/null
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-#include "librace.h"
-
-#define RW_LOCK_BIAS 0x00100000
-#define WRITE_LOCK_CMP RW_LOCK_BIAS
-
-typedef union {
- atomic_int lock;
-} rwlock_t;
-
-
-
-
-
-
-
-/* All other user-defined structs */
-static bool writer_lock_acquired;
-static int reader_lock_cnt;
-/* All other user-defined functions */
-/* Definition of interface info struct: Write_Trylock */
-typedef struct Write_Trylock_info {
-int __RET__;
-rwlock_t * rw;
-} Write_Trylock_info;
-/* End of info struct definition: Write_Trylock */
-
-/* ID function of interface: Write_Trylock */
-inline static call_id_t Write_Trylock_id(void *info, thread_id_t __TID__) {
- Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Trylock */
-
-/* Check action function of interface: Write_Trylock */
-inline static bool Write_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- if ( __RET__ == 1 ) writer_lock_acquired = true ;
- return true;
-}
-/* End of check action function: Write_Trylock */
-
-/* Definition of interface info struct: Read_Trylock */
-typedef struct Read_Trylock_info {
-int __RET__;
-rwlock_t * rw;
-} Read_Trylock_info;
-/* End of info struct definition: Read_Trylock */
-
-/* ID function of interface: Read_Trylock */
-inline static call_id_t Read_Trylock_id(void *info, thread_id_t __TID__) {
- Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Trylock */
-
-/* Check action function of interface: Read_Trylock */
-inline static bool Read_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- if ( __RET__ ) reader_lock_cnt ++ ;
- check_passed = __RET__ == ! writer_lock_acquired || ! __RET__;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Read_Trylock */
-
-/* Definition of interface info struct: Write_Lock */
-typedef struct Write_Lock_info {
-rwlock_t * rw;
-} Write_Lock_info;
-/* End of info struct definition: Write_Lock */
-
-/* ID function of interface: Write_Lock */
-inline static call_id_t Write_Lock_id(void *info, thread_id_t __TID__) {
- Write_Lock_info* theInfo = (Write_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Lock */
-
-/* Check action function of interface: Write_Lock */
-inline static bool Write_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Lock_info* theInfo = (Write_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = ! writer_lock_acquired && reader_lock_cnt == 0;
- if (!check_passed)
- return false;
- writer_lock_acquired = true ;
- return true;
-}
-/* End of check action function: Write_Lock */
-
-/* Definition of interface info struct: Write_Unlock */
-typedef struct Write_Unlock_info {
-rwlock_t * rw;
-} Write_Unlock_info;
-/* End of info struct definition: Write_Unlock */
-
-/* ID function of interface: Write_Unlock */
-inline static call_id_t Write_Unlock_id(void *info, thread_id_t __TID__) {
- Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Unlock */
-
-/* Check action function of interface: Write_Unlock */
-inline static bool Write_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = reader_lock_cnt == 0 && writer_lock_acquired;
- if (!check_passed)
- return false;
- writer_lock_acquired = false ;
- return true;
-}
-/* End of check action function: Write_Unlock */
-
-/* Definition of interface info struct: Read_Unlock */
-typedef struct Read_Unlock_info {
-rwlock_t * rw;
-} Read_Unlock_info;
-/* End of info struct definition: Read_Unlock */
-
-/* ID function of interface: Read_Unlock */
-inline static call_id_t Read_Unlock_id(void *info, thread_id_t __TID__) {
- Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Unlock */
-
-/* Check action function of interface: Read_Unlock */
-inline static bool Read_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = reader_lock_cnt > 0 && ! writer_lock_acquired;
- if (!check_passed)
- return false;
- reader_lock_cnt -- ;
- return true;
-}
-/* End of check action function: Read_Unlock */
-
-/* Definition of interface info struct: Read_Lock */
-typedef struct Read_Lock_info {
-rwlock_t * rw;
-} Read_Lock_info;
-/* End of info struct definition: Read_Lock */
-
-/* ID function of interface: Read_Lock */
-inline static call_id_t Read_Lock_id(void *info, thread_id_t __TID__) {
- Read_Lock_info* theInfo = (Read_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Lock */
-
-/* Check action function of interface: Read_Lock */
-inline static bool Read_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Lock_info* theInfo = (Read_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = ! writer_lock_acquired;
- if (!check_passed)
- return false;
- reader_lock_cnt ++ ;
- return true;
-}
-/* End of check action function: Read_Lock */
-
-#define INTERFACE_SIZE 6
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Lock_info *_info2 = (Read_Lock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition2(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition3(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition4(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition5(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition6(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition7(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition8(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition9(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Lock_info *_info2 = (Write_Lock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition10(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition11(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition12(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition13(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Lock_info *_info2 = (Write_Lock_info*) info2;
- return ! _info1-> __RET__;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- writer_lock_acquired = false ;
- reader_lock_cnt = 0 ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- return true;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 6 * 2);
- func_ptr_table[2 * 3] = (void*) &Write_Trylock_id;
- func_ptr_table[2 * 3 + 1] = (void*) &Write_Trylock_check_action;
- func_ptr_table[2 * 2] = (void*) &Read_Trylock_id;
- func_ptr_table[2 * 2 + 1] = (void*) &Read_Trylock_check_action;
- func_ptr_table[2 * 1] = (void*) &Write_Lock_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Write_Lock_check_action;
- func_ptr_table[2 * 5] = (void*) &Write_Unlock_id;
- func_ptr_table[2 * 5 + 1] = (void*) &Write_Unlock_check_action;
- func_ptr_table[2 * 4] = (void*) &Read_Unlock_id;
- func_ptr_table[2 * 4 + 1] = (void*) &Read_Unlock_check_action;
- func_ptr_table[2 * 0] = (void*) &Read_Lock_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Read_Lock_check_action;
- /* Read_Unlock(true) -> Write_Lock(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 4; // Read_Unlock
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 1; // Write_Lock
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Read_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
- struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit1->interface_num_before = 4; // Read_Unlock
- hbConditionInit1->hb_condition_num_before = 0; //
- hbConditionInit1->interface_num_after = 3; // Write_Trylock
- hbConditionInit1->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
- /* Write_Unlock(true) -> Write_Lock(true) */
- struct hb_rule *hbConditionInit2 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit2->interface_num_before = 5; // Write_Unlock
- hbConditionInit2->hb_condition_num_before = 0; //
- hbConditionInit2->interface_num_after = 1; // Write_Lock
- hbConditionInit2->hb_condition_num_after = 0; //
- /* Write_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
- struct hb_rule *hbConditionInit3 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit3->interface_num_before = 5; // Write_Unlock
- hbConditionInit3->hb_condition_num_before = 0; //
- hbConditionInit3->interface_num_after = 3; // Write_Trylock
- hbConditionInit3->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
- /* Write_Unlock(true) -> Read_Lock(true) */
- struct hb_rule *hbConditionInit4 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit4->interface_num_before = 5; // Write_Unlock
- hbConditionInit4->hb_condition_num_before = 0; //
- hbConditionInit4->interface_num_after = 0; // Read_Lock
- hbConditionInit4->hb_condition_num_after = 0; //
- /* Write_Unlock(true) -> Read_Trylock(HB_Read_Trylock_Succ) */
- struct hb_rule *hbConditionInit5 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit5->interface_num_before = 5; // Write_Unlock
- hbConditionInit5->hb_condition_num_before = 0; //
- hbConditionInit5->interface_num_after = 2; // Read_Trylock
- hbConditionInit5->hb_condition_num_after = 2; // HB_Read_Trylock_Succ
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 6);
- #define HB_RULE_TABLE_SIZE 6
- hb_rule_table[0] = hbConditionInit0;
- hb_rule_table[1] = hbConditionInit1;
- hb_rule_table[2] = hbConditionInit2;
- hb_rule_table[3] = hbConditionInit3;
- hb_rule_table[4] = hbConditionInit4;
- hb_rule_table[5] = hbConditionInit5;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 14);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 0;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 4;
- rule->rule = "true";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition2;
- commutativity_rule_table[2] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 3;
- rule->rule = "! _Method2 . __RET__";
- rule->condition = CommutativityCondition3;
- commutativity_rule_table[3] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 4;
- rule->rule = "true";
- rule->condition = CommutativityCondition4;
- commutativity_rule_table[4] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition5;
- commutativity_rule_table[5] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 3;
- rule->rule = "! _Method2 . __RET__";
- rule->condition = CommutativityCondition6;
- commutativity_rule_table[6] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition7;
- commutativity_rule_table[7] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 3;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition8;
- commutativity_rule_table[8] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition9;
- commutativity_rule_table[9] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 5;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition10;
- commutativity_rule_table[10] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 3;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition11;
- commutativity_rule_table[11] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 5;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition12;
- commutativity_rule_table[12] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition13;
- commutativity_rule_table[13] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 14;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-static inline int read_can_lock(rwlock_t *lock)
-{
- return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0;
-}
-
-static inline int write_can_lock(rwlock_t *lock)
-{
- return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS;
-}
-
-
-void __wrapper__read_lock(rwlock_t * rw);
-
-void read_lock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Read_Lock
- interface_begin->interface_name = "Read_Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_lock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Read_Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_Lock_info* info = (Read_Lock_info*) malloc(sizeof(Read_Lock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Read_Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_lock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Lock_Success_1 */
-
- if (priorvalue > 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Read_Lock_Success_1";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- while (priorvalue <= 0) {
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
- while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
- thrd_yield();
- }
- priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Lock_Success_2 */
-
- if (priorvalue > 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Read_Lock_Success_2";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-}
-
-
-void __wrapper__write_lock(rwlock_t * rw);
-
-void write_lock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Write_Lock
- interface_begin->interface_name = "Write_Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_lock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Write_Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_Lock_info* info = (Write_Lock_info*) malloc(sizeof(Write_Lock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Write_Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_lock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for commit point define check: Write_Lock_Success_1 */
-
- if (priorvalue == RW_LOCK_BIAS) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "Write_Lock_Success_1";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- while (priorvalue != RW_LOCK_BIAS) {
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
- while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
- thrd_yield();
- }
- priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for commit point define check: Write_Lock_Success_2 */
-
- if (priorvalue == RW_LOCK_BIAS) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "Write_Lock_Success_2";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-}
-
-int __wrapper__read_trylock(rwlock_t * rw);
-
-int read_trylock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 2; // Read_Trylock
- interface_begin->interface_name = "Read_Trylock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__read_trylock(rw);
- if (__RET__ == 1) {
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 2; // Read_Trylock
- hb_condition->hb_condition_num = 2;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
- }
-
- Read_Trylock_info* info = (Read_Trylock_info*) malloc(sizeof(Read_Trylock_info));
- info->__RET__ = __RET__;
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 2; // Read_Trylock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__read_trylock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for potential commit point: Potential_Read_Trylock_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 4;
- potential_cp_define->label_name = "Potential_Read_Trylock_Point";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (priorvalue > 0) {
- /* Automatically generated code for commit point define: Read_Trylock_Succ_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 5;
- cp_define->label_name = "Read_Trylock_Succ_Point";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "Potential_Read_Trylock_Point";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return 1;
- }
- /* Automatically generated code for commit point define: Read_Trylock_Fail_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 6;
- cp_define->label_name = "Read_Trylock_Fail_Point";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "Potential_Read_Trylock_Point";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
- return 0;
-}
-
-int __wrapper__write_trylock(rwlock_t * rw);
-
-int write_trylock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 3; // Write_Trylock
- interface_begin->interface_name = "Write_Trylock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__write_trylock(rw);
- if (__RET__ == 1) {
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 3; // Write_Trylock
- hb_condition->hb_condition_num = 1;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
- }
-
- Write_Trylock_info* info = (Write_Trylock_info*) malloc(sizeof(Write_Trylock_info));
- info->__RET__ = __RET__;
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 3; // Write_Trylock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__write_trylock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for potential commit point: Potential_Write_Trylock_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 7;
- potential_cp_define->label_name = "Potential_Write_Trylock_Point";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (priorvalue == RW_LOCK_BIAS) {
- /* Automatically generated code for commit point define: Write_Trylock_Succ_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 8;
- cp_define->label_name = "Write_Trylock_Succ_Point";
- cp_define->potential_cp_label_num = 7;
- cp_define->potential_label_name = "Potential_Write_Trylock_Point";
- cp_define->interface_num = 3;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return 1;
- }
- /* Automatically generated code for commit point define: Write_Trylock_Fail_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 9;
- cp_define->label_name = "Write_Trylock_Fail_Point";
- cp_define->potential_cp_label_num = 7;
- cp_define->potential_label_name = "Potential_Write_Trylock_Point";
- cp_define->interface_num = 3;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
- return 0;
-}
-
-void __wrapper__read_unlock(rwlock_t * rw);
-
-void read_unlock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 4; // Read_Unlock
- interface_begin->interface_name = "Read_Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_unlock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 4; // Read_Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_Unlock_info* info = (Read_Unlock_info*) malloc(sizeof(Read_Unlock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 4; // Read_Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_unlock(rwlock_t * rw)
-{
-
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
- /* Automatically generated code for commit point define check: Read_Unlock_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 10;
- cp_define_check->label_name = "Read_Unlock_Point";
- cp_define_check->interface_num = 4;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-}
-
-void __wrapper__write_unlock(rwlock_t * rw);
-
-void write_unlock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 5; // Write_Unlock
- interface_begin->interface_name = "Write_Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_unlock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 5; // Write_Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_Unlock_info* info = (Write_Unlock_info*) malloc(sizeof(Write_Unlock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 5; // Write_Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_unlock(rwlock_t * rw)
-{
-
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
- /* Automatically generated code for commit point define check: Write_Unlock_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 11;
- cp_define_check->label_name = "Write_Unlock_Point";
- cp_define_check->interface_num = 5;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
-
-}
-
-rwlock_t mylock;
-int shareddata;
-
-static void a(void *obj)
-{
- write_lock(&mylock);
- shareddata = 47;
- write_unlock(&mylock);
-}
-
-static void b(void *obj)
-{
- if (read_trylock(&mylock)) {
- read_unlock(&mylock);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t1, t2;
- atomic_init(&mylock.lock, RW_LOCK_BIAS);
-
- thrd_create(&t1, (thrd_start_t)&a, NULL);
- thrd_create(&t2, (thrd_start_t)&b, NULL);
-
- thrd_join(t1);
- thrd_join(t2);
-
- return 0;
-}
-
+++ /dev/null
-#include <stdio.h>
-#include <threads.h>
-#include <stdatomic.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-#include "librace.h"
-
-#define RW_LOCK_BIAS 0x00100000
-#define WRITE_LOCK_CMP RW_LOCK_BIAS
-
-typedef union {
- atomic_int lock;
-} rwlock_t;
-
-
-
-
-
-
-
-/* All other user-defined structs */
-static bool writer_lock_acquired;
-static int reader_lock_cnt;
-/* All other user-defined functions */
-/* Definition of interface info struct: Write_Trylock */
-typedef struct Write_Trylock_info {
-int __RET__;
-rwlock_t * rw;
-} Write_Trylock_info;
-/* End of info struct definition: Write_Trylock */
-
-/* ID function of interface: Write_Trylock */
-inline static call_id_t Write_Trylock_id(void *info, thread_id_t __TID__) {
- Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Trylock */
-
-/* Check action function of interface: Write_Trylock */
-inline static bool Write_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- if ( __RET__ == 1 ) writer_lock_acquired = true ;
- return true;
-}
-/* End of check action function: Write_Trylock */
-
-/* Definition of interface info struct: Read_Trylock */
-typedef struct Read_Trylock_info {
-int __RET__;
-rwlock_t * rw;
-} Read_Trylock_info;
-/* End of info struct definition: Read_Trylock */
-
-/* ID function of interface: Read_Trylock */
-inline static call_id_t Read_Trylock_id(void *info, thread_id_t __TID__) {
- Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Trylock */
-
-/* Check action function of interface: Read_Trylock */
-inline static bool Read_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
- int __RET__ = theInfo->__RET__;
- rwlock_t * rw = theInfo->rw;
-
- if ( __RET__ ) reader_lock_cnt ++ ;
- check_passed = __RET__ == ! writer_lock_acquired || ! __RET__;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Read_Trylock */
-
-/* Definition of interface info struct: Write_Lock */
-typedef struct Write_Lock_info {
-rwlock_t * rw;
-} Write_Lock_info;
-/* End of info struct definition: Write_Lock */
-
-/* ID function of interface: Write_Lock */
-inline static call_id_t Write_Lock_id(void *info, thread_id_t __TID__) {
- Write_Lock_info* theInfo = (Write_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Lock */
-
-/* Check action function of interface: Write_Lock */
-inline static bool Write_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Lock_info* theInfo = (Write_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = ! writer_lock_acquired && reader_lock_cnt == 0;
- if (!check_passed)
- return false;
- writer_lock_acquired = true ;
- return true;
-}
-/* End of check action function: Write_Lock */
-
-/* Definition of interface info struct: Write_Unlock */
-typedef struct Write_Unlock_info {
-rwlock_t * rw;
-} Write_Unlock_info;
-/* End of info struct definition: Write_Unlock */
-
-/* ID function of interface: Write_Unlock */
-inline static call_id_t Write_Unlock_id(void *info, thread_id_t __TID__) {
- Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Write_Unlock */
-
-/* Check action function of interface: Write_Unlock */
-inline static bool Write_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = reader_lock_cnt == 0 && writer_lock_acquired;
- if (!check_passed)
- return false;
- writer_lock_acquired = false ;
- return true;
-}
-/* End of check action function: Write_Unlock */
-
-/* Definition of interface info struct: Read_Unlock */
-typedef struct Read_Unlock_info {
-rwlock_t * rw;
-} Read_Unlock_info;
-/* End of info struct definition: Read_Unlock */
-
-/* ID function of interface: Read_Unlock */
-inline static call_id_t Read_Unlock_id(void *info, thread_id_t __TID__) {
- Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Unlock */
-
-/* Check action function of interface: Read_Unlock */
-inline static bool Read_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = reader_lock_cnt > 0 && ! writer_lock_acquired;
- if (!check_passed)
- return false;
- reader_lock_cnt -- ;
- return true;
-}
-/* End of check action function: Read_Unlock */
-
-/* Definition of interface info struct: Read_Lock */
-typedef struct Read_Lock_info {
-rwlock_t * rw;
-} Read_Lock_info;
-/* End of info struct definition: Read_Lock */
-
-/* ID function of interface: Read_Lock */
-inline static call_id_t Read_Lock_id(void *info, thread_id_t __TID__) {
- Read_Lock_info* theInfo = (Read_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Read_Lock */
-
-/* Check action function of interface: Read_Lock */
-inline static bool Read_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_Lock_info* theInfo = (Read_Lock_info*)info;
- rwlock_t * rw = theInfo->rw;
-
- check_passed = ! writer_lock_acquired;
- if (!check_passed)
- return false;
- reader_lock_cnt ++ ;
- return true;
-}
-/* End of check action function: Read_Lock */
-
-#define INTERFACE_SIZE 6
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Lock_info *_info2 = (Read_Lock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition2(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition3(void *info1, void *info2) {
- Read_Lock_info *_info1 = (Read_Lock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition4(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition5(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition6(void *info1, void *info2) {
- Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition7(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition8(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition9(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Lock_info *_info2 = (Write_Lock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition10(void *info1, void *info2) {
- Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
- Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition11(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition12(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
- return ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition13(void *info1, void *info2) {
- Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
- Write_Lock_info *_info2 = (Write_Lock_info*) info2;
- return ! _info1-> __RET__;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- writer_lock_acquired = false ;
- reader_lock_cnt = 0 ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- return true;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 6 * 2);
- func_ptr_table[2 * 3] = (void*) &Write_Trylock_id;
- func_ptr_table[2 * 3 + 1] = (void*) &Write_Trylock_check_action;
- func_ptr_table[2 * 2] = (void*) &Read_Trylock_id;
- func_ptr_table[2 * 2 + 1] = (void*) &Read_Trylock_check_action;
- func_ptr_table[2 * 1] = (void*) &Write_Lock_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Write_Lock_check_action;
- func_ptr_table[2 * 5] = (void*) &Write_Unlock_id;
- func_ptr_table[2 * 5 + 1] = (void*) &Write_Unlock_check_action;
- func_ptr_table[2 * 4] = (void*) &Read_Unlock_id;
- func_ptr_table[2 * 4 + 1] = (void*) &Read_Unlock_check_action;
- func_ptr_table[2 * 0] = (void*) &Read_Lock_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Read_Lock_check_action;
- /* Read_Unlock(true) -> Write_Lock(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 4; // Read_Unlock
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 1; // Write_Lock
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Read_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
- struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit1->interface_num_before = 4; // Read_Unlock
- hbConditionInit1->hb_condition_num_before = 0; //
- hbConditionInit1->interface_num_after = 3; // Write_Trylock
- hbConditionInit1->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
- /* Write_Unlock(true) -> Write_Lock(true) */
- struct hb_rule *hbConditionInit2 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit2->interface_num_before = 5; // Write_Unlock
- hbConditionInit2->hb_condition_num_before = 0; //
- hbConditionInit2->interface_num_after = 1; // Write_Lock
- hbConditionInit2->hb_condition_num_after = 0; //
- /* Write_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
- struct hb_rule *hbConditionInit3 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit3->interface_num_before = 5; // Write_Unlock
- hbConditionInit3->hb_condition_num_before = 0; //
- hbConditionInit3->interface_num_after = 3; // Write_Trylock
- hbConditionInit3->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
- /* Write_Unlock(true) -> Read_Lock(true) */
- struct hb_rule *hbConditionInit4 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit4->interface_num_before = 5; // Write_Unlock
- hbConditionInit4->hb_condition_num_before = 0; //
- hbConditionInit4->interface_num_after = 0; // Read_Lock
- hbConditionInit4->hb_condition_num_after = 0; //
- /* Write_Unlock(true) -> Read_Trylock(HB_Read_Trylock_Succ) */
- struct hb_rule *hbConditionInit5 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit5->interface_num_before = 5; // Write_Unlock
- hbConditionInit5->hb_condition_num_before = 0; //
- hbConditionInit5->interface_num_after = 2; // Read_Trylock
- hbConditionInit5->hb_condition_num_after = 2; // HB_Read_Trylock_Succ
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 6);
- #define HB_RULE_TABLE_SIZE 6
- hb_rule_table[0] = hbConditionInit0;
- hb_rule_table[1] = hbConditionInit1;
- hb_rule_table[2] = hbConditionInit2;
- hb_rule_table[3] = hbConditionInit3;
- hb_rule_table[4] = hbConditionInit4;
- hb_rule_table[5] = hbConditionInit5;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 14);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 0;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 4;
- rule->rule = "true";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition2;
- commutativity_rule_table[2] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 3;
- rule->rule = "! _Method2 . __RET__";
- rule->condition = CommutativityCondition3;
- commutativity_rule_table[3] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 4;
- rule->rule = "true";
- rule->condition = CommutativityCondition4;
- commutativity_rule_table[4] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition5;
- commutativity_rule_table[5] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 4;
- rule->interface_num_after = 3;
- rule->rule = "! _Method2 . __RET__";
- rule->condition = CommutativityCondition6;
- commutativity_rule_table[6] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 2;
- rule->rule = "true";
- rule->condition = CommutativityCondition7;
- commutativity_rule_table[7] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 3;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition8;
- commutativity_rule_table[8] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition9;
- commutativity_rule_table[9] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 5;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition10;
- commutativity_rule_table[10] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 3;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition11;
- commutativity_rule_table[11] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 5;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition12;
- commutativity_rule_table[12] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__";
- rule->condition = CommutativityCondition13;
- commutativity_rule_table[13] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 14;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-static inline int read_can_lock(rwlock_t *lock)
-{
- return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0;
-}
-
-static inline int write_can_lock(rwlock_t *lock)
-{
- return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS;
-}
-
-
-void __wrapper__read_lock(rwlock_t * rw);
-
-void read_lock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Read_Lock
- interface_begin->interface_name = "Read_Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_lock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Read_Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_Lock_info* info = (Read_Lock_info*) malloc(sizeof(Read_Lock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Read_Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_lock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Lock_Success_1 */
-
- if (priorvalue > 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Read_Lock_Success_1";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- while (priorvalue <= 0) {
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
- while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
- thrd_yield();
- }
- priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Lock_Success_2 */
-
- if (priorvalue > 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Read_Lock_Success_2";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-}
-
-
-void __wrapper__write_lock(rwlock_t * rw);
-
-void write_lock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Write_Lock
- interface_begin->interface_name = "Write_Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_lock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Write_Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_Lock_info* info = (Write_Lock_info*) malloc(sizeof(Write_Lock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Write_Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_lock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for commit point define check: Write_Lock_Success_1 */
-
- if (priorvalue == RW_LOCK_BIAS) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "Write_Lock_Success_1";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- while (priorvalue != RW_LOCK_BIAS) {
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
- while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
- thrd_yield();
- }
- priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for commit point define check: Write_Lock_Success_2 */
-
- if (priorvalue == RW_LOCK_BIAS) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "Write_Lock_Success_2";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-}
-
-int __wrapper__read_trylock(rwlock_t * rw);
-
-int read_trylock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 2; // Read_Trylock
- interface_begin->interface_name = "Read_Trylock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__read_trylock(rw);
- if (__RET__ == 1) {
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 2; // Read_Trylock
- hb_condition->hb_condition_num = 2;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
- }
-
- Read_Trylock_info* info = (Read_Trylock_info*) malloc(sizeof(Read_Trylock_info));
- info->__RET__ = __RET__;
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 2; // Read_Trylock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__read_trylock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
- /* Automatically generated code for potential commit point: Potential_Read_Trylock_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 4;
- potential_cp_define->label_name = "Potential_Read_Trylock_Point";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (priorvalue > 0) {
- /* Automatically generated code for commit point define: Read_Trylock_Succ_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 5;
- cp_define->label_name = "Read_Trylock_Succ_Point";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "Potential_Read_Trylock_Point";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return 1;
- }
- /* Automatically generated code for commit point define: Read_Trylock_Fail_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 6;
- cp_define->label_name = "Read_Trylock_Fail_Point";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "Potential_Read_Trylock_Point";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
- return 0;
-}
-
-int __wrapper__write_trylock(rwlock_t * rw);
-
-int write_trylock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 3; // Write_Trylock
- interface_begin->interface_name = "Write_Trylock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- int __RET__ = __wrapper__write_trylock(rw);
- if (__RET__ == 1) {
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 3; // Write_Trylock
- hb_condition->hb_condition_num = 1;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
- }
-
- Write_Trylock_info* info = (Write_Trylock_info*) malloc(sizeof(Write_Trylock_info));
- info->__RET__ = __RET__;
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 3; // Write_Trylock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-int __wrapper__write_trylock(rwlock_t * rw)
-{
- int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
- /* Automatically generated code for potential commit point: Potential_Write_Trylock_Point */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 7;
- potential_cp_define->label_name = "Potential_Write_Trylock_Point";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (priorvalue == RW_LOCK_BIAS) {
- /* Automatically generated code for commit point define: Write_Trylock_Succ_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 8;
- cp_define->label_name = "Write_Trylock_Succ_Point";
- cp_define->potential_cp_label_num = 7;
- cp_define->potential_label_name = "Potential_Write_Trylock_Point";
- cp_define->interface_num = 3;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return 1;
- }
- /* Automatically generated code for commit point define: Write_Trylock_Fail_Point */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 9;
- cp_define->label_name = "Write_Trylock_Fail_Point";
- cp_define->potential_cp_label_num = 7;
- cp_define->potential_label_name = "Potential_Write_Trylock_Point";
- cp_define->interface_num = 3;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
- return 0;
-}
-
-void __wrapper__read_unlock(rwlock_t * rw);
-
-void read_unlock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 4; // Read_Unlock
- interface_begin->interface_name = "Read_Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_unlock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 4; // Read_Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_Unlock_info* info = (Read_Unlock_info*) malloc(sizeof(Read_Unlock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 4; // Read_Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_unlock(rwlock_t * rw)
-{
-
- atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
- /* Automatically generated code for commit point define check: Read_Unlock_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 10;
- cp_define_check->label_name = "Read_Unlock_Point";
- cp_define_check->interface_num = 4;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-}
-
-void __wrapper__write_unlock(rwlock_t * rw);
-
-void write_unlock(rwlock_t * rw) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 5; // Write_Unlock
- interface_begin->interface_name = "Write_Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_unlock(rw);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 5; // Write_Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_Unlock_info* info = (Write_Unlock_info*) malloc(sizeof(Write_Unlock_info));
- info->rw = rw;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 5; // Write_Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_unlock(rwlock_t * rw)
-{
-
- atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
- /* Automatically generated code for commit point define check: Write_Unlock_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 11;
- cp_define_check->label_name = "Write_Unlock_Point";
- cp_define_check->interface_num = 5;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
-
-}
-
-rwlock_t mylock;
-int shareddata;
-
-static void a(void *obj)
-{
- write_lock(&mylock);
- shareddata = 47;
- write_unlock(&mylock);
-}
-
-static void b(void *obj)
-{
- if (write_trylock(&mylock)) {
- shareddata = 47;
- write_unlock(&mylock);
- }
-
- read_lock(&mylock);
- read_unlock(&mylock);
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- thrd_t t1, t2;
- atomic_init(&mylock.lock, RW_LOCK_BIAS);
-
- thrd_create(&t1, (thrd_start_t)&a, NULL);
- thrd_create(&t2, (thrd_start_t)&b, NULL);
-
- thrd_join(t1);
- thrd_join(t2);
-
- return 0;
-}
-
+++ /dev/null
-include ../benchmarks.mk
-
-TESTNAME = mcs-lock
-
-all: $(TESTNAME)
-
-$(TESTNAME): $(TESTNAME).cc $(TESTNAME).h
- $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
-
-clean:
- rm -f $(TESTNAME) *.o
+++ /dev/null
-#include <stdio.h>
-#include <threads.h>
-
-#include "mcs-lock.h"
-
-
-#include "librace.h"
-
-struct mcs_mutex *mutex;
-static uint32_t shared;
-
-void threadA(void *arg)
-{
- mcs_mutex::guard g(mutex);
- shared = 17;
- mutex->unlock(&g);
- mutex->lock(&g);
- }
-
-void threadB(void *arg)
-{
- mcs_mutex::guard g(mutex);
- mutex->unlock(&g);
- mutex->lock(&g);
- shared = 17;
- }
-
-int user_main(int argc, char **argv)
-{
- thrd_t A, B;
-
- mutex = new mcs_mutex();
-
- thrd_create(&A, &threadA, NULL);
- thrd_create(&B, &threadB, NULL);
- thrd_join(A);
- thrd_join(B);
- return 0;
-}
-
+++ /dev/null
-
-#include <stdatomic.h>
-#include <unrelacy.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-struct mcs_node {
- std::atomic<mcs_node *> next;
- std::atomic<int> gate;
-
- mcs_node() {
- next.store(0);
- gate.store(0);
- }
-};
-
-
-struct mcs_mutex {
-public:
- std::atomic<mcs_node *> m_tail;
-
- mcs_mutex() {
- __sequential_init();
-
- m_tail.store( NULL );
- }
- ~mcs_mutex() {
- }
-
- class guard {
- public:
- mcs_mutex * m_t;
- mcs_node m_node;
- guard(mcs_mutex * t) : m_t(t) { t->lock(this); }
- ~guard() { m_t->unlock(this); }
- };
-
-/* All other user-defined structs */
-static bool _lock_acquired;
-/* All other user-defined functions */
-/* Definition of interface info struct: Unlock */
-typedef struct Unlock_info {
-guard * I;
-} Unlock_info;
-/* End of info struct definition: Unlock */
-
-/* ID function of interface: Unlock */
-inline static call_id_t Unlock_id(void *info, thread_id_t __TID__) {
- Unlock_info* theInfo = (Unlock_info*)info;
- guard * I = theInfo->I;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Unlock */
-
-/* Check action function of interface: Unlock */
-inline static bool Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Unlock_info* theInfo = (Unlock_info*)info;
- guard * I = theInfo->I;
-
- check_passed = _lock_acquired == true;
- if (!check_passed)
- return false;
- _lock_acquired = false ;
- return true;
-}
-/* End of check action function: Unlock */
-
-/* Definition of interface info struct: Lock */
-typedef struct Lock_info {
-guard * I;
-} Lock_info;
-/* End of info struct definition: Lock */
-
-/* ID function of interface: Lock */
-inline static call_id_t Lock_id(void *info, thread_id_t __TID__) {
- Lock_info* theInfo = (Lock_info*)info;
- guard * I = theInfo->I;
-
- call_id_t __ID__ = 0;
- return __ID__;
-}
-/* End of ID function: Lock */
-
-/* Check action function of interface: Lock */
-inline static bool Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Lock_info* theInfo = (Lock_info*)info;
- guard * I = theInfo->I;
-
- check_passed = _lock_acquired == false ;;
- if (!check_passed)
- return false;
- _lock_acquired = true ;
- return true;
-}
-/* End of check action function: Lock */
-
-#define INTERFACE_SIZE 2
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- _lock_acquired = false ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- return true;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
- func_ptr_table[2 * 1] = (void*) &Unlock_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Unlock_check_action;
- func_ptr_table[2 * 0] = (void*) &Lock_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Lock_check_action;
- /* Unlock(true) -> Lock(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 1; // Unlock
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 0; // Lock
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
- #define HB_RULE_TABLE_SIZE 1
- hb_rule_table[0] = hbConditionInit0;
- /* Init commutativity_rule_table */
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 0;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-
-void lock(guard * I) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Lock
- interface_begin->interface_name = "Lock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__lock(I);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Lock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Lock_info* info = (Lock_info*) malloc(sizeof(Lock_info));
- info->I = I;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Lock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__lock(guard * I) {
- mcs_node * me = &(I->m_node);
-
- me->next.store(NULL, std::mo_relaxed );
- me->gate.store(1, std::mo_relaxed );
-
-
-
- mcs_node * pred = m_tail.exchange(me, std::mo_acq_rel);
- /* Automatically generated code for commit point define check: Lock_Enqueue_Point1 */
-
- if (pred == NULL) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Lock_Enqueue_Point1";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if ( pred != NULL ) {
-
- pred->next.store(me, std::mo_release );
-
-
- rl::linear_backoff bo;
- int my_gate = 1;
- while (my_gate ) {
-
- my_gate = me->gate.load(std::mo_acquire);
- /* Automatically generated code for commit point define check: Lock_Enqueue_Point2 */
-
- if (my_gate == 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Lock_Enqueue_Point2";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- thrd_yield();
- }
- }
- }
-
-
-void unlock(guard * I) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Unlock
- interface_begin->interface_name = "Unlock";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__unlock(I);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Unlock
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Unlock_info* info = (Unlock_info*) malloc(sizeof(Unlock_info));
- info->I = I;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Unlock
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__unlock(guard * I) {
- mcs_node * me = &(I->m_node);
-
- mcs_node * next = me->next.load(std::mo_acquire);
- if ( next == NULL )
- {
- mcs_node * tail_was_me = me;
- bool success;
-
-
- success = m_tail.compare_exchange_strong(
- tail_was_me,NULL,std::mo_acq_rel);
- /* Automatically generated code for commit point define check: Unlock_Point_Success_1 */
-
- if (success == true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "Unlock_Point_Success_1";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (success) {
-
- return;
- }
-
- rl::linear_backoff bo;
- for(;;) {
- next = me->next.load(std::mo_acquire);
- if ( next != NULL )
- break;
- thrd_yield();
- }
- }
-
-
-
- next->gate.store( 0, std::mo_release );
- /* Automatically generated code for commit point define check: Unlock_Point_Success_2 */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "Unlock_Point_Success_2";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-};
-void** mcs_mutex::func_ptr_table;
-hb_rule** mcs_mutex::hb_rule_table;
-commutativity_rule** mcs_mutex::commutativity_rule_table;
-bool mcs_mutex::_lock_acquired;
-
-
+++ /dev/null
-include ../benchmarks.mk
-
-TESTS = mpmc-queue testcase1 testcase2 testcase3
-
-all: $(TESTS)
-
-$(TESTS): % : %.cc mpmc-queue.h
- $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
-
-clean:
- rm -f $(TESTS) *.o
+++ /dev/null
-#include <inttypes.h>
-#include <threads.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <librace.h>
-
-#include "mpmc-queue.h"
-
-void threadA(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
-{
- int32_t *bin = queue->write_prepare();
- *bin = 1;
- printf("write_bin %d, val %d\n", bin, 1);
- queue->write_publish(bin);
-}
-
-void threadB(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
-{
- int32_t *bin;
- while (bin = queue->read_fetch()) {
- printf("Read: %d\n", *bin);
- queue->read_consume(bin);
- }
-}
-
-void threadC(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
-{
- int32_t *bin = queue->write_prepare();
- *bin = 1;
- queue->write_publish(bin);
-
- while (bin = queue->read_fetch()) {
- printf("Read: %d\n", *bin);
- queue->read_consume(bin);
- }
-}
-
-#define MAXREADERS 3
-#define MAXWRITERS 3
-#define MAXRDWR 3
-
-#ifdef CONFIG_MPMC_READERS
-#define DEFAULT_READERS (CONFIG_MPMC_READERS)
-#else
-#define DEFAULT_READERS 2
-#endif
-
-#ifdef CONFIG_MPMC_WRITERS
-#define DEFAULT_WRITERS (CONFIG_MPMC_WRITERS)
-#else
-#define DEFAULT_WRITERS 2
-#endif
-
-#ifdef CONFIG_MPMC_RDWR
-#define DEFAULT_RDWR (CONFIG_MPMC_RDWR)
-#else
-#define DEFAULT_RDWR 0
-#endif
-
-int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS, rdwr = DEFAULT_RDWR;
-
-void print_usage()
-{
- printf("Error: use the following options\n"
- " -r <num> Choose number of reader threads\n"
- " -w <num> Choose number of writer threads\n");
- exit(EXIT_FAILURE);
-}
-
-void process_params(int argc, char **argv)
-{
- const char *shortopts = "hr:w:";
- int opt;
- bool error = false;
-
- while (!error && (opt = getopt(argc, argv, shortopts)) != -1) {
- switch (opt) {
- case 'h':
- print_usage();
- break;
- case 'r':
- readers = atoi(optarg);
- break;
- case 'w':
- writers = atoi(optarg);
- break;
- default:
- error = true;
- break;
- }
- }
-
- if (writers < 1 || writers > MAXWRITERS)
- error = true;
- if (readers < 1 || readers > MAXREADERS)
- error = true;
-
- if (error)
- print_usage();
-}
-
-int user_main(int argc, char **argv)
-{
- struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> queue;
- thrd_t A[MAXWRITERS], B[MAXREADERS], C[MAXRDWR];
-
-
- printf("%d reader(s), %d writer(s)\n", readers, writers);
-
-#ifndef CONFIG_MPMC_NO_INITIAL_ELEMENT
- printf("Adding initial element\n");
- int32_t *bin = queue.write_prepare();
- *bin, 17;
- printf("init_write_bin %d, val %d\n", bin, 17);
- queue.write_publish(bin);
-#endif
-
- printf("Start threads\n");
-
- for (int i = 0; i < writers; i++)
- thrd_create(&A[i], (thrd_start_t)&threadA, &queue);
- for (int i = 0; i < readers; i++)
- thrd_create(&B[i], (thrd_start_t)&threadB, &queue);
-
- for (int i = 0; i < rdwr; i++)
- thrd_create(&C[i], (thrd_start_t)&threadC, &queue);
-
- for (int i = 0; i < writers; i++)
- thrd_join(A[i]);
- for (int i = 0; i < readers; i++)
- thrd_join(B[i]);
- for (int i = 0; i < rdwr; i++)
- thrd_join(C[i]);
-
- printf("Threads complete\n");
-
- return 0;
-}
-
+++ /dev/null
-#include <stdatomic.h>
-#include <unrelacy.h>
-#include <common.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-
-
-template <typename t_element, size_t t_size>
-struct mpmc_boundq_1_alt
-{
-private:
-
- unsigned int MASK;
-
- t_element m_array[t_size];
-
- atomic<unsigned int> m_rdwr;
- atomic<unsigned int> m_read;
- atomic<unsigned int> m_written;
-
-public:
-
- mpmc_boundq_1_alt()
- {
- __sequential_init();
-
- m_rdwr = 0;
- m_read = 0;
- m_written = 0;
- MASK = 0x1; }
-
-
-/* All other user-defined structs */
-/* All other user-defined functions */
-/* Definition of interface info struct: Publish */
-typedef struct Publish_info {
-t_element * bin;
-} Publish_info;
-/* End of info struct definition: Publish */
-
-/* ID function of interface: Publish */
-inline static call_id_t Publish_id(void *info, thread_id_t __TID__) {
- Publish_info* theInfo = (Publish_info*)info;
- t_element * bin = theInfo->bin;
-
- call_id_t __ID__ = ( call_id_t ) bin;
- return __ID__;
-}
-/* End of ID function: Publish */
-
-/* Check action function of interface: Publish */
-inline static bool Publish_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Publish_info* theInfo = (Publish_info*)info;
- t_element * bin = theInfo->bin;
-
- return true;
-}
-/* End of check action function: Publish */
-
-/* Definition of interface info struct: Fetch */
-typedef struct Fetch_info {
-t_element * __RET__;
-} Fetch_info;
-/* End of info struct definition: Fetch */
-
-/* ID function of interface: Fetch */
-inline static call_id_t Fetch_id(void *info, thread_id_t __TID__) {
- Fetch_info* theInfo = (Fetch_info*)info;
- t_element * __RET__ = theInfo->__RET__;
-
- call_id_t __ID__ = ( call_id_t ) __RET__;
- return __ID__;
-}
-/* End of ID function: Fetch */
-
-/* Check action function of interface: Fetch */
-inline static bool Fetch_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Fetch_info* theInfo = (Fetch_info*)info;
- t_element * __RET__ = theInfo->__RET__;
-
- return true;
-}
-/* End of check action function: Fetch */
-
-/* Definition of interface info struct: Prepare */
-typedef struct Prepare_info {
-t_element * __RET__;
-} Prepare_info;
-/* End of info struct definition: Prepare */
-
-/* ID function of interface: Prepare */
-inline static call_id_t Prepare_id(void *info, thread_id_t __TID__) {
- Prepare_info* theInfo = (Prepare_info*)info;
- t_element * __RET__ = theInfo->__RET__;
-
- call_id_t __ID__ = ( call_id_t ) __RET__;
- return __ID__;
-}
-/* End of ID function: Prepare */
-
-/* Check action function of interface: Prepare */
-inline static bool Prepare_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Prepare_info* theInfo = (Prepare_info*)info;
- t_element * __RET__ = theInfo->__RET__;
-
- return true;
-}
-/* End of check action function: Prepare */
-
-/* Definition of interface info struct: Consume */
-typedef struct Consume_info {
-t_element * bin;
-} Consume_info;
-/* End of info struct definition: Consume */
-
-/* ID function of interface: Consume */
-inline static call_id_t Consume_id(void *info, thread_id_t __TID__) {
- Consume_info* theInfo = (Consume_info*)info;
- t_element * bin = theInfo->bin;
-
- call_id_t __ID__ = ( call_id_t ) bin;
- return __ID__;
-}
-/* End of ID function: Consume */
-
-/* Check action function of interface: Consume */
-inline static bool Consume_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Consume_info* theInfo = (Consume_info*)info;
- t_element * bin = theInfo->bin;
-
- return true;
-}
-/* End of check action function: Consume */
-
-#define INTERFACE_SIZE 4
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Prepare_info *_info1 = (Prepare_info*) info1;
- Prepare_info *_info2 = (Prepare_info*) info2;
- return _info1-> __RET__ != _info2-> __RET__ || ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Prepare_info *_info1 = (Prepare_info*) info1;
- Publish_info *_info2 = (Publish_info*) info2;
- return _info1-> __RET__ != _info2-> bin || ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition2(void *info1, void *info2) {
- Prepare_info *_info1 = (Prepare_info*) info1;
- Fetch_info *_info2 = (Fetch_info*) info2;
- return _info1-> __RET__ != _info2-> __RET__ || ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition3(void *info1, void *info2) {
- Prepare_info *_info1 = (Prepare_info*) info1;
- Consume_info *_info2 = (Consume_info*) info2;
- return _info1-> __RET__ != _info2-> bin || ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition4(void *info1, void *info2) {
- Publish_info *_info1 = (Publish_info*) info1;
- Publish_info *_info2 = (Publish_info*) info2;
- return _info1-> bin != _info2-> bin;
-}
-inline static bool CommutativityCondition5(void *info1, void *info2) {
- Publish_info *_info1 = (Publish_info*) info1;
- Fetch_info *_info2 = (Fetch_info*) info2;
- return _info1-> bin != _info2-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition6(void *info1, void *info2) {
- Publish_info *_info1 = (Publish_info*) info1;
- Consume_info *_info2 = (Consume_info*) info2;
- return _info1-> bin != _info2-> bin;
-}
-inline static bool CommutativityCondition7(void *info1, void *info2) {
- Fetch_info *_info1 = (Fetch_info*) info1;
- Fetch_info *_info2 = (Fetch_info*) info2;
- return _info1-> __RET__ != _info2-> __RET__ || ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-inline static bool CommutativityCondition8(void *info1, void *info2) {
- Fetch_info *_info1 = (Fetch_info*) info1;
- Consume_info *_info2 = (Consume_info*) info2;
- return _info1-> __RET__ != _info2-> bin || ! _info1-> __RET__;
-}
-inline static bool CommutativityCondition9(void *info1, void *info2) {
- Consume_info *_info1 = (Consume_info*) info1;
- Consume_info *_info2 = (Consume_info*) info2;
- return _info1-> bin != _info2-> bin;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- return true;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 4 * 2);
- func_ptr_table[2 * 3] = (void*) &Publish_id;
- func_ptr_table[2 * 3 + 1] = (void*) &Publish_check_action;
- func_ptr_table[2 * 0] = (void*) &Fetch_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Fetch_check_action;
- func_ptr_table[2 * 2] = (void*) &Prepare_id;
- func_ptr_table[2 * 2 + 1] = (void*) &Prepare_check_action;
- func_ptr_table[2 * 1] = (void*) &Consume_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Consume_check_action;
- /* Consume(true) -> Prepare(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 1; // Consume
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 2; // Prepare
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Publish(true) -> Fetch(true) */
- struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit1->interface_num_before = 3; // Publish
- hbConditionInit1->hb_condition_num_before = 0; //
- hbConditionInit1->interface_num_after = 0; // Fetch
- hbConditionInit1->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 2);
- #define HB_RULE_TABLE_SIZE 2
- hb_rule_table[0] = hbConditionInit0;
- hb_rule_table[1] = hbConditionInit1;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 10);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 2;
- rule->rule = "_Method1 . __RET__ != _Method2 . __RET__ || ! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 3;
- rule->rule = "_Method1 . __RET__ != _Method2 . bin || ! _Method1 . __RET__";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 0;
- rule->rule = "_Method1 . __RET__ != _Method2 . __RET__ || ! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition2;
- commutativity_rule_table[2] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 2;
- rule->interface_num_after = 1;
- rule->rule = "_Method1 . __RET__ != _Method2 . bin || ! _Method1 . __RET__";
- rule->condition = CommutativityCondition3;
- commutativity_rule_table[3] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 3;
- rule->rule = "_Method1 . bin != _Method2 . bin";
- rule->condition = CommutativityCondition4;
- commutativity_rule_table[4] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 0;
- rule->rule = "_Method1 . bin != _Method2 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition5;
- commutativity_rule_table[5] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 3;
- rule->interface_num_after = 1;
- rule->rule = "_Method1 . bin != _Method2 . bin";
- rule->condition = CommutativityCondition6;
- commutativity_rule_table[6] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 0;
- rule->rule = "_Method1 . __RET__ != _Method2 . __RET__ || ! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition7;
- commutativity_rule_table[7] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 1;
- rule->rule = "_Method1 . __RET__ != _Method2 . bin || ! _Method1 . __RET__";
- rule->condition = CommutativityCondition8;
- commutativity_rule_table[8] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 1;
- rule->rule = "_Method1 . bin != _Method2 . bin";
- rule->condition = CommutativityCondition9;
- commutativity_rule_table[9] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 10;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-
-
-t_element * read_fetch() {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Fetch
- interface_begin->interface_name = "Fetch";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- t_element * __RET__ = __wrapper__read_fetch();
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Fetch
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Fetch_info* info = (Fetch_info*) malloc(sizeof(Fetch_info));
- info->__RET__ = __RET__;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Fetch
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-t_element * __wrapper__read_fetch() {
- unsigned int rdwr = m_rdwr.load(mo_acquire);
- /* Automatically generated code for potential commit point: Fetch_Potential_RW_Load */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 0;
- potential_cp_define->label_name = "Fetch_Potential_RW_Load";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- unsigned int rd,wr;
- for(;;) {
- rd = (rdwr>>16) & MASK;
- wr = rdwr & MASK;
-
- if ( wr == rd ) {
- /* Automatically generated code for commit point define: Fetch_RW_Load_Empty */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 1;
- cp_define->label_name = "Fetch_RW_Load_Empty";
- cp_define->potential_cp_label_num = 0;
- cp_define->potential_label_name = "Fetch_Potential_RW_Load";
- cp_define->interface_num = 0;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
-
- return false;
- }
-
-
- bool succ =
- m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel);
- /* Automatically generated code for commit point define check: Fetch_RW_RMW */
-
- if (succ) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 2;
- cp_define_check->label_name = "Fetch_RW_RMW";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (succ)
- break;
- else
- thrd_yield();
- }
-
- rl::backoff bo;
- while (true) {
-
- int written = m_written.load(mo_acquire);
- /* Automatically generated code for potential commit point: Fetch_Potential_W_Load */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 3;
- potential_cp_define->label_name = "Fetch_Potential_W_Load";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if ((written & MASK) != wr) {
- thrd_yield();
- } else {
- printf("Fetch: m_written=%d\n", written);
- break;
- }
- }
-
- /* Automatically generated code for commit point define: Fetch_W_Load */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 4;
- cp_define->label_name = "Fetch_W_Load";
- cp_define->potential_cp_label_num = 3;
- cp_define->potential_label_name = "Fetch_Potential_W_Load";
- cp_define->interface_num = 0;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
-
- t_element * p = & ( m_array[ rd % t_size ] );
-
- return p;
- }
-
-
-void read_consume(t_element * bin) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Consume
- interface_begin->interface_name = "Consume";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__read_consume(bin);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Consume
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Consume_info* info = (Consume_info*) malloc(sizeof(Consume_info));
- info->bin = bin;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Consume
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__read_consume(t_element * bin) {
-
- m_read.fetch_add(1,mo_release);
- /* Automatically generated code for commit point define check: Consume_R_RMW */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 5;
- cp_define_check->label_name = "Consume_R_RMW";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
-
-
-
-t_element * write_prepare() {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 2; // Prepare
- interface_begin->interface_name = "Prepare";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- t_element * __RET__ = __wrapper__write_prepare();
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 2; // Prepare
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Prepare_info* info = (Prepare_info*) malloc(sizeof(Prepare_info));
- info->__RET__ = __RET__;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 2; // Prepare
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-t_element * __wrapper__write_prepare() {
- unsigned int rdwr = m_rdwr.load(mo_acquire);
- /* Automatically generated code for potential commit point: Prepare_Potential_RW_Load */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 6;
- potential_cp_define->label_name = "Prepare_Potential_RW_Load";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- unsigned int rd,wr;
- for(;;) {
- rd = (rdwr>>16) & MASK;
- wr = rdwr & MASK;
-
- if ( wr == ((rd + t_size)&MASK) ) {
- /* Automatically generated code for commit point define: Prepare_RW_Load_Full */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 7;
- cp_define->label_name = "Prepare_RW_Load_Full";
- cp_define->potential_cp_label_num = 6;
- cp_define->potential_label_name = "Prepare_Potential_RW_Load";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- return NULL;
- }
-
-
- bool succ = m_rdwr.compare_exchange_weak(rdwr,(rd<<16) |
- ((wr+1)&MASK),mo_acq_rel);
- /* Automatically generated code for commit point define check: Prepare_RW_RMW */
-
- if (succ) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 8;
- cp_define_check->label_name = "Prepare_RW_RMW";
- cp_define_check->interface_num = 2;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (succ)
- break;
- else
- thrd_yield();
- }
-
- rl::backoff bo;
- while (true) {
-
- int read = m_read.load(mo_acquire);
- /* Automatically generated code for potential commit point: Prepare_Potential_R_Load */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 9;
- potential_cp_define->label_name = "Prepare_Potential_R_Load";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if ((read & MASK) != rd)
- thrd_yield();
- else
- break;
- }
-
- /* Automatically generated code for commit point define: Prepare_R_Load */
-
- if (true) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 10;
- cp_define->label_name = "Prepare_R_Load";
- cp_define->potential_cp_label_num = 9;
- cp_define->potential_label_name = "Prepare_Potential_R_Load";
- cp_define->interface_num = 2;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
-
- t_element * p = & ( m_array[ wr % t_size ] );
-
- return p;
- }
-
-
-void write_publish(t_element * bin) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 3; // Publish
- interface_begin->interface_name = "Publish";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__write_publish(bin);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 3; // Publish
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Publish_info* info = (Publish_info*) malloc(sizeof(Publish_info));
- info->bin = bin;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 3; // Publish
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__write_publish(t_element * bin)
- {
-
- int tmp = m_written.fetch_add(1,mo_release);
- /* Automatically generated code for commit point define check: Publish_W_RMW */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 11;
- cp_define_check->label_name = "Publish_W_RMW";
- cp_define_check->interface_num = 3;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- printf("publish: m_written=%d\n", tmp + 1);
- }
-
-
-
-};
-template <typename t_element, size_t t_size>
-void** mpmc_boundq_1_alt<t_element, t_size>::func_ptr_table;
-template <typename t_element, size_t t_size>
-hb_rule** mpmc_boundq_1_alt<t_element, t_size>::hb_rule_table;
-template <typename t_element, size_t t_size>
-commutativity_rule** mpmc_boundq_1_alt<t_element, t_size>::commutativity_rule_table;
-
-
+++ /dev/null
-#include <inttypes.h>
-#include <threads.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <librace.h>
-
-#include "mpmc-queue.h"
-
-void threadA(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
-{
- int32_t *bin;
- bin = queue->write_prepare();
- if (bin) {
- *bin = 1;
- printf("write_bin %d, val %d\n", bin, 1);
- queue->write_publish(bin);
- } else {
- printf("write failed\n");
- }
-}
-
-void threadB(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
-{
- int32_t *bin;
- bin = queue->read_fetch();
- if (bin) {
- printf("read_bin: %d, val %d\n", bin, *bin);
- queue->read_consume(bin);
- } else {
- printf("Read failed\n");
- }
-}
-
-int user_main(int argc, char **argv)
-{
- struct mpmc_boundq_1_alt<int32_t, 2> queue;
- thrd_t A, B;
-
- printf("Adding initial element\n");
- int32_t *bin;
- bin = queue.write_prepare();
- *bin = 17;
- printf("init_write_bin %d, val %d\n", bin, 17);
- queue.write_publish(bin);
-
- bin = queue.write_prepare();
- *bin = 27;
- printf("init_write_bin %d, val %d\n", bin, 27);
- queue.write_publish(bin);
-
-
- printf("Start threads\n");
-
- thrd_create(&A, (thrd_start_t)&threadA, &queue);
- thrd_create(&B, (thrd_start_t)&threadB, &queue);
-
- thrd_join(A);
- thrd_join(B);
- printf("Threads complete\n");
-
- return 0;
-}
-
+++ /dev/null
-#include <inttypes.h>
-#include <threads.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <librace.h>
-
-#include "mpmc-queue.h"
-
-void threadA(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
-{
- int32_t *bin;
- bin = queue->write_prepare();
- if (bin) {
- *bin = 1;
- printf("write_bin %d, val %d\n", bin, 1);
- queue->write_publish(bin);
- } else {
- printf("write failed\n");
- }
-}
-
-void threadB(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
-{
- int32_t *bin;
- bin = queue->read_fetch();
- if (bin) {
- printf("read_bin: %d, val %d\n", bin, *bin);
- queue->read_consume(bin);
- } else {
- printf("Read failed\n");
- }
-}
-
-int user_main(int argc, char **argv)
-{
- struct mpmc_boundq_1_alt<int32_t, 2> queue;
- thrd_t A, B;
-
- printf("Adding initial element\n");
- int32_t *bin;
- bin = queue.write_prepare();
- *bin = 17;
- printf("init_write_bin %d, val %d\n", bin, 17);
- queue.write_publish(bin);
-
- bin = queue.write_prepare();
- *bin = 27;
- printf("init_write_bin %d, val %d\n", bin, 27);
- queue.write_publish(bin);
-
-
- printf("Start threads\n");
-
- thrd_create(&A, (thrd_start_t)&threadA, &queue);
- thrd_create(&B, (thrd_start_t)&threadB, &queue);
-
- thrd_join(A);
- thrd_join(B);
- printf("Threads complete\n");
-
- return 0;
-}
-
+++ /dev/null
-#include <inttypes.h>
-#include <threads.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <librace.h>
-
-#include "mpmc-queue.h"
-
-void threadA(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
-{
- int32_t *bin;
-
-
- for (int i = 0; i < 1; i++) {
- bin = queue->write_prepare();
- if (bin) {
- *bin = 1;
- queue->write_publish(bin);
- printf("write_bin %d, val %d\n", bin, 1);
- } else {
- printf("write failed\n");
- }
-
- bin = queue->read_fetch();
- if (bin) {
- printf("read_bin: %d, val %d\n", bin, *bin);
- queue->read_consume(bin);
- } else {
- printf("read failed\n");
- }
- }
-
-}
-
-void threadB(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
-{
- int32_t *bin;
- for (int i = 0; i < 1; i++) {
- bin = queue->read_fetch();
- if (bin) {
- printf("read_bin: %d, val %d\n", bin, *bin);
- queue->read_consume(bin);
- } else {
- printf("read failed\n");
- }
- }
-
-
-}
-
-int user_main(int argc, char **argv)
-{
- struct mpmc_boundq_1_alt<int32_t, 1> queue;
- thrd_t A, A1, B;
-
- printf("Adding initial element\n");
- int32_t *bin;
- for (int i = 0; i < 1; i++) {
- printf("#%d, \n", i);
- bin = queue.write_prepare();
- *bin = 17;
- printf("init_write_bin %d, val %d\n", bin, 17);
- queue.write_publish(bin);
-
- bin = queue.read_fetch();
- if (bin) {
- printf("init_read: %d, val %d\n", bin, *bin);
- queue.read_consume(bin);
- }
- }
-
- for (int i = 0; i < 3; i++) {
-
- }
-
- printf("Start threads\n");
-
- thrd_create(&A, (thrd_start_t)&threadA, &queue);
- thrd_create(&A1, (thrd_start_t)&threadA, &queue);
- thrd_create(&B, (thrd_start_t)&threadB, &queue);
-
- thrd_join(A);
- thrd_join(A1);
- thrd_join(B);
- printf("Threads complete\n");
-
- return 0;
-}
-
+++ /dev/null
-#include <inttypes.h>
-#include <threads.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <librace.h>
-
-#include "mpmc-queue.h"
-
-void threadA(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
-{
- int32_t *bin;
-
-
- for (int i = 0; i < 1; i++) {
- bin = queue->write_prepare();
- if (bin) {
- *bin = 1;
- queue->write_publish(bin);
- printf("write_bin %d, val %d\n", bin, 1);
- } else {
- printf("write failed\n");
- }
-
- bin = queue->read_fetch();
- if (bin) {
- printf("read_bin: %d, val %d\n", bin, *bin);
- queue->read_consume(bin);
- } else {
- printf("read failed\n");
- }
- }
-
-}
-
-void threadB(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
-{
- int32_t *bin;
- for (int i = 0; i < 1; i++) {
- bin = queue->read_fetch();
- if (bin) {
- printf("read_bin: %d, val %d\n", bin, *bin);
- queue->read_consume(bin);
- } else {
- printf("read failed\n");
- }
- }
-
-
-}
-
-void threadC(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
-{
- int *bin;
- bin = queue->write_prepare();
- if (bin) {
- *bin = 1;
- queue->write_publish(bin);
- printf("write_bin %d, val %d\n", bin, 1);
- } else {
- printf("write failed\n");
- }
-}
-
-int user_main(int argc, char **argv)
-{
- struct mpmc_boundq_1_alt<int32_t, 1> queue;
- thrd_t A, A1, B, B1, C, C1;
-
- printf("Adding initial element\n");
- int32_t *bin;
- for (int i = 0; i < 0; i++) {
- printf("#%d, \n", i);
- bin = queue.write_prepare();
- *bin = 17;
- printf("init_write_bin %d, val %d\n", bin, 17);
- queue.write_publish(bin);
-
- }
-
- for (int i = 0; i < 3; i++) {
-
- }
-
- printf("Start threads\n");
-
- thrd_create(&A, (thrd_start_t)&threadB, &queue);
- thrd_create(&A1, (thrd_start_t)&threadC, &queue);
- thrd_create(&B, (thrd_start_t)&threadB, &queue);
- thrd_create(&B1, (thrd_start_t)&threadC, &queue);
- thrd_create(&C, (thrd_start_t)&threadB, &queue);
- thrd_create(&C1, (thrd_start_t)&threadC, &queue);
-
- thrd_join(A);
- thrd_join(A1);
- thrd_join(B);
- thrd_join(B1);
- thrd_join(C);
- thrd_join(C1);
- printf("Threads complete\n");
-
- return 0;
-}
-
+++ /dev/null
-include ../benchmarks.mk
-
-TESTNAME = main testcase1 testcase2 testcase3
-
-HEADERS = my_queue.h
-OBJECTS = main.o my_queue.o
-
-all: $(TESTNAME)
-
-main: $(HEADERS) $(OBJECTS)
- $(CC) -o $@ $(OBJECTS) $(CFLAGS) $(LDFLAGS)
-
-testcase1: $(HEADERS) my_queue.o testcase1.o
- $(CC) -o $@ my_queue.o testcase1.o $(CFLAGS) $(LDFLAGS)
-
-testcase2: $(HEADERS) my_queue.o testcase2.o
- $(CC) -o $@ my_queue.o testcase2.o $(CFLAGS) $(LDFLAGS)
-
-testcase3: $(HEADERS) my_queue.o testcase3.o
- $(CC) -o $@ my_queue.o testcase3.o $(CFLAGS) $(LDFLAGS)
-
-%.o: %.c
- $(CC) -c -o $@ $< $(CFLAGS)
-
-clean:
- rm -f $(TESTNAME) *.o
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <threads.h>
-
-#include "my_queue.h"
-#include "model-assert.h"
-
-static int procs = 2;
-static queue_t *queue;
-static thrd_t *threads;
-static unsigned int *input;
-static unsigned int *output;
-static int num_threads;
-
-int get_thread_num()
-{
- thrd_t curr = thrd_current();
- int i;
- for (i = 0; i < num_threads; i++)
- if (curr.priv == threads[i].priv)
- return i;
- return -1;
-}
-
-bool succ1, succ2;
-
-static void main_task(void *param)
-{
-
- unsigned int val;
- int pid = *((int *)param);
-
- if (pid % 2 == 0) {
- input[0] = 17;
- enqueue(queue, input[0]);
- printf("Thrd %d Enqueue %d.\n", get_thread_num(), input[0]);
-
- succ1 = dequeue(queue, &output[0]);
- if (succ1)
- printf("Thrd %d: Dequeue %d.\n", get_thread_num(), output[0]);
- else
- printf("Thrd %d: Dequeue NULL.\n", get_thread_num());
-
- } else if (pid % 2 == 1) {
- input[1] = 37;
- enqueue(queue, input[1]);
- printf("Thrd %d Enqueue %d.\n", get_thread_num(), input[1]);
-
- succ2 = dequeue(queue, &output[1]);
- if (succ2)
- printf("Thrd %d: Dequeue %d.\n", get_thread_num(), output[1]);
- else
- printf("Thrd %d: Dequeue NULL.\n", get_thread_num());
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- int i;
- int *param;
- unsigned int in_sum = 0, out_sum = 0;
-
- queue = calloc(1, sizeof(*queue));
-
- num_threads = procs;
- threads = malloc(num_threads * sizeof(thrd_t));
- param = malloc(num_threads * sizeof(*param));
- input = calloc(num_threads, sizeof(*input));
- output = calloc(num_threads, sizeof(*output));
-
- init_queue(queue, num_threads);
- for (i = 0; i < num_threads; i++) {
- param[i] = i;
- thrd_create(&threads[i], main_task, ¶m[i]);
- }
- for (i = 0; i < num_threads; i++)
- thrd_join(threads[i]);
-
-
- free(param);
- free(threads);
- free(queue);
-
- return 0;
-}
-
+++ /dev/null
-#include <threads.h>
-#include <stdlib.h>
-#include "librace.h"
-#include "model-assert.h"
-
-#include "my_queue.h"
-
-#define relaxed memory_order_relaxed
-#define release memory_order_release
-#define acquire memory_order_acquire
-
-#define MAX_FREELIST 4
-#define INITIAL_FREE 3
-
-#define POISON_IDX 0x666
-
-static unsigned int (*free_lists)[MAX_FREELIST];
-
-
-static unsigned int new_node()
-{
- int i;
- int t = get_thread_num();
- for (i = 0; i < MAX_FREELIST; i++) {
- unsigned int node = free_lists[t][i];
- if (node) {
- free_lists[t][i] = 0;
- return node;
- }
- }
-
- return 0;
-}
-
-
-static void reclaim(unsigned int node)
-{
- int i;
- int t = get_thread_num();
-
-
-
- for (i = 0; i < MAX_FREELIST; i++) {
-
- unsigned int idx = free_lists[t][i];
-
-
- if (idx == 0) {
- store_32(&free_lists[t][i], node);
- return;
- }
- }
-
- }
-
-void init_queue(queue_t *q, int num_threads)
-{
- int i, j;
- for (i = 0; i < MAX_NODES; i++) {
- atomic_init(&q->nodes[i].next, MAKE_POINTER(POISON_IDX, 0));
- }
-
-
-
- free_lists = malloc(num_threads * sizeof(*free_lists));
- for (i = 0; i < num_threads; i++) {
- for (j = 0; j < INITIAL_FREE; j++) {
- free_lists[i][j] = 2 + i * MAX_FREELIST + j;
- atomic_init(&q->nodes[free_lists[i][j]].next, MAKE_POINTER(POISON_IDX, 0));
- }
- }
-
-
- atomic_init(&q->head, MAKE_POINTER(1, 0));
- atomic_init(&q->tail, MAKE_POINTER(1, 0));
- atomic_init(&q->nodes[1].next, MAKE_POINTER(0, 0));
-}
-
-
-void enqueue(queue_t * q, unsigned int val) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Enqueue
- interface_begin->interface_name = "Enqueue";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__enqueue(q, val);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Enqueue
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Enqueue_info* info = (Enqueue_info*) malloc(sizeof(Enqueue_info));
- info->q = q;
- info->val = val;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Enqueue
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__enqueue(queue_t * q, unsigned int val)
-{
- int success = 0;
- unsigned int node;
- pointer tail;
- pointer next;
- pointer tmp;
-
- node = new_node();
- q->nodes[node].value = val;
- tmp = atomic_load_explicit(&q->nodes[node].next, relaxed);
- set_ptr(&tmp, 0); atomic_store_explicit(&q->nodes[node].next, tmp, relaxed);
-
- while (!success) {
-
- /* Automatically generated code for commit point clear: Enqueue_Clear */
-
- if (true) {
- struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
- cp_clear->label_name = "Enqueue_Clear";
- cp_clear->label_num = 0;
- struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_clear->type = CP_CLEAR;
- annotation_cp_clear->annotation = cp_clear;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
- }
-
-
- tail = atomic_load_explicit(&q->tail, acquire);
-
- next = atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire);
- if (tail == atomic_load_explicit(&q->tail, relaxed)) {
-
-
-
- if (get_ptr(next) == 0) { pointer value = MAKE_POINTER(node, get_count(next) + 1);
-
- success = atomic_compare_exchange_strong_explicit(&q->nodes[get_ptr(tail)].next,
- &next, value, release, relaxed);
- /* Automatically generated code for commit point define check: EnqueueUpdateNext */
-
- if (success) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "EnqueueUpdateNext";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- }
- if (!success) {
-
- unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire));
- pointer value = MAKE_POINTER(ptr,
- get_count(tail) + 1);
-
- bool succ = false;
- succ = atomic_compare_exchange_strong_explicit(&q->tail,
- &tail, value, relaxed, relaxed);
- if (succ) {
- }
- thrd_yield();
- }
- }
- }
-
- bool succ = atomic_compare_exchange_strong_explicit(&q->tail,
- &tail,
- MAKE_POINTER(node, get_count(tail) + 1),
- release, relaxed);
-}
-
-
-bool dequeue(queue_t * q, int * retVal) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Dequeue
- interface_begin->interface_name = "Dequeue";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- bool __RET__ = __wrapper__dequeue(q, retVal);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Dequeue
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Dequeue_info* info = (Dequeue_info*) malloc(sizeof(Dequeue_info));
- info->__RET__ = __RET__;
- info->q = q;
- info->retVal = retVal;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Dequeue
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-bool __wrapper__dequeue(queue_t * q, int * retVal)
-{
- unsigned int value = 0;
- int success = 0;
- pointer head;
- pointer tail;
- pointer next;
-
- while (!success) {
- /* Automatically generated code for commit point clear: Dequeue_Clear */
-
- if (true) {
- struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
- cp_clear->label_name = "Dequeue_Clear";
- cp_clear->label_num = 2;
- struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_clear->type = CP_CLEAR;
- annotation_cp_clear->annotation = cp_clear;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
- }
-
-
- head = atomic_load_explicit(&q->head, acquire);
- /* Automatically generated code for commit point define check: DequeueReadHead */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 3;
- cp_define_check->label_name = "DequeueReadHead";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
-
-
- tail = atomic_load_explicit(&q->tail, acquire);
-
-
- next = atomic_load_explicit(&q->nodes[get_ptr(head)].next, acquire);
- /* Automatically generated code for potential commit point: DequeueReadNext */
-
- if (true) {
- struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
- potential_cp_define->label_num = 4;
- potential_cp_define->label_name = "DequeueReadNext";
- struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
- annotation_potential_cp_define->annotation = potential_cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
- }
-
- if (atomic_load_explicit(&q->head, relaxed) == head) {
- if (get_ptr(head) == get_ptr(tail)) {
-
-
-
- if (get_ptr(next) == 0) { return false; }
-
- bool succ = false;
- succ = atomic_compare_exchange_strong_explicit(&q->tail,
- &tail,
- MAKE_POINTER(get_ptr(next), get_count(tail) + 1),
- release, relaxed);
- if (succ) {
- }
- thrd_yield();
- } else {
- value = q->nodes[get_ptr(next)].value;
-
- success = atomic_compare_exchange_strong_explicit(&q->head,
- &head,
- MAKE_POINTER(get_ptr(next), get_count(head) + 1),
- release, relaxed);
- /* Automatically generated code for commit point define check: DequeueUpdateHead */
-
- if (success) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 5;
- cp_define_check->label_name = "DequeueUpdateHead";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
-
- /* Automatically generated code for commit point define: DequeueReadNextVerify */
-
- if (success) {
- struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
- cp_define->label_num = 6;
- cp_define->label_name = "DequeueReadNextVerify";
- cp_define->potential_cp_label_num = 4;
- cp_define->potential_label_name = "DequeueReadNext";
- cp_define->interface_num = 1;
- struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define->type = CP_DEFINE;
- annotation_cp_define->annotation = cp_define;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
- }
-
- if (!success)
- thrd_yield();
- }
- }
- }
- reclaim(get_ptr(head));
- *retVal = value;
- return true;
-}
-
+++ /dev/null
-#ifndef _MY_QUEUE_H
-#define _MY_QUEUE_H
-
-#include <stdatomic.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-#define MAX_NODES 0xf
-
-typedef unsigned long long pointer;
-typedef atomic_ullong pointer_t;
-
-#define MAKE_POINTER(ptr, count) ((((pointer)count) << 32) | ptr)
-#define PTR_MASK 0xffffffffLL
-#define COUNT_MASK (0xffffffffLL << 32)
-
-static inline void set_count(pointer *p, unsigned int val) { *p = (*p & ~COUNT_MASK) | ((pointer)val << 32); }
-static inline void set_ptr(pointer *p, unsigned int val) { *p = (*p & ~PTR_MASK) | val; }
-static inline unsigned int get_count(pointer p) { return (p & COUNT_MASK) >> 32; }
-static inline unsigned int get_ptr(pointer p) { return p & PTR_MASK; }
-
-typedef struct node {
- unsigned int value;
- pointer_t next;
-} node_t;
-
-typedef struct {
- pointer_t head;
- pointer_t tail;
- node_t nodes[MAX_NODES + 1];
-} queue_t;
-
-void init_queue(queue_t *q, int num_threads);
-
-/* All other user-defined structs */
-static IntegerList * __queue;
-/* All other user-defined functions */
-/* Definition of interface info struct: Dequeue */
-typedef struct Dequeue_info {
-bool __RET__;
-queue_t * q;
-int * retVal;
-} Dequeue_info;
-/* End of info struct definition: Dequeue */
-
-/* ID function of interface: Dequeue */
-inline static call_id_t Dequeue_id(void *info, thread_id_t __TID__) {
- Dequeue_info* theInfo = (Dequeue_info*)info;
- bool __RET__ = theInfo->__RET__;
- queue_t * q = theInfo->q;
- int * retVal = theInfo->retVal;
-
- call_id_t __ID__ = __RET__ ? * retVal : 0;
- return __ID__;
-}
-/* End of ID function: Dequeue */
-
-/* Check action function of interface: Dequeue */
-inline static bool Dequeue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Dequeue_info* theInfo = (Dequeue_info*)info;
- bool __RET__ = theInfo->__RET__;
- queue_t * q = theInfo->q;
- int * retVal = theInfo->retVal;
-
- int elem = 0 ;
- if ( __RET__ ) {
- elem = front ( __queue ) ;
- pop_front ( __queue ) ;
- }
- check_passed = __RET__ ? * retVal == elem : true;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Dequeue */
-
-/* Definition of interface info struct: Enqueue */
-typedef struct Enqueue_info {
-queue_t * q;
- unsigned int val;
-} Enqueue_info;
-/* End of info struct definition: Enqueue */
-
-/* ID function of interface: Enqueue */
-inline static call_id_t Enqueue_id(void *info, thread_id_t __TID__) {
- Enqueue_info* theInfo = (Enqueue_info*)info;
- queue_t * q = theInfo->q;
- unsigned int val = theInfo->val;
-
- call_id_t __ID__ = val;
- return __ID__;
-}
-/* End of ID function: Enqueue */
-
-/* Check action function of interface: Enqueue */
-inline static bool Enqueue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Enqueue_info* theInfo = (Enqueue_info*)info;
- queue_t * q = theInfo->q;
- unsigned int val = theInfo->val;
-
- push_back ( __queue , val ) ;
- return true;
-}
-/* End of check action function: Enqueue */
-
-#define INTERFACE_SIZE 2
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Enqueue_info *_info1 = (Enqueue_info*) info1;
- Dequeue_info *_info2 = (Dequeue_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Dequeue_info *_info1 = (Dequeue_info*) info1;
- Dequeue_info *_info2 = (Dequeue_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- __queue = createIntegerList ( ) ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- if ( __queue ) destroyIntegerList ( __queue ) ;
- return true ;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
- func_ptr_table[2 * 1] = (void*) &Dequeue_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Dequeue_check_action;
- func_ptr_table[2 * 0] = (void*) &Enqueue_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Enqueue_check_action;
- /* Enqueue(true) -> Dequeue(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 0; // Enqueue
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 1; // Dequeue
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
- #define HB_RULE_TABLE_SIZE 1
- hb_rule_table[0] = hbConditionInit0;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 2);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 1;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 2;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-
-
-void __wrapper__enqueue(queue_t * q, unsigned int val);
-
-void __wrapper__enqueue(queue_t * q, unsigned int val) ;
-
-bool __wrapper__dequeue(queue_t * q, int * retVal);
-
-bool __wrapper__dequeue(queue_t * q, int * retVal) ;
-int get_thread_num();
-
-#endif
-
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <threads.h>
-
-#include "my_queue.h"
-#include "model-assert.h"
-
-static int procs = 2;
-static queue_t *queue;
-static thrd_t *threads;
-static unsigned int *input;
-static unsigned int *output;
-static int num_threads;
-
-int get_thread_num()
-{
- thrd_t curr = thrd_current();
- int i;
- for (i = 0; i < num_threads; i++)
- if (curr.priv == threads[i].priv)
- return i;
- return -1;
-}
-
-
-bool succ1, succ2;
-unsigned int output1, output2;
-
-static void main_task(void *param)
-{
- int pid = *((int *)param);
- if (pid % 4 == 0) {
- output1 = 1;
- succ1 = dequeue(queue, &output1);
- if (succ1)
- printf("Thrd 1: Dequeue %d.\n", output1);
- else
- printf("Thrd 1: Dequeue NULL.\n");
- } else if (pid % 4 == 1) {
- enqueue(queue, 2);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- int i;
- int *param;
- unsigned int in_sum = 0, out_sum = 0;
-
- queue = calloc(1, sizeof(*queue));
-
- num_threads = procs;
- threads = malloc(num_threads * sizeof(thrd_t));
- param = malloc(num_threads * sizeof(*param));
- input = calloc(num_threads, sizeof(*input));
- output = calloc(num_threads, sizeof(*output));
-
- init_queue(queue, num_threads);
- for (i = 0; i < num_threads; i++) {
- param[i] = i;
- thrd_create(&threads[i], main_task, ¶m[i]);
- }
- for (i = 0; i < num_threads; i++)
- thrd_join(threads[i]);
-
-
- free(param);
- free(threads);
- free(queue);
-
- return 0;
-}
-
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <threads.h>
-
-#include "my_queue.h"
-#include "model-assert.h"
-
-static int procs = 3;
-static queue_t *queue;
-static thrd_t *threads;
-static unsigned int *input;
-static unsigned int *output;
-static int num_threads;
-
-int get_thread_num()
-{
- thrd_t curr = thrd_current();
- int i;
- for (i = 0; i < num_threads; i++)
- if (curr.priv == threads[i].priv)
- return i;
- return -1;
-}
-
-
-bool succ1, succ2;
-unsigned int output1, output2;
-
-static void main_task(void *param)
-{
- int pid = *((int *)param);
- if (pid % 4 == 0) {
- output1 = 1;
- succ1 = dequeue(queue, &output1);
- if (succ1)
- printf("Thrd 1: Dequeue %d.\n", output1);
- else
- printf("Thrd 1: Dequeue NULL.\n");
- } else if (pid % 4 == 1) {
- enqueue(queue, 1);
- } else if (pid % 4 == 2) {
- enqueue(queue, 2);
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- int i;
- int *param;
- unsigned int in_sum = 0, out_sum = 0;
-
- queue = calloc(1, sizeof(*queue));
-
- num_threads = procs;
- threads = malloc(num_threads * sizeof(thrd_t));
- param = malloc(num_threads * sizeof(*param));
- input = calloc(num_threads, sizeof(*input));
- output = calloc(num_threads, sizeof(*output));
-
- init_queue(queue, num_threads);
- for (i = 0; i < num_threads; i++) {
- param[i] = i;
- thrd_create(&threads[i], main_task, ¶m[i]);
- }
- for (i = 0; i < num_threads; i++)
- thrd_join(threads[i]);
-
-
- free(param);
- free(threads);
- free(queue);
-
- return 0;
-}
-
+++ /dev/null
-#include <stdlib.h>
-#include <stdio.h>
-#include <threads.h>
-
-#include "my_queue.h"
-#include "model-assert.h"
-
-static int procs = 3;
-static queue_t *queue;
-static thrd_t *threads;
-static unsigned int *input;
-static unsigned int *output;
-static int num_threads;
-
-int get_thread_num()
-{
- thrd_t curr = thrd_current();
- int i;
- for (i = 0; i < num_threads; i++)
- if (curr.priv == threads[i].priv)
- return i;
- return -1;
-}
-
-
-bool succ1, succ2;
-unsigned int output1, output2;
-
-static void main_task(void *param)
-{
- int pid = *((int *)param);
- if (pid % 4 == 0) {
- output1 = 1;
- succ1 = dequeue(queue, &output1);
- if (succ1)
- printf("Thrd 1: Dequeue %d.\n", output1);
- else
- printf("Thrd 1: Dequeue NULL.\n");
- } else if (pid % 4 == 1) {
- enqueue(queue, 1);
- printf("Thrd 2: Enqueue %d.\n", 1);
- } else if (pid % 4 == 2) {
-
- output1 = 1;
- succ1 = dequeue(queue, &output1);
- if (succ1)
- printf("Thrd 3: Dequeue %d.\n", output1);
- else
- printf("Thrd 3: Dequeue NULL.\n");
- }
-}
-
-int user_main(int argc, char **argv)
-{
- __sequential_init();
-
- int i;
- int *param;
- unsigned int in_sum = 0, out_sum = 0;
-
- queue = calloc(1, sizeof(*queue));
-
- num_threads = procs;
- threads = malloc(num_threads * sizeof(thrd_t));
- param = malloc(num_threads * sizeof(*param));
- input = calloc(num_threads, sizeof(*input));
- output = calloc(num_threads, sizeof(*output));
-
- init_queue(queue, num_threads);
- for (i = 0; i < num_threads; i++) {
- param[i] = i;
- thrd_create(&threads[i], main_task, ¶m[i]);
- }
- for (i = 0; i < num_threads; i++)
- thrd_join(threads[i]);
-
-
- free(param);
- free(threads);
- free(queue);
-
- return 0;
-}
-
+++ /dev/null
-include ../benchmarks.mk
-
-all: rcu
-
-rcp: rcu.cc
- $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
-
-clean:
- rm -f $(TESTNAME) *.o
+++ /dev/null
-#include <atomic>
-#include <threads.h>
-#include <stdatomic.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-#include "librace.h"
-
-
-
-typedef struct Data {
- int data1;
- int data2;
-} Data;
-
-atomic<Data*> data;
-
-/* All other user-defined structs */
-static IntegerList * set;
-/* All other user-defined functions */
-inline static call_id_t getID ( int64_t d1 , int64_t d2 ) {
-return d1 + d2 ;
-}
-
-inline static bool print ( int64_t p ) {
-Data * d = ( Data * ) p ;
-model_print ( "Elem-> d1 = %d, d2 = %d\n" , d -> data1 , d -> data2 ) ;
-}
-bool equal ( int64_t p1 , int64_t p2 ) {
-if ( ! p1 || ! p2 ) return false ;
-Data * d1 = ( Data * ) p1 ;
-Data * d2 = ( Data * ) p2 ;
-if ( d1 -> data1 == d2 -> data1 && d1 -> data2 == d2 -> data2 ) {
-return true ;
-}
-else {
-return false ;
-}
-}
-
-inline static void _write ( int64_t d1 , int64_t d2 ) {
-Data * d = ( Data * ) MODEL_MALLOC ( sizeof ( Data ) ) ;
-d -> data1 = d1 ;
-d -> data2 = d2 ;
-push_back ( set , ( int64_t ) d ) ;
-}
-
-inline static bool _read ( Data * res ) {
-bool hasElem = has_elem_by_value ( set , ( int64_t ) res , & equal ) ;
-return hasElem ;
-}
-
-/* Definition of interface info struct: Write */
-typedef struct Write_info {
-Data * __RET__;
-int d1;
-int d2;
-} Write_info;
-/* End of info struct definition: Write */
-
-/* ID function of interface: Write */
-inline static call_id_t Write_id(void *info, thread_id_t __TID__) {
- Write_info* theInfo = (Write_info*)info;
- Data * __RET__ = theInfo->__RET__;
- int d1 = theInfo->d1;
- int d2 = theInfo->d2;
-
- call_id_t __ID__ = getID ( d1 , d2 ) ;;
- return __ID__;
-}
-/* End of ID function: Write */
-
-/* Check action function of interface: Write */
-inline static bool Write_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Write_info* theInfo = (Write_info*)info;
- Data * __RET__ = theInfo->__RET__;
- int d1 = theInfo->d1;
- int d2 = theInfo->d2;
-
- _write ( d1 , d2 ) ;
- return true;
-}
-/* End of check action function: Write */
-
-/* Definition of interface info struct: Read */
-typedef struct Read_info {
-Data * __RET__;
-} Read_info;
-/* End of info struct definition: Read */
-
-/* ID function of interface: Read */
-inline static call_id_t Read_id(void *info, thread_id_t __TID__) {
- Read_info* theInfo = (Read_info*)info;
- Data * __RET__ = theInfo->__RET__;
-
- call_id_t __ID__ = getID ( __RET__ -> data1 , __RET__ -> data2 );
- return __ID__;
-}
-/* End of ID function: Read */
-
-/* Check action function of interface: Read */
-inline static bool Read_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Read_info* theInfo = (Read_info*)info;
- Data * __RET__ = theInfo->__RET__;
-
- check_passed = _read ( __RET__ ) ;;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Read */
-
-#define INTERFACE_SIZE 2
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Write_info *_info1 = (Write_info*) info1;
- Read_info *_info2 = (Read_info*) info2;
- return true;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- set = createIntegerList ( ) ;
- Data * d = ( Data * ) MODEL_MALLOC ( sizeof ( Data ) ) ;
- d -> data1 = 0 ;
- d -> data2 = 0 ;
- push_back ( set , ( int64_t ) d ) ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- if ( set ) destroyIntegerList ( set ) ;
- return true ;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
- func_ptr_table[2 * 1] = (void*) &Write_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Write_check_action;
- func_ptr_table[2 * 0] = (void*) &Read_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Read_check_action;
- /* Write(true) -> Read(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 1; // Write
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 0; // Read
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Write(true) -> Write(true) */
- struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit1->interface_num_before = 1; // Write
- hbConditionInit1->hb_condition_num_before = 0; //
- hbConditionInit1->interface_num_after = 1; // Write
- hbConditionInit1->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 2);
- #define HB_RULE_TABLE_SIZE 2
- hb_rule_table[0] = hbConditionInit0;
- hb_rule_table[1] = hbConditionInit1;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 1);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 0;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 1;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-Data * __wrapper__read();
-
-Data * read() {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Read
- interface_begin->interface_name = "Read";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- Data * __RET__ = __wrapper__read();
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Read
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Read_info* info = (Read_info*) malloc(sizeof(Read_info));
- info->__RET__ = __RET__;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Read
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-Data * __wrapper__read() {
-
- Data *res = data.load(memory_order_acquire);
- /* Automatically generated code for commit point define check: Read_Success_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Read_Success_Point";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- return res;
-}
-
-Data * __wrapper__write(int d1, int d2);
-
-Data * write(int d1, int d2) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Write
- interface_begin->interface_name = "Write";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- Data * __RET__ = __wrapper__write(d1, d2);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Write
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Write_info* info = (Write_info*) malloc(sizeof(Write_info));
- info->__RET__ = __RET__;
- info->d1 = d1;
- info->d2 = d2;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Write
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-Data * __wrapper__write(int d1, int d2) {
- bool succ = false;
- Data *tmp = (Data*) malloc(sizeof(Data));
- do {
-
- Data *prev = data.load(memory_order_acquire);
- tmp->data1 = d1;
- tmp->data2 = d2;
-
- succ = data.compare_exchange_strong(prev, tmp,
- memory_order_release, memory_order_relaxed);
- /* Automatically generated code for commit point define check: Write_Success_Point */
-
- if (succ) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Write_Success_Point";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- } while (!succ);
- return tmp;
-}
-
-
-void threadA(void *arg) {
- write(1, 0);
-}
-
-void threadB(void *arg) {
- write(0, 2);
-}
-
-void threadC(void *arg) {
- write(2, 2);
-}
-
-void threadD(void *arg) {
- Data *d = read();
- printf("ThreadD: d1=%d, d2=%d\n", d->data1, d->data2);
-}
-
-int user_main(int argc, char **argv) {
- __sequential_init();
-
-
- thrd_t t1, t2, t3, t4;
- Data *dataInit = (Data*) malloc(sizeof(Data));
- dataInit->data1 = 0;
- dataInit->data2 = 0;
- atomic_init(&data, dataInit);
-
- thrd_create(&t1, threadA, NULL);
- thrd_create(&t2, threadB, NULL);
- thrd_create(&t4, threadD, NULL);
-
- thrd_join(t1);
- thrd_join(t2);
- thrd_join(t4);
-
- return 0;
-}
-
+++ /dev/null
-#!/bin/sh
-#
-# Runs a simple test (default: ./test/userprog.o)
-# Syntax:
-# ./run.sh [test program] [OPTIONS]
-# ./run.sh [OPTIONS]
-# ./run.sh [gdb [test program]]
-#
-# If you include a 'gdb' argument, the your program will be launched with gdb.
-# You can also supply a test program argument to run something besides the
-# default program.
-#
-
-# Get the directory in which this script and the binaries are located
-#BINDIR="${0%/*}"
-BINDIR=${HOME}/model-checker-priv/model-checker-priv
-
-BIN=${BINDIR}/test/userprog.o
-PREFIX=
-
-export LD_LIBRARY_PATH=${BINDIR}
-# For Mac OSX
-export DYLD_LIBRARY_PATH=${BINDIR}
-
-[ $# -gt 0 ] && [ "$1" = "gdb" ] && PREFIX=gdb && shift
-[ $# -gt 0 ] && [ -e "$1" ] && BIN="$1" && shift
-
-set -xe
-$PREFIX $BIN $@
+++ /dev/null
-include ../benchmarks.mk
-
-all: seqlock
-
-seqlock: seqlock.cc
- $(CXX) -o seqlock seqlock.cc $(CXXFLAGS) $(LDFLAGS)
-
-clean:
- rm -f $(TESTNAME) *.o seqlock
+++ /dev/null
-include ../benchmarks.mk
-
-TESTNAME = spsc-queue
-RELACYNAME = spsc-relacy
-
-all: $(TESTNAME)
-
-$(TESTNAME): $(TESTNAME).cc queue.h eventcount.h
- $(CXX) -o $@ $< $(CXXFLAGS) $(LDFLAGS)
-
-relacy: $(RELACYNAME)
-
-$(RELACYNAME): spsc-relacy.cc queue-relacy.h eventcount-relacy.h
-ifdef RELACYPATH
- $(CXX) -o $(RELACYNAME) spsc-relacy.cc -I$(RELACYPATH) -Wno-deprecated
-else
- @echo "Please define RELACYPATH"
- @echo " e.g., make RELACYPATH=/path-to-relacy"
- @exit 1
-endif
-
-clean:
- rm -f $(TESTNAME) $(RELACYNAME) *.o
+++ /dev/null
-#ifndef _EVENTCOUNT_H
-#define _EVENTCOUNT_H
-
-#include <atomic>
-#include <mutex>
-#include <condition_variable>
-
-class eventcount
-{
-public:
- eventcount() : waiters(0)
- {
- count = 0;
- }
-
- void signal_relaxed()
- {
- unsigned cmp = count.load(std::memory_order_relaxed);
- signal_impl(cmp);
- }
-
- void signal()
- {
- unsigned cmp = count.fetch_add(0, std::memory_order_seq_cst);
- signal_impl(cmp);
- }
-
- unsigned get()
- {
- unsigned cmp = count.fetch_or(0x80000000,
-std::memory_order_seq_cst);
- return cmp & 0x7FFFFFFF;
- }
-
- void wait(unsigned cmp)
- {
- unsigned ec = count.load(std::memory_order_seq_cst);
- if (cmp == (ec & 0x7FFFFFFF))
- {
- guard.lock($);
- ec = count.load(std::memory_order_seq_cst);
- if (cmp == (ec & 0x7FFFFFFF))
- {
- waiters += 1;
- cv.wait(guard);
- }
- guard.unlock($);
- }
- }
-
-private:
- std::atomic<unsigned> count;
- rl::var<unsigned> waiters;
- std::mutex guard;
- std::condition_variable cv;
-
- void signal_impl(unsigned cmp)
- {
- if (cmp & 0x80000000)
- {
- guard.lock($);
- while (false == count.compare_exchange_weak(cmp,
- (cmp + 1) & 0x7FFFFFFF, std::memory_order_relaxed));
- unsigned w = waiters($);
- waiters = 0;
- guard.unlock($);
- if (w)
- cv.notify_all($);
- }
- }
-};
-
-#endif
-
+++ /dev/null
-#ifndef _QUEUE_H
-#define _QUEUE_H
-
-#include <unrelacy.h>
-#include <atomic>
-
-#include <spec_lib.h>
-#include <stdlib.h>
-#include <cdsannotate.h>
-#include <specannotation.h>
-#include <model_memory.h>
-#include "common.h"
-
-#include "eventcount.h"
-
-
-template<typename T>
-class spsc_queue
-{
-
-public:
-
-
- spsc_queue()
- {
-
- __sequential_init();
-
-
- node* n = new node ();
- head = n;
- tail = n;
- }
-
- ~spsc_queue()
- {
- delete ((node*)head);
- }
-
-/* All other user-defined structs */
-static IntegerList * __queue;
-/* All other user-defined functions */
-/* Definition of interface info struct: Dequeue */
-typedef struct Dequeue_info {
-T __RET__;
-} Dequeue_info;
-/* End of info struct definition: Dequeue */
-
-/* ID function of interface: Dequeue */
-inline static call_id_t Dequeue_id(void *info, thread_id_t __TID__) {
- Dequeue_info* theInfo = (Dequeue_info*)info;
- T __RET__ = theInfo->__RET__;
-
- call_id_t __ID__ = __RET__ ? __RET__ : 0;
- return __ID__;
-}
-/* End of ID function: Dequeue */
-
-/* Check action function of interface: Dequeue */
-inline static bool Dequeue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Dequeue_info* theInfo = (Dequeue_info*)info;
- T __RET__ = theInfo->__RET__;
-
- int elem = 0 ;
- if ( __RET__ ) {
- elem = front ( __queue ) ;
- pop_front ( __queue ) ;
- }
- check_passed = __RET__ ? __RET__ == elem : true;
- if (!check_passed)
- return false;
- return true;
-}
-/* End of check action function: Dequeue */
-
-/* Definition of interface info struct: Enqueue */
-typedef struct Enqueue_info {
-T data;
-} Enqueue_info;
-/* End of info struct definition: Enqueue */
-
-/* ID function of interface: Enqueue */
-inline static call_id_t Enqueue_id(void *info, thread_id_t __TID__) {
- Enqueue_info* theInfo = (Enqueue_info*)info;
- T data = theInfo->data;
-
- call_id_t __ID__ = data;
- return __ID__;
-}
-/* End of ID function: Enqueue */
-
-/* Check action function of interface: Enqueue */
-inline static bool Enqueue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
- bool check_passed;
- Enqueue_info* theInfo = (Enqueue_info*)info;
- T data = theInfo->data;
-
- push_back ( __queue , data ) ;
- return true;
-}
-/* End of check action function: Enqueue */
-
-#define INTERFACE_SIZE 2
-static void** func_ptr_table;
-static hb_rule** hb_rule_table;
-static commutativity_rule** commutativity_rule_table;
-inline static bool CommutativityCondition0(void *info1, void *info2) {
- Enqueue_info *_info1 = (Enqueue_info*) info1;
- Dequeue_info *_info2 = (Dequeue_info*) info2;
- return true;
-}
-inline static bool CommutativityCondition1(void *info1, void *info2) {
- Dequeue_info *_info1 = (Dequeue_info*) info1;
- Dequeue_info *_info2 = (Dequeue_info*) info2;
- return ! _info1-> __RET__ || ! _info2-> __RET__;
-}
-
-/* Initialization of sequential varialbes */
-static void __SPEC_INIT__() {
- __queue = createIntegerList ( ) ;
-}
-
-/* Cleanup routine of sequential variables */
-static bool __SPEC_CLEANUP__() {
- if ( __queue ) destroyIntegerList ( __queue ) ;
- return true ;
-}
-
-/* Define function for sequential code initialization */
-inline static void __sequential_init() {
- /* Init func_ptr_table */
- func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
- func_ptr_table[2 * 1] = (void*) &Dequeue_id;
- func_ptr_table[2 * 1 + 1] = (void*) &Dequeue_check_action;
- func_ptr_table[2 * 0] = (void*) &Enqueue_id;
- func_ptr_table[2 * 0 + 1] = (void*) &Enqueue_check_action;
- /* Enqueue(true) -> Dequeue(true) */
- struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
- hbConditionInit0->interface_num_before = 0; // Enqueue
- hbConditionInit0->hb_condition_num_before = 0; //
- hbConditionInit0->interface_num_after = 1; // Dequeue
- hbConditionInit0->hb_condition_num_after = 0; //
- /* Init hb_rule_table */
- hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
- #define HB_RULE_TABLE_SIZE 1
- hb_rule_table[0] = hbConditionInit0;
- /* Init commutativity_rule_table */
- commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 2);
- commutativity_rule* rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 0;
- rule->interface_num_after = 1;
- rule->rule = "true";
- rule->condition = CommutativityCondition0;
- commutativity_rule_table[0] = rule;
- rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
- rule->interface_num_before = 1;
- rule->interface_num_after = 1;
- rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
- rule->condition = CommutativityCondition1;
- commutativity_rule_table[1] = rule;
- /* Pass init info, including function table info & HB rules & Commutativity Rules */
- struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
- anno_init->init_func = (void_func_t) __SPEC_INIT__;
- anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
- anno_init->func_table = func_ptr_table;
- anno_init->func_table_size = INTERFACE_SIZE;
- anno_init->hb_rule_table = hb_rule_table;
- anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
- anno_init->commutativity_rule_table = commutativity_rule_table;
- anno_init->commutativity_rule_table_size = 2;
- struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- init->type = INIT;
- init->annotation = anno_init;
- cdsannotate(SPEC_ANALYSIS, init);
-
-}
-
-/* End of Global construct generation in class */
-
-
-
-
-void enqueue(T data) {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 0; // Enqueue
- interface_begin->interface_name = "Enqueue";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- __wrapper__enqueue(data);
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 0; // Enqueue
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Enqueue_info* info = (Enqueue_info*) malloc(sizeof(Enqueue_info));
- info->data = data;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 0; // Enqueue
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
-}
-
-void __wrapper__enqueue(T data)
- {
- node* n = new node (data);
-
- head->next.store(n, std::memory_order_release);
- /* Automatically generated code for commit point define check: Enqueue_Point */
-
- if (true) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 0;
- cp_define_check->label_name = "Enqueue_Point";
- cp_define_check->interface_num = 0;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- head = n;
- ec.signal();
- }
-
-T dequeue() {
- /* Interface begins */
- struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
- interface_begin->interface_num = 1; // Dequeue
- interface_begin->interface_name = "Dequeue";
- struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_interface_begin->type = INTERFACE_BEGIN;
- annotation_interface_begin->annotation = interface_begin;
- cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
- T __RET__ = __wrapper__dequeue();
- struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
- hb_condition->interface_num = 1; // Dequeue
- hb_condition->hb_condition_num = 0;
- struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_hb_condition->type = HB_CONDITION;
- annotation_hb_condition->annotation = hb_condition;
- cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
-
- Dequeue_info* info = (Dequeue_info*) malloc(sizeof(Dequeue_info));
- info->__RET__ = __RET__;
- struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
- interface_end->interface_num = 1; // Dequeue
- interface_end->info = info;
- struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annoation_interface_end->type = INTERFACE_END;
- annoation_interface_end->annotation = interface_end;
- cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
- return __RET__;
-}
-
-T __wrapper__dequeue()
- {
- T data = try_dequeue();
- while (0 == data)
- {
- int cmp = ec.get();
- data = try_dequeue();
- if (data)
- break;
- ec.wait(cmp);
- data = try_dequeue();
- if (data)
- break;
- }
- return data;
- }
-
-private:
- struct node
- {
- std::atomic<node*> next;
- T data;
-
- node(T data = T())
- : data(data)
- {
- next = 0;
- }
- };
-
- node *head;
- node *tail;
-
-
-
- eventcount ec;
-
- T try_dequeue()
- {
- node *t = tail;
-
- node* n = t->next.load(std::memory_order_acquire);
- /* Automatically generated code for commit point define check: Dequeue_Point */
-
- if (n != 0) {
- struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
- cp_define_check->label_num = 1;
- cp_define_check->label_name = "Dequeue_Point";
- cp_define_check->interface_num = 1;
- struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
- annotation_cp_define_check->type = CP_DEFINE_CHECK;
- annotation_cp_define_check->annotation = cp_define_check;
- cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
- }
-
- if (0 == n)
- return 0;
- T data = n->data;
- delete (t);
- tail = n;
- return data;
- }
-};
-template<typename T>
-void** spsc_queue<T>::func_ptr_table;
-template<typename T>
-hb_rule** spsc_queue<T>::hb_rule_table;
-template<typename T>
-commutativity_rule** spsc_queue<T>::commutativity_rule_table;
-template<typename T>
-IntegerList * spsc_queue<T>::__queue;
-
-
-#endif
-
+++ /dev/null
-#include <threads.h>
-
-#include "queue.h"
-
-spsc_queue<int> *q;
-
- void thread(unsigned thread_index)
- {
- if (0 == thread_index)
- {
- q->enqueue(11);
- }
- else
- {
- int d = q->dequeue();
- }
- }
-
-int user_main(int argc, char **argv)
-{
- thrd_t A, B;
-
- q = new spsc_queue<int>();
-
- thrd_create(&A, (thrd_start_t)&thread, (void *)0);
- thrd_create(&B, (thrd_start_t)&thread, (void *)1);
- thrd_join(A);
- thrd_join(B);
-
- delete q;
-
- return 0;
-}
-
#!/bin/bash
-if [ -z $SPEC_COMPILER_HOME ]; then
- SPEC_COMPILER_HOME=~/spec-checker-compiler
-fi
+SPEC_COMPILER_HOME=$(pwd)
+
+echo "CDSSpec Compiler home: " $SPEC_COMPILER_HOME
JAVACC_PATH=$SPEC_COMPILER_HOME/lib
-PRE_SCANNER_FILE=$SPEC_COMPILER_HOME/grammer/pre_scanner.jj
-GRAMMER_FILE=$SPEC_COMPILER_HOME/grammer/spec_compiler.jj
UTIL_FILE=$SPEC_COMPILER_HOME/grammer/util.jj
-PRE_SCANNER_OUTPUT_PATH=$SPEC_COMPILER_HOME/src/edu/uci/eecs/specCompiler/grammerParser/preScanner
-GRAMMER_OUTPUT_PATH=$SPEC_COMPILER_HOME/src/edu/uci/eecs/specCompiler/grammerParser
-UTIL_OUTPUT_PATH=$SPEC_COMPILER_HOME/src/edu/uci/eecs/specCompiler/grammerParser/utilParser
+UTIL_OUTPUT_PATH=$SPEC_COMPILER_HOME/src/edu/uci/eecs/utilParser
echo "Deleting the old generated java files."
-rm -r $PRE_SCANNER_OUTPUT_PATH/*
-rm -r $GRAMMER_OUTPUT_PATH/*
-rm -r $UTIL_OUTPUT_PATH/*
+rm -rf $UTIL_OUTPUT_PATH/*
-mkdir -p $PRE_SCANNER_OUTPUT_PATH
-mkdir -p $GRAMMER_OUTPUT_PATH
mkdir -p $UTIL_OUTPUT_PATH
-java -cp $JAVACC_PATH/javacc.jar javacc -OUTPUT_DIRECTORY=$PRE_SCANNER_OUTPUT_PATH $PRE_SCANNER_FILE
-java -cp $JAVACC_PATH/javacc.jar javacc -OUTPUT_DIRECTORY=$GRAMMER_OUTPUT_PATH $GRAMMER_FILE
java -cp $JAVACC_PATH/javacc.jar javacc -OUTPUT_DIRECTORY=$UTIL_OUTPUT_PATH $UTIL_FILE
+++ /dev/null
-#!/bin/bash
-
-if [ -z $1 ]; then
- export SPEC_COMPILER_HOME=~/spec-checker-compiler
-else
- export SPEC_COMPILER_HOME=$1
-fi
--- /dev/null
+package edu.uci.eecs.codeGenerator;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import edu.uci.eecs.specExtraction.Code;
+
+/**
+ * <p>
+ * This class represents all the code additions that should be added to a
+ * specific file.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class CodeAdditions {
+
+ /**
+ * <p>
+ * This class represents the addition of code for a specific file. It
+ * records a list of lines to be inserted for a specific file, and the line
+ * after which the code should be inserted to the file.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+ public static class CodeAddition {
+ // The line after which the code should be inserted to the file
+ // E.g. insertingLine == 0 => insert the lines ine very beginning.
+ public final int insertingLine;
+
+ // The code to be added to the specified place
+ public final Code code;
+
+ public CodeAddition(int insertingLine, Code code) {
+ this.insertingLine = insertingLine;
+ this.code = code;
+ }
+
+ public static Comparator<CodeAddition> lineNumComparator = new Comparator<CodeAddition>() {
+ public int compare(CodeAddition addition1, CodeAddition addition2) {
+ return addition1.insertingLine - addition2.insertingLine;
+ }
+ };
+ }
+
+ // A list of code addition for the same file
+ public final ArrayList<CodeAddition> codeAdditions;
+
+ // The file that the list of additions belong to
+ public final File file;
+
+ public CodeAdditions(File file) {
+ this.file = file;
+ codeAdditions = new ArrayList<CodeAddition>();
+ }
+
+ public void addCodeAddition(CodeAddition a) {
+ this.codeAdditions.add(a);
+ }
+
+ /**
+ * <p>
+ * Whether the addition list is empty
+ * </p>
+ *
+ * @return
+ */
+ public boolean isEmpty() {
+ return this.codeAdditions.size() == 0;
+ }
+
+ /**
+ * <p>
+ * Sort the list of code additions to the same file in an increasing order
+ * by the inserting line number of the code additions. We will call this
+ * function so that we can process code addition more conveniently.
+ * </p>
+ */
+ public void sort() {
+ Collections.sort(codeAdditions, CodeAddition.lineNumComparator);
+ }
+}
--- /dev/null
+package edu.uci.eecs.codeGenerator;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+
+import edu.uci.eecs.codeGenerator.CodeAdditions.CodeAddition;
+import edu.uci.eecs.specExtraction.Code;
+import edu.uci.eecs.specExtraction.Construct;
+import edu.uci.eecs.specExtraction.EntryConstruct;
+import edu.uci.eecs.specExtraction.InterfaceConstruct;
+import edu.uci.eecs.specExtraction.OPConstruct;
+import edu.uci.eecs.specExtraction.SpecExtractor;
+import edu.uci.eecs.specExtraction.SpecNaming;
+import edu.uci.eecs.specExtraction.WrongAnnotationException;
+import edu.uci.eecs.utilParser.ParseException;
+
+/**
+ * <p>
+ * This class represents the engine to generate instrumented code. To construct
+ * an object of this file, users need provide a string that represents the
+ * sub-directory under the benchmarks directory, then the engine will explore
+ * all the C/C++ files that ends with ".cc/.cpp/.c/.h" and extract specification
+ * annotations and generate instrumented code in the generated directory.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class CodeGenerator {
+ // Files that we need to process
+ private ArrayList<File> files;
+
+ // Code addition list --- per file
+ private ArrayList<CodeAdditions> allAdditions;
+ // Line change map list --- per file; Each map represents the
+ // line->InterfaceConstruct mapping that will rename the interface
+ // declaration line.
+ private ArrayList<HashMap<Integer, InterfaceConstruct>> renamedLinesMapList;
+
+ // The string that users provide as a sub-directory in the benchmarks
+ // directory: e.g. ms-queue
+ public final String dirName;
+
+ // The original directory --- the benchmarks directory: e.g.
+ // ~/model-checker/benchmarks/
+ public final String originalDir;
+ // The directory for generated files: e.g. ~/model-checker/test-cdsspec/
+ public final String generatedDir;
+
+ // The specification annotation extractor
+ private SpecExtractor extractor;
+
+ public CodeGenerator(String dirName) {
+ this.dirName = dirName;
+ originalDir = Environment.BenchmarksDir + dirName
+ + "/";
+ generatedDir = Environment.GeneratedFilesDir + dirName
+ + "/";
+ try {
+ files = this.getSrcFiles(originalDir);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ extractor = new SpecExtractor();
+ try {
+ extractor.extract(files);
+ } catch (WrongAnnotationException e) {
+ e.printStackTrace();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * <p>
+ * This function initializes the list of code additions and line changes for
+ * all the files. For the code additions of a file, we sort them in an
+ * increasing order by the inserting line number.
+ * </p>
+ *
+ */
+ private void getAllCodeChanges() {
+ allAdditions = new ArrayList<CodeAdditions>();
+ renamedLinesMapList = new ArrayList<HashMap<Integer, InterfaceConstruct>>();
+ for (int i = 0; i < files.size(); i++) {
+ File file = files.get(i);
+ // One CodeAdditions per file
+ CodeAdditions additions = new CodeAdditions(file);
+ // Add the additions for this file to the list
+ allAdditions.add(additions);
+
+ // One CodeChange per file
+ HashMap<Integer, InterfaceConstruct> renamedLinesMap = new HashMap<Integer, InterfaceConstruct>();
+ // Add it the the list
+ renamedLinesMapList.add(renamedLinesMap);
+
+ // Extract all the additions
+ ArrayList<OPConstruct> OPList = extractor.OPListMap.get(file);
+ EntryConstruct entry = extractor.entryMap.get(file);
+ ArrayList<InterfaceConstruct> interfaceList = extractor.interfaceListMap
+ .get(file);
+ Code code = null;
+ CodeAddition addition = null;
+ // For ordering point constructs
+ if (OPList != null) {
+ for (OPConstruct con : OPList) {
+ code = CodeGeneratorUtils.Generate4OPConstruct(con);
+ addition = new CodeAddition(con.beginLineNum, code);
+ additions.addCodeAddition(addition);
+ }
+ }
+ // For entry constructs
+ if (entry != null) {
+ code = CodeGeneratorUtils.Generate4Entry(entry);
+ addition = new CodeAddition(entry.beginLineNum, code);
+ additions.addCodeAddition(addition);
+ }
+ // For interface constructs
+ if (interfaceList != null) {
+ for (InterfaceConstruct con : interfaceList) {
+ code = CodeGeneratorUtils.GenerateInterfaceWrapper(con);
+ addition = new CodeAddition(con.getEndLineNumFunction(),
+ code);
+ additions.addCodeAddition(addition);
+ // Record the line to be changed
+ renamedLinesMap.put(con.endLineNum + 1, con);
+ }
+ }
+
+ // Sort additions by line number increasingly
+ additions.sort();
+ }
+ }
+
+ /**
+ * <p>
+ * For a specific file, given the code additions and line changes mapping
+ * for that file, this function will generate the new code for that file and
+ * write it back to the destination directory.
+ * </p>
+ *
+ * @param file
+ * The file to be processed
+ * @param additions
+ * The sorted code additions for the file
+ * @param renamedLinesMap
+ * The line change mapping for the file
+ */
+ private void writeCodeChange(File file, CodeAdditions additions,
+ HashMap<Integer, InterfaceConstruct> renamedLinesMap) {
+ Code newCode = new Code();
+ BufferedReader br = null;
+ LineNumberReader lineReader = null;
+ int lineNum = 0;
+ String curLine = null;
+
+ String dest = generatedDir + file.getName();
+ CodeAddition curAddition = null;
+ int additionIdx = -1;
+ if (!additions.isEmpty()) {
+ additionIdx = 0;
+ curAddition = additions.codeAdditions.get(0);
+ }
+
+ try {
+ br = new BufferedReader(new FileReader(file));
+ lineReader = new LineNumberReader(br);
+ while ((curLine = lineReader.readLine()) != null) {
+ lineNum = lineReader.getLineNumber();
+ InterfaceConstruct construct = null;
+ if ((construct = renamedLinesMap.get(lineNum)) != null) {
+ // Rename line
+ String newLine = construct.getFunctionHeader()
+ .getRenamedFuncLine();
+ newCode.addLine(newLine);
+ } else {
+ // First add the current line
+ newCode.addLine(curLine);
+ // Then check if we need to add code
+ if (curAddition != null
+ && lineNum == curAddition.insertingLine) {
+ // Need to insert code
+ newCode.addLines(curAddition.code);
+ // Increase to the next code addition
+ additionIdx++;
+ curAddition = additionIdx == additions.codeAdditions
+ .size() ? null : additions.codeAdditions
+ .get(additionIdx);
+ }
+ }
+ }
+ // Write new code change to destination
+ CodeGeneratorUtils.write2File(dest, newCode.lines);
+ // System.out.println("/*************** " + file.getName()
+ // + " *************/");
+ // System.out.println(newCode);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * <p>
+ * This function is the main interface for the CodeGenerator class. After
+ * constructing a CodeGenerator object, users can call this function to
+ * complete the code generation and file writing process.
+ * </p>
+ */
+ public void generateCode() {
+ // Extract all the code additions and line change
+ getAllCodeChanges();
+
+ // Generate the header file and CPP file
+ Code generatedHeader = CodeGeneratorUtils
+ .GenerateCDSSpecHeaderFile(extractor);
+ Code generatedCPP = CodeGeneratorUtils
+ .GenerateCDSSpecCPPFile(extractor);
+ CodeGeneratorUtils
+ .write2File(generatedDir + SpecNaming.CDSSpecGeneratedName
+ + ".h", generatedHeader.lines);
+ CodeGeneratorUtils.write2File(generatedDir
+ + SpecNaming.CDSSpecGeneratedCPP, generatedCPP.lines);
+
+ // Iterate over each file
+ for (int i = 0; i < files.size(); i++) {
+ File file = files.get(i);
+ CodeAdditions additions = allAdditions.get(i);
+ HashMap<Integer, InterfaceConstruct> renamedLinesMap = renamedLinesMapList
+ .get(i);
+ writeCodeChange(file, additions, renamedLinesMap);
+ }
+ }
+
+ /**
+ * <p>
+ * This is just a testing function that outputs the generated code, but not
+ * actually write them to the disk.
+ * </p>
+ */
+ private void testGenerator() {
+ // Test code generation
+ Code generatedHeader = CodeGeneratorUtils
+ .GenerateCDSSpecHeaderFile(extractor);
+ Code generatedCPP = CodeGeneratorUtils
+ .GenerateCDSSpecCPPFile(extractor);
+
+ System.out.println("/***** Generated header file *****/");
+ System.out.println(generatedHeader);
+ System.out.println("/***** Generated cpp file *****/");
+ System.out.println(generatedCPP);
+
+ for (File file : extractor.OPListMap.keySet()) {
+ ArrayList<OPConstruct> list = extractor.OPListMap.get(file);
+ for (OPConstruct con : list) {
+ Code code = CodeGeneratorUtils.Generate4OPConstruct(con);
+ System.out.println("/***** *****/");
+ System.out.println(con.annotation);
+ System.out.println(code);
+ }
+ }
+
+ for (File f : extractor.entryMap.keySet()) {
+ EntryConstruct con = extractor.entryMap.get(f);
+ System.out.println("/***** *****/");
+ System.out.println(con.annotation);
+ System.out.println(CodeGeneratorUtils.Generate4Entry(con));
+ }
+
+ for (File file : extractor.interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = extractor.interfaceListMap
+ .get(file);
+ for (InterfaceConstruct con : list) {
+ Code code = CodeGeneratorUtils.GenerateInterfaceWrapper(con);
+ System.out.println("/***** Interface wrapper *****/");
+ System.out.println(con.getFunctionHeader().getHeaderLine());
+ System.out
+ .println(con.getFunctionHeader().getRenamedFuncLine());
+ System.out.println(code);
+ }
+ }
+ }
+
+ public ArrayList<File> getSrcFiles(String dirName)
+ throws FileNotFoundException {
+ ArrayList<File> res = new ArrayList<File>();
+ File dir = new File(dirName);
+ if (dir.isDirectory() && dir.exists()) {
+ for (String file : dir.list()) {
+ if (file.endsWith(".h") || file.endsWith(".c")
+ || file.endsWith(".cc") || file.endsWith(".cpp")) {
+ res.add(new File(dir.getAbsolutePath() + "/" + file));
+ }
+ }
+ } else {
+ throw new FileNotFoundException(dirName
+ + " is not a valid directory!");
+ }
+ return res;
+ }
+
+ static public void main(String[] args) {
+ String dirName = Environment.MS_QUEUE;
+ CodeGenerator generator = new CodeGenerator(dirName);
+ generator.generateCode();
+ }
+}
--- /dev/null
+package edu.uci.eecs.codeGenerator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import edu.uci.eecs.specExtraction.Code;
+import edu.uci.eecs.specExtraction.CommutativityRule;
+import edu.uci.eecs.specExtraction.EntryConstruct;
+import edu.uci.eecs.specExtraction.FunctionHeader;
+import edu.uci.eecs.specExtraction.GlobalConstruct;
+import edu.uci.eecs.specExtraction.InterfaceConstruct;
+import edu.uci.eecs.specExtraction.OPConstruct;
+import edu.uci.eecs.specExtraction.SpecExtractor;
+import edu.uci.eecs.specExtraction.SpecNaming;
+import edu.uci.eecs.specExtraction.VariableDeclaration;
+
+/**
+ * <p>
+ * Some utility functions for generating specification checking code.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class CodeGeneratorUtils {
+
+ public static void PrintCode(ArrayList<String> code) {
+ for (int i = 0; i < code.size(); i++) {
+ System.out.println(code.get(i));
+ }
+ }
+
+ public static String Comment(String comment) {
+ return "/** " + comment + " */";
+ }
+
+ public static String ShortComment(String comment) {
+ return "// " + comment;
+ }
+
+ public static String IncludeHeader(String header) {
+ return "#include " + header;
+ }
+
+ public static String Brace(String val) {
+ return "(" + val + ")";
+ }
+
+ public static String Quote(String val) {
+ return "\"" + val + "\"";
+ }
+
+ public static String Assign(String varName, String val) {
+ return varName + " = " + val + ";";
+ }
+
+ public static String AssignToPtr(String structName, String field, String val) {
+ return structName + "->" + field + " = " + val + ";";
+ }
+
+ public static String Declare(String type, String name) {
+ return type + " " + name + ";";
+ }
+
+ public static String Declare(VariableDeclaration varDecl) {
+ return Declare(varDecl.type, varDecl.name);
+ }
+
+ public static String DeclareDefine(String type, String var, String val) {
+ return type + " " + var + " = " + val + ";";
+ }
+
+ /**
+ * <p>
+ * Insert a number of tabs at the beginning of the line.
+ * </p>
+ *
+ * @param line
+ * Input line
+ * @param tabCnt
+ * The number of tabs to be inserted
+ * @return A line that starts with the specific inserted tabs
+ */
+ public static String TabbedLine(String line, int tabCnt) {
+ String res = "";
+ for (int i = 0; i < tabCnt; i++)
+ res = "\t" + res;
+ res = res + line;
+ return res;
+ }
+
+ /**
+ * <p>
+ * Insert a tab at the beginning of the line.
+ * </p>
+ *
+ * @param line
+ * Input line
+ * @return A line that starts with one inserted tab
+ */
+ public static String TabbedLine(String line) {
+ return "\t" + line;
+ }
+
+ /**
+ * <p>
+ * This function generates the code for the header file that our
+ * specification generates automatically --- cdsspec-generated.h.
+ * </p>
+ *
+ * @param extractor
+ * The SpecExtractor that contains the extracted information
+ * @return The generated code
+ */
+ public static Code GenerateCDSSpecHeaderFile(SpecExtractor extractor) {
+ HashSet<String> headerFiles = extractor.headerFiles;
+ GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
+ HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
+ HashSet<String> OPLabelSet = extractor.OPLabelSet;
+
+ Code code = new Code();
+
+ // Add auto-generated comments
+ code.addLine("/**");
+ code.addLine(TabbedLine("This is a header file auto-generated by CDSSpec compiler; together, CDSSpec"));
+ code.addLine(TabbedLine("compiler should have generated the accompanying implementation file that"));
+ code.addLine(TabbedLine("implements the some functions declared in this file. In order to instrument"));
+ code.addLine(TabbedLine("your benchmark for CDSSpec checker to check, you should include this header"));
+ code.addLine(TabbedLine("file in every file you use an CDSSpec annotation. Note that it should be"));
+ code.addLine(TabbedLine("placed in the end of all other header files. Currently we require a C++"));
+ code.addLine(TabbedLine("compiler that supports C++11."));
+ code.addLine("*/");
+ code.addLine("");
+
+ code.addLine("#ifndef _"
+ + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
+ '_') + "_H");
+ code.addLine("#define _"
+ + SpecNaming.CDSSpecGeneratedName.toUpperCase().replace('-',
+ '_') + "_H");
+ code.addLine("");
+
+ // System included headers
+ code.addLine(ShortComment("System included headers go here"));
+ for (String header : SpecNaming.includedHeadersList) {
+ code.addLine(IncludeHeader(header));
+ }
+ code.addLine("");
+
+ // Users included headers
+ code.addLine(ShortComment("User included headers go here"));
+ for (String header : headerFiles) {
+ code.addLine(IncludeHeader(header));
+ }
+ code.addLine("");
+
+ code.addLine("using namespace std;");
+ code.addLine("");
+ code.addLine("");
+
+ code.addLine(ShortComment("Declaration of some c-strings (CSTR)"));
+ code.addLine(ShortComment("A special empty string"));
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.EmptyCString));
+ code.addLine("");
+
+ // Interface name strings
+ code.addLine(ShortComment("Interface name strings"));
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ String name = construct.getName();
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(name)));
+ }
+ }
+ code.addLine("");
+
+ // Commutativity rule strings
+ code.addLine(ShortComment("Commutativity rule strings"));
+ for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.Commutativity + i)));
+ }
+ code.addLine("");
+
+ // Ordering points label strings
+ code.addLine(ShortComment("Ordering points label strings"));
+ for (String label : OPLabelSet) {
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(label)));
+ }
+ code.addLine("");
+
+ // Special function name strings
+ code.addLine(ShortComment("Special function name strings"));
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.InitalState)));
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.CopyState)));
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.FinalState)));
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.PrintState)));
+ code.addLine("");
+
+ // Interface name strings
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ String name = construct.getName();
+ code.addLine(ShortComment(name + " function strings"));
+ // Transition
+ String tmpFunc = name + "_" + SpecNaming.Transition;
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc)));
+ // PreCondition
+ tmpFunc = name + "_" + SpecNaming.PreCondition;
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc)));
+ // SideEffect
+ tmpFunc = name + "_" + SpecNaming.SideEffect;
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc)));
+ // PostCondition
+ tmpFunc = name + "_" + SpecNaming.PostCondition;
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc)));
+ // Print
+ tmpFunc = name + "_" + SpecNaming.PrintValue;
+ code.addLine(Declare("extern " + SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc)));
+ code.addLine("");
+ }
+ }
+
+ // Declare customized StateStruct
+ code.addLine(ShortComment("Declare customized StateStruct"));
+ code.addLine("typedef struct " + SpecNaming.StateStruct + " {");
+ for (VariableDeclaration decl : globalConstruct.declState) {
+ code.addLine(TabbedLine(Declare(decl)));
+ }
+ code.addLine("");
+ code.addLine(TabbedLine("SNAPSHOTALLOC"));
+ code.addLine("} " + SpecNaming.StateStruct + ";");
+ code.addLine("");
+
+ // Declare customized value struct
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ // Declare custom value struct for the interface
+ String name = construct.getName();
+ code.addLine(ShortComment("Declare custom value struct for "
+ + name));
+ code.addLine("typedef struct " + name + " {");
+ FunctionHeader funcHeader = construct.getFunctionHeader();
+ // RET
+ if (!funcHeader.returnType.equals("void"))
+ code.addLine(TabbedLine(Declare(funcHeader.returnType,
+ SpecNaming.RET)));
+ // Arguments
+ for (VariableDeclaration decl : funcHeader.args) {
+ code.addLine(TabbedLine(Declare(decl)));
+ }
+ code.addLine("} " + name + ";");
+ code.addLine("");
+ }
+ }
+
+ // Declare @Initial
+ code.addLine(ShortComment("Declare @" + SpecNaming.InitalState));
+ code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
+ + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
+ code.addLine("");
+ // Declare @Copy
+ code.addLine(ShortComment("Declare @" + SpecNaming.CopyState));
+ code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
+ + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
+ + " src);");
+ code.addLine("");
+ // Declare @Print
+ code.addLine(ShortComment("Declare @" + SpecNaming.PrintState));
+ if (!globalConstruct.printState.isEmpty()) {
+ code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
+ + SpecNaming.Method + " " + SpecNaming.Method1 + ");");
+ code.addLine("");
+ }
+
+ // Declare @Commutativity
+ code.addLine(ShortComment("Declare commutativity checking functions"));
+ for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
+ code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
+ + SpecNaming.Method + " m1, " + SpecNaming.Method + " m2);");
+ }
+ code.addLine("");
+
+ // Declare customized interface functions
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ // Declare interface functions
+ String name = construct.getName();
+ code.addLine("/********** " + name
+ + " functions **********/");
+ // Declare @Transition for INTERFACE
+ code.addLine(ShortComment("Declare @" + SpecNaming.Transition
+ + " for " + name));
+ code.addLine("void _" + name + "_" + SpecNaming.Transition
+ + "(" + SpecNaming.Method + " " + SpecNaming.Method1
+ + ", " + SpecNaming.Method + " " + SpecNaming.Method2
+ + ");");
+ code.addLine("");
+ // Declare @PreCondition
+ if (!construct.preCondition.isEmpty()) {
+ code.addLine(ShortComment("Declare @"
+ + SpecNaming.PreCondition + " for " + name));
+ code.addLine("bool _" + name + "_"
+ + SpecNaming.PreCondition + "(" + SpecNaming.Method
+ + " " + SpecNaming.Method1 + ");");
+ code.addLine("");
+ }
+ // Declare @SideEffect
+ if (!construct.sideEffect.isEmpty()) {
+ code.addLine(ShortComment("Declare @"
+ + SpecNaming.SideEffect + " for " + name));
+ code.addLine("void _" + name + "_" + SpecNaming.SideEffect
+ + "(" + SpecNaming.Method + " "
+ + SpecNaming.Method1 + ");");
+ code.addLine("");
+ }
+ // Declare @PostCondition
+ if (!construct.postCondition.isEmpty()) {
+ code.addLine(ShortComment("Declare @"
+ + SpecNaming.PostCondition + " for " + name));
+ code.addLine("bool _" + name + "_"
+ + SpecNaming.PostCondition + "("
+ + SpecNaming.Method + " " + SpecNaming.Method1
+ + ");");
+ code.addLine("");
+ }
+ // Declare @Print
+ if (!construct.print.isEmpty()) {
+ code.addLine(ShortComment("Declare @"
+ + SpecNaming.PrintValue + " for " + name));
+ code.addLine("void _" + name + "_" + SpecNaming.PrintValue
+ + "(" + SpecNaming.Method + " "
+ + SpecNaming.Method1 + ");");
+ code.addLine("");
+ }
+ }
+ }
+
+ // Declare INIT annotation instrumentation function
+ code.addLine(ShortComment("Declare INIT annotation instrumentation function"));
+ code.addLine("void _createInitAnnotation();");
+ code.addLine("");
+ code.addLine("#endif");
+
+ return code;
+ }
+
+ /**
+ * <p>
+ * This function generates the code for the CPP file that our specification
+ * generates automatically --- cdsspec-generated.cc.
+ * </p>
+ *
+ * @param extractor
+ * The SpecExtractor that contains the extracted information
+ * @return The generated code
+ */
+ public static Code GenerateCDSSpecCPPFile(SpecExtractor extractor) {
+ GlobalConstruct globalConstruct = extractor.getGlobalConstruct();
+ HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap = extractor.interfaceListMap;
+ HashSet<String> OPLabelSet = extractor.OPLabelSet;
+
+ Code code = new Code();
+ String line = null;
+
+ // Add auto-generated comments
+ code.addLine("/**");
+ code.addLine(TabbedLine("This is an implementation file auto-generated by CDSSpec compiler to"));
+ code.addLine(TabbedLine("instrument your benchmark for CDSSpec checker to check. Currently we require"));
+ code.addLine(TabbedLine("a C++ compiler that supports C++11."));
+ code.addLine("*/");
+ code.addLine("");
+
+ code.addLine("#include " + SpecNaming.CDSSpecGeneratedHeader);
+ code.addLine("");
+ code.addLine("");
+
+ code.addLine(ShortComment("Definition of some c-strings (CSTR)"));
+ code.addLine(ShortComment("A special empty string"));
+ code.addLine(DeclareDefine(SpecNaming.CString, SpecNaming.EmptyCString,
+ "\"\""));
+ code.addLine("");
+
+ // Interface name strings
+ code.addLine(ShortComment("Interface name strings"));
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ String name = construct.getName();
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(name), Quote(name)));
+ }
+ }
+ code.addLine("");
+
+ // Commutativity rule strings
+ code.addLine(ShortComment("Commutativity rule strings"));
+ for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
+ CommutativityRule rule = globalConstruct.commutativityRules
+ .get(i - 1);
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.Commutativity + i),
+ Quote(rule.toString())));
+ }
+ code.addLine("");
+
+ // Ordering points label strings
+ code.addLine(ShortComment("Ordering points label strings"));
+ for (String label : OPLabelSet) {
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(label), Quote(label)));
+ }
+ code.addLine("");
+
+ // Special function name strings
+ code.addLine(ShortComment("Special function name strings"));
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.InitalState), Quote("_"
+ + SpecNaming.InitalState.toLowerCase())));
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.CopyState), Quote("_"
+ + SpecNaming.CopyState.toLowerCase())));
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.FinalState), Quote("_"
+ + SpecNaming.FinalState.toLowerCase())));
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(SpecNaming.PrintState), Quote("_"
+ + SpecNaming.PrintState.toLowerCase())));
+ code.addLine("");
+
+ // Interface name strings
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ String name = construct.getName();
+ code.addLine(ShortComment(name + " function strings"));
+ // Transition
+ String tmpFunc = name + "_" + SpecNaming.Transition;
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
+ // PreCondition
+ tmpFunc = name + "_" + SpecNaming.PreCondition;
+ if (!construct.preCondition.isEmpty())
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
+ else
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc),
+ SpecNaming.EmptyCString));
+ // SideEffect
+ tmpFunc = name + "_" + SpecNaming.SideEffect;
+ if (!construct.sideEffect.isEmpty())
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
+ else
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc),
+ SpecNaming.EmptyCString));
+ // PostCondition
+ tmpFunc = name + "_" + SpecNaming.PostCondition;
+ if (!construct.postCondition.isEmpty())
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
+ else
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc),
+ SpecNaming.EmptyCString));
+ // Print
+ tmpFunc = name + "_" + SpecNaming.PrintValue;
+ if (!construct.print.isEmpty())
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc), Quote("_" + tmpFunc)));
+ else
+ code.addLine(DeclareDefine(SpecNaming.CString,
+ SpecNaming.AppendStr(tmpFunc),
+ SpecNaming.EmptyCString));
+ code.addLine("");
+ }
+ }
+
+ // Define @Initial
+ code.addLine(ShortComment("Define @" + SpecNaming.InitalState));
+ code.addLine("void _" + SpecNaming.InitalState.toLowerCase() + "("
+ + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
+ code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
+ + SpecNaming.StateInst, "new " + SpecNaming.StateStruct)));
+ // Define macros
+ for (VariableDeclaration decl : globalConstruct.declState) {
+ code.addLine(TabbedLine("#define " + decl.name + " "
+ + SpecNaming.StateInst + "->" + decl.name));
+ }
+ code.addLine(TabbedLine(ShortComment("User-defined intial state code")));
+ // Align the code with one tab
+ globalConstruct.initState.align(1);
+ code.addLines(globalConstruct.initState);
+ // Undefine macros
+ for (VariableDeclaration decl : globalConstruct.declState) {
+ code.addLine(TabbedLine("#undef " + decl.name));
+ }
+ code.addLine("");
+ code.addLine(TabbedLine(AssignToPtr(SpecNaming.Method1,
+ SpecNaming.StateInst, SpecNaming.StateInst)));
+ code.addLine("}");
+ code.addLine("");
+
+ // Define @Copy
+ code.addLine(ShortComment("Define @" + SpecNaming.CopyState));
+ code.addLine("void _" + SpecNaming.CopyState.toLowerCase() + "("
+ + SpecNaming.Method + " " + "dest, " + SpecNaming.Method
+ + " src) {");
+ // StateStruct *OLD = (StateStruct*) src->state;
+ code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
+ + SpecNaming.OldStateInst, Brace(SpecNaming.StateStruct + "*")
+ + " src->" + SpecNaming.StateInst)));
+ // StateStruct *NEW = new StateStruct;
+ code.addLine(TabbedLine(DeclareDefine(SpecNaming.StateStruct, "*"
+ + SpecNaming.NewStateInst, "new " + SpecNaming.StateStruct)));
+ if (!globalConstruct.autoGenCopy)
+ code.addLine(TabbedLine(ShortComment("User-defined state copy statements")));
+ else
+ // Auto-generated the copy function
+ code.addLine(TabbedLine(ShortComment("Auto-generated state copy statements")));
+ globalConstruct.copyState.align(1);
+ code.addLines(globalConstruct.copyState);
+ code.addLine("");
+ code.addLine(TabbedLine(AssignToPtr("dest", SpecNaming.StateInst,
+ SpecNaming.NewStateInst)));
+ code.addLine("}");
+ code.addLine("");
+
+ // Define @Print
+ if (!globalConstruct.printState.isEmpty()) {
+ code.addLine(ShortComment("Define @" + SpecNaming.PrintState));
+ code.addLine("void _" + SpecNaming.PrintState.toLowerCase() + "("
+ + SpecNaming.Method + " " + SpecNaming.Method1 + ") {");
+
+ // Initialize state struct fields
+ Code fieldsInit = GenerateStateFieldsInitialization(
+ SpecNaming.Method1, SpecNaming.StateInst, globalConstruct);
+ fieldsInit.align(1);
+ code.addLines(fieldsInit);
+ code.addLine("");
+ code.addLine(TabbedLine(ShortComment("Execute the print-out")));
+ // Align the code with one tab
+ globalConstruct.printState.align(1);
+ code.addLines(globalConstruct.printState);
+ code.addLine("}");
+ code.addLine("");
+ }
+
+ // Define @Commutativity
+ code.addLine(ShortComment("Define commutativity checking functions"));
+ for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
+ CommutativityRule rule = globalConstruct.commutativityRules
+ .get(i - 1);
+ code.addLine("bool _check" + SpecNaming.Commutativity + i + "("
+ + SpecNaming.Method + " m1, " + SpecNaming.Method
+ + " m2) {");
+ // if (m1->name == _ENQ_str && m2->name == _DEQ_str) {
+ code.addLine(TabbedLine("if (m1->name == "
+ + SpecNaming.AppendStr(rule.method1) + " && m2->name == "
+ + SpecNaming.AppendStr(rule.method2) + ") {"));
+ // Initialize M1 & M2 in commutativity rule
+ // e.g. ENQ *M1 = (ENQ*) m1->value;
+ code.addLine(TabbedLine(
+ DeclareDefine(rule.method1, "*M1", "(" + rule.method1
+ + "*) m1->value"), 2));
+ code.addLine(TabbedLine(
+ DeclareDefine(rule.method2, "*M2", "(" + rule.method2
+ + "*) m2->value"), 2));
+ code.addLine(TabbedLine("return " + rule.condition + ";", 2));
+ code.addLine(TabbedLine("}"));
+ code.addLine(TabbedLine("return false;"));
+
+ code.addLine("}");
+ code.addLine("");
+ }
+
+ // Define customized interface functions
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ Code fieldsInit = null;
+
+ // Define interface functions
+ String name = construct.getName();
+ code.addLine("/********** " + name
+ + " functions **********/");
+ // Define @Transition for INTERFACE
+ code.addLine(ShortComment("Define @" + SpecNaming.Transition
+ + " for " + name));
+ code.addLine("void _" + name + "_" + SpecNaming.Transition
+ + "(" + SpecNaming.Method + " " + SpecNaming.Method1
+ + ", " + SpecNaming.Method + " " + SpecNaming.Method2
+ + ") {");
+
+ // Initialize value struct fields
+ fieldsInit = GenerateInterfaceFieldsInitialization(
+ SpecNaming.Method2, "value", construct);
+ fieldsInit.align(1);
+ code.addLines(fieldsInit);
+
+ construct.transition.align(1);
+ code.addLine(TabbedLine(ShortComment("Execute Transition")));
+ code.addLines(construct.transition);
+
+ code.addLine("}");
+ code.addLine("");
+
+ // Define @PreCondition
+ if (!construct.preCondition.isEmpty()) {
+ code.addLine(ShortComment("Define @"
+ + SpecNaming.PreCondition + " for " + name));
+ code.addLine("bool _" + name + "_"
+ + SpecNaming.PreCondition + "(" + SpecNaming.Method
+ + " " + SpecNaming.Method1 + ") {");
+
+ // Initialize value struct fields
+ fieldsInit = GenerateInterfaceFieldsInitialization(
+ SpecNaming.Method1, "value", construct);
+ fieldsInit.align(1);
+ code.addLines(fieldsInit);
+
+ construct.preCondition.align(1);
+ code.addLine(TabbedLine(ShortComment("Execute PreCondition")));
+ code.addLines(construct.preCondition);
+
+ code.addLine("}");
+ code.addLine("");
+
+ }
+ // Define @SideEffect
+ if (!construct.sideEffect.isEmpty()) {
+ code.addLine(ShortComment("Define @"
+ + SpecNaming.SideEffect + " for " + name));
+ code.addLine("void _" + name + "_" + SpecNaming.SideEffect
+ + "(" + SpecNaming.Method + " "
+ + SpecNaming.Method1 + ") {");
+
+ // Initialize value struct fields
+ fieldsInit = GenerateInterfaceFieldsInitialization(
+ SpecNaming.Method1, "value", construct);
+ fieldsInit.align(1);
+ code.addLines(fieldsInit);
+
+ construct.sideEffect.align(1);
+ code.addLine(TabbedLine(ShortComment("Execute SideEffect")));
+ code.addLines(construct.sideEffect);
+
+ code.addLine("}");
+ code.addLine("");
+ }
+ // Define @PostCondition
+ if (!construct.postCondition.isEmpty()) {
+ code.addLine(ShortComment("Define @"
+ + SpecNaming.PostCondition + " for " + name));
+ code.addLine("bool _" + name + "_"
+ + SpecNaming.PostCondition + "("
+ + SpecNaming.Method + " " + SpecNaming.Method1
+ + ") {");
+
+ // Initialize value struct fields
+ fieldsInit = GenerateInterfaceFieldsInitialization(
+ SpecNaming.Method1, "value", construct);
+ fieldsInit.align(1);
+ code.addLines(fieldsInit);
+
+ construct.postCondition.align(1);
+ code.addLine(TabbedLine(ShortComment("Execute PostCondition")));
+ code.addLines(construct.postCondition);
+
+ code.addLine("}");
+ code.addLine("");
+ }
+ // Define @Print
+ if (!construct.print.isEmpty()) {
+ code.addLine(ShortComment("Define @"
+ + SpecNaming.PrintValue + " for " + name));
+ code.addLine("void _" + name + "_" + SpecNaming.PrintValue
+ + "(" + SpecNaming.Method + " "
+ + SpecNaming.Method1 + ") {");
+ // Initialize value struct fields
+ fieldsInit = GenerateInterfaceFieldsInitialization(
+ SpecNaming.Method1, "value", construct);
+ fieldsInit.align(1);
+ code.addLines(fieldsInit);
+
+ construct.print.align(1);
+ code.addLine(TabbedLine(ShortComment("Execute Print")));
+ code.addLines(construct.print);
+
+ code.addLine("}");
+ code.addLine("");
+ }
+ }
+ }
+
+ // Define INIT annotation instrumentation function
+ code.addLine(ShortComment("Define INIT annotation instrumentation function"));
+ code.addLine("void _createInitAnnotation() {");
+
+ // Init commutativity rules
+ code.addLine(TabbedLine(ShortComment("Init commutativity rules")));
+ code.addLine(TabbedLine(DeclareDefine("int",
+ SpecNaming.CommutativityRuleSizeInst,
+ Integer.toString(globalConstruct.commutativityRules.size()))));
+ String tmp = SpecNaming.NewSize
+ + Brace(SpecNaming.CommutativityRule + ", sizeof"
+ + Brace(SpecNaming.CommutativityRule) + " * "
+ + SpecNaming.CommutativityRuleSizeInst);
+ code.addLine(TabbedLine(DeclareDefine(SpecNaming.CommutativityRule, "*"
+ + SpecNaming.CommutativityRuleInst, tmp)));
+ for (int i = 1; i <= globalConstruct.commutativityRules.size(); i++) {
+ CommutativityRule rule = globalConstruct.commutativityRules
+ .get(i - 1);
+ code.addLine(TabbedLine(ShortComment("Initialize commutativity rule ")
+ + i));
+ // new( &commuteRules[0] )CommutativityRule(_ENQ_str, _DEQ_str,
+ // _Commutativity1_str, _checkCommutativity1)
+ line = "new"
+ + Brace(" &" + SpecNaming.CommutativityRuleInst + "["
+ + (i - 1) + "] ") + SpecNaming.CommutativityRule
+ + "(" + SpecNaming.AppendStr(rule.method1) + ", "
+ + SpecNaming.AppendStr(rule.method2) + ", "
+ + SpecNaming.AppendStr(SpecNaming.Commutativity + i) + ", "
+ + "_check" + SpecNaming.Commutativity + i + ");";
+ code.addLine(TabbedLine(line));
+ }
+
+ // Initialize AnnoInit
+ code.addLine(TabbedLine(ShortComment("Initialize AnnoInit")));
+ // AnnoInit *init = new AnnoInit(
+ code.addLine(TabbedLine(SpecNaming.AnnoInit + " *"
+ + SpecNaming.AnnoInitInst + " = new " + SpecNaming.AnnoInit
+ + "("));
+ // new NamedFunction(_Initial_str, INITIAL, (void*) _initial),
+ code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
+ + SpecNaming.AppendStr(SpecNaming.InitalState) + ", "
+ + SpecNaming.InitalState.toUpperCase() + ", " + "(void*) _"
+ + SpecNaming.InitalState.toLowerCase() + "),", 2));
+ // new NamedFunction(_Final_str, FINAL, (void*) NULL_FUNC),
+ line = "new " + SpecNaming.NamedFunction + "("
+ + SpecNaming.AppendStr(SpecNaming.FinalState) + ", "
+ + SpecNaming.FinalState.toUpperCase() + ", " + "(void*) ";
+ if (globalConstruct.finalState.isEmpty()) {
+ line = line + SpecNaming.NullFunc + "),";
+ } else {
+ line = line + "_" + SpecNaming.FinalState.toUpperCase();
+ }
+ code.addLine(TabbedLine(line, 2));
+ // new NamedFunction(_Copy_str, COPY, (void*) _copy),
+ code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
+ + SpecNaming.AppendStr(SpecNaming.CopyState) + ", "
+ + SpecNaming.CopyState.toUpperCase() + ", " + "(void*) _"
+ + SpecNaming.CopyState.toLowerCase() + "),", 2));
+ // new NamedFunction(_Print_str, PRINT_STATE, (void*) _print),
+ code.addLine(TabbedLine("new " + SpecNaming.NamedFunction + "("
+ + SpecNaming.AppendStr(SpecNaming.PrintState) + ", "
+ + SpecNaming.PrintStateType + ", " + "(void*) _"
+ + SpecNaming.PrintState.toLowerCase() + "),", 2));
+ // commuteRules, CommuteRuleSize);
+ code.addLine(TabbedLine(SpecNaming.CommutativityRuleInst + ", "
+ + SpecNaming.CommutativityRuleSizeInst + ");", 2));
+ code.addLine("");
+
+ // Declare StateFunctions map
+ code.addLine(TabbedLine(ShortComment("Declare StateFunctions map")));
+ code.addLine(TabbedLine(Declare(SpecNaming.StateFunctions, "*"
+ + SpecNaming.StateFunctionsInst)));
+ code.addLine("");
+
+ // StateFunction for interface
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ for (InterfaceConstruct construct : list) {
+ String name = construct.getName();
+ code.addLine(TabbedLine(ShortComment("StateFunction for "
+ + name)));
+ // stateFuncs = new StateFunctions(
+ code.addLine(TabbedLine(SpecNaming.StateFunctionsInst
+ + " = new " + SpecNaming.StateFunctions + "("));
+ // new NamedFunction(_ENQ_Transition_str, TRANSITION, (void*)
+ // _ENQ_Transition),
+ // Transition
+ code.addLine(TabbedLine(
+ "new "
+ + SpecNaming.NamedFunction
+ + "("
+ + SpecNaming.AppendStr(name + "_"
+ + SpecNaming.Transition) + ", "
+ + SpecNaming.TransitionType + ", (void*) _"
+ + name + "_" + SpecNaming.Transition + "),", 2));
+ // PreCondition
+ line = "new "
+ + SpecNaming.NamedFunction
+ + "("
+ + SpecNaming.AppendStr(name + "_"
+ + SpecNaming.PreCondition) + ", "
+ + SpecNaming.PreConditionType + ", (void*) ";
+ if (construct.preCondition.isEmpty()) {
+ line = line + SpecNaming.NullFunc + "),";
+ } else {
+ line = line + "_" + name + "_" + SpecNaming.PreCondition
+ + "),";
+ }
+ code.addLine(TabbedLine(line, 2));
+ // SideEffect
+ line = "new "
+ + SpecNaming.NamedFunction
+ + "("
+ + SpecNaming.AppendStr(name + "_"
+ + SpecNaming.SideEffect) + ", "
+ + SpecNaming.SideEffectType + ", (void*) ";
+ if (construct.sideEffect.isEmpty()) {
+ line = line + SpecNaming.NullFunc + "),";
+ } else {
+ line = line + "_" + name + "_" + SpecNaming.SideEffect
+ + "),";
+ }
+ code.addLine(TabbedLine(line, 2));
+ // PostCondition
+ line = "new "
+ + SpecNaming.NamedFunction
+ + "("
+ + SpecNaming.AppendStr(name + "_"
+ + SpecNaming.PostCondition) + ", "
+ + SpecNaming.PostConditionType + ", (void*) ";
+ if (construct.postCondition.isEmpty()) {
+ line = line + SpecNaming.NullFunc + "),";
+ } else {
+ line = line + "_" + name + "_" + SpecNaming.PostCondition
+ + "),";
+ }
+ code.addLine(TabbedLine(line, 2));
+ // Print (PrintValue
+ line = "new "
+ + SpecNaming.NamedFunction
+ + "("
+ + SpecNaming.AppendStr(name + "_"
+ + SpecNaming.PrintValue) + ", "
+ + SpecNaming.PrintValueType + ", (void*) ";
+ if (construct.print.isEmpty()) {
+ line = line + SpecNaming.NullFunc + "),";
+ } else {
+ line = line + "_" + name + "_" + SpecNaming.PrintValue
+ + ")";
+ }
+ code.addLine(TabbedLine(line, 2));
+ code.addLine(TabbedLine(");"));
+
+ // init->addInterfaceFunctions(_ENQ_str, stateFuncs);
+ code.addLine(TabbedLine(SpecNaming.AnnoInitInst
+ + "->"
+ + SpecNaming.AddInterfaceFunctions
+ + Brace(SpecNaming.AppendStr(name) + ", "
+ + SpecNaming.StateFunctionsInst) + ";"));
+ code.addLine("");
+ }
+ }
+
+ // Create and instrument with the INIT annotation
+ code.addLine(TabbedLine(ShortComment("Create and instrument with the INIT annotation")));
+ // cdsannotate(SPEC_ANALYSIS, new SpecAnnotation(INIT, init));
+ code.addLine(TabbedLine(SpecNaming.CDSAnnotateFunc
+ + Brace(SpecNaming.SPEC_ANALYSIS
+ + ", new "
+ + SpecNaming.SpecAnnotation
+ + Brace(SpecNaming.AnnoTypeInit + ", "
+ + SpecNaming.AnnoInitInst)) + ";"));
+
+ code.addLine("}");
+ code.addLine("");
+
+ return code;
+ }
+
+ /**
+ * <p>
+ * This function generates a list of lines that initialize the fields of the
+ * global state struct. See below.
+ * </p>
+ *
+ * <p>
+ * <code>
+ * StateStruct *state = (StateStruct*) _M->state;
+ * <br>
+ * IntList * q = state->q;
+ * </code>
+ * </p>
+ *
+ * <p>
+ * In this example, _M --> methodInst, state --> inst.
+ * </p>
+ *
+ * @param methodInst
+ * See description
+ * @param inst
+ * See description
+ * @param construct
+ * The global state construct
+ * @return The generated code
+ */
+ public static Code GenerateStateFieldsInitialization(String methodInst,
+ String inst, GlobalConstruct construct) {
+ Code res = new Code();
+ res.addLine(ShortComment("Initialize " + SpecNaming.StateStruct
+ + " fields"));
+ res.addLine(DeclareDefine(SpecNaming.StateStruct, "*" + inst, "("
+ + SpecNaming.StateStruct + "*) " + methodInst + "->state"));
+ for (VariableDeclaration decl : construct.declState) {
+ res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
+ + decl.name));
+ }
+ return res;
+ }
+
+ /**
+ * <p>
+ * This function generates a list of lines that initialize the fields of a
+ * specific interface struct. See below.
+ * </p>
+ *
+ * <p>
+ * <code>
+ * ENQ *info = (ENQ*) _M->value;
+ * <br>
+ * IntList * q = info->q;
+ * </code>
+ * </p>
+ *
+ * <p>
+ * In this example, ENQ --> structType, _M --> methodInst, info --> inst
+ * </p>
+ *
+ * @param methodInst
+ * See description
+ * @param inst
+ * See description
+ * @param construct
+ * The corresponding interface construct
+ * @return The generated code
+ */
+ public static Code GenerateInterfaceFieldsInitialization(String methodInst,
+ String inst, InterfaceConstruct construct) {
+ Code res = new Code();
+ String name = construct.getName();
+ res.addLine(ShortComment("Initialize fields for " + name));
+ // The very first assignment "
+ res.addLine(DeclareDefine(name, "*" + inst, "(" + name + "*) "
+ + methodInst + "->value"));
+ // Don't leave out the RET field
+ if (!construct.getFunctionHeader().isReturnVoid()) {
+ res.addLine(DeclareDefine(construct.getFunctionHeader().returnType,
+ SpecNaming.RET, "value->" + SpecNaming.RET));
+ }
+ // For arguments
+ for (VariableDeclaration decl : construct.getFunctionHeader().args) {
+ res.addLine(DeclareDefine(decl.type, decl.name, inst + "->"
+ + decl.name));
+ }
+ return res;
+ }
+
+ /**
+ * <p>
+ * This function generates the code to be inserted right after the ordering
+ * point construct (instrumentation code)
+ * </p>
+ *
+ * @param construct
+ * The corresponding ordering point construct
+ * @return The generated code
+ */
+ public static Code Generate4OPConstruct(OPConstruct construct) {
+ Code code = new Code();
+ String curLine = construct.annotation;
+ String label = construct.label;
+ String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
+ code.addLine(prefixTabs + "if (" + construct.condition + ")");
+ switch (construct.type) {
+ case OPDefine:
+ code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPDefineAnnoFunc
+ + "();");
+ break;
+ case PotentialOP:
+ code.addLine(prefixTabs + "\t"
+ + SpecNaming.CreatePotentialOPAnnoFunc + "("
+ + SpecNaming.AppendStr(label) + ");");
+ break;
+ case OPCheck:
+ code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPCheckAnnoFunc
+ + "(" + SpecNaming.AppendStr(label) + ");");
+ break;
+ case OPClear:
+ code.addLine(prefixTabs + "\t" + SpecNaming.CreateOPClearAnnoFunc
+ + "();");
+ break;
+ case OPClearDefine:
+ code.addLine(prefixTabs + "\t"
+ + SpecNaming.CreateOPClearDefineAnnoFunc + "();");
+ break;
+ default:
+ break;
+ }
+ return code;
+ }
+
+ /**
+ * <p>
+ * This function generates the code to be inserted right after the entry
+ * construct (instrumentation code)
+ * </p>
+ *
+ * @param construct
+ * The corresponding entry construct
+ * @return
+ */
+ public static Code Generate4Entry(EntryConstruct construct) {
+ Code res = new Code();
+ String curLine = construct.annotation;
+ String prefixTabs = curLine.substring(0, curLine.indexOf("/**"));
+ // _createInitAnnotation();
+ res.addLine(prefixTabs + SpecNaming.CreateInitAnnoFunc + "();");
+ return res;
+ }
+
+ /**
+ * <p>
+ * This function generates the new interface wrapper code to be inserted
+ * right after the end of the interface definition
+ * </p>
+ *
+ * @param construct
+ * The corresponding interface construct
+ * @return The generated code
+ */
+ public static Code GenerateInterfaceWrapper(InterfaceConstruct construct) {
+ Code code = new Code();
+
+ String name = construct.getName();
+ String beginLine = construct.getFunctionHeader().getHeaderLine();
+ Pattern regexpSpace = Pattern.compile("^(\\s*)\\S.*$");
+ Matcher matcherSpace = regexpSpace.matcher(beginLine);
+ String prefixTabs = "";
+ if (matcherSpace.find())
+ prefixTabs = matcherSpace.group(1);
+
+ // Add one line to separate
+ code.addLine("");
+ code.addLine(prefixTabs
+ + ShortComment("Generated wrapper interface for " + name));
+ if (beginLine.indexOf('{') == -1) { // We need to add the '{' to the end
+ // of the line
+ code.addLine(beginLine + " {");
+ } else {
+ code.addLine(beginLine);
+ }
+ // Instrument with the INTERFACE_BEGIN annotation
+ code.addLine(prefixTabs
+ + "\t"
+ + ShortComment("Instrument with the INTERFACE_BEGIN annotation"));
+ // AnnoInterfaceInfo *info = _createInterfaceBeginAnnotation(_DEQ_str);
+ code.addLine(prefixTabs
+ + "\t"
+ + DeclareDefine(SpecNaming.AnnoInterfaceInfo, "*"
+ + SpecNaming.AnnoInterfaceInfoInst,
+ SpecNaming.CreateInterfaceBeginAnnoFunc
+ + Brace(SpecNaming.AppendStr(name))));
+ // Call the actual function
+ code.addLine(prefixTabs + "\t"
+ + ShortComment("Call the actual function"));
+ // bool RET = dequeue_ORIGINAL__(q, retVal, reclaimNode);
+ code.addLine(prefixTabs + "\t"
+ + construct.getFunctionHeader().getRenamedCall() + ";");
+ code.addLine("");
+
+ // Initialize the value struct
+ code.addLine(prefixTabs + "\t"
+ + ShortComment("Initialize the value struct"));
+ // The very first assignment "
+ code.addLine(prefixTabs + "\t"
+ + DeclareDefine(name, "*value", "new " + name));
+ // Don't leave out the RET field
+ if (!construct.getFunctionHeader().isReturnVoid())
+ code.addLine(prefixTabs + "\t"
+ + AssignToPtr("value", SpecNaming.RET, SpecNaming.RET));
+ // For arguments
+ for (VariableDeclaration decl : construct.getFunctionHeader().args)
+ code.addLine(prefixTabs + "\t"
+ + AssignToPtr("value", decl.name, decl.name));
+ code.addLine("");
+
+ // Store the value info into the current MethodCall
+ code.addLine(prefixTabs
+ + "\t"
+ + ShortComment("Store the value info into the current MethodCall"));
+ code.addLine(prefixTabs
+ + "\t"
+ + AssignToPtr(SpecNaming.AnnoInterfaceInfoInst, "value",
+ "value"));
+ code.addLine("");
+
+ // Return if necessary
+ if (!construct.getFunctionHeader().isReturnVoid())
+ code.addLine(prefixTabs + "\treturn " + SpecNaming.RET + ";");
+ code.addLine(prefixTabs + "}");
+
+ return code;
+ }
+
+ /**
+ * <p>
+ * Write a list of lines (as the whole of the file) to a file ---
+ * newFileName. If that file does not exist, we create that file and then
+ * write the lines.
+ * </p>
+ *
+ * @param newFileName
+ * The name of the file to be written
+ * @param content
+ * The list of lines that as a whole become the content of the
+ * file
+ */
+ public static void write2File(String newFileName, ArrayList<String> content) {
+ File newFile = new File(newFileName);
+ newFile.getParentFile().mkdirs();
+ if (!newFile.exists()) {
+ try {
+ newFile.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ BufferedWriter bw = null;
+ try {
+ bw = new BufferedWriter(new FileWriter(newFile));
+ for (int i = 0; i < content.size(); i++) {
+ bw.write(content.get(i) + "\n");
+ }
+ bw.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (bw != null)
+ try {
+ bw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
--- /dev/null
+package edu.uci.eecs.codeGenerator;
+
+/**
+ * <p>
+ * This class contains some constant strings related to the code generation
+ * process.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class Environment {
+ public final static String HomeDir = System.getProperty("user.dir");
+ public final static String ModelCheckerHome = System
+ .getProperty("user.home")
+ + "/model-checker-priv/model-checker-priv/";
+ public final static String BenchmarksDir = ModelCheckerHome
+ + "/benchmarks/";
+ public final static String ModelCheckerTestDir = ModelCheckerHome
+ + "/test-cdsspec/";
+ public final static String GeneratedFilesDir = ModelCheckerTestDir;
+
+ public final static String REGISTER = "register";
+ public final static String MS_QUEUE = "ms-queue";
+ public final static String LINUXRWLOCKS = "linuxrwlocks";
+
+}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-
-import com.sun.xml.internal.ws.wsdl.parser.ParserUtil;
-
-import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
-
-public class CodeAddition {
- public static Comparator<CodeAddition> lineNumComparator = new Comparator<CodeAddition>() {
- public int compare(CodeAddition addition1, CodeAddition addition2) {
- return addition1.lineNum - addition2.lineNum;
- }
- };
-
- public final int lineNum;
- public final ArrayList<String> newCode;
-
- public CodeAddition(int lineNum, ArrayList<String> newCode) {
- this.lineNum = lineNum;
- this.newCode = newCode;
- }
-
- public String toString() {
- return "Line: " + lineNum + "\n" + ParserUtils.array2Str(newCode);
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-
-import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
-import edu.uci.eecs.specCompiler.specExtraction.Construct;
-import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
-import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.IDExtractor;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
-import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
-import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
-
-/**
- * <p>
- * This class will generate the annotated C code that can run on the current
- * model checker.
- * </p>
- *
- * @author peizhaoo
- *
- */
-public class CodeGenerator {
- private SemanticsChecker _semantics;
- private SpecExtractor _extractor;
-
- private File[] srcFiles;
-
- private HashMap<File, SourceFileInfo> srcFilesInfo;
-
- private HashMap<File, ArrayList<CodeAddition>> codeAdditions;
- private String homeDir;
-
- public CodeGenerator(File[] srcFiles) {
- this.srcFiles = srcFiles;
- _extractor = new SpecExtractor();
- _extractor.extract(srcFiles);
-
- this.srcFilesInfo = _extractor.srcFilesInfo;
-
- this.codeAdditions = new HashMap<File, ArrayList<CodeAddition>>();
-
- _semantics = new SemanticsChecker(_extractor);
- try {
- _semantics.check();
- System.out.println(_semantics);
- } catch (SemanticsCheckerException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * <p>
- * Generate all the global code, including the "@DefineVar" in each
- * "@Interface" define
- * </p>
- */
- private void globalConstruct2Code(GlobalConstruct construct) {
- ArrayList<String> newCode = CodeVariables.generateGlobalVarDeclaration(
- _semantics, construct);
- // Add it to the codeAdditions
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
- }
- CodeAddition addition = new CodeAddition(construct.beginLineNum,
- newCode);
- codeAdditions.get(construct.file).add(addition);
- newCode = CodeVariables.generateStaticVarDefine(_semantics, construct);
- if (newCode.size() > 0) {
- addition = new CodeAddition(
- _semantics.getClassEndConstruct().beginLineNum, newCode);
- codeAdditions.get(construct.file).add(addition);
- }
- }
-
- // Wrap the interface and then renaem it
- private void interface2Code(InterfaceConstruct construct) {
- // If there's no define construct for it, we generate the wrapper just
- // in place without declaration
- InterfaceDefineConstruct defineConstruct = _semantics.interfaceName2DefineConstruct
- .get(construct.name);
- ArrayList<String> newCode;
- int lineNum;
- CodeAddition addition;
- // Then generate the wrapper if necessary
- if (defineConstruct != null) { // Need to have a wrapper declaration
- newCode = CodeVariables.generateInterfaceWrapperDeclaration(
- _semantics, construct);
- lineNum = construct.beginLineNum;
- // Add the wrapper declaration
- addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions
- .put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
-
- // Add the wrapper definition
- newCode = CodeVariables.generateInterfaceWrapperDefinition(
- _semantics, construct);
- lineNum = defineConstruct.beginLineNum;
- // Add the wrapper declaration
- addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(defineConstruct.file)) {
- codeAdditions.put(defineConstruct.file,
- new ArrayList<CodeAddition>());
- }
- codeAdditions.get(defineConstruct.file).add(addition);
- } else { // No declaration needed but should add forward declaration in
- // Class
- // Last generate the definition
- newCode = new ArrayList<String>();
- if (_semantics.getOption("CLASS") == null) {
- newCode.addAll(CodeVariables
- .generateInterfaceWrapperDeclaration(_semantics,
- construct));
- }
- newCode.addAll(CodeVariables.generateInterfaceWrapperDefinition(
- _semantics, construct));
- lineNum = construct.beginLineNum;
- // Add the wrapper declaration
- addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions
- .put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
- }
-
- // Don't forget to rename the interface
- CodeVariables.renameInterface(_semantics, construct);
- }
-
- private void potentialCPDefine2Code(PotentialCPDefineConstruct construct) {
- int lineNum = construct.beginLineNum;
- ArrayList<String> newCode = CodeVariables.generatePotentialCPDefine(
- _semantics, construct);
-
- CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
- }
-
- private void CPDefine2Code(CPDefineConstruct construct) {
- int lineNum = construct.beginLineNum;
- ArrayList<String> newCode = CodeVariables.generateCPDefine(_semantics,
- construct);
-
- CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
- }
-
- private void CPDefineCheck2Code(CPDefineCheckConstruct construct) {
- int lineNum = construct.beginLineNum;
- ArrayList<String> newCode = CodeVariables.generateCPDefineCheck(
- _semantics, construct);
-
- CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
- }
-
- private void CPClear2Code(CPClearConstruct construct) {
- int lineNum = construct.beginLineNum;
- ArrayList<String> newCode = CodeVariables.generateCPClear(
- _semantics, construct);
-
- CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
- }
-
-
- /**
- * private void ClassEnd2Code(ClassEndConstruct construct) { int lineNum =
- * construct.beginLineNum; ArrayList<String> newCode =
- * CodeVariables.generateStaticVarDefine(_semantics,
- * _semantics.getGlobalConstruct());
- *
- * CodeAddition addition = new CodeAddition(lineNum, newCode); if
- * (!codeAdditions.containsKey(construct.file)) {
- * codeAdditions.put(construct.file, new ArrayList<CodeAddition>()); }
- * codeAdditions.get(construct.file).add(addition); }
- */
-
- private void EntryPoint2Code(EntryPointConstruct construct) {
- int lineNum = construct.beginLineNum;
- ArrayList<String> newCode = new ArrayList<String>();
- newCode.addAll(CodeVariables.generateEntryPointInitCall());
-
- CodeAddition addition = new CodeAddition(lineNum, newCode);
- if (!codeAdditions.containsKey(construct.file)) {
- codeAdditions.put(construct.file, new ArrayList<CodeAddition>());
- }
- codeAdditions.get(construct.file).add(addition);
- }
-
- private ArrayList<String> insertAnnotation2Src(
- ArrayList<CodeAddition> additions, ArrayList<String> content) {
- int totalSize = content.size();
- for (int i = 0; i < additions.size(); i++) {
- totalSize += additions.size();
- }
- ArrayList<String> newContent = new ArrayList<String>(totalSize);
- int curSrcLine = 0;
- for (int i = 0; i < additions.size(); i++) {
- CodeAddition addition = additions.get(i);
- if (curSrcLine < addition.lineNum) {
- // Be careful, subList is the interval [begin, end)
- newContent
- .addAll(content.subList(curSrcLine, addition.lineNum));
- curSrcLine = addition.lineNum;
- }
- newContent.addAll(addition.newCode);
- }
- newContent.addAll(content.subList(curSrcLine, content.size()));
- return newContent;
- }
-
- public void generateCode() {
- for (int i = 0; i < _semantics.constructs.size(); i++) {
- Construct construct = _semantics.constructs.get(i);
- if (construct instanceof GlobalConstruct) {
- globalConstruct2Code((GlobalConstruct) construct);
- } else if (construct instanceof InterfaceConstruct) {
- interface2Code((InterfaceConstruct) construct);
- } else if (construct instanceof PotentialCPDefineConstruct) {
- potentialCPDefine2Code((PotentialCPDefineConstruct) construct);
- } else if (construct instanceof CPDefineConstruct) {
- CPDefine2Code((CPDefineConstruct) construct);
- } else if (construct instanceof CPDefineCheckConstruct) {
- CPDefineCheck2Code((CPDefineCheckConstruct) construct);
- } else if (construct instanceof CPClearConstruct) {
- CPClear2Code((CPClearConstruct) construct);
- } else if (construct instanceof EntryPointConstruct) {
- EntryPoint2Code((EntryPointConstruct) construct);
- }
- }
-
- // ClassEndConstruct endConstruct = _semantics.getClassEndConstruct();
- // if (endConstruct != null) {
- // ClassEnd2Code(endConstruct);
- // }
-
- // Sort code additions
- for (File file : codeAdditions.keySet()) {
- ArrayList<CodeAddition> additions = codeAdditions.get(file);
-
- if (additions.size() == 0) // Simply do nothing
- continue;
- ArrayList<String> content = _semantics.srcFilesInfo.get(file).content;
- Collections.sort(additions, CodeAddition.lineNumComparator);
- // Insert generated annotation to the source files
- ArrayList<String> newContent = insertAnnotation2Src(additions,
- content);
- // Write it back to file
- ParserUtils.write2File(file, newContent);
- }
- }
-
- public static void main(String[] argvs) {
- String homeDir = Environment.HOME_DIRECTORY;
-
- File[] srcLinuxRWLock1 = {
- new File(homeDir
- + "/benchmark/linuxrwlocks/linuxrwlocks.c") };
- File[] srcLinuxRWLock2 = {
- new File(homeDir
- + "/benchmark/linuxrwlocks/testcase1.c") };
- File[] srcLinuxRWLock3 = {
- new File(homeDir
- + "/benchmark/linuxrwlocks/testcase2.c") };
-//
- File[] srcHashtable = {
- new File(homeDir
- + "/benchmark/concurrent-hashmap/hashmap.h"),
- new File(homeDir + "/benchmark/concurrent-hashmap/testcase1.cc"),
- new File(homeDir + "/benchmark/concurrent-hashmap/main.cc")};
-
- File[] srcMSQueue = {
- new File(homeDir + "/benchmark/ms-queue/my_queue.c"),
- new File(homeDir + "/benchmark/ms-queue/testcase1.c"),
- new File(homeDir + "/benchmark/ms-queue/testcase2.c"),
- new File(homeDir + "/benchmark/ms-queue/testcase3.c"),
- new File(homeDir + "/benchmark/ms-queue/main.c"),
- new File(homeDir + "/benchmark/ms-queue/my_queue.h") };
-
- File[] srcRCU = { new File(homeDir
- + "/benchmark/read-copy-update/rcu.cc") };
-//
- File[] srcTrylock = { new File(homeDir
- + "/benchmark/trylock/trylock.c") };
-
- File[] srcSeqlock = { new File(homeDir
- + "/benchmark/seqlock/seqlock.h"),
- new File(homeDir
- + "/benchmark/seqlock/seqlock.cc")
- };
-
- File[] srcDeque = {
- new File(homeDir + "/benchmark/chase-lev-deque-bugfix/deque.c"),
- new File(homeDir + "/benchmark/chase-lev-deque-bugfix/main.c"),
- new File(homeDir + "/benchmark/chase-lev-deque-bugfix/testcase1.c"),
- new File(homeDir + "/benchmark/chase-lev-deque-bugfix/testcase2.c"),
- new File(homeDir + "/benchmark/chase-lev-deque-bugfix/deque.h") };
-//
- File[] srcMCSLock = {
- new File(homeDir + "/benchmark/mcs-lock/mcs-lock.cc"),
- new File(homeDir + "/benchmark/mcs-lock/mcs-lock.h") };
-//
- File[] srcSPSCQueue = {
- new File(homeDir + "/benchmark/spsc-bugfix/spsc-queue.cc"),
- new File(homeDir + "/benchmark/spsc-bugfix/eventcount.h"),
- new File(homeDir + "/benchmark/spsc-bugfix/queue.h") };
-
- File[] srcMPMCQueue = {
- new File(homeDir + "/benchmark/mpmc-queue/mpmc-queue.h"),
- new File(homeDir + "/benchmark/mpmc-queue/testcase1.cc"),
- new File(homeDir + "/benchmark/mpmc-queue/testcase2.cc"),
- new File(homeDir + "/benchmark/mpmc-queue/testcase3.cc"),
- new File(homeDir + "/benchmark/mpmc-queue/mpmc-queue.cc") };
-//
-// File[][] sources = {srcLinuxRWLock1 , srcMSQueue, srcRCU,
-// srcDeque, srcMCSLock, srcSPSCQueue, srcMPMCQueue, srcHashtable };
-
- File[][] sources = {srcDeque, srcLinuxRWLock1, srcLinuxRWLock2, srcLinuxRWLock3, srcMCSLock, srcHashtable, srcRCU, srcMSQueue, srcSPSCQueue, srcMPMCQueue, srcSeqlock};
-
-// File[][] sources = {srcSeqlock};
- // Compile all the benchmarks
- for (int i = 0; i < sources.length; i++) {
- CodeGenerator gen = new CodeGenerator(sources[i]);
- gen.generateCode();
- }
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.io.File;
-
-import edu.uci.eecs.specCompiler.grammerParser.utilParser.UtilParser;
-import edu.uci.eecs.specCompiler.grammerParser.utilParser.ParseException;
-import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CommutativityRule;
-import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
-import edu.uci.eecs.specCompiler.specExtraction.Construct;
-import edu.uci.eecs.specCompiler.specExtraction.FunctionHeader;
-import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.SequentialDefineSubConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.VariableDeclaration;
-
-/**
- * <p>
- * Defines a list of commonly used constant strings.
- * </p>
- *
- * @author peizhaoo
- *
- */
-public class CodeVariables {
- // C++ code or library
- public static final String HEADER_STDLIB = "<stdlib.h>";
- public static final String HEADER_THREADS = "<threads.h>";
- public static final String HEADER_STDINT = "<stdint.h>";
- public static final String HEADER_MODELMEMORY = "<model_memory.h>";
- public static final String HEADER_MODELTYPES = "<modeltypes.h>";
- public static final String ThreadIDType = "thread_id_t";
- 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_COMMON = "<common.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 CDSAnnotate = "cdsannotate";
- public static final String CDSAnnotateType = "SPEC_ANALYSIS";
- public static final String IDType = "call_id_t";
-
- public static final String SPEC_ANNO_TYPE = "spec_anno_type";
- public static final String SPEC_ANNO_TYPE_INIT = "INIT";
- public static final String SPEC_ANNO_TYPE_HB_RULE = "HB_RULE";
- public static final String SPEC_ANNO_TYPE_INTERFACE_BEGIN = "INTERFACE_BEGIN";
- 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_ANNO_TYPE_CP_DEFINE_CHECK = "CP_DEFINE_CHECK";
- public static final String SPEC_ANNO_TYPE_CP_CLEAR = "CP_CLEAR";
- public static final String SPEC_ANNO_TYPE_CP_DEFINE = "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_INIT = "anno_init";
- public static final String HB_RULE = "hb_rule";
- public static final String COMMUTATIVITY_RULE = "commutativity_rule";
- public static final String ANNO_INTERFACE_BEGIN = "anno_interface_begin";
- public static final String ANNO_INTERFACE_END = "anno_interface_end";
- public static final String ANNO_POTENTIAL_CP_DEFINE = "anno_potential_cp_define";
- public static final String ANNO_CP_DEFINE = "anno_cp_define";
- public static final String ANNO_CP_DEFINE_CHECK = "anno_cp_define_check";
- public static final String ANNO_CP_CLEAR = "anno_cp_clear";
- public static final String ANNO_HB_CONDITION = "anno_hb_condition";
-
- // Specification variables
- public static final String SPEC_INTERFACE_WRAPPER = "__wrapper_";
- public static final String DEFAULT_ID = "0";
-
- // Specification library
- public static final String HEADER_SPEC_LIB = "<spec_lib.h>";
- 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 = "spec_private_hashtable";
- 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__";
- public static final String MACRO_THREAD_ID = "__TID__";
-
- public static void printCode(ArrayList<String> code) {
- for (int i = 0; i < code.size(); i++) {
- System.out.println(code.get(i));
- }
- }
-
- private static String COMMENT(String comment) {
- return "/* " + comment + " */";
- }
-
- private static String SHORT_COMMENT(String comment) {
- return " // " + comment;
- }
-
- 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 GET_FIELD_BY_PTR(String ptr, String field) {
- return ptr + "->" + field;
- }
-
- private static String GET_FIELD(String var, String field) {
- return var + "->" + field;
- }
-
- private static String BRACE(String val) {
- return "(" + val + ")";
- }
-
- private static String ASSIGN(String structName, String field, String val) {
- return structName + "." + field + " = " + val + ";";
- }
-
- private static String ASSIGN(String varName, String val) {
- return varName + " = " + val + ";";
- }
-
- private static String ASSIGN_PTR(String structName, String field, String val) {
- return structName + "." + field + " = &" + val + ";";
- }
-
- private static String ASSIGN_TO_PTR(String structName, String field,
- String val) {
- return structName + "->" + field + " = " + val + ";";
- }
-
- private static String ASSIGN_PTR_TO_PTR(String structName, String field,
- String val) {
- return structName + "->" + field + " = &" + val + ";";
- }
-
- private static String STRUCT_NEW_DECLARE_DEFINE(String type, String name) {
- return "struct " + type + " *" + name + " = (struct " + type
- + "*) malloc(sizeof(struct " + type + "));";
- }
-
- private static String DECLARE(String type, String name) {
- return type + " " + name + ";";
- }
-
- private static String DECLARE(VariableDeclaration varDecl) {
- String type = varDecl.type, name = varDecl.name;
- return type + " " + name + ";";
- }
-
- private static String DECLARE_DEFINE(String type, String var, String val) {
- return type + " " + var + " = " + val + ";";
- }
-
- private static String ANNOTATE(SemanticsChecker semantics, String structName) {
- return CDSAnnotate + "(" + CDSAnnotateType + ", " + structName + ");";
- }
-
- private static ArrayList<String> DEFINE_INFO_STRUCT(String interfaceName,
- FunctionHeader header) {
- ArrayList<String> code = new ArrayList<String>();
- code.add("typedef struct " + interfaceName + "_info {");
- if (!header.returnType.equals("void")) {
- code.add(DECLARE(header.returnType, MACRO_RETURN));
- }
- for (int i = 0; i < header.args.size(); i++) {
- code.add(DECLARE(header.args.get(i)));
- }
- code.add("} " + interfaceName + "_info;");
- return code;
- }
-
- private static ArrayList<String> DEFINE_ID_FUNC(
- InterfaceConstruct construct, FunctionHeader header) {
- String interfaceName = construct.name;
- ArrayList<String> code = new ArrayList<String>();
- String idCode = construct.idCode;
- code.add("inline static " + IDType + " " + interfaceName + "_id("
- + "void *info, " + ThreadIDType + " " + MACRO_THREAD_ID + ") {");
-
- // Read info struct
- if (!header.returnType.equals("void") || header.args.size() != 0) {
- String infoStructType = interfaceName + "_info", infoStructName = "theInfo";
- code.add(DECLARE_DEFINE("\t" + infoStructType + "*",
- infoStructName, BRACE(infoStructType + "*") + "info"));
- if (!header.returnType.equals("void")) {
- code.add((DECLARE_DEFINE("\t" + header.returnType,
- MACRO_RETURN,
- GET_FIELD_BY_PTR(infoStructName, MACRO_RETURN))));
- }
- for (int i = 0; i < header.args.size(); i++) {
- String type = header.args.get(i).type, var = header.args.get(i).name;
- code.add("\t"
- + (DECLARE_DEFINE(type, var,
- GET_FIELD_BY_PTR(infoStructName, var))));
- }
- code.add("");
- }
-
- if (!idCode.equals("")) {
- code.add("\t" + DECLARE_DEFINE(IDType, MACRO_ID, idCode));
- } else {
- code.add("\t" + DECLARE_DEFINE(IDType, MACRO_ID, DEFAULT_ID));
- }
- code.add("\treturn " + MACRO_ID + ";");
- code.add("}");
- return code;
- }
-
- private static ArrayList<String> DEFINE_CHECK_ACTION_FUNC(
- InterfaceConstruct construct, FunctionHeader header) {
- String interfaceName = construct.name;
- ArrayList<String> code = new ArrayList<String>();
- code.add("inline static bool " + interfaceName
- + "_check_action(void *info, " + IDType + " " + MACRO_ID + ", "
- + ThreadIDType + " " + MACRO_THREAD_ID + ") {");
- code.add("\t" + DECLARE("bool", "check_passed"));
- // Read info struct
- if (!header.returnType.equals("void") || header.args.size() != 0) {
- String infoStructType = interfaceName + "_info", infoStructName = "theInfo";
- code.add("\t"
- + DECLARE_DEFINE(infoStructType + "*", infoStructName,
- BRACE(infoStructType + "*") + "info"));
- if (!header.returnType.equals("void")) {
- code.add("\t"
- + (DECLARE_DEFINE(header.returnType, MACRO_RETURN,
- GET_FIELD_BY_PTR(infoStructName, MACRO_RETURN))));
- }
- for (int i = 0; i < header.args.size(); i++) {
- String type = header.args.get(i).type, var = header.args.get(i).name;
- code.add("\t"
- + (DECLARE_DEFINE(type, var,
- GET_FIELD_BY_PTR(infoStructName, var))));
- }
- code.add("");
- }
- // __COND_SAT
- if (!construct.condition.equals("")) {
- code.add("\t"
- + DECLARE_DEFINE("bool", MACRO_COND, construct.condition));
- }
- // Check
- if (!construct.check.equals("")) {
- code.add("\t" + ASSIGN("check_passed", construct.check));
- code.add("\tif (!check_passed)");
- code.add("\t\treturn false;");
-
- }
- // Action
- if (construct.action.size() > 0) {
- addAllCodeWithIndent(code, construct.action, "\t");
- }
- // Post_check
- if (!construct.postCheck.equals("")) {
- code.add("\t" + ASSIGN("check_passed", construct.postCheck));
- code.add("\tif (!check_passed)");
- code.add("\t\treturn false;");
- }
- // Post_action
- if (construct.postAction.size() > 0) {
- addAllCodeWithIndent(code, construct.postAction, "\t");
- }
- // Return true finally
- code.add("\treturn true;");
-
- code.add("}");
-
- return code;
- }
-
- private static void addAllCodeWithIndent(ArrayList<String> allCode,
- ArrayList<String> target, String indent) {
- for (int i = 0; i < target.size(); i++) {
- allCode.add(indent + target.get(i));
- }
- }
-
- public static HashSet<String> getAllHeaders(SemanticsChecker semantics) {
- HashSet<String> headers = new HashSet<String>();
- for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
- File f = semantics.interfaceName2Construct.get(interfaceName).file;
- headers.addAll(semantics.srcFilesInfo.get(f).headers);
- }
- headers.add(HEADER_STDLIB);
- headers.add(HEADER_STDINT);
- headers.add(HEADER_MODELMEMORY);
- headers.add(HEADER_MODELTYPES);
- headers.add(HEADER_SPEC_LIB);
- headers.add(HEADER_STDINT);
- headers.add(HEADER_CDSANNOTATE);
- // headers.add(HEADER_COMMON);
- headers.add(HEADER_SPECANNOTATION);
- return headers;
- }
-
- private static void makeFunctionStatic(ArrayList<String> funcDefine) {
- String headLine = funcDefine.get(0);
- headLine = "inline static " + headLine;
- funcDefine.set(0, headLine);
- }
-
- private static String makeVariablesStatic(VariableDeclaration varDecl) {
- String res = "static " + varDecl.type + " " + varDecl.name + ";";
- return res;
- }
-
- private static FunctionHeader getFunctionHeader(SemanticsChecker semantics,
- Construct construct) {
- ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
- String headerLine = content.get(construct.beginLineNum + 1), templateLine = null;
- if (headerLine.startsWith("template")) {
- templateLine = headerLine;
- headerLine = content.get(construct.beginLineNum + 2);
- }
- headerLine = headerLine.substring(0, headerLine.indexOf(')') + 1);
- try {
- FunctionHeader header = UtilParser.parseFuncHeader(headerLine);
- if (templateLine != null) {
- ArrayList<VariableDeclaration> templateArgs = UtilParser
- .getTemplateArg(templateLine);
- header.setTemplateList(templateArgs);
- }
- return header;
- } catch (ParseException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public static ArrayList<String> generateGlobalVarDeclaration(
- SemanticsChecker semantics, GlobalConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- HashSet<String> allHeaders = getAllHeaders(semantics);
-
- SequentialDefineSubConstruct code = construct.code;
- // User-defined structs first
- newCode.add(COMMENT("All other user-defined structs"));
- ArrayList<ArrayList<String>> declareStructs = code.declareStructs;
- for (int i = 0; i < declareStructs.size(); i++) {
- ArrayList<String> declareStruct = declareStructs.get(i);
- newCode.addAll(declareStruct);
- newCode.add("");
- }
- // User-defined variables
- ArrayList<VariableDeclaration> varDecls = code.declareVar;
- for (int i = 0; i < varDecls.size(); i++) {
- VariableDeclaration varDecl = varDecls.get(i);
- // Don't forget to make them static
- newCode.add(makeVariablesStatic(varDecl));
- }
- // User-defined functions
- newCode.add(COMMENT("All other user-defined functions"));
- ArrayList<ArrayList<String>> defineFuncs = code.defineFuncs;
- for (int i = 0; i < defineFuncs.size(); i++) {
- ArrayList<String> defineFunc = defineFuncs.get(i);
- makeFunctionStatic(defineFunc);
- newCode.addAll(defineFunc);
- newCode.add("");
- }
-
- for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
- InterfaceConstruct iConstruct = semantics.interfaceName2Construct
- .get(interfaceName);
- FunctionHeader funcHeader = getFunctionHeader(semantics, iConstruct);
- // Define necessary info structure
- if (!funcHeader.returnType.equals("void")
- || funcHeader.args.size() > 0) {
- newCode.add(COMMENT("Definition of interface info struct: "
- + interfaceName));
- newCode.addAll(DEFINE_INFO_STRUCT(interfaceName, funcHeader));
- newCode.add(COMMENT("End of info struct definition: "
- + interfaceName));
- newCode.add("");
- }
-
- // Define ID function
- newCode.add(COMMENT("ID function of interface: " + interfaceName));
- newCode.addAll(DEFINE_ID_FUNC(iConstruct, funcHeader));
- newCode.add(COMMENT("End of ID function: " + interfaceName));
- newCode.add("");
-
- // Define check_action function
- newCode.add(COMMENT("Check action function of interface: "
- + interfaceName));
- newCode.addAll(DEFINE_CHECK_ACTION_FUNC(iConstruct, funcHeader));
- newCode.add(COMMENT("End of check action function: "
- + interfaceName));
- newCode.add("");
- }
- // Interface function pointer table
- String interfaceSize = Integer
- .toString(semantics.interfaceName2Construct.size());
- newCode.add(DEFINE("INTERFACE_SIZE", interfaceSize));
- // Make it static
- newCode.add("static " + DECLARE("void**", "func_ptr_table"));
- // Happens-before initialization rules
- // Should make it static
- newCode.add("static " + DECLARE(HB_RULE + "**", "hb_rule_table"));
-
- // Declare the Commutativity Rule table
- newCode.add("static "
- + DECLARE(COMMUTATIVITY_RULE + "**", "commutativity_rule_table"));
- // Define the Commutativity Rule condition functions
- ArrayList<CommutativityRule> rules = semantics.getGlobalConstruct().commutativityRules;
- for (int i = 0; i < rules.size(); i++) {
- CommutativityRule rule = rules.get(i);
- String infoStructType1 = rule.method1 + "_info";
- String infoStructType2 = rule.method2 + "_info";
- String condition = rule.condition;
- String conditionFuncName = "CommutativityCondition"
- + Integer.toString(i);
-
- // Replace the "_M1." and "_M2." with the actual info struct
- condition = condition.replaceAll("_Method1 \\.", "_info1->");
- condition = condition.replaceAll("_Method2 \\.", "_info2->");
-
- // Declare the signature of the condition function
- newCode.add("inline static bool " + conditionFuncName
- + "(void *info1, void *info2) {");
-
- // Cast the "void*" type to the actual info type
- newCode.add("\t"
- + DECLARE_DEFINE(infoStructType1, "*_info1", "("
- + infoStructType1 + "*) info1"));
- newCode.add("\t"
- + DECLARE_DEFINE(infoStructType2, "*_info2", "("
- + infoStructType2 + "*) info2"));
- newCode.add("\treturn " + condition + ";");
-
- // End of the condition function
- newCode.add("}");
- }
-
- newCode.add("");
-
- // Beginning initialization
- // Define the __SPEC_INIT__ function to initialize user-defined
- // variables
- newCode.add(COMMENT("Initialization of sequential varialbes"));
- newCode.add("static void __SPEC_INIT__() {");
- addAllCodeWithIndent(newCode, construct.code.initVar, "\t");
- newCode.add("}");
- newCode.add("");
-
- // Define the __SPEC_CLEAN__ function for clean-up
- newCode.add(COMMENT("Cleanup routine of sequential variables"));
- newCode.add("static bool __SPEC_CLEANUP__() {");
- if (construct.code.cleanupCode.size() > 0) {
- addAllCodeWithIndent(newCode, construct.code.cleanupCode, "\t");
- } else {
- newCode.add("\treturn true;"); // If not specified return true
- }
-
- newCode.add("}");
- newCode.add("");
-
- newCode.add(COMMENT("Define function for sequential code initialization"));
- newCode.add("inline static void __sequential_init() {");
-
- // Init func_ptr_table
- newCode.add("\t" + COMMENT("Init func_ptr_table"));
- newCode.add("\t"
- + ASSIGN("func_ptr_table", "(void**) malloc(sizeof(void*) * "
- + semantics.interface2Num.size() + " * 2)"));
- for (String interfaceName : semantics.interfaceName2Construct.keySet()) {
- String interfaceNum = Integer.toString(semantics.interface2Num
- .get(interfaceName));
- newCode.add("\t"
- + ASSIGN("func_ptr_table[2 * " + interfaceNum + "]",
- "(void*) &" + interfaceName + "_id"));
- newCode.add("\t"
- + ASSIGN("func_ptr_table[2 * " + interfaceNum + " + 1]",
- "(void*) &" + interfaceName + "_check_action"));
- }
-
- // Init Happens-before rules table
- newCode.addAll(generateHBInitAnnotation(semantics));
-
- // Init Commutativity rules table
- newCode.addAll(generateCommutativityAnnotation(semantics));
-
- // Pass init info, including function table info & HB rules
- newCode.add("\t"
- + COMMENT("Pass init info, including function table info & HB rules & Commutativity Rules"));
- String structName = "anno_init", anno = "init";
- newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(ANNO_INIT, structName));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "init_func",
- "(void_func_t) __SPEC_INIT__"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "cleanup_func",
- "(cleanup_func_t) __SPEC_CLEANUP__"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "func_table", "func_ptr_table"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "func_table_size", "INTERFACE_SIZE"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "hb_rule_table", "hb_rule_table"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "hb_rule_table_size",
- "HB_RULE_TABLE_SIZE"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "commutativity_rule_table",
- "commutativity_rule_table"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "commutativity_rule_table_size",
- Integer.toString(rules.size())));
-
- newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t" + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INIT));
- newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t" + ANNOTATE(semantics, anno));
-
- newCode.add("");
- newCode.add("}");
- newCode.add("");
-
- newCode.add(COMMENT("End of Global construct generation in class"));
-
- // printCode(newCode);
- return newCode;
- }
-
- public static ArrayList<String> generateStaticVarDefine(
- SemanticsChecker semantics, GlobalConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- String className = semantics.getClassName();
- if (className == null)
- return newCode; // No need to define any static variables
- String templateList = semantics.getTemplateStr();
- String varPrefix;
- if (templateList == null) {
- varPrefix = className + "::";
- } else {
- varPrefix = className + templateList + "::";
- }
- String templateDecl = semantics.getTemplateFullStr();
- if (templateList == null) {
- newCode.add(DECLARE("void**", varPrefix + "func_ptr_table"));
- newCode.add(DECLARE("hb_rule**", varPrefix + "hb_rule_table"));
- newCode.add(DECLARE("commutativity_rule**", varPrefix + "commutativity_rule_table"));
- for (int i = 0; i < construct.code.declareVar.size(); i++) {
- VariableDeclaration varDecl = construct.code.declareVar.get(i);
- newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name));
- }
- } else {
- newCode.add(templateDecl);
- newCode.add(DECLARE("void**", varPrefix + "func_ptr_table"));
- newCode.add(templateDecl);
- newCode.add(DECLARE("hb_rule**", varPrefix + "hb_rule_table"));
- newCode.add(templateDecl);
- newCode.add(DECLARE("commutativity_rule**", varPrefix + "commutativity_rule_table"));
- for (int i = 0; i < construct.code.declareVar.size(); i++) {
- VariableDeclaration varDecl = construct.code.declareVar.get(i);
- newCode.add(templateDecl);
- newCode.add(DECLARE(varDecl.type, varPrefix + varDecl.name));
- }
- }
- return newCode;
- }
-
- private static ArrayList<String> generateHBInitAnnotation(
- SemanticsChecker semantics) {
- ArrayList<String> newCode = new ArrayList<String>();
-
- int hbConditionInitIdx = 0;
- for (ConditionalInterface left : semantics.getHBConditions().keySet()) {
- for (ConditionalInterface right : semantics.getHBConditions().get(
- left)) {
- String structVarName = "hbConditionInit" + hbConditionInitIdx;
- // String annotationVarName = "hb_rule" + hbConditionInitIdx;
- hbConditionInitIdx++;
- 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("\t" + COMMENT(left + " -> " + right));
-
- newCode.add("\t"
- + STRUCT_NEW_DECLARE_DEFINE(HB_RULE, structVarName));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structVarName, "interface_num_before",
- interfaceNumBefore)
- + SHORT_COMMENT(left.interfaceName));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structVarName,
- "hb_condition_num_before", hbLabelNumBefore)
- + SHORT_COMMENT(left.hbConditionLabel));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structVarName, "interface_num_after",
- interfaceNumAfter)
- + SHORT_COMMENT(right.interfaceName));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structVarName,
- "hb_condition_num_after", hbLabelNumAfter)
- + SHORT_COMMENT(right.hbConditionLabel));
- }
- }
- // Init hb_rule_table
- newCode.add("\t" + COMMENT("Init hb_rule_table"));
- newCode.add("\t"
- + ASSIGN("hb_rule_table", "(" + HB_RULE
- + "**) malloc(sizeof(" + HB_RULE + "*) * "
- + hbConditionInitIdx + ")"));
- // Define HB_RULE_TABLE_SIZE
- newCode.add("\t"
- + DEFINE("HB_RULE_TABLE_SIZE",
- Integer.toString(hbConditionInitIdx)));
- for (int i = 0; i < hbConditionInitIdx; i++) {
- newCode.add("\t"
- + ASSIGN("hb_rule_table[" + i + "]", "hbConditionInit" + i));
- }
- return newCode;
- }
-
- private static ArrayList<String> generateCommutativityAnnotation(
- SemanticsChecker semantics) {
- ArrayList<String> newCode = new ArrayList<String>();
- ArrayList<CommutativityRule> rules = semantics.getGlobalConstruct().commutativityRules;
-
- // Init commutativity_rule_table
- newCode.add("\t" + COMMENT("Init commutativity_rule_table"));
-
- // Users have not defined any commutativity rules
- if (rules.size() == 0)
- return newCode;
-
- newCode.add("\t"
- + ASSIGN("commutativity_rule_table", "(" + COMMUTATIVITY_RULE
- + "**) malloc(sizeof(" + COMMUTATIVITY_RULE + "*) * "
- + rules.size() + ")"));
-
- // Declare a rule pointer
- newCode.add("\t" + DECLARE("commutativity_rule*", "rule"));
-
- for (int i = 0; i < rules.size(); i++) {
- CommutativityRule rule = rules.get(i);
- Integer method = semantics.interface2Num.get(rule.method1);
- if (method == null) {
- System.out.println("Wrong method label in commutativity rule: " + rule.method1);
- }
- String interfaceNumBefore = Integer.toString(method);
- String interfaceNumAfter = Integer.toString(semantics.interface2Num
- .get(rule.method2));
- String conditionFuncName = "CommutativityCondition" + i;
-
- // Construct a new rule
- newCode.add("\t"
- + ASSIGN("rule",
- "(commutativity_rule*) malloc (sizeof(commutativity_rule))"));
- newCode.add("\t"
- + ASSIGN_TO_PTR("rule", "interface_num_before",
- interfaceNumBefore));
- newCode.add("\t"
- + ASSIGN_TO_PTR("rule", "interface_num_after",
- interfaceNumAfter));
- newCode.add("\t"
- + ASSIGN_TO_PTR("rule", "rule",
- "\"" + rule.condition + "\""));
-
- newCode.add("\t"
- + ASSIGN_TO_PTR("rule", "condition", conditionFuncName));
-
- // Assign the rule to the corresponding commutativity table slot
- newCode.add("\t"
- + ASSIGN("commutativity_rule_table[" + i + "]", "rule"));
- }
-
- return newCode;
- }
-
- public static ArrayList<String> generateEntryPointInitCall() {
- ArrayList<String> newCode = new ArrayList<String>();
- newCode.add("\t" + "__sequential_init();");
- return newCode;
- }
-
- public static ArrayList<String> generateInterfaceWrapperDeclaration(
- SemanticsChecker semantics, InterfaceConstruct construct) {
- FunctionHeader header = getFunctionHeader(semantics, construct);
- ArrayList<String> declaration = new ArrayList<String>();
- declaration.add(header.getRenamedHeader(SPEC_INTERFACE_WRAPPER)
- .getDeclaration() + ";");
- return declaration;
- }
-
- // Only generate the definition of the wrapper, don't do any renaming
- public static ArrayList<String> generateInterfaceWrapperDefinition(
- SemanticsChecker semantics, InterfaceConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- String interfaceName = construct.name;
-
- FunctionHeader header = getFunctionHeader(semantics, construct);
- String interfaceNum = Integer.toString(semantics.interface2Num
- .get(construct.name));
-
- newCode.add(header.getTemplateFullStr());
- newCode.add(header.getFuncStr() + " {");
- // Wrapper function body
- newCode.add("\t" + COMMENT("Interface begins"));
- // Interface begin
- String structName = "interface_begin";
- newCode.add("\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_BEGIN,
- "interface_begin"));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)
- + SHORT_COMMENT(construct.name));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "interface_name", "\""
- + construct.name + "\""));
-
- String anno = "annotation_interface_begin";
- newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_BEGIN));
- newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t" + ANNOTATE(semantics, anno));
- // Call original renamed function
- if (header.returnType.equals("void")) {
- newCode.add("\t" + header.getRenamedCall(SPEC_INTERFACE_WRAPPER)
- + ";");
- } else {
- newCode.add("\t"
- + DECLARE_DEFINE(header.returnType, MACRO_RETURN,
- header.getRenamedCall(SPEC_INTERFACE_WRAPPER)));
- }
- // HB conditions
- for (String label : construct.hbConditions.keySet()) {
- String condition = construct.hbConditions.get(label);
- String hbCondNum = Integer.toString(semantics.hbLabel2Num
- .get(label));
- newCode.add("\t" + "if " + BRACE(condition) + " {");
- structName = "hb_condition";
- newCode.add("\t\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)
- + SHORT_COMMENT(construct.name));
-
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "hb_condition_num", hbCondNum));
- anno = "annotation_hb_condition";
- newCode.add("\t\t"
- + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION));
- newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t\t" + ANNOTATE(semantics, anno));
- newCode.add("\t" + "}");
- newCode.add("");
- }
- // Also add the true condition if any
- if (semantics.containsConditionalInterface(new ConditionalInterface(
- interfaceName, ""))) {
- structName = "hb_condition";
- newCode.add("\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_HB_CONDITION, structName));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)
- + SHORT_COMMENT(construct.name));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "hb_condition_num", "0"));
- anno = "annotation_hb_condition";
- newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_HB_CONDITION));
- newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t" + ANNOTATE(semantics, anno));
- newCode.add("");
- }
- // Interface end
- String infoStructType = null, infoName = null;
- if (!header.returnType.equals("void") || header.args.size() > 0) {
- infoStructType = interfaceName + "_info";
- infoName = "info";
- newCode.add("\t"
- + DECLARE_DEFINE(infoStructType + "*", infoName,
- BRACE(infoStructType + "*") + " malloc(sizeof("
- + infoStructType + "))"));
- if (!header.returnType.equals("void")) {
- newCode.add("\t"
- + ASSIGN_TO_PTR(infoName, MACRO_RETURN, MACRO_RETURN));
- }
- for (int i = 0; i < header.args.size(); i++) {
- String argName = header.args.get(i).name;
- newCode.add("\t" + ASSIGN_TO_PTR(infoName, argName, argName));
- }
- } else {
- infoName = "NULL";
- }
- structName = "interface_end";
- anno = "annoation_interface_end";
- newCode.add("\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_INTERFACE_END, structName));
- newCode.add("\t"
- + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum)
- + SHORT_COMMENT(construct.name));
- newCode.add("\t" + ASSIGN_TO_PTR(structName, "info", infoName));
- newCode.add("\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_INTERFACE_END));
- newCode.add("\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t" + ANNOTATE(semantics, anno));
- // Return __RET__ if it's not void
- if (!header.returnType.equals("void")) {
- newCode.add("\t" + "return " + MACRO_RETURN + ";");
- }
- // End of the wrapper function
- newCode.add("}");
-
- // printCode(newCode);
- return newCode;
- }
-
- // Rename the interface name for declaration or definition
- public static void renameInterface(SemanticsChecker semantics,
- Construct construct) {
- FunctionHeader header = getFunctionHeader(semantics, construct);
- ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
- int lineNum = construct.beginLineNum;
- String headerLine = content.get(construct.beginLineNum);
- if (headerLine.startsWith("template")) {
- headerLine = content.get(construct.beginLineNum + 1);
- lineNum++;
- }
- String newLine = header.getRenamedHeader(SPEC_INTERFACE_WRAPPER)
- .toString();
- String oldLine = content.get(lineNum + 1);
-
- if (construct instanceof InterfaceConstruct) {
- InterfaceConstruct iConstruct = (InterfaceConstruct) construct;
- InterfaceDefineConstruct defineConstruct = semantics.interfaceName2DefineConstruct
- .get(iConstruct.name);
- if (defineConstruct != null) { // There is a defineConstruct
- newLine = newLine + " ;";
- renameInterface(semantics, defineConstruct);
- } else { // This is a declare & define construct
- if (oldLine.indexOf('{') != -1)
- newLine = newLine + " {";
- }
- } else {
- if (oldLine.indexOf('{') != -1)
- newLine = newLine + " {";
- }
-
- content.set(lineNum + 1, newLine);
- }
-
- public static void addAtomicReturn(SemanticsChecker semantics,
- Construct construct) {
- int lineNum = construct.beginLineNum - 1;
- ArrayList<String> content = semantics.srcFilesInfo.get(construct.file).content;
- String oldLine = content.get(lineNum);
- String newLine = "uint64_t " + MACRO_ATOMIC_RETURN + " = " + oldLine;
- content.set(lineNum, newLine);
- }
-
- public static ArrayList<String> generatePotentialCPDefine(
- SemanticsChecker semantics, PotentialCPDefineConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- // Add atomic return variable if the predicate accesses to it
- if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
- addAtomicReturn(semantics, construct);
- }
- // Generate redundant header files
- newCode.add("\t"
- + COMMENT("Automatically generated code for potential commit point: "
- + construct.label));
- newCode.add("");
- // Add annotation
- newCode.add("\t" + "if (" + construct.condition + ") {");
- String structName = "potential_cp_define", anno = "annotation_potential_cp_define";
- newCode.add("\t\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_POTENTIAL_CP_DEFINE,
- structName));
- String labelNum = Integer.toString(semantics.commitPointLabel2Num
- .get(construct.label));
- newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "label_name", "\""
- + construct.label + "\""));
-
- newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(anno, "type",
- SPEC_ANNO_TYPE_POTENTIAL_CP_DEFINE));
- newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t\t" + ANNOTATE(semantics, anno));
- newCode.add("\t" + "}");
- return newCode;
- }
-
- public static String getCPInterfaceNum(SemanticsChecker semantics,
- String commitPointLabel) {
- HashMap<String, InterfaceConstruct> cp2Interface = semantics.CPLabel2InterfaceConstruct;
- InterfaceConstruct iConstruct = cp2Interface.get(commitPointLabel);
- String interfaceName = iConstruct.name;
- String interfaceNum = Integer.toString(semantics.interface2Num
- .get(interfaceName));
- return interfaceNum;
- }
-
- /**
- * <p>
- * Commit point define check should be unique to each interface, meaning
- * that they are not shared between different interfaces
- * </p>
- *
- * @param semantics
- * @param construct
- * @return
- */
- public static ArrayList<String> generateCPDefineCheck(
- SemanticsChecker semantics, CPDefineCheckConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- // Add atomic return variable if the predicate accesses to it
- if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
- addAtomicReturn(semantics, construct);
- }
- // Generate redundant header files
- newCode.add("\t"
- + COMMENT("Automatically generated code for commit point define check: "
- + construct.label));
- newCode.add("");
- // Add annotation
-
- newCode.add("\t" + "if (" + construct.condition + ") {");
- String structName = "cp_define_check", anno = "annotation_cp_define_check";
- newCode.add("\t\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE_CHECK, structName));
- String labelNum = Integer.toString(semantics.commitPointLabel2Num
- .get(construct.label));
- String interfaceNum = getCPInterfaceNum(semantics, construct.label);
- newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "label_name", "\""
- + construct.label + "\""));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum));
-
- newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE_CHECK));
- newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t\t" + ANNOTATE(semantics, anno));
- newCode.add("\t" + "}");
- return newCode;
- }
-
- /**
- * <p>
- * Commit point define check should be unique to each interface, meaning
- * that they are not shared between different interfaces
- * </p>
- *
- * @param semantics
- * @param construct
- * @return
- */
- public static ArrayList<String> generateCPClear(SemanticsChecker semantics,
- CPClearConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- // Add atomic return variable if the predicate accesses to it
- if (construct.condition.indexOf(MACRO_ATOMIC_RETURN) != -1) {
- addAtomicReturn(semantics, construct);
- }
- // Generate redundant header files
- newCode.add("\t"
- + COMMENT("Automatically generated code for commit point clear: "
- + construct.label));
- newCode.add("");
- // Add annotation
-
- newCode.add("\t" + "if (" + construct.condition + ") {");
- String structName = "cp_clear", anno = "annotation_cp_clear";
- newCode.add("\t\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_CLEAR, structName));
-
- String labelNum = Integer.toString(semantics.commitPointLabel2Num
- .get(construct.label));
- String labelName = construct.label;
- newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_name",
- "\"" + labelName + "\""));
- newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num",
- labelNum));
-
- newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_CLEAR));
- newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t\t" + ANNOTATE(semantics, anno));
- newCode.add("\t" + "}");
- return newCode;
- }
-
- /**
- * <p>
- * Commit point define should be unique to each interface, meaning that they
- * are not shared between different interfaces
- * </p>
- *
- * @param semantics
- * @param construct
- * @return
- */
- public static ArrayList<String> generateCPDefine(
- SemanticsChecker semantics, CPDefineConstruct construct) {
- ArrayList<String> newCode = new ArrayList<String>();
- // Generate redundant header files
- newCode.add("\t"
- + COMMENT("Automatically generated code for commit point define: "
- + construct.label));
- newCode.add("");
- // Add annotation
- newCode.add("\t" + "if (" + construct.condition + ") {");
- String structName = "cp_define", anno = "annotation_cp_define";
- newCode.add("\t\t"
- + STRUCT_NEW_DECLARE_DEFINE(ANNO_CP_DEFINE, structName));
- String labelNum = Integer.toString(semantics.commitPointLabel2Num
- .get(construct.label));
- String interfaceNum = getCPInterfaceNum(semantics, construct.label);
- String potentialLabelNum = Integer
- .toString(semantics.commitPointLabel2Num
- .get(construct.potentialCPLabel));
- newCode.add("\t\t" + ASSIGN_TO_PTR(structName, "label_num", labelNum));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "label_name", "\""
- + construct.label + "\""));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "potential_cp_label_num",
- potentialLabelNum));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "potential_label_name", "\""
- + construct.potentialCPLabel + "\""));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(structName, "interface_num", interfaceNum));
- newCode.add("\t\t" + STRUCT_NEW_DECLARE_DEFINE(SPEC_ANNOTATION, anno));
- newCode.add("\t\t"
- + ASSIGN_TO_PTR(anno, "type", SPEC_ANNO_TYPE_CP_DEFINE));
- newCode.add("\t\t" + ASSIGN_TO_PTR(anno, "annotation", structName));
- newCode.add("\t\t" + ANNOTATE(semantics, anno));
- newCode.add("\t" + "}");
- return newCode;
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-public class Environment {
- public static String HOME_DIRECTORY = System.getProperty("user.dir");
- public static String GENERATED_FILE_DIR = HOME_DIRECTORY + "/" + "output";
- public static String MODEL_CHECKER_HOME_DIR = System
- .getProperty("user.home") + "/test/model-checker-priv";
- public static String MODEL_CHECKER_TEST_DIR = MODEL_CHECKER_HOME_DIR + "/test";
-
- public static String MS_QUEUE = MODEL_CHECKER_TEST_DIR = MODEL_CHECKER_TEST_DIR + "/ms-queue";
- public static String LINUXRWLOCKS = MODEL_CHECKER_TEST_DIR = MODEL_CHECKER_TEST_DIR + "/linuxrwlocks";
- public static String CLIFFC_HASHTABLE = MODEL_CHECKER_TEST_DIR = MODEL_CHECKER_TEST_DIR + "/cliffc-hashtable";
-
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-public class InterfaceWrongFormatException extends Exception {
- public InterfaceWrongFormatException(String msg) {
- super(msg);
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.ArrayList;
-
-/**
- * <p>
- * This class represents the structured code before and after compilation.
- * </p>
- * @author peizhaoo
- *
- */
-public class ProgramUnit {
- private File[] files;
-
- private HashMap<File, ArrayList<String>> newCode;
-
- public ProgramUnit(File[] files) {
- this.files = files;
- }
-
- public void compileSpec() {
-
- }
-
- public void writeToFile() {
-
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import edu.uci.eecs.specCompiler.grammerParser.ParseException;
-import edu.uci.eecs.specCompiler.specExtraction.CPClearConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineCheckConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.CPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ClassBeginConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ClassEndConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ConditionalInterface;
-import edu.uci.eecs.specCompiler.specExtraction.Construct;
-import edu.uci.eecs.specCompiler.specExtraction.EntryPointConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.GlobalConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.InterfaceDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.ParserUtils;
-import edu.uci.eecs.specCompiler.specExtraction.PotentialCPDefineConstruct;
-import edu.uci.eecs.specCompiler.specExtraction.SourceFileInfo;
-import edu.uci.eecs.specCompiler.specExtraction.SpecExtractor;
-
-/**
- * <p>
- * A specificaiton semantics checker that checks the consistency of the
- * specifications after they are extracted from the source code.
- * </p>
- *
- * @author peizhaoo
- *
- */
-public class SemanticsChecker {
- public final HashMap<File, SourceFileInfo> srcFilesInfo;
- public final ArrayList<Construct> constructs;
- public final HashMap<String, Construct> CPLabel2Construct;
- public final HashMap<String, PotentialCPDefineConstruct> potentialCPLabel2Construct;
- public final HashMap<String, InterfaceConstruct> interfaceName2Construct;
- public final HashMap<String, InterfaceDefineConstruct> interfaceName2DefineConstruct;
- public final HashMap<String, InterfaceConstruct> CPLabel2InterfaceConstruct;
-
- public final HashMap<String, Integer> interface2Num;
- public final HashMap<Integer, String> num2Interface;
- public final HashMap<String, Integer> hbLabel2Num;
- public final HashMap<Integer, String> num2HBLabel;
- public final HashMap<String, Integer> commitPointLabel2Num;
- public final HashMap<Integer, String> num2CommitPointLabel;
-
- private HashMap<String, String> options;
- private HashMap<ConditionalInterface, HashSet<ConditionalInterface>> hbConditions;
- private ArrayList<EntryPointConstruct> entryPointConstructs;
- private ClassBeginConstruct classBeginConstruct;
- private ClassEndConstruct classEndConstruct;
- private GlobalConstruct globalConstruct;
-
- private String templateStr;
- private String templateFullStr;
- private String className;
-
- private int _interfaceNum;
- private int _hbLabelNum;
- private int _commitPointNum;
-
- public SemanticsChecker(SpecExtractor extractor) {
- this.srcFilesInfo = extractor.srcFilesInfo;
- this.constructs = extractor.getConstructs();
- this.CPLabel2Construct = new HashMap<String, Construct>();
- this.potentialCPLabel2Construct = new HashMap<String, PotentialCPDefineConstruct>();
- this.interfaceName2Construct = new HashMap<String, InterfaceConstruct>();
- this.interfaceName2DefineConstruct = new HashMap<String, InterfaceDefineConstruct>();
- this.CPLabel2InterfaceConstruct = new HashMap<String, InterfaceConstruct>();
- this.entryPointConstructs = new ArrayList<EntryPointConstruct>();
- this.classBeginConstruct = null;
- this.classEndConstruct = null;
-
- this.interface2Num = new HashMap<String, Integer>();
- this.num2Interface = new HashMap<Integer, String>();
- this.hbLabel2Num = new HashMap<String, Integer>();
- this.num2HBLabel = new HashMap<Integer, String>();
- // Immediately init the true HB-condition to be 0
- hbLabel2Num.put("", 0);
- num2HBLabel.put(0, "");
-
- this.commitPointLabel2Num = new HashMap<String, Integer>();
- this.num2CommitPointLabel = new HashMap<Integer, String>();
-
- _interfaceNum = 0;
- _hbLabelNum = 0;
- _commitPointNum = 0;
-
- templateStr = null;
- templateFullStr = null;
- className = null;
- }
-
- public ClassBeginConstruct getClassBeginConstruct() {
- return this.classBeginConstruct;
- }
-
- public ClassEndConstruct getClassEndConstruct() {
- return this.classEndConstruct;
- }
-
- public String getTemplateFullStr() {
- return this.templateFullStr;
- }
-
- public String getTemplateStr() {
- return this.templateStr;
- }
-
- public String getClassName() {
- return this.className;
- }
-
- public GlobalConstruct getGlobalConstruct() {
- return this.globalConstruct;
- }
-
- public HashMap<ConditionalInterface, HashSet<ConditionalInterface>> getHBConditions() {
- return this.hbConditions;
- }
-
- /**
- * Check if the conditional interface is in the HB checking list
- *
- * @param condInterface
- * @return
- */
- public boolean containsConditionalInterface(
- ConditionalInterface condInterface) {
- if (hbConditions.containsKey(condInterface))
- return true;
- for (ConditionalInterface key : hbConditions.keySet()) {
- if (hbConditions.get(key).contains(condInterface))
- return true;
- }
- return false;
- }
-
- public String getOption(String key) {
- return options.get(key);
- }
-
- private void checkHBLabelConsistency(ConditionalInterface inst)
- throws SemanticsCheckerException {
- String interfaceName = inst.interfaceName, label = inst.hbConditionLabel;
- if (!interfaceName2Construct.containsKey(interfaceName)) {
- throw new SemanticsCheckerException(
- "In global construct, no interface \"" + interfaceName
- + "\"!");
- } else if (!label.equals("")) {
- InterfaceConstruct iConstruct = (InterfaceConstruct) interfaceName2Construct
- .get(interfaceName);
- if (!iConstruct.hbConditions.containsKey(label)) {
- throw new SemanticsCheckerException("Interface "
- + interfaceName + " doesn't contain HB_codition: "
- + label + "!");
- }
-
- // Number the HB-condition label
- hbLabel2Num.put(label, _hbLabelNum++);
- num2HBLabel.put(_hbLabelNum, label);
- }
- }
-
- private void checkLabelDuplication(Construct construct, String label)
- throws SemanticsCheckerException {
- if (potentialCPLabel2Construct.containsKey(label)
- || CPLabel2Construct.containsKey(label))
- throw new SemanticsCheckerException("In construct: " + construct
- + "\"" + label + "\" has duplication.");
- }
-
- private void checkOptions() throws SemanticsCheckerException {
- // FIXME: We don't have any check here
- }
-
- private void postCheck() throws SemanticsCheckerException {
- // C++ data structure with Class must provide the beginning and ending
- // of its declaration
- if (getOption("Class") != null) {
- if (classBeginConstruct == null || classEndConstruct == null) {
- throw new SemanticsCheckerException(
- "Class must provide the boundary explicitly!");
- }
- }
- // It must provide the entry point
- if (entryPointConstructs.size() == 0) {
- throw new SemanticsCheckerException(
- "The program must have at least one entry point!");
- }
-
- // Check if interface define construct labels are correct
- for (String name : interfaceName2DefineConstruct.keySet()) {
- if (!interfaceName2Construct.containsKey(name)) {
- throw new SemanticsCheckerException("Label \"" + name
- + "\" does not have interface declaration!");
- }
- }
- }
-
- public void check() throws SemanticsCheckerException {
- boolean hasGlobalConstruct = false;
- // First grab the information from the interface
- for (int i = 0; i < constructs.size(); i++) {
- Construct inst = constructs.get(i);
- if (inst instanceof InterfaceConstruct) {
- InterfaceConstruct iConstruct = (InterfaceConstruct) inst;
- if (interfaceName2Construct.containsKey(iConstruct.name)) {
- throw new SemanticsCheckerException("Interface name: "
- + iConstruct.name + " duplicates!");
- }
- // Number the interface label
- interface2Num.put(iConstruct.name, _interfaceNum++);
- num2Interface.put(_interfaceNum, iConstruct.name);
-
- interfaceName2Construct.put(iConstruct.name,
- (InterfaceConstruct) constructs.get(i));
-
- for (int j = 0; j < iConstruct.commitPointSet.size(); j++) {
- String label = iConstruct.commitPointSet.get(j);
- // if (!CPLabel2InterfaceConstruct.containsKey(label)) {
- // CPLabel2InterfaceConstruct.put(label,
- // new ArrayList<InterfaceConstruct>());
- // }
- // CPLabel2InterfaceConstruct.get(label).add(iConstruct);
- if (!CPLabel2InterfaceConstruct.containsKey(label)) {
- CPLabel2InterfaceConstruct.put(label, iConstruct);
- } else {
- throw new SemanticsCheckerException(
- "Commit point has multiple interfaces!");
- }
-
- }
- }
- }
-
- String label;
- for (int i = 0; i < constructs.size(); i++) {
- Construct construct = constructs.get(i);
- if (construct instanceof GlobalConstruct) {
- GlobalConstruct theConstruct = (GlobalConstruct) construct;
- globalConstruct = theConstruct;
- if (!hasGlobalConstruct)
- hasGlobalConstruct = true;
- else {
- throw new SemanticsCheckerException(
- "More than one global construct!");
- }
- // Record the options and check them
- options = theConstruct.options;
-
- // Record the HB conditions and check it
- hbConditions = theConstruct.hbRelations;
- for (ConditionalInterface left : hbConditions.keySet()) {
- HashSet<ConditionalInterface> set = hbConditions.get(left);
- checkHBLabelConsistency(left);
-
- for (ConditionalInterface right : set) {
- checkHBLabelConsistency(right);
- }
- }
- } else if (construct instanceof PotentialCPDefineConstruct) {
- PotentialCPDefineConstruct theConstruct = (PotentialCPDefineConstruct) construct;
- label = theConstruct.label;
- checkLabelDuplication(construct, label);
- // Number the commit point potential commit point label
- commitPointLabel2Num.put(label, _commitPointNum++);
- num2CommitPointLabel.put(_commitPointNum, label);
-
- potentialCPLabel2Construct.put(label,
- (PotentialCPDefineConstruct) construct);
- } else if (construct instanceof CPDefineCheckConstruct) {
- CPDefineCheckConstruct theConstruct = (CPDefineCheckConstruct) construct;
- label = theConstruct.label;
- checkLabelDuplication(construct, label);
- // Number the commit point define check label
- commitPointLabel2Num.put(label, _commitPointNum++);
- num2CommitPointLabel.put(_commitPointNum, label);
-
- CPLabel2Construct.put(label, construct);
- } else if (construct instanceof CPClearConstruct) {
- CPClearConstruct theConstruct = (CPClearConstruct) construct;
- label = theConstruct.label;
- checkLabelDuplication(construct, label);
- // Number the commit point define check label
- commitPointLabel2Num.put(label, _commitPointNum++);
- num2CommitPointLabel.put(_commitPointNum, label);
-
- CPLabel2Construct.put(label, construct);
- } else if (construct instanceof CPDefineConstruct) {
- CPDefineConstruct theConstruct = (CPDefineConstruct) construct;
- label = theConstruct.label;
- checkLabelDuplication(construct, label);
- // Number the commit point define label
- commitPointLabel2Num.put(label, _commitPointNum++);
- num2CommitPointLabel.put(_commitPointNum, label);
-
- CPLabel2Construct.put(label, construct);
- } else if (construct instanceof EntryPointConstruct) {
- entryPointConstructs.add((EntryPointConstruct) construct);
- } else if (construct instanceof InterfaceDefineConstruct) {
- InterfaceDefineConstruct theConstruct = (InterfaceDefineConstruct) construct;
- String name = theConstruct.name;
- if (interfaceName2DefineConstruct.containsKey(name)) {
- throw new SemanticsCheckerException(
- "Interface define label duplicates!");
- }
- interfaceName2DefineConstruct.put(name, theConstruct);
- } else if (construct instanceof ClassBeginConstruct) {
- classBeginConstruct = (ClassBeginConstruct) construct;
- ArrayList<String> content = srcFilesInfo
- .get(classBeginConstruct.file).content;
- String firstLine = content
- .get(classBeginConstruct.beginLineNum + 1), secondLine;
- if (firstLine.startsWith("template")) {
- secondLine = content
- .get(classBeginConstruct.beginLineNum + 1);
- templateFullStr = firstLine;
- templateStr = ParserUtils.getTemplateStr(firstLine);
- className = ParserUtils.getClassName(secondLine);
- } else {
- className = ParserUtils.getClassName(firstLine);
- }
-
- } else if (construct instanceof ClassEndConstruct) {
- classEndConstruct = (ClassEndConstruct) construct;
- className = getOption("CLASS");
- }
- }
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
-
- sb.append("Interface name 2 Construct:\n");
- for (String interfaceName : interfaceName2Construct.keySet()) {
- sb.append(interfaceName + "\t"
- + interfaceName2Construct.get(interfaceName) + "\n");
- }
-
- sb.append("Interface name 2 define construct:\n");
- for (String interfaceName : interfaceName2DefineConstruct.keySet()) {
- sb.append(interfaceName + "\t"
- + interfaceName2DefineConstruct.get(interfaceName) + "\n");
- }
-
- sb.append("Potential commit point label 2 Construct:\n");
- for (String label : potentialCPLabel2Construct.keySet()) {
- sb.append(label + "\t" + potentialCPLabel2Construct.get(label)
- + "\n");
- }
-
- sb.append("Commit point label 2 Construct:\n");
- for (String label : CPLabel2Construct.keySet()) {
- sb.append(label + "\t" + CPLabel2Construct.get(label) + "\n");
- }
- return sb.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.codeGenerator;
-
-public class SemanticsCheckerException extends Exception {
- public SemanticsCheckerException(String msg) {
- super(msg);
- }
-}
\ No newline at end of file
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class CPClearConstruct extends Construct {
- public final String label;
- public final String condition;
-
- public CPClearConstruct(File file, int beginLineNum, String label,
- String condition) {
- super(file, beginLineNum);
- this.label = label;
- this.condition = condition;
- }
-
- public String toString() {
- StringBuffer res = new StringBuffer();
- res.append("@Commit_point_define_check:\n");
- res.append("Label: " + label + "\n");
- res.append("Condition: " + condition + "\n");
- return res.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class CPDefineCheckConstruct extends Construct {
- public final boolean isAdditionalOrderingPoint;
-
- public final String label;
- public final String condition;
-
- public CPDefineCheckConstruct(File file, int beginLineNum, String label,
- String condition) {
- super(file, beginLineNum);
- this.isAdditionalOrderingPoint = false;
- this.label = label;
- this.condition = condition;
- }
-
- public CPDefineCheckConstruct(File file, int beginLineNum,
- boolean isAdditionalOrderingPoint, String label, String condition) {
- super(file, beginLineNum);
- this.isAdditionalOrderingPoint = isAdditionalOrderingPoint;
- this.label = label;
- this.condition = condition;
- }
-
- public String toString() {
- StringBuffer res = new StringBuffer();
- res.append("@Commit_point_define_check:\n");
- res.append("Label: " + label + "\n");
- res.append("Condition: " + condition + "\n");
- return res.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class CPDefineConstruct extends Construct {
- public final boolean isAdditionalOrderingPoint;
- public final String label;
- public final String potentialCPLabel;
- public final String condition;
-
- public CPDefineConstruct(File file, int beginLineNum, String label,
- String potentialCPLabel, String condition) {
- super(file, beginLineNum);
- this.isAdditionalOrderingPoint = false;
- this.label = label;
- this.potentialCPLabel = potentialCPLabel;
- this.condition = condition;
- }
-
- public CPDefineConstruct(File file, int beginLineNum,
- boolean isAdditionalOrderingPoint, String label,
- String potentialCPLabel, String condition) {
- super(file, beginLineNum);
- this.isAdditionalOrderingPoint = isAdditionalOrderingPoint;
- this.label = label;
- this.potentialCPLabel = potentialCPLabel;
- this.condition = condition;
- }
-
- public String toString() {
- StringBuffer res = new StringBuffer();
- res.append("@Potential_commit_point_define:\n");
- res.append("Label: " + label + "\n");
- res.append("Potential_CP_label: " + potentialCPLabel + "\n");
- res.append("Condition: " + condition + "\n");
- return res.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class ClassBeginConstruct extends Construct {
- public ClassBeginConstruct(File file, int beginLineNum) {
- super(file, beginLineNum);
- }
-
- public String toString() {
- return "@Class_begin";
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class ClassEndConstruct extends Construct {
- public ClassEndConstruct(File file, int beginLineNum) {
- super(file, beginLineNum);
- }
-
- public String toString() {
- return "@Class_end";
- }
-}
\ No newline at end of file
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-public class CommutativityRule {
- public final String method1, method2;
-
- public final String condition;
-
- public CommutativityRule(String m1, String m2, String condition) {
- this.method1 = m1;
- this.method2 = m2;
- this.condition = condition;
- }
-
- public String toString() {
- return "@Commutativity: " + method1 + " <-> " + method2 + ": " + condition;
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-public class ConditionalInterface {
- public final String interfaceName;
- public final String hbConditionLabel;
-
- public ConditionalInterface(String interfaceName, String hbConditionLabel) {
- this.interfaceName = interfaceName;
- this.hbConditionLabel = hbConditionLabel;
- }
-
- public boolean equals(Object other) {
- if (!(other instanceof ConditionalInterface))
- return false;
- ConditionalInterface another = (ConditionalInterface) other;
- return another.interfaceName.equals(interfaceName)
- && (another.hbConditionLabel.equals(hbConditionLabel) || another.hbConditionLabel
- .equals(""));
- }
-
- public int hashCode() {
- return interfaceName.hashCode() << 5 ^ hbConditionLabel.hashCode();
- }
-
- public String toString() {
- if (hbConditionLabel.equals(""))
- return interfaceName + "(true)";
- else
- return interfaceName + "(" + hbConditionLabel + ")";
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-/**
- * <p>
- * An abstract class for all different specification constructs.
- * </p>
- *
- * @author peizhaoo
- *
- */
-abstract public class Construct {
- public final File file;
- public final int beginLineNum;
-
- public Construct(File file, int beginLineNum) {
- this.file = file;
- this.beginLineNum = beginLineNum;
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class EntryPointConstruct extends Construct {
- public EntryPointConstruct(File file, int beginLineNum) {
- super(file, beginLineNum);
- }
-
- public String toString() {
- return "@Entry_point";
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.util.ArrayList;
-
-import com.sun.xml.internal.ws.wsdl.parser.ParserUtil;
-
-public class FunctionHeader {
- private ArrayList<VariableDeclaration> templateList;
-
- public final String returnType;
- public final QualifiedName qualifiedName;
- public final ArrayList<VariableDeclaration> args;
-
- public FunctionHeader(String returnType, QualifiedName qualifiedName,
- ArrayList<VariableDeclaration> args) {
- this.templateList = null;
- this.returnType = returnType;
- this.qualifiedName = qualifiedName;
- this.args = args;
- }
-
- public void setTemplateList(ArrayList<VariableDeclaration> templateList) {
- this.templateList = templateList;
- }
-
- public ArrayList<VariableDeclaration> getTemplateList() {
- return this.templateList;
- }
-
- public String getTemplateFullStr() {
- String templateStr = "";
- if (templateList == null)
- return templateStr;
- VariableDeclaration decl;
- decl = templateList.get(0);
- templateStr = "<" + decl.type + " " + decl.name;
- for (int i = 1; i < templateList.size(); i++) {
- decl = templateList.get(i);
- templateStr = templateStr + ", " + decl.type + " " + decl.name;
- }
- templateStr = templateStr + ">";
- return templateStr;
- }
-
- public String getTemplateArgStr() {
- String templateStr = null;
- if (templateList.size() == 0)
- return templateStr;
- templateStr = "<" + templateList.get(0).name;
- for (int i = 1; i < templateList.size(); i++) {
- templateStr = templateStr + ", " + templateList.get(i);
- }
- templateStr = templateStr + ">";
- return templateStr;
- }
-
- public String getFuncStr() {
- String res = returnType + " " + qualifiedName.fullName + "(";
- if (args.size() >= 1) {
- res = res + args.get(0);
- }
- for (int i = 1; i < args.size(); i++) {
- res = res + ", " + args.get(i);
- }
- res = res + ")";
- return res;
- }
-
- public String toString() {
- String res = returnType + " " + qualifiedName.fullName + "(";
- if (args.size() >= 1) {
- res = res + args.get(0);
- }
- for (int i = 1; i < args.size(); i++) {
- res = res + ", " + args.get(i);
- }
- res = res + ")";
- return res;
- }
-
- public FunctionHeader getRenamedHeader(String prefix) {
- String newFullName = qualifiedName.qualifiedName + prefix + "_"
- + qualifiedName.bareName;
- FunctionHeader newHeader = new FunctionHeader(returnType,
- new QualifiedName(newFullName), args);
- return newHeader;
- }
-
- // No support for template right now
- public String getDeclaration() {
- String res = returnType + " " + qualifiedName.fullName + "(";
- if (args.size() >= 1) {
- res = res + args.get(0).type + " " + args.get(0).name;
- }
- for (int i = 1; i < args.size(); i++) {
- res = res + ", " + args.get(i).type + " " + args.get(i).name;
- }
- res = res + ")";
- return res;
- }
-
- public String getRenamedCall(String prefix) {
- String res = prefix + "_" + qualifiedName.fullName + "(";
- if (args.size() >= 1) {
- res = res + args.get(0).name;
- }
- for (int i = 1; i < args.size(); i++) {
- res = res + ", " + args.get(i).name;
- }
- res = res + ")";
- return res;
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-
-public class GlobalConstruct extends Construct {
- public final SequentialDefineSubConstruct code;
- private final HashMap<String, HashSet<ConditionalInterface>> interfaceCluster;
- private final HashMap<ConditionalInterface, HashSet<ConditionalInterface>> originalHBRelations;
- public final HashMap<ConditionalInterface, HashSet<ConditionalInterface>> hbRelations;
- public final ArrayList<CommutativityRule> commutativityRules;
- public final HashMap<String, String> options;
-
- public GlobalConstruct(File file, int beginLineNum,
- SequentialDefineSubConstruct code, HashMap<String, String> options) {
- super(file, beginLineNum);
- this.code = code;
- this.interfaceCluster = new HashMap<String, HashSet<ConditionalInterface>>();
- this.originalHBRelations = new HashMap<ConditionalInterface, HashSet<ConditionalInterface>>();
- this.hbRelations = new HashMap<ConditionalInterface, HashSet<ConditionalInterface>>();
- this.options = options;
- this.commutativityRules = new ArrayList<CommutativityRule>();
- }
-
- public void addInterface2Cluster(String clusterName,
- ConditionalInterface condInterface) {
- if (!interfaceCluster.containsKey(clusterName)) {
- interfaceCluster.put(clusterName,
- new HashSet<ConditionalInterface>());
- }
- HashSet<ConditionalInterface> set = interfaceCluster.get(clusterName);
- set.add(condInterface);
- }
-
- public void addHBCondition(ConditionalInterface left,
- ConditionalInterface right) {
- if (!originalHBRelations.containsKey(left)) {
- originalHBRelations.put(left, new HashSet<ConditionalInterface>());
- }
- HashSet<ConditionalInterface> set = originalHBRelations.get(left);
- set.add(right);
- }
-
- public void addCommutativityRule(String method1, String method2, String condition) {
- CommutativityRule rule = new CommutativityRule(method1, method2, condition);
- if (!commutativityRules.contains(rule)) {
- commutativityRules.add(rule);
- }
- }
-
- private void addUnfoldedHBCondition(ConditionalInterface left,
- ConditionalInterface right) {
- if (!hbRelations.containsKey(left)) {
- hbRelations.put(left, new HashSet<ConditionalInterface>());
- }
- HashSet<ConditionalInterface> set = hbRelations.get(left);
- set.add(right);
- }
-
- private HashSet<ConditionalInterface> getByName(
- ConditionalInterface condInterface) {
- if (interfaceCluster.containsKey(condInterface.interfaceName))
- return interfaceCluster.get(condInterface.interfaceName);
- HashSet<ConditionalInterface> res = new HashSet<ConditionalInterface>();
- res.add(condInterface);
- return res;
- }
-
- public void unfoldInterfaceCluster() {
- for (ConditionalInterface left : originalHBRelations.keySet()) {
- HashSet<ConditionalInterface> rights = originalHBRelations
- .get(left);
- for (ConditionalInterface right : rights) {
- HashSet<ConditionalInterface> leftCondInterfaces = getByName(left), rightCondInterfaces = getByName(right);
- for (ConditionalInterface l : leftCondInterfaces) {
- for (ConditionalInterface r : rightCondInterfaces) {
- addUnfoldedHBCondition(l, r);
- }
- }
- }
- }
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder("GlobalConstruct:\n");
- sb.append("@Code:\n");
- sb.append(code);
-
- sb.append("@Happens_before:\n");
- for (ConditionalInterface left : hbRelations.keySet()) {
- HashSet<ConditionalInterface> rights = hbRelations.get(left);
- sb.append(left + " -> ");
- for (ConditionalInterface right : rights) {
- sb.append(right + " | ");
- }
- sb.append(".\n");
- }
-
- return sb.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-public class IDExtractor {
- private String code;
- private int index = 0;
-
- private int idBeginIdx, idEndIdx;
-
- public IDExtractor(String code) {
- this.code = code;
- this.index = 0;
- }
-
- public IDExtractor(String code, int beginIdx) {
- this.code = code;
- this.index = beginIdx;
- }
-
- public void reset(int beginIdx) {
- this.index = beginIdx;
- }
-
- public void reset() {
- this.index = 0;
- }
-
- public int getIDBeginIdx() {
- return this.idBeginIdx;
- }
-
- public int getIDEndIdx() {
- return this.idEndIdx;
- }
-
- public int lineNumOfID() {
- int cnt = 0;
- for (int i = 0; i < idBeginIdx; i++) {
- if (code.charAt(i) == '\n')
- cnt++;
- }
- return cnt;
- }
-
- public int lineBeginIdxOfID() {
- int i;
- for (i = idBeginIdx - 1; i >= 0; i--) {
- if (code.charAt(i) == '\n')
- break;
- }
- return i + 1;
- }
-
- public int lineEndIdxOfID() {
- int i = 0;
- for (i = idEndIdx + 1; i < code.length(); i++) {
- if (code.charAt(i) == '\n') {
- break;
- }
- }
- return i - 1;
- }
-
- public String getPrevID() {
- int beginIdx = index;
- int endIdx = index;
- char ch;
- while (true) {
- ch = code.charAt(endIdx);
- if ((ch == '_' || (ch >= 'a' && ch <= 'z') || ch >= 'A'
- && ch <= 'Z')) {
- break;
- }
- endIdx--;
- }
- beginIdx = endIdx;
- while (true) {
- ch = code.charAt(beginIdx);
- if (!((ch == '_' || (ch >= 'a' && ch <= 'z') || ch >= 'A'
- && ch <= 'Z'))) {
- break;
- }
- beginIdx--;
- }
- index = beginIdx;
- if (beginIdx > endIdx)
- return null;
- idBeginIdx = beginIdx + 1;
- idEndIdx = endIdx;
- return code.substring(beginIdx + 1, endIdx + 1);
- }
-
- public String getNextID() {
- int beginIdx = index;
- int endIdx = index;
- char ch;
- while (true) {
- ch = code.charAt(beginIdx);
- if ((ch == '_' || (ch >= 'a' && ch <= 'z') || ch >= 'A'
- && ch <= 'Z')) {
- break;
- }
- beginIdx++;
- }
- endIdx = beginIdx;
- while (true) {
- ch = code.charAt(endIdx);
- if (!((ch == '_' || (ch >= 'a' && ch <= 'z') || ch >= 'A'
- && ch <= 'Z'))) {
- break;
- }
- endIdx++;
- }
- index = endIdx;
- if (beginIdx > endIdx)
- return null;
- idBeginIdx = beginIdx;
- idEndIdx = endIdx - 1;
- return code.substring(beginIdx, endIdx);
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class InterfaceConstruct extends Construct {
- public final String name;
- public final ArrayList<String> commitPointSet;
- public final String condition;
- public final HashMap<String, String> hbConditions;
- public final String idCode;
- public final String check;
- public final ArrayList<String> action;
- public final ArrayList<String> postAction;
- public final String postCheck;
-
- public InterfaceConstruct(File file, int beginLineNum, String name,
- ArrayList<String> commitPointSet, String condition,
- HashMap<String, String> hbConditions, String idCode, String check,
- ArrayList<String> action, ArrayList<String> postAction, String postCheck) {
- super(file, beginLineNum);
- this.name = name;
- this.commitPointSet = commitPointSet;
- this.condition = condition;
- this.hbConditions = hbConditions;
- this.idCode = idCode;
- this.check = check;
- this.action = action;
- this.postAction = postAction;
- this.postCheck = postCheck;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder("InterfaceConstruct:\n");
- sb.append("@Interface: " + name + "\n");
- sb.append("@Commit_point_set: ");
- for (String commitPoint : commitPointSet) {
- sb.append(commitPoint + " | ");
- }
- sb.append(".\n");
- sb.append("@Condition: ");
- sb.append(condition + "\n");
- sb.append("@HBConditions: \n");
- for (String hbLabel : hbConditions.keySet()) {
- String hbCondition = hbConditions.get(hbLabel);
- sb.append(hbLabel + " :: " + hbCondition + "\n");
- }
- sb.append("@ID: ");
- sb.append(idCode + "\n");
- sb.append("@Check: " + check + "\n");
- sb.append(ParserUtils.array2Str(action));
- sb.append("@Post_action:\n");
- sb.append(ParserUtils.array2Str(postAction));
- sb.append("@Post_check: " + postCheck + "\n");
-
- return sb.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class InterfaceDefineConstruct extends Construct {
- public final String name;
-
- public InterfaceDefineConstruct(File file, int beginLineNum, String name) {
- super(file, beginLineNum);
- this.name = name;
- }
-
- public String toString() {
- return "@Interface_define: " + name;
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import edu.uci.eecs.specCompiler.codeGenerator.Environment;
-import edu.uci.eecs.specCompiler.grammerParser.utilParser.ParseException;
-import edu.uci.eecs.specCompiler.grammerParser.utilParser.UtilParser;
-
-/**
- * <p> Utility functions for parsing the specifications </p>
- * @author peizhaoo
- *
- */
-public class ParserUtils {
- public static String trimSpace(String line) {
- int i, j;
- char ch;
- for (i = 0; i < line.length(); i++) {
- ch = line.charAt(i);
- if (ch != ' ' && ch != '\t')
- break;
- }
- for (j = line.length() - 1; j >= 0; j--) {
- ch = line.charAt(j);
- if (ch != ' ' && ch != '\t')
- break;
- }
- if (i > j)
- return "";
- else
- return line.substring(i, j + 1);
- }
-
- public static String array2Str(ArrayList code) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < code.size(); i++) {
- sb.append(code.get(i) + "\n");
- }
- return sb.toString();
- }
-
- public static String getClassName(String classDefineLine) {
- IDExtractor extractor = new IDExtractor(classDefineLine,
- classDefineLine.length() - 1);
- return extractor.getPrevID();
- }
-
- public static String getTemplateStr(String templateLine) {
- String templateStr = null;
- ArrayList<VariableDeclaration> templateArgs;
- try {
- templateArgs = UtilParser.getTemplateArg(templateLine);
- templateStr = "<" + templateArgs.get(0).name;
- for (int i = 1; i < templateArgs.size(); i++) {
- templateStr = templateStr + ", " + templateArgs.get(i).name;
- }
- templateStr = templateStr + ">";
- } catch (ParseException e) {
- e.printStackTrace();
- }
-
- return templateStr;
- }
-
- public static void write2File(File file, ArrayList<String> content) {
- String newFileName = Environment.GENERATED_FILE_DIR + "/"
- + file.getParentFile().getName() + "/" + file.getName();
-
- File newFile = new File(newFileName);
- newFile.getParentFile().mkdirs();
- if (!newFile.exists()) {
- try {
- newFile.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- try {
- BufferedWriter bw = new BufferedWriter(new FileWriter(newFile));
- for (int i = 0; i < content.size(); i++) {
- bw.write(content.get(i) + "\n");
- }
- bw.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.File;
-
-public class PotentialCPDefineConstruct extends Construct {
- public final boolean isAdditionalOrderingPoint;
-
- public final String label;
- public final String condition;
-
- public PotentialCPDefineConstruct(File file, int beginLineNum,
- String label, String condition) {
- super(file, beginLineNum);
- this.isAdditionalOrderingPoint = false;
- this.label = label;
- this.condition = condition;
- }
-
- public PotentialCPDefineConstruct(File file, int beginLineNum,
- boolean isAdditionalOrderingPoint, String label, String condition) {
- super(file, beginLineNum);
- this.isAdditionalOrderingPoint = isAdditionalOrderingPoint;
- this.label = label;
- this.condition = condition;
- }
-
- public String toString() {
- StringBuffer res = new StringBuffer();
- res.append("@Potential_commit_point_define:\n");
- res.append("Label: " + label + "\n");
- res.append("Condition: " + condition + "\n");
- return res.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-public class QualifiedName {
- public final String fullName;
- public final String bareName;
- public final String qualifiedName;
-
- public QualifiedName(String fullName) {
- this.fullName = fullName;
- this.bareName = getBareName();
- this.qualifiedName = getQualifiedName();
- }
-
- private String getBareName() {
- int beginIdx;
- beginIdx = fullName.lastIndexOf(':');
- if (beginIdx == -1)
- return fullName;
- else
- return fullName.substring(beginIdx + 1);
- }
-
- private String getQualifiedName() {
- int endIdx = fullName.lastIndexOf(bareName);
- if (endIdx == 0)
- return "";
- return fullName.substring(0, endIdx);
- }
-
- public String toString() {
- return fullName + "\n" + bareName;
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.util.ArrayList;
-
-public class SequentialDefineSubConstruct {
- public final ArrayList<String> initVar;
- public final ArrayList<String> cleanupCode;
- public final ArrayList<ArrayList<String>> defineFuncs;
- public final ArrayList<VariableDeclaration> declareVar;
- public final ArrayList<ArrayList<String>> declareStructs;
-
- public SequentialDefineSubConstruct(
- ArrayList<ArrayList<String>> declareStruct,
- ArrayList<VariableDeclaration> declareVar,
- ArrayList<String> initVar, ArrayList<String> cleanupCode,
- ArrayList<ArrayList<String>> defineFuncs) {
- this.declareStructs = declareStruct;
- this.declareVar = declareVar;
- this.initVar = initVar;
- this.cleanupCode = cleanupCode;
- this.defineFuncs = defineFuncs;
- }
-
- public String toString() {
- StringBuffer res = new StringBuffer();
- res.append("@Sequential_define:\n");
- res.append("@DeclareStruct:\n");
- for (int i = 0; i < declareStructs.size(); i++) {
- res.append(ParserUtils.array2Str(declareStructs.get(i)) + "\n");
- }
- res.append("@DeclareVar:\n");
- res.append(ParserUtils.array2Str(declareVar));
- res.append("@InitVar:\n");
- res.append(ParserUtils.array2Str(initVar));
- res.append("@DefineFunc:\n");
- for (int i = 0; i < defineFuncs.size(); i++) {
- res.append(ParserUtils.array2Str(defineFuncs.get(i)) + "\n");
- }
- return res.toString();
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import edu.uci.eecs.specCompiler.codeGenerator.Environment;
-
-public class SourceFileInfo {
- public final File file;
- public final ArrayList<String> content;
- public final ArrayList<String> headers;
- public final ArrayList<Construct> constructs;
-
- public SourceFileInfo(File file, ArrayList<String> content,
- ArrayList<String> headers, ArrayList<Construct> constructs) {
- this.file = file;
- this.content = content;
- this.headers = headers;
- this.constructs = constructs;
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof SourceFileInfo))
- return false;
- SourceFileInfo another = (SourceFileInfo) o;
- return another.file.equals(file);
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.LineNumberReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-
-import edu.uci.eecs.specCompiler.grammerParser.ParseException;
-import edu.uci.eecs.specCompiler.grammerParser.SpecParser;
-import edu.uci.eecs.specCompiler.grammerParser.TokenMgrError;
-
-/**
- * <p>
- * This class represents the specification extractor of the specification. The
- * main function of this class is to read C/C++11 source files and extract the
- * corresponding specifications, and record corresponding information such as
- * location, e.g., the file name and the line number, to help the code
- * generation process.
- * </p>
- *
- * @author peizhaoo
- *
- */
-public class SpecExtractor {
- public final HashMap<File, SourceFileInfo> srcFilesInfo;
-
- public SpecExtractor() {
- srcFilesInfo = new HashMap<File, SourceFileInfo>();
- }
-
- public ArrayList<Construct> getConstructs() {
- ArrayList<Construct> constructs = new ArrayList<Construct>();
- for (File f : srcFilesInfo.keySet()) {
- constructs.addAll(srcFilesInfo.get(f).constructs);
- }
- return constructs;
- }
-
- /**
- * <p>
- * Given a list of files, it scans each file and add found SpecConstrcut to
- * the _constructs list.
- * </p>
- *
- * @param files
- * @throws SpecNotMatchException
- */
- public void extract(File[] files) {
- for (int i = 0; i < files.length; i++)
- extract(files[i]);
- }
-
- public void extract(File file) {
- if (srcFilesInfo.containsKey(file))
- return;
- SourceFileInfo srcFileInfo;
- try {
- srcFileInfo = SpecParser.ParseFile(file);
- for (int i = 0; i < srcFileInfo.content.size(); i++) {
- System.out.println(srcFileInfo.content.get(i));
- }
- ParserUtils.write2File(srcFileInfo.file, srcFileInfo.content);
- srcFilesInfo.put(file, srcFileInfo);
- } catch (ParseException e) {
- e.printStackTrace();
- } catch (TokenMgrError e) {
- e.printStackTrace();
- }
- }
-
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-import java.util.HashMap;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.LineNumberReader;
-
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
-/**
- * <p>
- * This class will scan all the input files, extract all the "special comments"
- * (specifications). It should include information: 1. Beginning and end line of
- * the specs; 2. The next two lines of code if it is interface constrcut.
- * </p>
- *
- * @author peizhaoo
- *
- */
-public class SpecInfoScanner {
- public final HashMap<File, Construct> constructs;
-
- public SpecInfoScanner() {
- constructs = new HashMap<File, Construct>();
- }
-
- /**
- * <p>
- * Scan
- * </p>
- *
- * @param file
- */
- private void scanFile(File file) {
- try {
- FileReader fr = new FileReader(file);
- LineNumberReader lnr = new LineNumberReader(fr);
- String line = null;
- // Info to keep when parsing the Spec
- // 0 for default, 1 for potential sepc, 2 for in spec
- int state = 0;
- Pattern pBegin = Pattern.compile("^[\\s|\\t]*/**"), pEnd = Pattern
- .compile("*/$");
- while ((line = lnr.readLine()) != null) {
- Matcher m1 = pBegin.matcher(line);
- if (m1.matches())
- state = 1; // Go to 'potential spec' state
- if (state == 1) {
-
- }
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public void scanFiles(File[] files) {
- for (int i = 0; i < files.length; i++) {
- scanFile(files[i]);
- }
- }
-}
+++ /dev/null
-package edu.uci.eecs.specCompiler.specExtraction;
-
-public class VariableDeclaration {
- public String type;
- public String name;
-
- public VariableDeclaration(String type, String name) {
- this.type = type;
- this.name = name;
- }
-
- public String toString() {
- return type + " " + name;
- }
-}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.util.ArrayList;
+
+import edu.uci.eecs.specExtraction.SpecUtils.IntObj;
+
+/**
+ * <p>
+ * This class represents a piece of code --- a list of strings (lines). Such a
+ * wrapper makes code extraction and generation easier.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class Code {
+
+ // The list that represents all the lines of this code snippet
+ public final ArrayList<String> lines;
+
+ public Code() {
+ lines = new ArrayList<String>();
+ }
+
+ /**
+ * <p>
+ * It adds a line, which is very likely to be a simple C/C++ statement,
+ * which is a string lines of statement.
+ * </p>
+ *
+ * @param line
+ * A C/C++ line of statement
+ */
+ public void addLine(String line) {
+ lines.add(line);
+ }
+
+ /**
+ * <p>
+ * It adds a list of lines, which are very likely to be simple C/C++
+ * statements.
+ * </p>
+ *
+ * @param line
+ * A list of C/C++ lines of statement
+ */
+ public void addLines(ArrayList<String> code) {
+ for (int i = 0; i < code.size(); i++)
+ lines.add(code.get(i));
+ }
+
+ /**
+ * <p>
+ * It adds a list of lines, which are very likely to be simple C/C++
+ * statements.
+ * </p>
+ *
+ * @param line
+ * A Code object --- list of C/C++ lines of statement
+ */
+ public void addLines(Code code) {
+ addLines(code.lines);
+ }
+
+ /**
+ * @return Whether this code snippet is empty
+ */
+ public boolean isEmpty() {
+ return lines.size() == 0;
+ }
+
+ /**
+ * <p>
+ * Align the set of code with an initial number of tabs. This basically
+ * tries to make the generated code more readable.
+ *
+ * @param initialTabsCnt
+ * The number of tabs that we want to put before the code
+ * initially.
+ */
+ public void align(int initialTabsCnt) {
+ int tabLevel = initialTabsCnt;
+ IntObj idx = new IntObj(0);
+ alignHelper(idx, tabLevel, false);
+ }
+
+ /**
+ * <p>
+ * This is a helper function to align a list of code. Caller should
+ * initialize an IntObj with intial value "0", and pass with the initial tab
+ * level and pass the value of "false" to the noBraceKeyword.
+ *
+ * @param idx
+ * The IntObj that represents the current index of the code lines
+ * @param tabLevel
+ * The tab level we are currently at
+ * @param noBraceKeyword
+ * Whether we just encountered a "noBraceKeyword"
+ */
+ private void alignHelper(IntObj idx, int tabLevel, boolean noBraceKeyword) {
+ for (; idx.getVal() < lines.size(); idx.inc()) {
+ String curLine = lines.get(idx.getVal());
+ String newLine = null;
+ // Return to the previous recursive level
+ if (closingBrace(curLine)) {
+ return;
+ }
+ if ((noBraceKeyword && !keywordBrace(curLine) && !keywordNoBrace(curLine))) {
+ // Before returning, we just need to first add the line with the
+ // current tab
+ newLine = makeTabs(tabLevel) + curLine;
+ lines.set(idx.getVal(), newLine);
+ return;
+ }
+
+ newLine = makeTabs(tabLevel) + curLine;
+ lines.set(idx.getVal(), newLine);
+
+ if (keywordBrace(curLine)) {
+ idx.inc();
+ alignHelper(idx, tabLevel + 1, false);
+ // Add the closing line
+ curLine = lines.get(idx.getVal());
+ newLine = makeTabs(tabLevel) + curLine;
+ lines.set(idx.getVal(), newLine);
+ } else if (keywordNoBrace(curLine)) { // No brace
+ idx.inc();
+ alignHelper(idx, tabLevel + 1, true);
+ if (noBraceKeyword)
+ return;
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Lines that starts with a key word and ends with ";".
+ * </p>
+ *
+ * @param curLine
+ * @return
+ */
+ private boolean closingBrace(String curLine) {
+ return curLine.endsWith("}");
+ }
+
+ /**
+ * <p>
+ * Lines that starts with a key word and ends with "{".
+ * </p>
+ *
+ * @param curLine
+ * @return
+ */
+ private boolean keywordBrace(String curLine) {
+ return (curLine.startsWith("for") || curLine.startsWith("ForEach")
+ || curLine.startsWith("if") || curLine.startsWith("else")
+ || curLine.startsWith("while") || curLine.startsWith("do"))
+ && curLine.endsWith("{");
+ }
+
+ /**
+ * <p>
+ * Lines that starts with a key word and ends with no "{" and no ";".
+ * </p>
+ *
+ * @param curLine
+ * @return
+ */
+ private boolean keywordNoBrace(String curLine) {
+ return (curLine.startsWith("for") || curLine.startsWith("ForEach")
+ || curLine.startsWith("if") || curLine.startsWith("else")
+ || curLine.startsWith("while") || curLine.startsWith("do"))
+ && !curLine.endsWith("{") && !curLine.endsWith(";");
+ }
+
+ /**
+ * @param tabCnt
+ * The number of tabs
+ * @return Generate a string whose content is a specific number (tabCnt) of
+ * tab symbols.
+ */
+ private String makeTabs(int tabCnt) {
+ String res = "";
+ for (int i = 0; i < tabCnt; i++)
+ res = res + "\t";
+ return res;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < lines.size(); i++) {
+ sb.append(lines.get(i) + "\n");
+ }
+ return sb.toString();
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+/**
+ * <p> This class represents a commutativity rule in the specification.
+ * @author Peizhao Ou
+ *
+ */
+public class CommutativityRule {
+ public final String method1, method2;
+
+ public final String condition;
+
+ public CommutativityRule(String m1, String m2, String condition) {
+ this.method1 = m1;
+ this.method2 = m2;
+ this.condition = condition;
+ }
+
+ public String toString() {
+ return method1 + " <-> " + method2 + ": " + condition;
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+
+/**
+ * <p>
+ * An abstract class for all different specification constructs, including
+ * global construct, interface construct and ordering point construct.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+abstract public class Construct {
+ // The file that this construct is in
+ public final File file;
+ // The beginning line number of this construct (the plain text line number)
+ public final int beginLineNum;
+
+ public Construct(File file, int beginLineNum) {
+ this.file = file;
+ this.beginLineNum = beginLineNum;
+ }
+
+ public String toString() {
+ return file.getName() + ": Line " + Integer.toString(beginLineNum);
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+
+/**
+ * <p>
+ * This class is a subclass of Construct. It represents a complete entry
+ * annotation.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class EntryConstruct extends Construct {
+
+ // The original line of text of the entry annotation
+ public final String annotation;
+
+ public EntryConstruct(File file, int beginLineNum, String annotation) {
+ super(file, beginLineNum);
+ this.annotation = annotation;
+ }
+
+ public String toString() {
+ StringBuffer res = new StringBuffer();
+ res.append(super.toString() + "\n");
+ res.append("@Entry");
+ return res.toString();
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.util.ArrayList;
+
+/**
+ * <p>
+ * This represents a function declaration header. For example,
+ * "void myFunction(int arg1, bool arg2)" is a function declaration header.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class FunctionHeader {
+ private ArrayList<VariableDeclaration> templateList;
+
+ // The return type of the function
+ public final String returnType;
+ // The function name
+ public final QualifiedName funcName;
+ // The argument list (with formal parameter names)
+ public final ArrayList<VariableDeclaration> args;
+
+ // The actually function definition line in plain text.
+ // E.g. "void myFunction(int arg1, bool arg2) {"
+ private String headerLine;
+
+ public FunctionHeader(String returnType, QualifiedName qualifiedName,
+ ArrayList<VariableDeclaration> args) {
+ this.templateList = null;
+ this.returnType = returnType;
+ this.funcName = qualifiedName;
+ this.args = args;
+ }
+
+ /**
+ *
+ * @return Whether the return type is void
+ */
+ public boolean isReturnVoid() {
+ return returnType.equals("void");
+ }
+
+ public void setTemplateList(ArrayList<VariableDeclaration> templateList) {
+ this.templateList = templateList;
+ }
+
+ public ArrayList<VariableDeclaration> getTemplateList() {
+ return this.templateList;
+ }
+
+ public String getTemplateFullStr() {
+ String templateStr = "";
+ if (templateList == null)
+ return templateStr;
+ VariableDeclaration decl;
+ decl = templateList.get(0);
+ templateStr = "<" + decl.type + " " + decl.name;
+ for (int i = 1; i < templateList.size(); i++) {
+ decl = templateList.get(i);
+ templateStr = templateStr + ", " + decl.type + " " + decl.name;
+ }
+ templateStr = templateStr + ">";
+ return templateStr;
+ }
+
+ public String getTemplateArgStr() {
+ String templateStr = null;
+ if (templateList.size() == 0)
+ return templateStr;
+ templateStr = "<" + templateList.get(0).name;
+ for (int i = 1; i < templateList.size(); i++) {
+ templateStr = templateStr + ", " + templateList.get(i);
+ }
+ templateStr = templateStr + ">";
+ return templateStr;
+ }
+
+ public String getFuncStr() {
+ String res = returnType + " " + funcName.fullName + "(";
+ if (args.size() >= 1) {
+ res = res + args.get(0);
+ }
+ for (int i = 1; i < args.size(); i++) {
+ res = res + ", " + args.get(i);
+ }
+ res = res + ")";
+ return res;
+ }
+
+ public String toString() {
+ String res = returnType + " " + funcName.fullName + "(";
+ if (args.size() >= 1) {
+ res = res + args.get(0);
+ }
+ for (int i = 1; i < args.size(); i++) {
+ res = res + ", " + args.get(i);
+ }
+ res = res + ")";
+ return res;
+ }
+
+ public String getRenamedFuncName() {
+ return funcName.qualifiedName + SpecNaming.WrapperPrefix + "_"
+ + funcName.bareName;
+ }
+
+ public FunctionHeader getRenamedHeader(String prefix) {
+ String newFullName = getRenamedFuncName();
+ FunctionHeader newHeader = new FunctionHeader(returnType,
+ new QualifiedName(newFullName), args);
+ return newHeader;
+ }
+
+ public FunctionHeader getRenamedHeader() {
+ return getRenamedHeader(SpecNaming.WrapperPrefix);
+ }
+
+ /**
+ *
+ * @return The string that represents the renamed function header line. For
+ * example, we would return
+ * <code>"bool Wrapper_myFunc(int x, int y)"</code> for the fucntion
+ * <code>"bool myFunc(int x, int y) {"</code>
+ */
+ public String getRenamedFuncLine() {
+ String bareName = this.funcName.bareName;
+ String newName = this.getRenamedFuncName();
+ return this.headerLine.replaceFirst(bareName, newName);
+ }
+
+ /**
+ *
+ * @return The string that represents the renamed function call. For
+ * example, we would return <code>"bool RET = myFunc(x, y)"</code>
+ * for the fucntion <code>"bool myFunc(int x, int y)"</code>
+ */
+ public String getRenamedCall() {
+ return getRenamedCall(SpecNaming.WrapperPrefix);
+ }
+
+ /**
+ *
+ * @return The original plain text line of the function header
+ */
+ public String getHeaderLine() {
+ return headerLine;
+ }
+
+
+ // No support for template right now
+ public String getDeclaration() {
+ String res = returnType + " " + funcName.fullName + "(";
+ if (args.size() >= 1) {
+ res = res + args.get(0).type + " " + args.get(0).name;
+ }
+ for (int i = 1; i < args.size(); i++) {
+ res = res + ", " + args.get(i).type + " " + args.get(i).name;
+ }
+ res = res + ")";
+ return res;
+ }
+
+ public String getRenamedCall(String prefix) {
+ String res = "";
+ if (!isReturnVoid()) {
+ res = res + "bool " + SpecNaming.RET + " = ";
+ }
+ res = res + prefix + "_" + funcName.fullName + "(";
+ if (args.size() >= 1) {
+ res = res + args.get(0).name;
+ }
+ for (int i = 1; i < args.size(); i++) {
+ res = res + ", " + args.get(i).name;
+ }
+ res = res + ")";
+ return res;
+ }
+
+ public void setHeaderLine(String headerLine) {
+ this.headerLine = headerLine;
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import edu.uci.eecs.specExtraction.SpecUtils.IntObj;
+import edu.uci.eecs.specExtraction.SpecUtils.Primitive;
+
+/**
+ * <p>
+ * This class is a subclass of Construct. It represents a complete global state
+ * annotation.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class GlobalConstruct extends Construct {
+ public final ArrayList<VariableDeclaration> declState;
+ public final Code initState;
+ public final Code copyState;
+ public final Code finalState;
+ public final Code printState;
+ public final ArrayList<CommutativityRule> commutativityRules;
+
+ public final boolean autoGenCopy;
+
+ public GlobalConstruct(File file, int beginLineNum,
+ ArrayList<String> annotations) throws WrongAnnotationException {
+ super(file, beginLineNum);
+ declState = new ArrayList<VariableDeclaration>();
+ initState = new Code();
+ copyState = new Code();
+ finalState = new Code();
+ printState = new Code();
+ commutativityRules = new ArrayList<CommutativityRule>();
+
+ processAnnotations(annotations);
+
+ if (copyState.isEmpty()) {
+ Code code = generateAutoCopyFunction();
+ copyState.addLines(code);
+ autoGenCopy = true;
+ } else {
+ autoGenCopy = false;
+ }
+ }
+
+ /**
+ * <p>
+ * This function will automatically generate the copy statements for
+ * supported types if the user has not defined the "@Copy" primitive
+ * </p>
+ *
+ * @return The auto-generated copy statements
+ * @throws WrongAnnotationException
+ */
+ private Code generateAutoCopyFunction() throws WrongAnnotationException {
+ Code code = new Code();
+ for (VariableDeclaration decl : declState) {
+ String type = decl.type;
+ String name = decl.name;
+ // Primitive types
+ if (type.equals("int") || type.equals("unsigned")
+ || type.equals("unsigned int")
+ || type.equals("int unsigned") || type.equals("double")
+ || type.equals("double")) {
+ // NEW->x = OLD->x;
+ code.addLine(SpecNaming.NewStateInst + "->" + name + " = "
+ + SpecNaming.OldStateInst + "->" + name + ";");
+ } else if (type.equals("IntList") || type.equals("IntSet")
+ || type.equals("IntMap")) {
+ // Supported types
+ // New->q = IntList(OLD->q);
+ code.addLine(SpecNaming.NewStateInst + "->" + name + " = "
+ + type + "(" + SpecNaming.OldStateInst + "->" + name
+ + ");");
+ } else if (type.equals("IntList *") || type.equals("IntSet *")
+ || type.equals("IntMap *")) {
+ // Supported pointer types
+ // New->q = new IntList(*OLD->q);
+ String originalType = SpecUtils.trimSpace(type
+ .replace('*', ' '));
+ code.addLine(SpecNaming.NewStateInst + "->" + name + " = new "
+ + originalType + "(*" + SpecNaming.OldStateInst + "->"
+ + name + ");");
+ } else {
+ WrongAnnotationException
+ .err(file,
+ beginLineNum,
+ "You have types in the state declaration that we do not support auto-gen copy function.");
+ }
+ }
+
+ return code;
+ }
+
+ /**
+ * <p>
+ * Assert that the global state primitive is valid; if not, throws an
+ * exception.
+ * </p>
+ *
+ * @param file
+ * Current file
+ * @param primitive
+ * The primitive that we have extracted earlier
+ * @throws WrongAnnotationException
+ */
+ private void assertValidPrimitive(File file, Primitive primitive)
+ throws WrongAnnotationException {
+ int lineNum = primitive.beginLineNum;
+ String name = primitive.name;
+ if (!name.equals(SpecNaming.DeclareState)
+ && !name.equals(SpecNaming.InitalState)
+ && !name.equals(SpecNaming.CopyState)
+ && !name.equals(SpecNaming.FinalState)
+ && !name.equals(SpecNaming.Commutativity)
+ && !name.equals(SpecNaming.PrintState)) {
+ WrongAnnotationException.err(file, lineNum, name
+ + " is NOT a valid CDSSpec global state primitive.");
+ }
+ }
+
+ /**
+ * <p>
+ * Given a "@DeclareState" primitive that has a list of strings of
+ * declarations, we initialize our local "declState" members.
+ *
+ * @param primitive
+ * @throws WrongAnnotationException
+ */
+ private void processDeclState(Primitive primitive)
+ throws WrongAnnotationException {
+ for (int i = 0; i < primitive.contents.size(); i++) {
+ int lineNum = i + primitive.beginLineNum;
+ String declLine = primitive.contents.get(i);
+ VariableDeclaration tmp = new VariableDeclaration(file, lineNum,
+ declLine);
+ declState.add(tmp);
+ }
+ }
+
+ /**
+ * <p>
+ * Given a "@DeclareState" primitive that has a list of strings of
+ * declarations, we initialize our local "declState" members.
+ *
+ * @param primitive
+ * @throws WrongAnnotationException
+ */
+ private void processCommutativity(Primitive primitive)
+ throws WrongAnnotationException {
+ // Mathch commutativity rule
+ Pattern regexpCommute = Pattern
+ .compile("\\s*(\\w+)\\s*<->\\s*(\\w+)\\s*\\((.*)\\)\\s*$");
+ Matcher matcherCommute = regexpCommute.matcher("");
+
+ for (int i = 0; i < primitive.contents.size(); i++) {
+ // FIXME: Currently we only allow a one-line commutativity rule
+ int curLineNum = primitive.beginLineNum + i;
+ String line = primitive.contents.get(i);
+ matcherCommute.reset(line);
+ if (matcherCommute.find()) {
+ String method1 = matcherCommute.group(1);
+ String method2 = matcherCommute.group(2);
+ String code = matcherCommute.group(3);
+ String rule = SpecUtils.trimSpace(SpecUtils
+ .trimTrailingCommentSymbol(code));
+ commutativityRules.add(new CommutativityRule(method1, method2,
+ rule));
+ } else {
+ WrongAnnotationException
+ .err(file,
+ curLineNum,
+ "The @Commutativity annotation should be: @Commutativity: Method1 <-> Method2 (condition)\n\t"
+ + "Problematic line: \"" + line + "\"");
+ }
+ // Done with processing the current commutativity
+ }
+ }
+
+ private void processAnnotations(ArrayList<String> annotations)
+ throws WrongAnnotationException {
+ IntObj curIdx = new IntObj(0);
+ Primitive primitive = null;
+
+ while ((primitive = SpecUtils.extractPrimitive(file, beginLineNum,
+ annotations, curIdx)) != null) {
+ String name = primitive.name;
+ assertValidPrimitive(file, primitive);
+ if (primitive.contents.size() == 0)
+ continue;
+ if (name.equals(SpecNaming.DeclareState)) {
+ processDeclState(primitive);
+ } else if (name.equals(SpecNaming.InitalState)) {
+ initState.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.CopyState)) {
+ copyState.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.FinalState)) {
+ finalState.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.PrintState)) {
+ printState.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.Commutativity)) {
+ processCommutativity(primitive);
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder("");
+ sb.append(super.toString() + "\n");
+ sb.append("@DeclareState:\n");
+ sb.append(declState);
+ sb.append("\n");
+ sb.append("@InitState:\n");
+ sb.append(initState);
+ if (!printState.isEmpty()) {
+ sb.append("@Print:\n");
+ sb.append(printState);
+ }
+
+ for (int i = 0; i < commutativityRules.size(); i++) {
+ sb.append("@Commutativity: " + commutativityRules + "\n");
+ }
+ return sb.toString();
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import edu.uci.eecs.specExtraction.SpecUtils.IntObj;
+import edu.uci.eecs.specExtraction.SpecUtils.Primitive;
+import edu.uci.eecs.utilParser.ParseException;
+import edu.uci.eecs.utilParser.UtilParser;
+
+/**
+ * <p>
+ * This class is a subclass of Construct. It represents a complete interface
+ * annotation.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class InterfaceConstruct extends Construct {
+ private String name;
+ public final Code transition;
+ public final Code preCondition;
+ public final Code sideEffect;
+ public final Code postCondition;
+ public final Code print;
+
+ // The ending line number of the specification annotation construct
+ public final int endLineNum;
+
+ // The ending line number of the function definition
+ private int endLineNumFunction;
+ // The function header of the corresponding interface --- The list of
+ // variable declarations that represent the RETURN value and
+ // arguments of the interface
+ private FunctionHeader funcHeader;
+
+ public InterfaceConstruct(File file, int beginLineNum, int endLineNum,
+ ArrayList<String> annotations) throws WrongAnnotationException {
+ super(file, beginLineNum);
+ this.endLineNum = endLineNum;
+ this.name = null;
+ this.transition = new Code();
+ this.preCondition = new Code();
+ this.sideEffect = new Code();
+ this.postCondition = new Code();
+ this.print = new Code();
+
+ processAnnotations(annotations);
+ }
+
+ public FunctionHeader getFunctionHeader() {
+ return this.funcHeader;
+ }
+
+ public boolean equals(Object other) {
+ if (!(other instanceof InterfaceConstruct)) {
+ return false;
+ }
+ InterfaceConstruct o = (InterfaceConstruct) other;
+ if (o.name.equals(this.name))
+ return true;
+ else
+ return false;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * <p>
+ * Assert that the interface primitive is valid; if not, throws an exception
+ * </p>
+ *
+ * @param file
+ * Current file
+ * @param primitive
+ * The primitive string that we have extracted earlier
+ * @throws WrongAnnotationException
+ */
+ private void assertValidPrimitive(File file, Primitive primitive)
+ throws WrongAnnotationException {
+ int lineNum = primitive.beginLineNum;
+ String name = primitive.name;
+ if (!name.equals(SpecNaming.Interface)
+ && !name.equals(SpecNaming.Transition)
+ && !name.equals(SpecNaming.PreCondition)
+ && !name.equals(SpecNaming.SideEffect)
+ && !name.equals(SpecNaming.PostCondition)
+ && !name.equals(SpecNaming.PrintValue)) {
+ WrongAnnotationException.err(file, lineNum, name
+ + " is NOT a valid CDSSpec interface primitive.");
+ }
+ }
+
+ /**
+ * <p>
+ * Assert that the "@Interface" primitive has correct syntax; if not, throws
+ * an exception. If so, it basically checks whether content of the primitive
+ * is a valid word and then return interface label name.
+ * </p>
+ *
+ * @param file
+ * Current file
+ * @param lineNum
+ * Current line number
+ * @param primitive
+ * The primitive string that we have extracted earlier
+ * @throws WrongAnnotationException
+ */
+ private String extractInterfaceName(File file, Primitive primitive)
+ throws WrongAnnotationException {
+ int lineNum = primitive.beginLineNum;
+ String name = primitive.name;
+ if (primitive.contents.size() != 1)
+ WrongAnnotationException.err(file, lineNum,
+ "The @Interface primitive: " + name + " has wrong syntax.");
+ String line = primitive.contents.get(0);
+ SpecUtils.matcherWord.reset(line);
+ if (!SpecUtils.matcherWord.find())
+ WrongAnnotationException.err(file, lineNum, name
+ + " is NOT a valid CDSSpec @Interface primitive.");
+ return line;
+ }
+
+ private void processAnnotations(ArrayList<String> annotations)
+ throws WrongAnnotationException {
+ IntObj curIdx = new IntObj(0);
+ Primitive primitive = null;
+
+ while ((primitive = SpecUtils.extractPrimitive(file, beginLineNum,
+ annotations, curIdx)) != null) {
+ String name = primitive.name;
+ assertValidPrimitive(file, primitive);
+ if (primitive.contents.size() == 0)
+ continue;
+ if (name.equals(SpecNaming.Interface)) {
+ this.name = extractInterfaceName(file, primitive);
+ } else if (name.equals(SpecNaming.Transition)) {
+ this.transition.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.PreCondition)) {
+ this.preCondition.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.SideEffect)) {
+ this.sideEffect.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.PostCondition)) {
+ this.postCondition.addLines(primitive.contents);
+ } else if (name.equals(SpecNaming.PrintValue)) {
+ this.print.addLines(primitive.contents);
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * This function is called to extract all the declarations that should go to
+ * the corresponding value struct --- a C++ struct to be generated for this
+ * interface that contains the information of the return value and the
+ * arguments.
+ * </p>
+ *
+ * @param line
+ * The line that represents the interface declaration line
+ * @throws ParseException
+ */
+ public void processFunctionDeclaration(String line) throws ParseException {
+ // FIXME: Currently we only allow the declaration to be one-liner
+ funcHeader = UtilParser.parseFuncHeader(line);
+ // Record the original declaration line
+ funcHeader.setHeaderLine(line);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString() + "\n");
+ sb.append("@Interface: " + name + "\n");
+ if (!transition.isEmpty())
+ sb.append("@Transition:\n" + transition);
+ if (!preCondition.isEmpty())
+ sb.append("@PreCondition:\n" + preCondition);
+ if (!sideEffect.isEmpty())
+ sb.append("@SideEffect:\n" + sideEffect);
+ if (!postCondition.isEmpty())
+ sb.append("@PostCondition:\n" + postCondition);
+ if (!print.isEmpty())
+ sb.append("@Print:\n" + print + "\n");
+ sb.append(funcHeader);
+
+ return sb.toString();
+ }
+
+ public int getEndLineNumFunction() {
+ return endLineNumFunction;
+ }
+
+ public void setEndLineNumFunction(int endLineNumFunction) {
+ this.endLineNumFunction = endLineNumFunction;
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <p>
+ * This class represents one complete ordering point annotation. We integrate
+ * all ordering point annotations into this class. We use the ordering point
+ * type (OPType) to differentiate each specific ordering point annotation.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class OPConstruct extends Construct {
+ // The ordering point type
+ public final OPType type;
+ // The ordering point label --- only for OPCheck and PotentialOP; otherwise
+ // null
+ public final String label;
+ // The condition under which the current annotation will be instrumented
+ public final String condition;
+
+ // The original line of text of the entry annotation
+ public final String annotation;
+
+ public OPConstruct(File file, int beginLineNum, OPType type, String label,
+ String condition, String annotation) {
+ super(file, beginLineNum);
+ this.type = type;
+ this.label = label;
+ // Trim the preceding and trailing spaces
+ this.condition = SpecUtils.trimSpace(condition);
+ this.annotation = annotation;
+ }
+
+ public String toString() {
+ StringBuffer res = new StringBuffer();
+ res.append(super.toString() + "\n");
+ res.append("@");
+ res.append(type);
+ if (type == OPType.PotentialOP || type == OPType.OPCheck) {
+ res.append("(" + label + ")");
+ }
+ res.append(": ");
+ res.append(condition + "\n");
+ return res.toString();
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+/**
+ * <p>
+ * The ordering point types.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public enum OPType {
+ OPDefine, PotentialOP, OPCheck, OPClear, OPClearDefine
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+/**
+ * <p>
+ * This class represents a qualified variable name in C++, e.g.
+ * Base::Mine::func. We use this class in the FunctionHeader class to represent
+ * the name of the function. However, for the sake of simplicity in usage, we
+ * only use it as a plain string with the bareName.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class QualifiedName {
+ // The full name --- Base::Mine::func
+ public final String fullName;
+ // The bare name --- func
+ public final String bareName;
+ // The qualified name --- Base::Mine
+ public final String qualifiedName;
+
+ public QualifiedName(String fullName) {
+ this.fullName = fullName;
+ this.bareName = getBareName();
+ this.qualifiedName = getQualifiedName();
+ }
+
+ private String getBareName() {
+ int beginIdx;
+ beginIdx = fullName.lastIndexOf(':');
+ if (beginIdx == -1)
+ return fullName;
+ else
+ return fullName.substring(beginIdx + 1);
+ }
+
+ private String getQualifiedName() {
+ int endIdx = fullName.lastIndexOf(bareName);
+ if (endIdx == 0)
+ return "";
+ return fullName.substring(0, endIdx);
+ }
+
+ public String toString() {
+ return fullName + "\n" + bareName;
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import edu.uci.eecs.codeGenerator.CodeGeneratorUtils;
+import edu.uci.eecs.codeGenerator.Environment;
+import edu.uci.eecs.utilParser.ParseException;
+
+/**
+ * <p>
+ * This class represents the specification extractor of the specification. The
+ * main function of this class is to read C/C++11 source files and extract the
+ * corresponding specifications, and record corresponding information such as
+ * location, e.g., the file name and the line number, to help the code
+ * generation process.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class SpecExtractor {
+ public final HashMap<File, ArrayList<InterfaceConstruct>> interfaceListMap;
+ public final HashMap<File, ArrayList<OPConstruct>> OPListMap;
+ public final HashSet<String> OPLabelSet;
+ // Note that we only allow one entry per file at most
+ public final HashMap<File, EntryConstruct> entryMap;
+
+ public final HashSet<String> headerFiles;
+
+ private GlobalConstruct globalConstruct;
+
+ public SpecExtractor() {
+ interfaceListMap = new HashMap<File, ArrayList<InterfaceConstruct>>();
+ OPListMap = new HashMap<File, ArrayList<OPConstruct>>();
+ OPLabelSet = new HashSet<String>();
+ entryMap = new HashMap<File, EntryConstruct>();
+ headerFiles = new HashSet<String>();
+ globalConstruct = null;
+ }
+
+ private void addInterfaceConstruct(InterfaceConstruct construct) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(construct.file);
+ if (list == null) {
+ list = new ArrayList<InterfaceConstruct>();
+ interfaceListMap.put(construct.file, list);
+ }
+ list.add(construct);
+ }
+
+ private void addOPConstruct(OPConstruct construct) {
+ ArrayList<OPConstruct> list = OPListMap.get(construct.file);
+ if (list == null) {
+ list = new ArrayList<OPConstruct>();
+ OPListMap.put(construct.file, list);
+ }
+ list.add(construct);
+ }
+
+ private void addEntryConstruct(File file, EntryConstruct construct) throws WrongAnnotationException {
+ EntryConstruct old = entryMap.get(file);
+ if (old == null)
+ entryMap.put(file, construct);
+ else { // Error processing
+ String errMsg = "Multiple @Entry annotations in the same file.\n\t Other @Entry at Line " + old.beginLineNum
+ + ".";
+ WrongAnnotationException.err(file, construct.beginLineNum, errMsg);
+ }
+ }
+
+ public GlobalConstruct getGlobalConstruct() {
+ return this.globalConstruct;
+ }
+
+ /**
+ * <p>
+ * A print out function for the purpose of debugging. Note that we better
+ * call this function after having called the checkSemantics() function to
+ * check annotation consistency.
+ * </p>
+ */
+ public void printAnnotations() {
+ System.out.println("/********** Print out of specification extraction **********/");
+ System.out.println("// Extracted header files");
+ for (String header : headerFiles)
+ System.out.println(header);
+
+ System.out.println("// Global State Construct");
+ if (globalConstruct != null)
+ System.out.println(globalConstruct);
+
+ for (File file : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(file);
+ System.out.println("// Interface in file: " + file.getName());
+ for (InterfaceConstruct construct : list) {
+ System.out.println(construct);
+ System.out.println("EndLineNumFunc: " + construct.getEndLineNumFunction());
+ }
+ }
+
+ for (File file : OPListMap.keySet()) {
+ System.out.println("// Ordering points in file: " + file.getName());
+ ArrayList<OPConstruct> list = OPListMap.get(file);
+ for (OPConstruct construct : list)
+ System.out.println(construct);
+ }
+
+ for (File file : entryMap.keySet()) {
+ System.out.println("// Entry in file: " + file.getName());
+ System.out.println(entryMap.get(file));
+ }
+ }
+
+ /**
+ * <p>
+ * Perform basic semantics checking of the extracted specification.
+ * </p>
+ *
+ * @return
+ * @throws WrongAnnotationException
+ */
+ public void checkSemantics() throws WrongAnnotationException {
+ String errMsg = null;
+
+ // Assert that we have defined and only defined one global state
+ // annotation
+ if (globalConstruct == null) {
+ errMsg = "Spec error: There should be one global state annotation.\n";
+ throw new WrongAnnotationException(errMsg);
+ }
+
+ // Assert that the interface constructs have unique label name
+ HashMap<String, InterfaceConstruct> interfaceMap = new HashMap<String, InterfaceConstruct>();
+ for (File f : interfaceListMap.keySet()) {
+ ArrayList<InterfaceConstruct> list = interfaceListMap.get(f);
+ if (list != null) {
+ for (InterfaceConstruct construct : list) {
+ InterfaceConstruct existingConstruct = interfaceMap.get(construct.getName());
+ if (existingConstruct != null) { // Error
+ errMsg = "Interface labels duplication with: \"" + construct.getName() + "\" in File \""
+ + existingConstruct.file.getName() + "\", Line " + existingConstruct.beginLineNum + ".";
+ WrongAnnotationException.err(construct.file, construct.beginLineNum, errMsg);
+ } else {
+ interfaceMap.put(construct.getName(), construct);
+ }
+ }
+ }
+ }
+
+ // Process ordering point labels
+ for (File file : OPListMap.keySet()) {
+ ArrayList<OPConstruct> list = OPListMap.get(file);
+ for (OPConstruct construct : list) {
+ if (construct.type == OPType.OPCheck || construct.type == OPType.PotentialOP) {
+ String label = construct.label;
+ OPLabelSet.add(label);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * <p>
+ * This function applies on a String (a plain line of text) to check whether
+ * the current line is a C/C++ header include statement. If it is, it
+ * extracts the header file name and store it, and returns true; otherwise,
+ * it returns false.
+ * </p>
+ *
+ * @param line
+ * The line of text to be processed
+ * @return Returns true if the current line is a C/C++ header include
+ * statement
+ */
+ public boolean extractHeaders(String line) {
+ // "^( |\t)*#include( |\t)+("|<)([a-zA-Z_0-9\-\.])+("|>)"
+ Pattern regexp = Pattern.compile("^( |\\t)*(#include)( |\\t)+(\"|<)([a-zA-Z_0-9\\-\\.]+)(\"|>)");
+ Matcher matcher = regexp.matcher(line);
+
+ // process the line.
+ if (matcher.find()) {
+ String header = null;
+ String braceSymbol = matcher.group(4);
+ if (braceSymbol.equals("<"))
+ header = "<" + matcher.group(5) + ">";
+ else
+ header = "\"" + matcher.group(5) + "\"";
+ if (!SpecNaming.isPreIncludedHeader(header)) {
+ headerFiles.add(header);
+ }
+ return true;
+ } else
+ return false;
+ }
+
+ /**
+ * <p>
+ * A sub-routine to extract the construct from beginning till end. When
+ * called, we have already match the beginning of the construct. We will
+ * call this sub-routine when we extract the interface construct and the
+ * global state construct.
+ * </p>
+ *
+ * <p>
+ * The side effect of this function is that the lineReader has just read the
+ * end of the construct, meaning that the caller can get the end line number
+ * by calling lineReader.getLineNumber().
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param lineReader
+ * The LineNumberReader that we are using when processing the
+ * current file.
+ * @param file
+ * The file that we are processing
+ * @param curLine
+ * The current line that we are processing. It should be the
+ * beginning line of the annotation construct.
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @return Returns the annotation string list of the current construct
+ * @throws WrongAnnotationException
+ */
+ private ArrayList<String> extractTillConstructEnd(File file, LineNumberReader lineReader, String curLine,
+ int beginLineNum) throws WrongAnnotationException {
+ ArrayList<String> annotations = new ArrayList<String>();
+ annotations.add(curLine);
+ // System.out.println(curLine);
+ // Initial settings for matching lines
+ // "\*/( |\t)*$"
+ Pattern regexpEnd = Pattern.compile("\\*/( |\\t)*$");
+ Matcher matcher = regexpEnd.matcher(curLine);
+ if (matcher.find()) { // The beginning line is also the end line
+ annotations.add(curLine);
+ return annotations;
+ } else {
+ try {
+ String line;
+ while ((line = lineReader.readLine()) != null) {
+ // process the line.
+ // System.out.println(line);
+
+ matcher.reset(line); // reset the input
+ annotations.add(line);
+ if (matcher.find())
+ return annotations;
+ }
+ WrongAnnotationException.err(file, beginLineNum,
+ "The interface annotation should have the matching closing symbol closing \"*/\"");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * <p>
+ * A sub-routine to extract the global construct. When called, we have
+ * already match the beginning of the construct.
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param lineReader
+ * The LineNumberReader that we are using when processing the
+ * current file.
+ * @param curLine
+ * The current line that we are processing. It should be the
+ * beginning line of the annotation construct.
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @throws WrongAnnotationException
+ */
+ private void extractGlobalConstruct(File file, LineNumberReader lineReader, String curLine, int beginLineNum)
+ throws WrongAnnotationException {
+ ArrayList<String> annotations = extractTillConstructEnd(file, lineReader, curLine, beginLineNum);
+ GlobalConstruct construct = new GlobalConstruct(file, beginLineNum, annotations);
+ if (globalConstruct != null) { // Check if we have seen a global state
+ // construct earlier
+ File otherDefinitionFile = globalConstruct.file;
+ int otherDefinitionLine = globalConstruct.beginLineNum;
+ String errMsg = "Multiple definition of global state.\n" + "\tAnother definition is in File \""
+ + otherDefinitionFile.getName() + "\" (Line " + otherDefinitionLine + ").";
+ WrongAnnotationException.err(file, beginLineNum, errMsg);
+ }
+ globalConstruct = construct;
+ }
+
+ /**
+ * @param file
+ * The current file we are processing
+ * @param lineReader
+ * Call this function when the lineReader will read the beginning
+ * of the definition right away
+ * @return The line number of the ending line of the interfae definition. If
+ * returning -1, it means the curl symbols in the interface do not
+ * match
+ * @throws WrongAnnotationException
+ */
+ private int findEndLineNumFunction(File file, LineNumberReader lineReader) throws WrongAnnotationException {
+ String line;
+ // FIXME: We assume that in the string of the code, there does not exist
+ // the symbol '{' & '{'
+ try {
+ boolean foundFirstCurl = false;
+ int unmatchedCnt = 0;
+ while ((line = lineReader.readLine()) != null) {
+ // process the line.
+ // System.out.println(line);
+
+ // Extract the one-liner construct first
+ extractOneLineConstruct(file, lineReader.getLineNumber(), line);
+
+ for (int i = 0; i < line.length(); i++) {
+ char ch = line.charAt(i);
+ if (ch == '{') {
+ foundFirstCurl = true;
+ unmatchedCnt++;
+ } else if (ch == '}') {
+ unmatchedCnt--;
+ }
+ // The current line is the end of the function
+ if (foundFirstCurl && unmatchedCnt == 0) {
+ int endLineNumFunction = lineReader.getLineNumber();
+ return endLineNumFunction;
+ }
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ // -1 means the curl symbols in the interface do not match
+ return -1;
+ }
+
+ /**
+ * <p>
+ * A sub-routine to extract the interface construct. When called, we have
+ * already match the beginning of the construct, and we also need to find
+ * the ending line number of the closing brace of the corresponding
+ * function.
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param lineReader
+ * The LineNumberReader that we are using when processing the
+ * current file.
+ * @param curLine
+ * The current line that we are processing. It should be the
+ * beginning line of the annotation construct.
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @throws WrongAnnotationException
+ * @throws IOException
+ * @throws ParseException
+ */
+ private void extractInterfaceConstruct(File file, LineNumberReader lineReader, String curLine, int beginLineNum)
+ throws WrongAnnotationException, IOException, ParseException {
+ ArrayList<String> annotations = extractTillConstructEnd(file, lineReader, curLine, beginLineNum);
+ int endLineNum = lineReader.getLineNumber();
+ InterfaceConstruct construct = new InterfaceConstruct(file, beginLineNum, endLineNum, annotations);
+ addInterfaceConstruct(construct);
+
+ // Process the corresponding interface function declaration header
+ String line = null;
+ int lineNum = -1;
+ String errMsg;
+ try {
+ line = lineReader.readLine();
+ lineNum = lineReader.getLineNumber();
+ construct.processFunctionDeclaration(line);
+ } catch (IOException e) {
+ errMsg = "Spec error in file \"" + file.getName() + "\", Line " + lineNum
+ + " :\n\tThe function declaration should take only one line and have the correct syntax (follow the annotations immediately)\n";
+ System.out.println(errMsg);
+ throw e;
+ } catch (ParseException e) {
+ errMsg = "Spec error in file \"" + file.getName() + "\", Line " + lineNum
+ + " :\n\tThe function declaration should take only one line and have the correct syntax (follow the annotations immediately)\n";
+ System.out.println(errMsg);
+ throw e;
+ }
+
+ // Now we find the end of the interface definition
+ int endLineNumFunction = findEndLineNumFunction(file, lineReader);
+ construct.setEndLineNumFunction(endLineNumFunction);
+ if (endLineNumFunction == -1) {
+ WrongAnnotationException.err(file, beginLineNum,
+ "The interface definition does NOT have matching curls '}'");
+ }
+ }
+
+ /**
+ * <p>
+ * A sub-routine to extract the ordering point construct. When called, we
+ * have already match the beginning of the construct.
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @param curLine
+ * The current line that we are processing. It should be the
+ * beginning line of the annotation construct.
+ * @param type
+ * The type of ordering point construct we are processing
+ * @throws WrongAnnotationException
+ */
+ private void extractOPConstruct(File file, int beginLineNum, String curLine, OPType type)
+ throws WrongAnnotationException {
+ String condition = null;
+ String label = null;
+
+ // "(\(\s?(\w+)\s?\))?\s:\s?(.+)\*/\s?$"
+ Pattern regexp = Pattern.compile("(\\(\\s*(\\w+)\\s*\\))?\\s*:\\s*(.+)\\*/\\s*$");
+ Matcher matcher = regexp.matcher(curLine);
+ if (matcher.find()) {
+ label = matcher.group(2);
+ condition = matcher.group(3);
+ } else {
+ WrongAnnotationException.err(file, beginLineNum,
+ "Wrong syntax for the ordering point construct. You might need a colon before the condition.");
+ }
+ OPConstruct op = new OPConstruct(file, beginLineNum, type, label, condition, curLine);
+ addOPConstruct(op);
+ }
+
+ /**
+ * <p>
+ * A sub-routine to extract the entry construct. When called, we have
+ * already match the beginning of the construct.
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @param curLine
+ * Current line being processed
+ * @throws WrongAnnotationException
+ */
+ public void extractEntryConstruct(File file, int beginLineNum, String curLine) throws WrongAnnotationException {
+ addEntryConstruct(file, new EntryConstruct(file, beginLineNum, curLine));
+ }
+
+ /**
+ * <p>
+ * A sub-routine to extract those annotation constructs that take only one
+ * line --- Entry, OPDefine, PotentialOP, OPCheck, OPClear and OPClearDefin.
+ * </p>
+ *
+ * @param file
+ * The file that we are processing
+ * @param beginLineNum
+ * The beginning line number of the interface construct
+ * annotation
+ * @param curLine
+ * The current line that we are processing. It should be the
+ * beginning line of the annotation construct.
+ * @throws WrongAnnotationException
+ */
+ private void extractOneLineConstruct(File file, int beginLineNum, String curLine) throws WrongAnnotationException {
+ // "/\*\*\s*@(Entry|OPDefine|PotentialOP|OPCheck|OPClear|OPClearDefine)"
+ Pattern regexpBegin = Pattern.compile("/\\*\\*\\s*@(\\w+)");
+ Matcher matcher = regexpBegin.matcher(curLine);
+ matcher.reset(curLine);
+ if (matcher.find()) {
+ String name = matcher.group(1);
+ if (name.equals("Entry"))
+ extractEntryConstruct(file, beginLineNum, curLine);
+ else if (name.equals("OPDefine") || name.equals("PotentialOP") || name.equals("OPCheck")
+ || name.equals("OPClear") || name.equals("OPClearDefine"))
+ extractOPConstruct(file, beginLineNum, curLine, OPType.valueOf(name));
+ }
+ }
+
+ /**
+ * <p>
+ * This function will process a given C/C++ file ( .h, .c or .cc). It will
+ * extract all the headers included in that file, and all the annotation
+ * constructs specified in that file. We then will store the information in
+ * the corresponding containers.
+ * </p>
+ *
+ * <p>
+ * The basic idea is to read the file line by line, and then use regular
+ * expression to match the specific annotations or the header files.
+ * </p>
+ *
+ * @param file
+ * The file object of the corresponding file to be processed
+ * @throws WrongAnnotationException
+ * @throws ParseException
+ */
+ public void extractConstruct(File file) throws WrongAnnotationException, ParseException {
+ BufferedReader br = null;
+ LineNumberReader lineReader = null;
+ try {
+ // Initial settings for processing the lines
+ br = new BufferedReader(new FileReader(file));
+ lineReader = new LineNumberReader(br);
+ // "/\*\*\s*@(DeclareState|Interface)"
+ Pattern regexpBegin = Pattern.compile("/\\*\\*\\s*@(DeclareState|Interface)");
+ Matcher matcher = regexpBegin.matcher("");
+
+ String line;
+ while ((line = lineReader.readLine()) != null) {
+ // Start to process the line
+
+ // First try to process the line to see if it's a header file
+ // include
+ boolean succ = extractHeaders(line);
+ if (succ) // It's a header line and we successfully extract it
+ continue;
+
+ int beginLineNum = lineReader.getLineNumber();
+ // Extract the one-liner construct first
+ extractOneLineConstruct(file, beginLineNum, line);
+
+ // Now we process the line to see if it's an annotation (State
+ // or Interface)
+ matcher.reset(line); // reset the input
+ if (matcher.find()) { // Found the beginning line
+ // The matching annotation name
+ String constructName = matcher.group(1);
+
+ // Process each annotation accordingly
+ if (constructName.equals(SpecNaming.DeclareState)) {
+ extractGlobalConstruct(file, lineReader, line, beginLineNum);
+ } else if (constructName.equals(SpecNaming.Interface)) {
+ extractInterfaceConstruct(file, lineReader, line, beginLineNum);
+ } else {
+ WrongAnnotationException.err(file, beginLineNum,
+ constructName + " is not a supported annotation.");
+ }
+
+ }
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ lineReader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Given a list of files, it scans each file and add found SpecConstrcut to
+ * the _constructs list.
+ * </p>
+ *
+ * @param files
+ * The list of files that needs to be processed. In general, this
+ * list only need to contain those that have specification
+ * annotations
+ * @throws WrongAnnotationException
+ * @throws ParseException
+ */
+ public void extract(File[] files) throws WrongAnnotationException, ParseException {
+ for (int i = 0; i < files.length; i++)
+ extract(files[i]);
+
+ // Check basic specification semantics
+ checkSemantics();
+ }
+
+ public void extract(ArrayList<File> files) throws WrongAnnotationException, ParseException {
+ for (int i = 0; i < files.size(); i++)
+ extract(files.get(i));
+
+ // Check basic specification semantics
+ checkSemantics();
+ }
+
+ /**
+ * <p>
+ * Extract the specification annotations and header files in the current
+ * file. This function should generally be called by extractFiles.
+ * </p>
+ *
+ * @param files
+ * The list of files that needs to be processed. In general, this
+ * list only need to contain those that have specification
+ * annotations
+ * @throws WrongAnnotationException
+ * @throws ParseException
+ */
+ public void extract(File file) throws WrongAnnotationException, ParseException {
+ extractConstruct(file);
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * <p>
+ * This class contains most of the constant strings that we will be using
+ * throughout the whole annotation extraction and code generation process.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class SpecNaming {
+
+ // Specification annotation naming
+
+ // Global construct
+ public static final String DeclareState = "DeclareState";
+ public static final String InitalState = "Initial";
+ public static final String CopyState = "Copy";
+ public static final String FinalState = "Final";
+ public static final String PrintState = "Print";
+ public static final String Commutativity = "Commutativity";
+
+ // Interface construct
+ public static final String Interface = "Interface";
+ public static final String Transition = "Transition";
+ public static final String PreCondition = "PreCondition";
+ public static final String SideEffect = "SideEffect";
+ public static final String PostCondition = "PostCondition";
+ public static final String PrintValue = "Print";
+
+ public static final String PrintStateType = "PRINT_STATE";
+ public static final String PrintValueType = "PRINT_VALUE";
+ public static final String TransitionType = "TRANSITION";
+ public static final String PreConditionType = "PRE_CONDITION";
+ public static final String SideEffectType = "SIDE_EFFECT";
+ public static final String PostConditionType = "POST_CONDITION";
+
+ // Ordering point construct
+ public static final String OPDefine = "OPDefine";
+ public static final String PotentialOP = "PotentialOP";
+ public static final String OPCheck = "OPCheck";
+ public static final String OPClear = "OPClear";
+ public static final String OPClearDefine = "OPClearDefine";
+ // Entry construct
+ public static final String Entry = "Entry";
+
+ // Generated header file name
+ public static final String CDSSpecGeneratedName = "cdsspec-generated";
+ public static final String CDSSpecGeneratedHeader = "\""
+ + CDSSpecGeneratedName + ".h\"";
+ // Generated hedaer file comment
+ public static final String CDSSpecGeneratedHeaderComment = "This is a header file auto-generated by CDSSpec compiler; together, CDSSpec\n"
+ + "compiler should have generated the accompanying implementation file that\n"
+ + "implements the some functions declared in this file. In order to instrument\n"
+ + "your benchmark for CDSSpec checker to check, you should include this header\n"
+ + "file in every file you use an CDSSpec annotation. Note that it should be\n"
+ + "placed in the end of all other header files. Currently we require a C++\n"
+ + "compiler that supports C++11.";
+
+ // Generated CPP file name
+ public static final String CDSSpecGeneratedCPP = "cdsspec-generated.cc";
+ // Generated CPP file comment
+ public static final String CDSSpecGeneratedCPPComment = "This is an implementation file auto-generated by CDSSpec compiler to\n"
+ + "instrument your benchmark for CDSSpec checker to check. Currently we require\n"
+ + "a C++ compiler that supports C++11.";
+
+ // Pre-included header files
+ public static final HashSet<String> includedHeaders;
+ public static final ArrayList<String> includedHeadersList;
+
+ public static final String ATOMIC = "<atomic>";
+ public static final String THREADS = "<threads.h>";
+ public static final String STDATOMIC = "<stdatomic.h>";
+ public static final String STDLIB = "<stdlib.h>";
+ public static final String STDIO = "<stdio.h>";
+
+ public static final String MODELTYPES = "<modeltypes.h>";
+ public static final String CDSANNOTATE = "<cdsannotate.h>";
+ public static final String MYMEMORY = "\"mymemory.h\"";
+ public static final String MODELASSERT = "\"model-assert.h\"";
+ public static final String LIBRACE = "\"librace.h\"";
+ public static final String SPECANNOTATION = "\"specannotation.h\"";
+ public static final String SPECCOMMON = "\"spec_common.h\"";
+ public static final String CDSSPEC = "\"cdsspec.h\"";
+ public static final String METHODCALL = "\"methodcall.h\"";
+
+ static {
+ // Initialize the header set and list
+ includedHeaders = new HashSet<String>();
+ includedHeadersList = new ArrayList<String>();
+
+ // Add each header to the set
+ includedHeadersList.add(ATOMIC);
+ includedHeadersList.add(THREADS);
+ includedHeadersList.add(STDATOMIC);
+ includedHeadersList.add(STDLIB);
+ includedHeadersList.add(STDIO);
+
+ includedHeadersList.add(MODELTYPES);
+ includedHeadersList.add(CDSANNOTATE);
+ includedHeadersList.add(MYMEMORY);
+ includedHeadersList.add(MODELASSERT);
+ includedHeadersList.add(LIBRACE);
+ includedHeadersList.add(SPECANNOTATION);
+ includedHeadersList.add(SPECCOMMON);
+ includedHeadersList.add(METHODCALL);
+ includedHeadersList.add(CDSSPEC);
+
+ // Add files to list
+ for (String header : includedHeadersList) {
+ includedHeaders.add(header);
+ }
+ }
+
+ public static boolean isPreIncludedHeader(String header) {
+ return includedHeaders.contains(header)
+ || header.equals(CDSSpecGeneratedHeader);
+ }
+
+ // Some CDSSpec keywords and function names
+ public static final String NewSize = "NEW_SIZE";
+ // Some CDSSpec types
+ public static final String CString = "CSTR";
+ public static final String EmptyCString = "_EMPTY";
+ public static final String NullFunc = "NULL_FUNC";
+
+ public static final String StateStruct = "StateStruct";
+ public static final String Method = "Method";
+ public static final String CommutativityRule = "CommutativityRule";
+ public static final String StateFunctions = "StateFunctions";
+ public static final String NamedFunction = "NamedFunction";
+
+ public static final String SPEC_ANALYSIS = "SPEC_ANALYSIS";
+ // Spec annotations
+ public static final String AnnoInit = "AnnoInit";
+ public static final String AnnoTypeInit = "INIT";
+ public static final String AnnoInterfaceInfo = "AnnoInterfaceInfo";
+ public static final String SpecAnnotation = "SpecAnnotation";
+
+ // Some CDSSpec state functions
+ public static final String InitialFunc = "_Initial";
+ public static final String CopyFunc = "_Copy";
+ public static final String FinalFunc = "_Final";
+ public static final String PrintStateFunc = "_PrintState";
+
+ // Functions for instrumenting annotation
+ public static final String CreateInitAnnoFunc = "_createInitAnnotation";
+ public static final String CreateInterfaceBeginAnnoFunc = "_createInterfaceBeginAnnotation";
+ public static final String CreateOPDefineAnnoFunc = "_createOPDefineAnnotation";
+ public static final String CreatePotentialOPAnnoFunc = "_createPotentialOPAnnotation";
+ public static final String CreateOPCheckAnnoFunc = "_createOPCheckAnnotation";
+ public static final String CreateOPClearAnnoFunc = "_createOPClearAnnotation";
+ public static final String CreateOPClearDefineAnnoFunc = "_createOPClearDefineAnnotation";
+
+ // Other CDSSpec functions
+ public static final String AddInterfaceFunctions = "addInterfaceFunctions";
+ public static final String CDSAnnotateFunc = "cdsannotate";
+
+ // Special instances
+ public static final String Method1 = "_M";
+ public static final String Method2 = "_exec";
+ public static final String StateInst = "state";
+ public static final String OldStateInst = "OLD";
+ public static final String NewStateInst = "NEW";
+ // Specification types and macros
+ public static final String RET = "RET";
+
+ // The wrapper prefix that we want to attach to the function name
+ public static final String WrapperPrefix = "Wrapper";
+
+ public static final String CommutativityRuleInst = "commuteRules";
+ public static final String CommutativityRuleSizeInst = "CommuteRuleSize";
+ public static final String StateFunctionsInst = "stateFuncs";
+ public static final String AnnoInitInst = "init";
+ public static final String AnnoInterfaceInfoInst = "info";
+
+ public static String AppendStr(String original) {
+ return "_" + original + "_str";
+ }
+
+ public static String CheckCommutativity(int ruleNum) {
+ return "_checkCommutativity" + ruleNum;
+ }
+
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <p>
+ * This class contains a list of static utility functions for extracting
+ * specification annotations more conveniently.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class SpecUtils {
+
+ /**
+ * <p>
+ * This inner class defines a primitive --- a sub-annotation. For example,
+ * the "@DeclareState" in the global state is one primitive. We record the
+ * beginning line number of that primitive, the name of the primitive and a
+ * list of lines that belong to that primitive.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+ public static class Primitive {
+ public final int beginLineNum;
+ public final String name;
+ public final ArrayList<String> contents;
+
+ public Primitive(String name, int beginLineNum) {
+ this.name = name;
+ this.beginLineNum = beginLineNum;
+ contents = new ArrayList<String>();
+ }
+
+ public void addLine(String line) {
+ contents.add(line);
+ }
+
+ public String toString() {
+ return "@" + name + ":\n" + contents;
+ }
+ };
+
+ /**
+ * <p>
+ * This is a customized wrap of integer so that we can use integer type as
+ * if they were in a C/C++ pass-by-reference fashion. It basically wraps an
+ * int primitive to allow read, write and increment its internal int value.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+ public static class IntObj {
+ private int value;
+
+ public IntObj(int value) {
+ this.value = value;
+ }
+
+ public void setVal(int value) {
+ this.value = value;
+ }
+
+ public int getVal() {
+ return this.value;
+ }
+
+ public void dec() {
+ this.value--;
+ }
+
+ public void inc() {
+ this.value++;
+ }
+
+ public String toString() {
+ return Integer.toString(value);
+ }
+ }
+
+ // A regular expression pattern that matches "@WORD:"
+ public static final Pattern regexpPrimitive = Pattern.compile("@(\\w+):");
+ // The matcher for the primitive regular expression
+ public static final Matcher matcherPrimitive = regexpPrimitive.matcher("");
+
+ // Match code after colon: ":" + Code + "$"
+ public static final Pattern regexpCode = Pattern.compile(":(.*)$");
+ public static final Matcher matcherCode = regexpCode.matcher("");
+
+ // Match a valid word: "^\w+$"
+ public static final Pattern regexpWord = Pattern.compile("^\\w+$");
+ public static final Matcher matcherWord = regexpWord.matcher("");
+
+ /**
+ * <p>
+ * This function will look for the first line that contains a primitive from
+ * the "curIdx", and then extracts all the non-empty lines of that primitive
+ * until it gets to the end of the list or the beginning of the next
+ * primitive. It returns a list of the actual code for that primitive. When
+ * we are done with the function call, the curIdx either points to the next
+ * primitive or the end of the annotation list.
+ * </p>
+ *
+ * @param file
+ * The file begin processing
+ * @param beginLineNum
+ * The beginning line number of the first annotation lines
+ * @param annotations
+ * The list of annotations
+ * @param curIdx
+ * The current index (the index of the line that we are
+ * processing). We will update the current index after calling
+ * this function. Keep in mind that this is a customized wrap of
+ * integer so that we can use it as if it is a C/C++ reference
+ * @return The primitive starting from the curIdx till either the end of the
+ * annotations or the beginning line of the next primitive
+ * @throws WrongAnnotationException
+ */
+ public static Primitive extractPrimitive(File file, int beginLineNum,
+ ArrayList<String> annotations, IntObj curIdx)
+ throws WrongAnnotationException {
+ if (curIdx.getVal() == annotations.size()) // The current index points
+ // to the end
+ // of the list
+ return null;
+
+ String line = null;
+ int curLineNum = -1;
+ Primitive primitive = null;
+ // Find the first primitive
+ for (; curIdx.getVal() < annotations.size(); curIdx.inc()) {
+ line = annotations.get(curIdx.getVal());
+ curLineNum = curIdx.getVal() + beginLineNum;
+ matcherPrimitive.reset(line);
+ if (matcherPrimitive.find()) {
+ String name = matcherPrimitive.group(1);
+ primitive = new Primitive(name, curLineNum);
+ break;
+ }
+ }
+ // Assert that we must have found one primitive
+ if (primitive == null) {
+ WrongAnnotationException
+ .err(file, curLineNum,
+ "Something is wrong! We must have found one primitve here!\n");
+ }
+
+ // Process the current "primitive"
+ // Deal with the first special line. E.g. @DeclareState: int x;
+ String code = null;
+ matcherCode.reset(line);
+ if (matcherCode.find()) {
+ code = matcherCode.group(1);
+ String trimmedCode = trimSpace(trimTrailingCommentSymbol(code));
+ if (!trimmedCode.equals("")) {
+ primitive.addLine(trimmedCode);
+ }
+ } else {
+ WrongAnnotationException
+ .err(file, curLineNum,
+ "The state annotation should have correct primitive syntax (sub-annotations)");
+ }
+
+ // Deal with other normal line. E.g. y = 1;
+ curIdx.inc();
+ ;
+ for (; curIdx.getVal() < annotations.size(); curIdx.inc()) {
+ curLineNum = beginLineNum + curIdx.getVal();
+ line = annotations.get(curIdx.getVal());
+ matcherPrimitive.reset(line);
+ if (!matcherPrimitive.find()) {
+ // This is another line that we should add to the result
+ code = trimSpace(trimTrailingCommentSymbol(line));
+ if (!code.equals(""))
+ primitive.addLine(code);
+ } else
+ // We get to the end of the current primitive
+ break;
+ }
+
+ if (primitive.contents.size() == 0) { // The content of the primitive is
+ // empty
+ WrongAnnotationException.warning(file, curLineNum, "Primitive "
+ + primitive.name + " is empty.");
+ }
+ return primitive;
+ }
+
+ /**
+ *
+ * @param line
+ * The line to be processed
+ * @return The string whose beginning and ending space have been trimmed
+ */
+ public static String trimSpace(String line) {
+ // "^\s*(.*?)\s*$"
+ Pattern regexp = Pattern.compile("^\\s*(.*?)\\s*$");
+ Matcher matcher = regexp.matcher(line);
+ if (matcher.find()) {
+ return matcher.group(1);
+ } else {
+ return line;
+ }
+ }
+
+ /**
+ * <p>
+ * It processed the line in a way that it removes the trailing C/C++ comment
+ * symbols "STAR SLASH"
+ * </p>
+ *
+ * @param line
+ * @return
+ */
+ public static String trimTrailingCommentSymbol(String line) {
+ Pattern regexp = Pattern.compile("(.*?)\\s*(\\*/)?\\s*$");
+ Matcher matcher = regexp.matcher(line);
+ if (matcher.find()) {
+ return matcher.group(1);
+ } else {
+ return null;
+ }
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * <p>
+ * This class represents a variable declaration in C/C++, in which there exist a
+ * type and a name.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class VariableDeclaration {
+ public final String type;
+ public final String name;
+
+ public VariableDeclaration(String type, String name) {
+ this.type = SpecUtils.trimSpace(type);
+ this.name = SpecUtils.trimSpace(name);
+ }
+
+ public VariableDeclaration(File file, int lineNum, String line)
+ throws WrongAnnotationException {
+ // "([<>\*\w\s]+)\s?(\w+)\s;"
+ Pattern regexp = Pattern.compile("([<>&\\*\\w\\s]+)\\s?(\\w+)\\s?;");
+ Matcher matcher = regexp.matcher(line);
+ if (matcher.find()) {
+ type = matcher.group(1);
+ name = matcher.group(2);
+ } else {
+ type = null;
+ name = null;
+ WrongAnnotationException.err(file, lineNum, "The declaration: \""
+ + line + "\" has wrong syntax.");
+ }
+ }
+
+ public String toString() {
+ return type + ": " + name;
+ }
+}
--- /dev/null
+package edu.uci.eecs.specExtraction;
+
+import java.io.File;
+
+/**
+ * <p>
+ * This class is the main error processing exception in processing the
+ * annotations.
+ * </p>
+ *
+ * @author Peizhao Ou
+ *
+ */
+public class WrongAnnotationException extends Exception {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ public WrongAnnotationException(String msg) {
+ super(msg);
+ }
+
+ /**
+ * <p>
+ * This is a utility function for more conveniently generating specification
+ * error exceptions. We help locate the error by the line number in the
+ * processing file, and an associated error message.
+ * </p>
+ *
+ * @param file
+ * The file that we see the error
+ * @param line
+ * The associated line number of the error
+ * @param msg
+ * The error message printout
+ * @throws WrongAnnotationException
+ */
+ public static void err(File file, int line, String msg)
+ throws WrongAnnotationException {
+ String errMsg = "Spec error in file \"" + file.getName() + "\", Line "
+ + line + " :\n\t" + msg + "\n";
+ throw new WrongAnnotationException(errMsg);
+ }
+
+ /**
+ * <p>
+ * This is a utility function for more conveniently generating specification
+ * warning. We help locate the warning by the line number in the processing
+ * file, and an associated warning message.
+ * </p>
+ *
+ * @param file
+ * The file that we see the warning
+ * @param line
+ * The associated line number of the warning
+ * @param msg
+ * The warning message printout
+ * @throws WrongAnnotationException
+ */
+ public static void warning(File file, int line, String msg) {
+ String errMsg = "Spec WARNING in file \"" + file.getName()
+ + "\", Line " + line + " :\n\t" + msg + "\n";
+ System.out.println(errMsg);
+ }
+}