edits
authorPeizhao Ou <peizhaoo@uci.edu>
Wed, 18 Nov 2015 13:59:31 +0000 (05:59 -0800)
committerPeizhao Ou <peizhaoo@uci.edu>
Wed, 18 Nov 2015 13:59:31 +0000 (05:59 -0800)
70 files changed:
benchmark/ms-queue/my_queue.c
benchmark/ms-queue/testcase2.c
benchmark/ms-queue/testcase3.c
output/chase-lev-deque-bugfix/deque.c [new file with mode: 0644]
output/chase-lev-deque-bugfix/deque.h [new file with mode: 0644]
output/chase-lev-deque-bugfix/deque.o [new file with mode: 0644]
output/chase-lev-deque-bugfix/main [new file with mode: 0755]
output/chase-lev-deque-bugfix/main.c [new file with mode: 0644]
output/chase-lev-deque-bugfix/testcase.c [new file with mode: 0644]
output/chase-lev-deque-bugfix/testcase1 [new file with mode: 0755]
output/chase-lev-deque-bugfix/testcase1.c [new file with mode: 0644]
output/chase-lev-deque-bugfix/testcase2 [new file with mode: 0755]
output/chase-lev-deque-bugfix/testcase2.c [new file with mode: 0644]
output/cliffc-hashtable/cliffc_hashtable.h [new file with mode: 0644]
output/cliffc-hashtable/main.cc [new file with mode: 0644]
output/concurrent-hashmap/hashmap.h [new file with mode: 0644]
output/concurrent-hashmap/hashmap.o [new file with mode: 0644]
output/concurrent-hashmap/main [new file with mode: 0755]
output/concurrent-hashmap/main.cc [new file with mode: 0644]
output/concurrent-hashmap/testcase1 [new file with mode: 0755]
output/concurrent-hashmap/testcase1.cc [new file with mode: 0644]
output/linuxrwlocks/linuxrwlocks [new file with mode: 0755]
output/linuxrwlocks/linuxrwlocks.c [new file with mode: 0644]
output/linuxrwlocks/testcase1 [new file with mode: 0755]
output/linuxrwlocks/testcase1.c [new file with mode: 0644]
output/linuxrwlocks/testcase2 [new file with mode: 0755]
output/linuxrwlocks/testcase2.c [new file with mode: 0644]
output/mcs-lock/mcs-lock [new file with mode: 0755]
output/mcs-lock/mcs-lock.cc [new file with mode: 0644]
output/mcs-lock/mcs-lock.h [new file with mode: 0644]
output/mpmc-queue/mpmc-1r2w [new file with mode: 0755]
output/mpmc-queue/mpmc-1r2w-noinit [new file with mode: 0755]
output/mpmc-queue/mpmc-2r1w [new file with mode: 0755]
output/mpmc-queue/mpmc-2r1w-noinit [new file with mode: 0755]
output/mpmc-queue/mpmc-queue [new file with mode: 0755]
output/mpmc-queue/mpmc-queue-noinit [new file with mode: 0755]
output/mpmc-queue/mpmc-queue-rdwr [new file with mode: 0755]
output/mpmc-queue/mpmc-queue.cc [new file with mode: 0644]
output/mpmc-queue/mpmc-queue.h [new file with mode: 0644]
output/mpmc-queue/mpmc-rdwr-noinit [new file with mode: 0755]
output/mpmc-queue/testcase [new file with mode: 0755]
output/mpmc-queue/testcase.cc [new file with mode: 0644]
output/mpmc-queue/testcase1 [new file with mode: 0755]
output/mpmc-queue/testcase1.cc [new file with mode: 0644]
output/mpmc-queue/testcase2 [new file with mode: 0755]
output/mpmc-queue/testcase2.cc [new file with mode: 0644]
output/mpmc-queue/testcase3 [new file with mode: 0755]
output/mpmc-queue/testcase3.cc [new file with mode: 0644]
output/ms-queue/Makefile
output/ms-queue/main [new file with mode: 0755]
output/ms-queue/main.c [new file with mode: 0644]
output/ms-queue/main.o [new file with mode: 0644]
output/ms-queue/my_queue.c [new file with mode: 0644]
output/ms-queue/my_queue.h [new file with mode: 0644]
output/ms-queue/my_queue.o [new file with mode: 0644]
output/ms-queue/testcase1 [new file with mode: 0755]
output/ms-queue/testcase1.o [new file with mode: 0644]
output/ms-queue/testcase2 [new file with mode: 0755]
output/ms-queue/testcase2.c
output/ms-queue/testcase2.o [new file with mode: 0644]
output/ms-queue/testcase3 [new file with mode: 0755]
output/ms-queue/testcase3.c [new file with mode: 0644]
output/ms-queue/testcase3.o [new file with mode: 0644]
output/read-copy-update/rcu [new file with mode: 0755]
output/read-copy-update/rcu.cc [new file with mode: 0644]
output/spsc-bugfix/eventcount.h [new file with mode: 0644]
output/spsc-bugfix/queue.h [new file with mode: 0644]
output/spsc-bugfix/spsc-queue [new file with mode: 0755]
output/spsc-bugfix/spsc-queue.cc [new file with mode: 0644]
src/edu/uci/eecs/specCompiler/codeGenerator/CodeGenerator.java

index d5e889db0113c288d23d9703b813f8a708f9ee1f..b942be572b09d83aca4892ac11f2ba1588ee0342 100644 (file)
@@ -140,11 +140,11 @@ void enqueue(queue_t *q, unsigned int val)
                                unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire));
                                pointer value = MAKE_POINTER(ptr,
                                                get_count(tail) + 1);
-                               /****FIXME: miss ****/
+                               /**** SPEC (sequential, testcase2.c) ****/
                                // Second release can be just relaxed
                                bool succ = false;
                                succ = atomic_compare_exchange_strong_explicit(&q->tail,
-                                               &tail, value, release, relaxed);
+                                               &tail, value, relaxed, relaxed);
                                if (succ) {
                                        //printf("miss2_enqueue CAS succ\n");
                                }
@@ -214,13 +214,13 @@ bool dequeue(queue_t *q, int *retVal)
                                if (get_ptr(next) == 0) { // NULL       
                                        return false; // NULL
                                }
-                               /**** FIXME: miss ****/
+                               /**** SPEC (sequential testcase3.c) ****/
                                // Second release can be just relaxed
                                bool succ = false;
                                succ = atomic_compare_exchange_strong_explicit(&q->tail,
                                                &tail,
                                                MAKE_POINTER(get_ptr(next), get_count(tail) + 1),
-                                               release, relaxed);
+                                                       release, relaxed);
                                if (succ) {
                                        //printf("miss4_dequeue CAS succ\n");
                                }
index 8ab6dbfca0d8126aadd3d01fd9728c37750f053a..4da629ea0144f6caa3f7ee3b302482ddbc450865 100644 (file)
@@ -5,7 +5,7 @@
 #include "my_queue.h"
 #include "model-assert.h"
 
-static int procs = 2;
+static int procs = 3;
 static queue_t *queue;
 static thrd_t *threads;
 static unsigned int *input;
@@ -39,13 +39,9 @@ static void main_task(void *param)
                else
                        printf("Thrd 1: Dequeue NULL.\n");
        } else if (pid % 4 == 1) {
+               enqueue(queue, 1);
+       } else if (pid % 4 == 2) {
                enqueue(queue, 2);
-               output2 = 1;
-               succ2 = dequeue(queue, &output2);
-               if (succ2)
-                       printf("Thrd 2: Dequeue %d.\n", output2);
-               else
-                       printf("Thrd 2: Dequeue NULL.\n");
        }
 }
 
index 8ab6dbfca0d8126aadd3d01fd9728c37750f053a..526593cf6a052f78006241cba04d5ed73ef510b0 100644 (file)
@@ -5,7 +5,7 @@
 #include "my_queue.h"
 #include "model-assert.h"
 
-static int procs = 2;
+static int procs = 3;
 static queue_t *queue;
 static thrd_t *threads;
 static unsigned int *input;
@@ -39,13 +39,17 @@ static void main_task(void *param)
                else
                        printf("Thrd 1: Dequeue NULL.\n");
        } else if (pid % 4 == 1) {
-               enqueue(queue, 2);
-               output2 = 1;
-               succ2 = dequeue(queue, &output2);
-               if (succ2)
-                       printf("Thrd 2: Dequeue %d.\n", output2);
+               enqueue(queue, 1);
+               printf("Thrd 2: Enqueue %d.\n", 1);
+       } else if (pid % 4 == 2) {
+               //enqueue(queue, 2);
+
+               output1 = 1;
+               succ1 = dequeue(queue, &output1);
+               if (succ1)
+                       printf("Thrd 3: Dequeue %d.\n", output1);
                else
-                       printf("Thrd 2: Dequeue NULL.\n");
+                       printf("Thrd 3: Dequeue NULL.\n");
        }
 }
 
diff --git a/output/chase-lev-deque-bugfix/deque.c b/output/chase-lev-deque-bugfix/deque.c
new file mode 100644 (file)
index 0000000..15ffe0f
--- /dev/null
@@ -0,0 +1,270 @@
+#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);
+                                                               
+       }
+       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;
+}
+
diff --git a/output/chase-lev-deque-bugfix/deque.h b/output/chase-lev-deque-bugfix/deque.h
new file mode 100644 (file)
index 0000000..3a3a869
--- /dev/null
@@ -0,0 +1,233 @@
+#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
+
diff --git a/output/chase-lev-deque-bugfix/deque.o b/output/chase-lev-deque-bugfix/deque.o
new file mode 100644 (file)
index 0000000..9314807
Binary files /dev/null and b/output/chase-lev-deque-bugfix/deque.o differ
diff --git a/output/chase-lev-deque-bugfix/main b/output/chase-lev-deque-bugfix/main
new file mode 100755 (executable)
index 0000000..a7e3297
Binary files /dev/null and b/output/chase-lev-deque-bugfix/main differ
diff --git a/output/chase-lev-deque-bugfix/main.c b/output/chase-lev-deque-bugfix/main.c
new file mode 100644 (file)
index 0000000..edd09ba
--- /dev/null
@@ -0,0 +1,55 @@
+#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;
+}
+
diff --git a/output/chase-lev-deque-bugfix/testcase.c b/output/chase-lev-deque-bugfix/testcase.c
new file mode 100644 (file)
index 0000000..5723259
--- /dev/null
@@ -0,0 +1,62 @@
+#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;
+}
+
diff --git a/output/chase-lev-deque-bugfix/testcase1 b/output/chase-lev-deque-bugfix/testcase1
new file mode 100755 (executable)
index 0000000..c419a11
Binary files /dev/null and b/output/chase-lev-deque-bugfix/testcase1 differ
diff --git a/output/chase-lev-deque-bugfix/testcase1.c b/output/chase-lev-deque-bugfix/testcase1.c
new file mode 100644 (file)
index 0000000..91550f2
--- /dev/null
@@ -0,0 +1,63 @@
+#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;
+}
+
diff --git a/output/chase-lev-deque-bugfix/testcase2 b/output/chase-lev-deque-bugfix/testcase2
new file mode 100755 (executable)
index 0000000..41500c3
Binary files /dev/null and b/output/chase-lev-deque-bugfix/testcase2 differ
diff --git a/output/chase-lev-deque-bugfix/testcase2.c b/output/chase-lev-deque-bugfix/testcase2.c
new file mode 100644 (file)
index 0000000..dc28d1b
--- /dev/null
@@ -0,0 +1,60 @@
+#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;
+}
+
diff --git a/output/cliffc-hashtable/cliffc_hashtable.h b/output/cliffc-hashtable/cliffc_hashtable.h
new file mode 100644 (file)
index 0000000..d102f2f
--- /dev/null
@@ -0,0 +1,911 @@
+#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
+
diff --git a/output/cliffc-hashtable/main.cc b/output/cliffc-hashtable/main.cc
new file mode 100644 (file)
index 0000000..8b6f75e
--- /dev/null
@@ -0,0 +1,111 @@
+#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;
+}
+
+
+
diff --git a/output/concurrent-hashmap/hashmap.h b/output/concurrent-hashmap/hashmap.h
new file mode 100644 (file)
index 0000000..5a05cd3
--- /dev/null
@@ -0,0 +1,471 @@
+#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
+
diff --git a/output/concurrent-hashmap/hashmap.o b/output/concurrent-hashmap/hashmap.o
new file mode 100644 (file)
index 0000000..268350d
Binary files /dev/null and b/output/concurrent-hashmap/hashmap.o differ
diff --git a/output/concurrent-hashmap/main b/output/concurrent-hashmap/main
new file mode 100755 (executable)
index 0000000..a9b7a82
Binary files /dev/null and b/output/concurrent-hashmap/main differ
diff --git a/output/concurrent-hashmap/main.cc b/output/concurrent-hashmap/main.cc
new file mode 100644 (file)
index 0000000..f39f3b6
--- /dev/null
@@ -0,0 +1,35 @@
+#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;
+}
+
+
+
diff --git a/output/concurrent-hashmap/testcase1 b/output/concurrent-hashmap/testcase1
new file mode 100755 (executable)
index 0000000..54701c1
Binary files /dev/null and b/output/concurrent-hashmap/testcase1 differ
diff --git a/output/concurrent-hashmap/testcase1.cc b/output/concurrent-hashmap/testcase1.cc
new file mode 100644 (file)
index 0000000..059718e
--- /dev/null
@@ -0,0 +1,37 @@
+#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;
+}
+
+
+
diff --git a/output/linuxrwlocks/linuxrwlocks b/output/linuxrwlocks/linuxrwlocks
new file mode 100755 (executable)
index 0000000..ecd7511
Binary files /dev/null and b/output/linuxrwlocks/linuxrwlocks differ
diff --git a/output/linuxrwlocks/linuxrwlocks.c b/output/linuxrwlocks/linuxrwlocks.c
new file mode 100644 (file)
index 0000000..5929374
--- /dev/null
@@ -0,0 +1,940 @@
+#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;
+}
+
diff --git a/output/linuxrwlocks/testcase1 b/output/linuxrwlocks/testcase1
new file mode 100755 (executable)
index 0000000..b92d0b9
Binary files /dev/null and b/output/linuxrwlocks/testcase1 differ
diff --git a/output/linuxrwlocks/testcase1.c b/output/linuxrwlocks/testcase1.c
new file mode 100644 (file)
index 0000000..f47527c
--- /dev/null
@@ -0,0 +1,926 @@
+#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;
+}
+
diff --git a/output/linuxrwlocks/testcase2 b/output/linuxrwlocks/testcase2
new file mode 100755 (executable)
index 0000000..28de7a6
Binary files /dev/null and b/output/linuxrwlocks/testcase2 differ
diff --git a/output/linuxrwlocks/testcase2.c b/output/linuxrwlocks/testcase2.c
new file mode 100644 (file)
index 0000000..3c142ad
--- /dev/null
@@ -0,0 +1,930 @@
+#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;
+}
+
diff --git a/output/mcs-lock/mcs-lock b/output/mcs-lock/mcs-lock
new file mode 100755 (executable)
index 0000000..2025053
Binary files /dev/null and b/output/mcs-lock/mcs-lock differ
diff --git a/output/mcs-lock/mcs-lock.cc b/output/mcs-lock/mcs-lock.cc
new file mode 100644 (file)
index 0000000..d95341e
--- /dev/null
@@ -0,0 +1,40 @@
+#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;
+}
+
diff --git a/output/mcs-lock/mcs-lock.h b/output/mcs-lock/mcs-lock.h
new file mode 100644 (file)
index 0000000..c19e776
--- /dev/null
@@ -0,0 +1,332 @@
+
+#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;
+
+
diff --git a/output/mpmc-queue/mpmc-1r2w b/output/mpmc-queue/mpmc-1r2w
new file mode 100755 (executable)
index 0000000..18ad44d
Binary files /dev/null and b/output/mpmc-queue/mpmc-1r2w differ
diff --git a/output/mpmc-queue/mpmc-1r2w-noinit b/output/mpmc-queue/mpmc-1r2w-noinit
new file mode 100755 (executable)
index 0000000..8619185
Binary files /dev/null and b/output/mpmc-queue/mpmc-1r2w-noinit differ
diff --git a/output/mpmc-queue/mpmc-2r1w b/output/mpmc-queue/mpmc-2r1w
new file mode 100755 (executable)
index 0000000..fceaea1
Binary files /dev/null and b/output/mpmc-queue/mpmc-2r1w differ
diff --git a/output/mpmc-queue/mpmc-2r1w-noinit b/output/mpmc-queue/mpmc-2r1w-noinit
new file mode 100755 (executable)
index 0000000..9b40cbd
Binary files /dev/null and b/output/mpmc-queue/mpmc-2r1w-noinit differ
diff --git a/output/mpmc-queue/mpmc-queue b/output/mpmc-queue/mpmc-queue
new file mode 100755 (executable)
index 0000000..ebb01df
Binary files /dev/null and b/output/mpmc-queue/mpmc-queue differ
diff --git a/output/mpmc-queue/mpmc-queue-noinit b/output/mpmc-queue/mpmc-queue-noinit
new file mode 100755 (executable)
index 0000000..caec501
Binary files /dev/null and b/output/mpmc-queue/mpmc-queue-noinit differ
diff --git a/output/mpmc-queue/mpmc-queue-rdwr b/output/mpmc-queue/mpmc-queue-rdwr
new file mode 100755 (executable)
index 0000000..043c874
Binary files /dev/null and b/output/mpmc-queue/mpmc-queue-rdwr differ
diff --git a/output/mpmc-queue/mpmc-queue.cc b/output/mpmc-queue/mpmc-queue.cc
new file mode 100644 (file)
index 0000000..83b05f2
--- /dev/null
@@ -0,0 +1,141 @@
+#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;
+}
+
diff --git a/output/mpmc-queue/mpmc-queue.h b/output/mpmc-queue/mpmc-queue.h
new file mode 100644 (file)
index 0000000..00eaf67
--- /dev/null
@@ -0,0 +1,700 @@
+#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;
+
+
diff --git a/output/mpmc-queue/mpmc-rdwr-noinit b/output/mpmc-queue/mpmc-rdwr-noinit
new file mode 100755 (executable)
index 0000000..0f12666
Binary files /dev/null and b/output/mpmc-queue/mpmc-rdwr-noinit differ
diff --git a/output/mpmc-queue/testcase b/output/mpmc-queue/testcase
new file mode 100755 (executable)
index 0000000..5c9c9ad
Binary files /dev/null and b/output/mpmc-queue/testcase differ
diff --git a/output/mpmc-queue/testcase.cc b/output/mpmc-queue/testcase.cc
new file mode 100644 (file)
index 0000000..936315c
--- /dev/null
@@ -0,0 +1,65 @@
+#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;
+}
+
diff --git a/output/mpmc-queue/testcase1 b/output/mpmc-queue/testcase1
new file mode 100755 (executable)
index 0000000..6d8a654
Binary files /dev/null and b/output/mpmc-queue/testcase1 differ
diff --git a/output/mpmc-queue/testcase1.cc b/output/mpmc-queue/testcase1.cc
new file mode 100644 (file)
index 0000000..936315c
--- /dev/null
@@ -0,0 +1,65 @@
+#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;
+}
+
diff --git a/output/mpmc-queue/testcase2 b/output/mpmc-queue/testcase2
new file mode 100755 (executable)
index 0000000..59fdfe4
Binary files /dev/null and b/output/mpmc-queue/testcase2 differ
diff --git a/output/mpmc-queue/testcase2.cc b/output/mpmc-queue/testcase2.cc
new file mode 100644 (file)
index 0000000..a311400
--- /dev/null
@@ -0,0 +1,91 @@
+#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;
+}
+
diff --git a/output/mpmc-queue/testcase3 b/output/mpmc-queue/testcase3
new file mode 100755 (executable)
index 0000000..f0939b9
Binary files /dev/null and b/output/mpmc-queue/testcase3 differ
diff --git a/output/mpmc-queue/testcase3.cc b/output/mpmc-queue/testcase3.cc
new file mode 100644 (file)
index 0000000..fc91497
--- /dev/null
@@ -0,0 +1,105 @@
+#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;
+}
+
index 78ea6a644d60604145a0ac08811f29cbe33ab9e7..d75881c8094acd1173d6cacb70d7ae6579e2d6e8 100644 (file)
@@ -1,6 +1,6 @@
 include ../benchmarks.mk
 
-TESTNAME = main testcase1 testcase2
+TESTNAME = main testcase1 testcase2 testcase3
 
 HEADERS = my_queue.h
 OBJECTS = main.o my_queue.o
@@ -16,6 +16,9 @@ testcase1: $(HEADERS) my_queue.o testcase1.o
 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)
 
diff --git a/output/ms-queue/main b/output/ms-queue/main
new file mode 100755 (executable)
index 0000000..0621f42
Binary files /dev/null and b/output/ms-queue/main differ
diff --git a/output/ms-queue/main.c b/output/ms-queue/main.c
new file mode 100644 (file)
index 0000000..e5cbd07
--- /dev/null
@@ -0,0 +1,88 @@
+#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, &param[i]);
+       }
+       for (i = 0; i < num_threads; i++)
+               thrd_join(threads[i]);
+
+
+       free(param);
+       free(threads);
+       free(queue);
+
+       return 0;
+}
+
diff --git a/output/ms-queue/main.o b/output/ms-queue/main.o
new file mode 100644 (file)
index 0000000..b1618c1
Binary files /dev/null and b/output/ms-queue/main.o differ
diff --git a/output/ms-queue/my_queue.c b/output/ms-queue/my_queue.c
new file mode 100644 (file)
index 0000000..1a09033
--- /dev/null
@@ -0,0 +1,333 @@
+#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;
+}
+
diff --git a/output/ms-queue/my_queue.h b/output/ms-queue/my_queue.h
new file mode 100644 (file)
index 0000000..90849d8
--- /dev/null
@@ -0,0 +1,204 @@
+#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
+
diff --git a/output/ms-queue/my_queue.o b/output/ms-queue/my_queue.o
new file mode 100644 (file)
index 0000000..b35d4c9
Binary files /dev/null and b/output/ms-queue/my_queue.o differ
diff --git a/output/ms-queue/testcase1 b/output/ms-queue/testcase1
new file mode 100755 (executable)
index 0000000..35c5e69
Binary files /dev/null and b/output/ms-queue/testcase1 differ
diff --git a/output/ms-queue/testcase1.o b/output/ms-queue/testcase1.o
new file mode 100644 (file)
index 0000000..d55a3eb
Binary files /dev/null and b/output/ms-queue/testcase1.o differ
diff --git a/output/ms-queue/testcase2 b/output/ms-queue/testcase2
new file mode 100755 (executable)
index 0000000..8a4c860
Binary files /dev/null and b/output/ms-queue/testcase2 differ
index f5b21332a7379d1aaf522d78c979d6e822c59f30..116df3596a8251ffba9cf91c443de9686815a0d4 100644 (file)
@@ -5,7 +5,7 @@
 #include "my_queue.h"
 #include "model-assert.h"
 
-static int procs = 2;
+static int procs = 3;
 static queue_t *queue;
 static thrd_t *threads;
 static unsigned int *input;
@@ -37,13 +37,9 @@ static void main_task(void *param)
                else
                        printf("Thrd 1: Dequeue NULL.\n");
        } else if (pid % 4 == 1) {
+               enqueue(queue, 1);
+       } else if (pid % 4 == 2) {
                enqueue(queue, 2);
-               output2 = 1;
-               succ2 = dequeue(queue, &output2);
-               if (succ2)
-                       printf("Thrd 2: Dequeue %d.\n", output2);
-               else
-                       printf("Thrd 2: Dequeue NULL.\n");
        }
 }
 
diff --git a/output/ms-queue/testcase2.o b/output/ms-queue/testcase2.o
new file mode 100644 (file)
index 0000000..8a45d38
Binary files /dev/null and b/output/ms-queue/testcase2.o differ
diff --git a/output/ms-queue/testcase3 b/output/ms-queue/testcase3
new file mode 100755 (executable)
index 0000000..9c35f67
Binary files /dev/null and b/output/ms-queue/testcase3 differ
diff --git a/output/ms-queue/testcase3.c b/output/ms-queue/testcase3.c
new file mode 100644 (file)
index 0000000..e4fb362
--- /dev/null
@@ -0,0 +1,84 @@
+#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, &param[i]);
+       }
+       for (i = 0; i < num_threads; i++)
+               thrd_join(threads[i]);
+
+
+       free(param);
+       free(threads);
+       free(queue);
+
+       return 0;
+}
+
diff --git a/output/ms-queue/testcase3.o b/output/ms-queue/testcase3.o
new file mode 100644 (file)
index 0000000..3dff7b1
Binary files /dev/null and b/output/ms-queue/testcase3.o differ
diff --git a/output/read-copy-update/rcu b/output/read-copy-update/rcu
new file mode 100755 (executable)
index 0000000..8e26721
Binary files /dev/null and b/output/read-copy-update/rcu differ
diff --git a/output/read-copy-update/rcu.cc b/output/read-copy-update/rcu.cc
new file mode 100644 (file)
index 0000000..adc4766
--- /dev/null
@@ -0,0 +1,352 @@
+#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;
+}
+
diff --git a/output/spsc-bugfix/eventcount.h b/output/spsc-bugfix/eventcount.h
new file mode 100644 (file)
index 0000000..a7dd1ee
--- /dev/null
@@ -0,0 +1,74 @@
+#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
+
diff --git a/output/spsc-bugfix/queue.h b/output/spsc-bugfix/queue.h
new file mode 100644 (file)
index 0000000..456b7d1
--- /dev/null
@@ -0,0 +1,340 @@
+#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
+
diff --git a/output/spsc-bugfix/spsc-queue b/output/spsc-bugfix/spsc-queue
new file mode 100755 (executable)
index 0000000..90244b2
Binary files /dev/null and b/output/spsc-bugfix/spsc-queue differ
diff --git a/output/spsc-bugfix/spsc-queue.cc b/output/spsc-bugfix/spsc-queue.cc
new file mode 100644 (file)
index 0000000..e824eed
--- /dev/null
@@ -0,0 +1,34 @@
+#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;
+}
+
index 7491e708a0ca3f8d9fd346ced5c10e27106c3d01..28609e6de8c3a47262adaed1e4ca4b9d714ddada 100644 (file)
@@ -344,8 +344,8 @@ public class CodeGenerator {
 //             File[][] sources = {srcLinuxRWLock1 , srcMSQueue, srcRCU,
 //                             srcDeque, srcMCSLock, srcSPSCQueue, srcMPMCQueue, srcHashtable };
 
-//              File[][] sources = {srcDeque, srcLinuxRWLock1, srcLinuxRWLock2, srcLinuxRWLock3, srcMCSLock, srcHashtable, srcRCU};
-                File[][] sources = {srcMPMCQueue};
+                File[][] sources = {srcDeque, srcLinuxRWLock1, srcLinuxRWLock2, srcLinuxRWLock3, srcMCSLock, srcHashtable, srcRCU, srcMSQueue, srcSPSCQueue, srcMPMCQueue};
+//              File[][] sources = {srcMSQueue};
                // Compile all the benchmarks
                for (int i = 0; i < sources.length; i++) {
                        CodeGenerator gen = new CodeGenerator(sources[i]);