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");
}
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");
}
#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;
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");
}
}
#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;
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");
}
}
--- /dev/null
+#include <stdatomic.h>
+#include <inttypes.h>
+#include "deque.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+Deque * create() {
+ Deque * q = (Deque *) calloc(1, sizeof(Deque));
+ Array * a = (Array *) calloc(1, sizeof(Array)+2*sizeof(atomic_int));
+ atomic_store_explicit(&q->array, a, memory_order_relaxed);
+ atomic_store_explicit(&q->top, 0, memory_order_relaxed);
+ atomic_store_explicit(&q->bottom, 0, memory_order_relaxed);
+ atomic_store_explicit(&a->size, 2, memory_order_relaxed);
+ return q;
+}
+
+
+
+int take(Deque * q) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Take
+ interface_begin->interface_name = "Take";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__take(q);
+ Take_info* info = (Take_info*) malloc(sizeof(Take_info));
+ info->__RET__ = __RET__;
+ info->q = q;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Take
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__take(Deque * q) {
+ size_t b = atomic_load_explicit(&q->bottom, memory_order_relaxed) - 1;
+ /* Automatically generated code for commit point define check: Take_Read_Bottom */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Take_Read_Bottom";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
+
+ atomic_store_explicit(&q->bottom, b, memory_order_relaxed);
+
+ atomic_thread_fence(memory_order_seq_cst);
+ size_t t = atomic_load_explicit(&q->top, memory_order_relaxed);
+
+ int x;
+ if (t <= b) {
+
+ int size = atomic_load_explicit(&a->size,memory_order_relaxed);
+ x = atomic_load_explicit(&a->buffer[b % size], memory_order_relaxed);
+
+ if (t == b) {
+
+ bool succ = atomic_compare_exchange_strong_explicit(&q->top, &t, t +
+ 1, memory_order_seq_cst, memory_order_relaxed);
+
+
+ /* Automatically generated code for commit point define check: Take_Additional_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Take_Additional_Point";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (!succ) {
+
+ x = EMPTY;
+ }
+ atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed);
+ }
+ } else {
+ x = EMPTY;
+ atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed);
+ }
+ return x;
+}
+
+void resize(Deque *q) {
+ Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
+ size_t size=atomic_load_explicit(&a->size, memory_order_relaxed);
+ size_t new_size=size << 1;
+ Array *new_a = (Array *) calloc(1, new_size * sizeof(atomic_int) + sizeof(Array));
+ size_t top=atomic_load_explicit(&q->top, memory_order_relaxed);
+ size_t bottom=atomic_load_explicit(&q->bottom, memory_order_relaxed);
+ atomic_store_explicit(&new_a->size, new_size, memory_order_relaxed);
+ size_t i;
+ for(i=top; i < bottom; i++) {
+ atomic_store_explicit(&new_a->buffer[i % new_size], atomic_load_explicit(&a->buffer[i % size], memory_order_relaxed), memory_order_relaxed);
+ }
+
+ atomic_store_explicit(&q->array, new_a, memory_order_release);
+ }
+
+
+void push(Deque * q, int x) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Push
+ interface_begin->interface_name = "Push";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__push(q, x);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Push
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Push_info* info = (Push_info*) malloc(sizeof(Push_info));
+ info->q = q;
+ info->x = x;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Push
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__push(Deque * q, int x) {
+ size_t b = atomic_load_explicit(&q->bottom, memory_order_relaxed);
+
+ size_t t = atomic_load_explicit(&q->top, memory_order_acquire);
+ Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed);
+ if (b - t > atomic_load_explicit(&a->size, memory_order_relaxed) - 1) {
+ resize(q);
+
+ }
+ int size = atomic_load_explicit(&a->size, memory_order_relaxed);
+
+ atomic_store_explicit(&a->buffer[b % size], x, memory_order_relaxed);
+
+
+ atomic_thread_fence(memory_order_release);
+ /* Automatically generated code for commit point define check: Push_Update_Bottom */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "Push_Update_Bottom";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed);
+
+}
+
+
+int steal(Deque * q) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 2; // Steal
+ interface_begin->interface_name = "Steal";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__steal(q);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 2; // Steal
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Steal_info* info = (Steal_info*) malloc(sizeof(Steal_info));
+ info->__RET__ = __RET__;
+ info->q = q;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 2; // Steal
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__steal(Deque * q) {
+ size_t t = atomic_load_explicit(&q->top, memory_order_acquire);
+
+ atomic_thread_fence(memory_order_seq_cst);
+
+ size_t b = atomic_load_explicit(&q->bottom, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Steal_Read_Bottom */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "Steal_Read_Bottom";
+ cp_define_check->interface_num = 2;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+
+ int x = EMPTY;
+ if (t < b) {
+
+
+ Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_acquire);
+
+ int size = atomic_load_explicit(&a->size, memory_order_relaxed);
+ x = atomic_load_explicit(&a->buffer[t % size], memory_order_relaxed);
+
+
+ bool succ = atomic_compare_exchange_strong_explicit(&q->top, &t, t + 1,
+ memory_order_seq_cst, memory_order_relaxed);
+
+
+ /* Automatically generated code for commit point define check: Steal_Additional_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 4;
+ cp_define_check->label_name = "Steal_Additional_Point";
+ cp_define_check->interface_num = 2;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+
+ if (!succ) {
+
+ return ABORT;
+ }
+ }
+ return x;
+}
+
--- /dev/null
+#ifndef DEQUE_H
+#define DEQUE_H
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+typedef struct {
+ atomic_size_t size;
+ atomic_int buffer[];
+} Array;
+
+typedef struct {
+ atomic_size_t top, bottom;
+ atomic_uintptr_t array;
+} Deque;
+
+#define EMPTY 0xffffffff
+#define ABORT 0xfffffffe
+
+/* All other user-defined structs */
+static IntegerList * __deque;
+/* All other user-defined functions */
+inline static bool succ ( int res ) {
+return res != EMPTY && res != ABORT ;
+}
+
+/* Definition of interface info struct: Steal */
+typedef struct Steal_info {
+int __RET__;
+Deque * q;
+} Steal_info;
+/* End of info struct definition: Steal */
+
+/* ID function of interface: Steal */
+inline static call_id_t Steal_id(void *info, thread_id_t __TID__) {
+ Steal_info* theInfo = (Steal_info*)info;
+ int __RET__ = theInfo->__RET__;
+ Deque * q = theInfo->q;
+
+ call_id_t __ID__ = succ ( __RET__ ) ? __RET__ : DEFAULT_CALL_ID;
+ return __ID__;
+}
+/* End of ID function: Steal */
+
+/* Check action function of interface: Steal */
+inline static bool Steal_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Steal_info* theInfo = (Steal_info*)info;
+ int __RET__ = theInfo->__RET__;
+ Deque * q = theInfo->q;
+
+ int elem = 0 ;
+ if ( succ ( __RET__ ) ) {
+ elem = front ( __deque ) ;
+ pop_front ( __deque ) ;
+ }
+ check_passed = succ ( __RET__ ) ? __RET__ == elem : true;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Steal */
+
+/* Definition of interface info struct: Take */
+typedef struct Take_info {
+int __RET__;
+Deque * q;
+} Take_info;
+/* End of info struct definition: Take */
+
+/* ID function of interface: Take */
+inline static call_id_t Take_id(void *info, thread_id_t __TID__) {
+ Take_info* theInfo = (Take_info*)info;
+ int __RET__ = theInfo->__RET__;
+ Deque * q = theInfo->q;
+
+ call_id_t __ID__ = succ ( __RET__ ) ? __RET__ : DEFAULT_CALL_ID;
+ return __ID__;
+}
+/* End of ID function: Take */
+
+/* Check action function of interface: Take */
+inline static bool Take_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Take_info* theInfo = (Take_info*)info;
+ int __RET__ = theInfo->__RET__;
+ Deque * q = theInfo->q;
+
+ int elem = 0 ;
+ if ( succ ( __RET__ ) ) {
+ elem = back ( __deque ) ;
+ pop_back ( __deque ) ;
+ }
+ check_passed = succ ( __RET__ ) ? __RET__ == elem : true;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Take */
+
+/* Definition of interface info struct: Push */
+typedef struct Push_info {
+Deque * q;
+int x;
+} Push_info;
+/* End of info struct definition: Push */
+
+/* ID function of interface: Push */
+inline static call_id_t Push_id(void *info, thread_id_t __TID__) {
+ Push_info* theInfo = (Push_info*)info;
+ Deque * q = theInfo->q;
+ int x = theInfo->x;
+
+ call_id_t __ID__ = x;
+ return __ID__;
+}
+/* End of ID function: Push */
+
+/* Check action function of interface: Push */
+inline static bool Push_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Push_info* theInfo = (Push_info*)info;
+ Deque * q = theInfo->q;
+ int x = theInfo->x;
+
+ push_back ( __deque , x ) ;
+ return true;
+}
+/* End of check action function: Push */
+
+#define INTERFACE_SIZE 3
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Push_info *_info1 = (Push_info*) info1;
+ Steal_info *_info2 = (Steal_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Take_info *_info1 = (Take_info*) info1;
+ Steal_info *_info2 = (Steal_info*) info2;
+ return true;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ __deque = createIntegerList ( ) ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ if ( __deque ) destroyIntegerList ( __deque ) ;
+ return true ;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 3 * 2);
+ func_ptr_table[2 * 2] = (void*) &Steal_id;
+ func_ptr_table[2 * 2 + 1] = (void*) &Steal_check_action;
+ func_ptr_table[2 * 0] = (void*) &Take_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Take_check_action;
+ func_ptr_table[2 * 1] = (void*) &Push_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Push_check_action;
+ /* Push(true) -> Steal(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 1; // Push
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 2; // Steal
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
+ #define HB_RULE_TABLE_SIZE 1
+ hb_rule_table[0] = hbConditionInit0;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 2);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 2;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+
+Deque * create();
+void resize(Deque *q);
+
+int __wrapper__take(Deque * q);
+
+int __wrapper__take(Deque * q) ;
+
+void __wrapper__push(Deque * q, int x);
+
+void __wrapper__push(Deque * q, int x) ;
+
+int __wrapper__steal(Deque * q);
+
+int __wrapper__steal(Deque * q) ;
+
+#endif
+
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include "model-assert.h"
+
+#include "deque.h"
+
+Deque *q;
+int a;
+int b;
+int c;
+
+static void task(void * param) {
+ a=steal(q);
+ if (a == ABORT) {
+ printf("Steal NULL\n");
+ } else {
+ printf("Steal %d\n", a);
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t;
+ q=create();
+ thrd_create(&t, task, 0);
+ push(q, 1);
+ printf("Push 1\n");
+ push(q, 2);
+ printf("Push 2\n");
+ push(q, 4);
+ printf("Push 4\n");
+ b=take(q);
+ if (b == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", b);
+ }
+ c=take(q);
+ if (c == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", c);
+ }
+ thrd_join(t);
+
+
+ return 0;
+}
+
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include "model-assert.h"
+
+#include "deque.h"
+
+Deque *q;
+int a;
+int b;
+int c;
+int x;
+
+static void task(void * param) {
+ a=steal(q);
+ if (a == ABORT) {
+ printf("Steal NULL\n");
+ } else {
+ printf("Steal %d\n", a);
+ }
+ x=steal(q);
+ if (x == ABORT) {
+ printf("Steal NULL\n");
+ } else {
+ printf("Steal %d\n", x);
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t;
+ q=create();
+ thrd_create(&t, task, 0);
+ push(q, 1);
+ printf("Push 1\n");
+ push(q, 2);
+ printf("Push 2\n");
+ push(q, 4);
+ printf("Push 4\n");
+ b=take(q);
+ if (b == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", b);
+ }
+ c=take(q);
+ if (c == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", c);
+ }
+ thrd_join(t);
+
+
+ return 0;
+}
+
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include "model-assert.h"
+
+#include "deque.h"
+
+Deque *q;
+int a;
+int b;
+int c;
+int x;
+
+static void task(void * param) {
+ a=steal(q);
+ if (a == ABORT) {
+ printf("Steal NULL\n");
+ } else {
+ printf("Steal %d\n", a);
+ }
+
+ x=steal(q);
+ if (x == ABORT) {
+ printf("Steal NULL\n");
+ } else {
+ printf("Steal %d\n", x);
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t;
+ q=create();
+ thrd_create(&t, task, 0);
+ push(q, 1);
+ printf("Push 1\n");
+ push(q, 2);
+ printf("Push 2\n");
+ push(q, 4);
+ printf("Push 4\n");
+ b=take(q);
+ if (b == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", b);
+ }
+ c=take(q);
+ if (c == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", c);
+ }
+ thrd_join(t);
+
+
+ return 0;
+}
+
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include "model-assert.h"
+
+#include "deque.h"
+
+Deque *q;
+int a;
+int b;
+int c;
+int x;
+
+static void task(void * param) {
+ a=steal(q);
+ if (a == ABORT) {
+ printf("Steal NULL\n");
+ } else {
+ printf("Steal %d\n", a);
+ }
+
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t;
+ q=create();
+ push(q, 1);
+ printf("Push 1\n");
+ push(q, 2);
+ printf("Push 2\n");
+ push(q, 4);
+ printf("Push 4\n");
+ push(q, 5);
+ printf("Push 5\n");
+ thrd_create(&t, task, 0);
+
+ b=take(q);
+ if (b == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", b);
+ }
+ c=take(q);
+ if (c == EMPTY) {
+ printf("Take NULL\n");
+ } else {
+ printf("Take %d\n", c);
+ }
+ thrd_join(t);
+
+
+ return 0;
+}
+
--- /dev/null
+#ifndef CLIFFC_HASHTABLE_H
+#define CLIFFC_HASHTABLE_H
+
+#include <iostream>
+#include <atomic>
+#include "stdio.h"
+#ifdef STANDALONE
+#include <assert.h>
+#define MODEL_ASSERT assert
+#else
+#include <model-assert.h>
+#endif
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+using namespace std;
+
+
+
+template<typename TypeK, typename TypeV>
+class cliffc_hashtable;
+
+
+struct kvs_data {
+ int _size;
+ atomic<void*> *_data;
+
+ kvs_data(int sz) {
+ _size = sz;
+ int real_size = sz * 2 + 2;
+ _data = new atomic<void*>[real_size];
+ int *hashes = new int[_size];
+ int i;
+ for (i = 0; i < _size; i++) {
+ hashes[i] = 0;
+ }
+ for (i = 2; i < real_size; i++) {
+ _data[i].store(NULL, memory_order_relaxed);
+ }
+ _data[1].store(hashes, memory_order_relaxed);
+ }
+
+ ~kvs_data() {
+ int *hashes = (int*) _data[1].load(memory_order_relaxed);
+ delete hashes;
+ delete[] _data;
+ }
+};
+
+struct slot {
+ bool _prime;
+ void *_ptr;
+
+ slot(bool prime, void *ptr) {
+ _prime = prime;
+ _ptr = ptr;
+ }
+};
+
+
+
+
+template<typename TypeK, typename TypeV>
+class cliffc_hashtable {
+/* All other user-defined structs */
+static spec_table * map;
+static spec_table * id_map;
+static id_tag_t * tag;
+/* All other user-defined functions */
+inline static bool equals_key ( void * ptr1 , void * ptr2 ) {
+TypeK * key1 = ( TypeK * ) ptr1 , * key2 = ( TypeK * ) ptr2 ;
+if ( key1 == NULL || key2 == NULL ) return false ;
+return key1 -> equals ( key2 ) ;
+}
+
+inline static bool equals_val ( void * ptr1 , void * ptr2 ) {
+if ( ptr1 == ptr2 ) return true ;
+TypeV * val1 = ( TypeV * ) ptr1 , * val2 = ( TypeV * ) ptr2 ;
+if ( val1 == NULL || val2 == NULL ) return false ;
+return val1 -> equals ( val2 ) ;
+}
+
+inline static bool equals_id ( void * ptr1 , void * ptr2 ) {
+id_tag_t * id1 = ( id_tag_t * ) ptr1 , * id2 = ( id_tag_t * ) ptr2 ;
+if ( id1 == NULL || id2 == NULL ) return false ;
+return ( * id1 ) . tag == ( * id2 ) . tag ;
+}
+
+inline static call_id_t getKeyTag ( TypeK * key ) {
+if ( ! spec_table_contains ( id_map , key ) ) {
+call_id_t cur_id = current ( tag ) ;
+spec_table_put ( id_map , key , ( void * ) cur_id ) ;
+next ( tag ) ;
+return cur_id ;
+}
+else {
+call_id_t res = ( call_id_t ) spec_table_get ( id_map , key ) ;
+return res ;
+}
+}
+
+/* Definition of interface info struct: Put */
+typedef struct Put_info {
+TypeV * __RET__;
+TypeK * key;
+TypeV * val;
+} Put_info;
+/* End of info struct definition: Put */
+
+/* ID function of interface: Put */
+inline static call_id_t Put_id(void *info, thread_id_t __TID__) {
+ Put_info* theInfo = (Put_info*)info;
+ TypeV * __RET__ = theInfo->__RET__;
+ TypeK * key = theInfo->key;
+ TypeV * val = theInfo->val;
+
+ call_id_t __ID__ = getKeyTag ( key );
+ return __ID__;
+}
+/* End of ID function: Put */
+
+/* Check action function of interface: Put */
+inline static bool Put_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Put_info* theInfo = (Put_info*)info;
+ TypeV * __RET__ = theInfo->__RET__;
+ TypeK * key = theInfo->key;
+ TypeV * val = theInfo->val;
+
+ TypeV * _Old_Val = ( TypeV * ) spec_table_get ( map , key ) ;
+ spec_table_put ( map , key , val ) ;
+ bool passed = false ;
+ if ( ! passed ) {
+ int old = _Old_Val == NULL ? 0 : _Old_Val -> _val ;
+ int ret = __RET__ == NULL ? 0 : __RET__ -> _val ;
+ }
+ check_passed = equals_val ( __RET__ , _Old_Val );
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Put */
+
+/* Definition of interface info struct: Get */
+typedef struct Get_info {
+TypeV * __RET__;
+TypeK * key;
+} Get_info;
+/* End of info struct definition: Get */
+
+/* ID function of interface: Get */
+inline static call_id_t Get_id(void *info, thread_id_t __TID__) {
+ Get_info* theInfo = (Get_info*)info;
+ TypeV * __RET__ = theInfo->__RET__;
+ TypeK * key = theInfo->key;
+
+ call_id_t __ID__ = getKeyTag ( key );
+ return __ID__;
+}
+/* End of ID function: Get */
+
+/* Check action function of interface: Get */
+inline static bool Get_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Get_info* theInfo = (Get_info*)info;
+ TypeV * __RET__ = theInfo->__RET__;
+ TypeK * key = theInfo->key;
+
+ TypeV * _Old_Val = ( TypeV * ) spec_table_get ( map , key ) ;
+ bool passed = false ;
+ if ( ! passed ) {
+ int old = _Old_Val == NULL ? 0 : _Old_Val -> _val ;
+ int ret = __RET__ == NULL ? 0 : __RET__ -> _val ;
+ }
+ check_passed = equals_val ( _Old_Val , __RET__ );
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Get */
+
+#define INTERFACE_SIZE 2
+static void** func_ptr_table;
+static anno_hb_init** hb_init_table;
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ map = new_spec_table_default ( equals_key ) ;
+ id_map = new_spec_table_default ( equals_id ) ;
+ tag = new_id_tag ( ) ;
+}
+
+/* Cleanup routine of sequential variables */
+static void __SPEC_CLEANUP__() {
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
+ func_ptr_table[2 * 1] = (void*) &Put_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Put_check_action;
+ func_ptr_table[2 * 0] = (void*) &Get_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Get_check_action;
+ /* Put(true) -> Put(true) */
+ struct anno_hb_init *hbConditionInit0 = (struct anno_hb_init*) malloc(sizeof(struct anno_hb_init));
+ hbConditionInit0->interface_num_before = 1; // Put
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 1; // Put
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Put(true) -> Get(true) */
+ struct anno_hb_init *hbConditionInit1 = (struct anno_hb_init*) malloc(sizeof(struct anno_hb_init));
+ hbConditionInit1->interface_num_before = 1; // Put
+ hbConditionInit1->hb_condition_num_before = 0; //
+ hbConditionInit1->interface_num_after = 0; // Get
+ hbConditionInit1->hb_condition_num_after = 0; //
+ /* Init hb_init_table */
+ hb_init_table = (anno_hb_init**) malloc(sizeof(anno_hb_init*) * 2);
+ #define HB_INIT_TABLE_SIZE 2
+ hb_init_table[0] = hbConditionInit0;
+ hb_init_table[1] = hbConditionInit1;
+ /* Pass init info, including function table info & HB rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void*) __SPEC_INIT__;
+ anno_init->cleanup_func = (void*) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_init_table = hb_init_table;
+ anno_init->hb_init_table_size = HB_INIT_TABLE_SIZE;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+friend class CHM;
+
+ private:
+ class CHM {
+ friend class cliffc_hashtable;
+ private:
+ atomic<kvs_data*> _newkvs;
+
+ atomic_int _size;
+
+ atomic_int _slots;
+
+ atomic_int _copy_idx;
+
+ atomic_int _copy_done;
+
+ public:
+ CHM(int size) {
+ _newkvs.store(NULL, memory_order_relaxed);
+ _size.store(size, memory_order_relaxed);
+ _slots.store(0, memory_order_relaxed);
+
+ _copy_idx.store(0, memory_order_relaxed);
+ _copy_done.store(0, memory_order_relaxed);
+ }
+
+ ~CHM() {}
+
+ private:
+
+ bool table_full(int reprobe_cnt, int len) {
+ return
+ reprobe_cnt >= REPROBE_LIMIT &&
+ _slots.load(memory_order_relaxed) >= reprobe_limit(len);
+ }
+
+ kvs_data* resize(cliffc_hashtable *topmap, kvs_data *kvs) {
+
+ kvs_data *newkvs = _newkvs.load(memory_order_acquire);
+ if (newkvs != NULL)
+ return newkvs;
+
+ int oldlen = kvs->_size;
+ int sz = _size.load(memory_order_relaxed);
+ int newsz = sz;
+
+ if (sz >= (oldlen >> 2)) { newsz = oldlen << 1; if (sz >= (oldlen >> 1))
+ newsz = oldlen << 2; }
+
+ if (newsz <= oldlen) newsz = oldlen << 1;
+ if (newsz < oldlen) newsz = oldlen;
+
+
+ newkvs = _newkvs.load(memory_order_acquire);
+ if (newkvs != NULL) return newkvs;
+
+ newkvs = new kvs_data(newsz);
+ void *chm = (void*) new CHM(sz);
+ newkvs->_data[0].store(chm, memory_order_relaxed);
+
+ kvs_data *cur_newkvs;
+
+ if ((cur_newkvs = _newkvs.load(memory_order_acquire)) != NULL)
+ return cur_newkvs;
+ kvs_data *desired = (kvs_data*) NULL;
+ kvs_data *expected = (kvs_data*) newkvs;
+
+ if (!_newkvs.compare_exchange_strong(desired, expected, memory_order_release,
+ memory_order_relaxed)) {
+ delete newkvs;
+
+ newkvs = _newkvs.load(memory_order_acquire);
+ }
+ return newkvs;
+ }
+
+ void help_copy_impl(cliffc_hashtable *topmap, kvs_data *oldkvs,
+ bool copy_all) {
+ MODEL_ASSERT (get_chm(oldkvs) == this);
+
+ kvs_data *newkvs = _newkvs.load(memory_order_acquire);
+ int oldlen = oldkvs->_size;
+ int min_copy_work = oldlen > 1024 ? 1024 : oldlen;
+
+ int panic_start = -1;
+ int copyidx;
+ while (_copy_done.load(memory_order_relaxed) < oldlen) {
+ copyidx = _copy_idx.load(memory_order_relaxed);
+ if (panic_start == -1) { copyidx = _copy_idx.load(memory_order_relaxed);
+ while (copyidx < (oldlen << 1) &&
+ !_copy_idx.compare_exchange_strong(copyidx, copyidx +
+ min_copy_work, memory_order_relaxed, memory_order_relaxed))
+ copyidx = _copy_idx.load(memory_order_relaxed);
+ if (!(copyidx < (oldlen << 1)))
+ panic_start = copyidx;
+ }
+
+ int workdone = 0;
+ for (int i = 0; i < min_copy_work; i++)
+ if (copy_slot(topmap, (copyidx + i) & (oldlen - 1), oldkvs,
+ newkvs))
+ workdone++;
+ if (workdone > 0)
+ copy_check_and_promote(topmap, oldkvs, workdone);
+
+ copyidx += min_copy_work;
+ if (!copy_all && panic_start == -1)
+ return; }
+ copy_check_and_promote(topmap, oldkvs, 0); }
+
+ kvs_data* copy_slot_and_check(cliffc_hashtable *topmap, kvs_data
+ *oldkvs, int idx, void *should_help) {
+
+ kvs_data *newkvs = _newkvs.load(memory_order_acquire);
+ if (copy_slot(topmap, idx, oldkvs, newkvs))
+ copy_check_and_promote(topmap, oldkvs, 1); return (should_help == NULL) ? newkvs : topmap->help_copy(newkvs);
+ }
+
+ void copy_check_and_promote(cliffc_hashtable *topmap, kvs_data*
+ oldkvs, int workdone) {
+ int oldlen = oldkvs->_size;
+ int copyDone = _copy_done.load(memory_order_relaxed);
+ if (workdone > 0) {
+ while (true) {
+ copyDone = _copy_done.load(memory_order_relaxed);
+ if (_copy_done.compare_exchange_weak(copyDone, copyDone +
+ workdone, memory_order_relaxed, memory_order_relaxed))
+ break;
+ }
+ }
+
+ if (copyDone + workdone == oldlen &&
+ topmap->_kvs.load(memory_order_relaxed) == oldkvs) {
+
+ kvs_data *newkvs = _newkvs.load(memory_order_acquire);
+
+ topmap->_kvs.compare_exchange_strong(oldkvs, newkvs, memory_order_release,
+ memory_order_relaxed);
+ }
+ }
+
+ bool copy_slot(cliffc_hashtable *topmap, int idx, kvs_data *oldkvs,
+ kvs_data *newkvs) {
+ slot *key_slot;
+ while ((key_slot = key(oldkvs, idx)) == NULL)
+ CAS_key(oldkvs, idx, NULL, TOMBSTONE);
+
+ slot *oldval = val(oldkvs, idx);
+ while (!is_prime(oldval)) {
+ slot *box = (oldval == NULL || oldval == TOMBSTONE)
+ ? TOMBPRIME : new slot(true, oldval->_ptr);
+ if (CAS_val(oldkvs, idx, oldval, box)) {
+ if (box == TOMBPRIME)
+ return 1; oldval = box; break;
+ }
+ oldval = val(oldkvs, idx); }
+
+ if (oldval == TOMBPRIME) return false;
+ slot *old_unboxed = new slot(false, oldval->_ptr);
+ int copied_into_new = (putIfMatch(topmap, newkvs, key_slot, old_unboxed,
+ NULL) == NULL);
+
+ while (!CAS_val(oldkvs, idx, oldval, TOMBPRIME))
+ oldval = val(oldkvs, idx);
+
+ return copied_into_new;
+ }
+ };
+
+
+
+ private:
+ static const int Default_Init_Size = 4;
+ static slot* const MATCH_ANY;
+ static slot* const NO_MATCH_OLD;
+
+ static slot* const TOMBPRIME;
+ static slot* const TOMBSTONE;
+
+ static const int REPROBE_LIMIT = 10;
+ atomic<kvs_data*> _kvs;
+
+ public:
+ cliffc_hashtable() {
+ __sequential_init();
+
+ kvs_data *kvs = new kvs_data(Default_Init_Size);
+ void *chm = (void*) new CHM(0);
+ kvs->_data[0].store(chm, memory_order_relaxed);
+ _kvs.store(kvs, memory_order_relaxed);
+ }
+
+ cliffc_hashtable(int init_size) {
+
+ __sequential_init();
+
+ kvs_data *kvs = new kvs_data(init_size);
+ void *chm = (void*) new CHM(0);
+ kvs->_data[0].store(chm, memory_order_relaxed);
+ _kvs.store(kvs, memory_order_relaxed);
+ }
+
+
+TypeV * get(TypeK * key) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Get
+ interface_begin->interface_name = "Get";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ TypeV * __RET__ = __wrapper__get(key);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Get
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Get_info* info = (Get_info*) malloc(sizeof(Get_info));
+ info->__RET__ = __RET__;
+ info->key = key;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Get
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+TypeV * __wrapper__get(TypeK * key) {
+ slot *key_slot = new slot(false, key);
+ int fullhash = hash(key_slot);
+
+ kvs_data *kvs = _kvs.load(memory_order_acquire);
+
+ slot *V = get_impl(this, kvs, key_slot, fullhash);
+ if (V == NULL) return NULL;
+ MODEL_ASSERT (!is_prime(V));
+ return (TypeV*) V->_ptr;
+ }
+
+
+TypeV * put(TypeK * key, TypeV * val) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Put
+ interface_begin->interface_name = "Put";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ TypeV * __RET__ = __wrapper__put(key, val);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Put
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Put_info* info = (Put_info*) malloc(sizeof(Put_info));
+ info->__RET__ = __RET__;
+ info->key = key;
+ info->val = val;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Put
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+TypeV * __wrapper__put(TypeK * key, TypeV * val) {
+ return putIfMatch(key, val, NO_MATCH_OLD);
+ }
+
+
+ TypeV* putIfAbsent(TypeK *key, TypeV *value) {
+ return putIfMatch(key, val, TOMBSTONE);
+ }
+
+
+ TypeV* remove(TypeK *key) {
+ return putIfMatch(key, TOMBSTONE, NO_MATCH_OLD);
+ }
+
+
+ bool remove(TypeK *key, TypeV *val) {
+ slot *val_slot = val == NULL ? NULL : new slot(false, val);
+ return putIfMatch(key, TOMBSTONE, val) == val;
+
+ }
+
+
+ TypeV* replace(TypeK *key, TypeV *val) {
+ return putIfMatch(key, val, MATCH_ANY);
+ }
+
+
+ bool replace(TypeK *key, TypeV *oldval, TypeV *newval) {
+ return putIfMatch(key, newval, oldval) == oldval;
+ }
+
+ private:
+ static CHM* get_chm(kvs_data* kvs) {
+ CHM *res = (CHM*) kvs->_data[0].load(memory_order_relaxed);
+ return res;
+ }
+
+ static int* get_hashes(kvs_data *kvs) {
+ return (int *) kvs->_data[1].load(memory_order_relaxed);
+ }
+
+ static inline slot* key(kvs_data *kvs, int idx) {
+ MODEL_ASSERT (idx >= 0 && idx < kvs->_size);
+ slot *res = (slot*) kvs->_data[idx * 2 + 2].load(memory_order_relaxed);
+ /* Automatically generated code for potential commit point: Read_Key_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 0;
+ potential_cp_define->label_name = "Read_Key_Point";
+ potential_cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ return res;
+ }
+
+
+ static inline slot* val(kvs_data *kvs, int idx) {
+ MODEL_ASSERT (idx >= 0 && idx < kvs->_size);
+
+ slot *res = (slot*) kvs->_data[idx * 2 + 3].load(memory_order_acquire);
+ /* Automatically generated code for potential commit point: Read_Val_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 1;
+ potential_cp_define->label_name = "Read_Val_Point";
+ potential_cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ return res;
+
+
+ }
+
+ static int hash(slot *key_slot) {
+ MODEL_ASSERT(key_slot != NULL && key_slot->_ptr != NULL);
+ TypeK* key = (TypeK*) key_slot->_ptr;
+ int h = key->hashCode();
+ h += (h << 15) ^ 0xffffcd7d;
+ h ^= (h >> 10);
+ h += (h << 3);
+ h ^= (h >> 6);
+ h += (h << 2) + (h << 14);
+ return h ^ (h >> 16);
+ }
+
+ static int reprobe_limit(int len) {
+ return REPROBE_LIMIT + (len >> 2);
+ }
+
+ static inline bool is_prime(slot *val) {
+ return (val != NULL) && val->_prime;
+ }
+
+ static bool keyeq(slot *K, slot *key_slot, int *hashes, int hash,
+ int fullhash) {
+ MODEL_ASSERT (K != NULL);
+ TypeK* key_ptr = (TypeK*) key_slot->_ptr;
+ return
+ K == key_slot ||
+ ((hashes[hash] == 0 || hashes[hash] == fullhash) &&
+ K != TOMBSTONE &&
+ key_ptr->equals(K->_ptr));
+ }
+
+ static bool valeq(slot *val_slot1, slot *val_slot2) {
+ MODEL_ASSERT (val_slot1 != NULL);
+ TypeK* ptr1 = (TypeV*) val_slot1->_ptr;
+ if (val_slot2 == NULL || ptr1 == NULL) return false;
+ return ptr1->equals(val_slot2->_ptr);
+ }
+
+ static inline bool CAS_key(kvs_data *kvs, int idx, void *expected, void *desired) {
+ bool res = kvs->_data[2 * idx + 2].compare_exchange_strong(expected,
+ desired, memory_order_relaxed, memory_order_relaxed);
+ /* Automatically generated code for potential commit point: Write_Key_Point */
+
+ if (res) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 2;
+ potential_cp_define->label_name = "Write_Key_Point";
+ potential_cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ return res;
+ }
+
+
+ static inline bool CAS_val(kvs_data *kvs, int idx, void *expected, void
+ *desired) {
+
+ bool res = kvs->_data[2 * idx + 3].compare_exchange_strong(expected,
+ desired, memory_order_acq_rel, memory_order_relaxed);
+ /* Automatically generated code for potential commit point: Write_Val_Point */
+
+ if (res) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 3;
+ potential_cp_define->label_name = "Write_Val_Point";
+ potential_cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ return res;
+ }
+
+ slot* get_impl(cliffc_hashtable *topmap, kvs_data *kvs, slot* key_slot, int
+ fullhash) {
+ int len = kvs->_size;
+ CHM *chm = get_chm(kvs);
+ int *hashes = get_hashes(kvs);
+
+ int idx = fullhash & (len - 1);
+ int reprobe_cnt = 0;
+ while (true) {
+ slot *K = key(kvs, idx);
+ /* Automatically generated code for commit point define: Get_Point1 */
+
+ if (K == NULL) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 4;
+ cp_define->label_name = "Get_Point1";
+ cp_define->potential_cp_label_num = 0;
+ cp_define->potential_label_name = "Read_Key_Point";
+ cp_define->interface_num = 0;
+ cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ slot *V = val(kvs, idx);
+
+ if (K == NULL) {
+ return NULL; }
+
+ if (keyeq(K, key_slot, hashes, idx, fullhash)) {
+ if (!is_prime(V)) {
+ /* Automatically generated code for commit point clear: Get_Clear */
+
+ if (true) {
+ struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
+ struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_clear->type = CP_CLEAR;
+ annotation_cp_clear->annotation = cp_clear;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
+ }
+
+
+ /* Automatically generated code for commit point define: Get_Point2 */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 6;
+ cp_define->label_name = "Get_Point2";
+ cp_define->potential_cp_label_num = 1;
+ cp_define->potential_label_name = "Read_Val_Point";
+ cp_define->interface_num = 0;
+ cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return (V == TOMBSTONE) ? NULL : V; }
+ return get_impl(topmap, chm->copy_slot_and_check(topmap, kvs,
+ idx, key_slot), key_slot, fullhash);
+ }
+
+ if (++reprobe_cnt >= REPROBE_LIMIT ||
+ key_slot == TOMBSTONE) {
+
+ kvs_data *newkvs = chm->_newkvs.load(memory_order_acquire);
+
+ return newkvs == NULL ? NULL : get_impl(topmap,
+ topmap->help_copy(newkvs), key_slot, fullhash);
+ }
+
+ idx = (idx + 1) & (len - 1); }
+ }
+
+ TypeV* putIfMatch(TypeK *key, TypeV *value, slot *old_val) {
+ if (old_val == NULL) {
+ return NULL;
+ }
+ slot *key_slot = new slot(false, key);
+
+ slot *value_slot = new slot(false, value);
+
+ kvs_data *kvs = _kvs.load(memory_order_acquire);
+
+ slot *res = putIfMatch(this, kvs, key_slot, value_slot, old_val);
+ MODEL_ASSERT (res != NULL);
+ MODEL_ASSERT (!is_prime(res));
+ return res == TOMBSTONE ? NULL : (TypeV*) res->_ptr;
+ }
+
+
+ static slot* putIfMatch(cliffc_hashtable *topmap, kvs_data *kvs, slot
+ *key_slot, slot *val_slot, slot *expVal) {
+ MODEL_ASSERT (val_slot != NULL);
+ MODEL_ASSERT (!is_prime(val_slot));
+ MODEL_ASSERT (!is_prime(expVal));
+
+ int fullhash = hash(key_slot);
+ int len = kvs->_size;
+ CHM *chm = get_chm(kvs);
+ int *hashes = get_hashes(kvs);
+ int idx = fullhash & (len - 1);
+
+ int reprobe_cnt = 0;
+ slot *K;
+ slot *V;
+ kvs_data *newkvs;
+
+ while (true) { K = key(kvs, idx);
+ V = val(kvs, idx);
+ if (K == NULL) { if (val_slot == TOMBSTONE) return val_slot;
+ if (CAS_key(kvs, idx, NULL, key_slot)) {
+ /* Automatically generated code for commit point define: Put_WriteKey */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 7;
+ cp_define->label_name = "Put_WriteKey";
+ cp_define->potential_cp_label_num = 2;
+ cp_define->potential_label_name = "Write_Key_Point";
+ cp_define->interface_num = 1;
+ cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ chm->_slots.fetch_add(1, memory_order_relaxed); hashes[idx] = fullhash; break;
+ }
+ K = key(kvs, idx); MODEL_ASSERT (K != NULL);
+ }
+
+ if (keyeq(K, key_slot, hashes, idx, fullhash))
+ break;
+ if (++reprobe_cnt >= reprobe_limit(len) ||
+ K == TOMBSTONE) { newkvs = chm->resize(topmap, kvs);
+ if (expVal != NULL) topmap->help_copy(newkvs);
+ return putIfMatch(topmap, newkvs, key_slot, val_slot, expVal);
+ }
+
+ idx = (idx + 1) & (len - 1); }
+ if (val_slot == V) return V;
+
+ newkvs = chm->_newkvs.load(memory_order_acquire);
+
+ if (newkvs == NULL &&
+ ((V == NULL && chm->table_full(reprobe_cnt, len)) || is_prime(V))) {
+ newkvs = chm->resize(topmap, kvs); }
+
+ if (newkvs != NULL)
+ return putIfMatch(topmap, chm->copy_slot_and_check(topmap, kvs, idx,
+ expVal), key_slot, val_slot, expVal);
+
+ while (true) {
+ MODEL_ASSERT (!is_prime(V));
+
+ if (expVal != NO_MATCH_OLD &&
+ V != expVal &&
+ (expVal != MATCH_ANY || V == TOMBSTONE || V == NULL) &&
+ !(V == NULL && expVal == TOMBSTONE) &&
+ (expVal == NULL || !valeq(expVal, V))) {
+
+
+
+ return V; }
+
+ if (CAS_val(kvs, idx, V, val_slot)) {
+ /* Automatically generated code for commit point define: Put_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 8;
+ cp_define->label_name = "Put_Point";
+ cp_define->potential_cp_label_num = 3;
+ cp_define->potential_label_name = "Write_Val_Point";
+ cp_define->interface_num = 1;
+ cp_define->is_additional_point = false;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ if (expVal != NULL) { if ((V == NULL || V == TOMBSTONE) &&
+ val_slot != TOMBSTONE)
+ chm->_size.fetch_add(1, memory_order_relaxed);
+ if (!(V == NULL || V == TOMBSTONE) &&
+ val_slot == TOMBSTONE)
+ chm->_size.fetch_add(-1, memory_order_relaxed);
+ }
+ return (V == NULL && expVal != NULL) ? TOMBSTONE : V;
+ }
+ V = val(kvs, idx);
+ if (is_prime(V))
+ return putIfMatch(topmap, chm->copy_slot_and_check(topmap, kvs,
+ idx, expVal), key_slot, val_slot, expVal);
+ }
+ }
+
+ kvs_data* help_copy(kvs_data *helper) {
+
+ kvs_data *topkvs = _kvs.load(memory_order_acquire);
+ CHM *topchm = get_chm(topkvs);
+ if (topchm->_newkvs.load(memory_order_relaxed) == NULL) return helper;
+ topchm->help_copy_impl(this, topkvs, false);
+ return helper;
+ }
+};
+template<typename TypeK, typename TypeV>
+void** cliffc_hashtable<TypeK, TypeV>::func_ptr_table;
+template<typename TypeK, typename TypeV>
+anno_hb_init** cliffc_hashtable<TypeK, TypeV>::hb_init_table;
+template<typename TypeK, typename TypeV>
+spec_table * cliffc_hashtable<TypeK, TypeV>::map;
+template<typename TypeK, typename TypeV>
+spec_table * cliffc_hashtable<TypeK, TypeV>::id_map;
+template<typename TypeK, typename TypeV>
+id_tag_t * cliffc_hashtable<TypeK, TypeV>::tag;
+
+
+#endif
+
--- /dev/null
+#include <iostream>
+#include <threads.h>
+#include "cliffc_hashtable.h"
+
+using namespace std;
+
+template<typename TypeK, typename TypeV>
+slot* const cliffc_hashtable<TypeK, TypeV>::MATCH_ANY = new slot(false, NULL);
+
+template<typename TypeK, typename TypeV>
+slot* const cliffc_hashtable<TypeK, TypeV>::NO_MATCH_OLD = new slot(false, NULL);
+
+template<typename TypeK, typename TypeV>
+slot* const cliffc_hashtable<TypeK, TypeV>::TOMBPRIME = new slot(true, NULL);
+
+template<typename TypeK, typename TypeV>
+slot* const cliffc_hashtable<TypeK, TypeV>::TOMBSTONE = new slot(false, NULL);
+
+
+class IntWrapper {
+ private:
+ public:
+ int _val;
+
+ IntWrapper(int val) : _val(val) {}
+
+ IntWrapper() : _val(0) {}
+
+ IntWrapper(IntWrapper& copy) : _val(copy._val) {}
+
+ int get() {
+ return _val;
+ }
+
+ int hashCode() {
+ return _val;
+ }
+
+ bool operator==(const IntWrapper& rhs) {
+ return false;
+ }
+
+ bool equals(const void *another) {
+ if (another == NULL)
+ return false;
+ IntWrapper *ptr =
+ (IntWrapper*) another;
+ return ptr->_val == _val;
+ }
+};
+
+cliffc_hashtable<IntWrapper, IntWrapper> *table;
+IntWrapper *val1, *val2;
+IntWrapper *k0, *k1, *k2, *k3, *k4, *k5;
+IntWrapper *v0, *v1, *v2, *v3, *v4, *v5;
+
+void threadA(void *arg) {
+ IntWrapper *Res;
+ int res;
+ Res = table->put(k3, v3);
+ res = Res == NULL ? 0 : Res->_val;
+ printf("Put1: key_%d, val_%d, res_%d\n", k3->_val, v3->_val, res);
+
+ Res = table->get(k2);
+ res = Res == NULL ? 0 : Res->_val;
+ printf("Get2: key_%d, res_%d\n", k2->_val, res);
+}
+
+void threadB(void *arg) {
+ IntWrapper *Res;
+ int res;
+ Res = table->put(k2, v2);
+ res = Res == NULL ? 0 : Res->_val;
+ printf("Put3: key_%d, val_%d, res_%d\n", k2->_val, v2->_val, res);
+
+ Res = table->get(k3);
+ res = Res == NULL ? 0 : Res->_val;
+ printf("Get4: key_%d, res_%d\n", k3->_val, res);
+}
+
+void threadC(void *arg) {
+}
+
+int user_main(int argc, char *argv[]) {
+ thrd_t t1, t2, t3;
+ table = new cliffc_hashtable<IntWrapper, IntWrapper>(32);
+ k1 = new IntWrapper(3);
+ k2 = new IntWrapper(5);
+ k3 = new IntWrapper(11);
+ k4 = new IntWrapper(7);
+ k5 = new IntWrapper(13);
+
+ v0 = new IntWrapper(2048);
+ v1 = new IntWrapper(1024);
+ v2 = new IntWrapper(47);
+ v3 = new IntWrapper(73);
+ v4 = new IntWrapper(81);
+ v5 = new IntWrapper(99);
+
+ thrd_create(&t1, threadA, NULL);
+ thrd_create(&t2, threadB, NULL);
+ thrd_create(&t3, threadC, NULL);
+ thrd_join(t1);
+ thrd_join(t2);
+ thrd_join(t3);
+
+ return 0;
+}
+
+
+
--- /dev/null
+#ifndef _HASHMAP_H
+#define _HASHMAP_H
+
+#include <iostream>
+#include <atomic>
+#include "stdio.h"
+#include <stdlib.h>
+#include <mutex>
+
+#include <spec_lib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+
+#include "common.h"
+
+#define relaxed memory_order_relaxed
+#define release memory_order_release
+#define acquire memory_order_acquire
+#define acq_rel memory_order_acq_rel
+#define seq_cst memory_order_seq_cst
+
+using namespace std;
+
+
+
+class Entry {
+ public:
+ int key;
+ atomic_int value;
+ int hash;
+ atomic<Entry*> next;
+
+ Entry(int h, int k, int v, Entry *n) {
+ this->hash = h;
+ this->key = k;
+ this->value.store(v, relaxed);
+ this->next.store(n, relaxed);
+ }
+};
+
+class Segment {
+ public:
+ int count;
+ mutex segMutex;
+
+ void lock() {
+ segMutex.lock();
+ }
+
+ void unlock() {
+ segMutex.unlock();
+ }
+
+ Segment() {
+ this->count = 0;
+ }
+};
+
+
+class HashMap {
+ public:
+
+/* All other user-defined structs */
+static IntegerMap * __map;
+/* All other user-defined functions */
+/* Definition of interface info struct: Put */
+typedef struct Put_info {
+int __RET__;
+int key;
+int value;
+} Put_info;
+/* End of info struct definition: Put */
+
+/* ID function of interface: Put */
+inline static call_id_t Put_id(void *info, thread_id_t __TID__) {
+ Put_info* theInfo = (Put_info*)info;
+ int __RET__ = theInfo->__RET__;
+ int key = theInfo->key;
+ int value = theInfo->value;
+
+ call_id_t __ID__ = value;
+ return __ID__;
+}
+/* End of ID function: Put */
+
+/* Check action function of interface: Put */
+inline static bool Put_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Put_info* theInfo = (Put_info*)info;
+ int __RET__ = theInfo->__RET__;
+ int key = theInfo->key;
+ int value = theInfo->value;
+
+ putIntegerMap ( __map , key , value ) ;
+ return true;
+}
+/* End of check action function: Put */
+
+/* Definition of interface info struct: Get */
+typedef struct Get_info {
+int __RET__;
+int key;
+} Get_info;
+/* End of info struct definition: Get */
+
+/* ID function of interface: Get */
+inline static call_id_t Get_id(void *info, thread_id_t __TID__) {
+ Get_info* theInfo = (Get_info*)info;
+ int __RET__ = theInfo->__RET__;
+ int key = theInfo->key;
+
+ call_id_t __ID__ = __RET__;
+ return __ID__;
+}
+/* End of ID function: Get */
+
+/* Check action function of interface: Get */
+inline static bool Get_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Get_info* theInfo = (Get_info*)info;
+ int __RET__ = theInfo->__RET__;
+ int key = theInfo->key;
+
+ int res = getIntegerMap ( __map , key ) ;
+ check_passed = __RET__ ? res == __RET__ : true;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Get */
+
+#define INTERFACE_SIZE 2
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Put_info *_info1 = (Put_info*) info1;
+ Put_info *_info2 = (Put_info*) info2;
+ return _info1-> key != _info2-> key;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Put_info *_info1 = (Put_info*) info1;
+ Get_info *_info2 = (Get_info*) info2;
+ return _info1-> key != _info2-> key;
+}
+inline static bool CommutativityCondition2(void *info1, void *info2) {
+ Get_info *_info1 = (Get_info*) info1;
+ Get_info *_info2 = (Get_info*) info2;
+ return true;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ __map = createIntegerMap ( ) ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ if ( __map ) destroyIntegerMap ( __map ) ;
+ return true ;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
+ func_ptr_table[2 * 1] = (void*) &Put_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Put_check_action;
+ func_ptr_table[2 * 0] = (void*) &Get_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Get_check_action;
+ /* Put(true) -> Get(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 1; // Put
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 0; // Get
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
+ #define HB_RULE_TABLE_SIZE 1
+ hb_rule_table[0] = hbConditionInit0;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 3);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 1;
+ rule->rule = "_Method1 . key != _Method2 . key";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 0;
+ rule->rule = "_Method1 . key != _Method2 . key";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 0;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition2;
+ commutativity_rule_table[2] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 3;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+ atomic<Entry*> *table;
+
+ int capacity;
+ int size;
+
+ static const int CONCURRENCY_LEVEL = 4;
+
+ static const int SEGMENT_MASK = CONCURRENCY_LEVEL - 1;
+
+ Segment *segments[CONCURRENCY_LEVEL];
+
+ static const int DEFAULT_INITIAL_CAPACITY = 16;
+
+
+ HashMap() {
+ __sequential_init();
+
+ this->size = 0;
+ this->capacity = DEFAULT_INITIAL_CAPACITY;
+ this->table = new atomic<Entry*>[capacity];
+ for (int i = 0; i < capacity; i++) {
+ atomic_init(&table[i], NULL);
+ }
+ for (int i = 0; i < CONCURRENCY_LEVEL; i++) {
+ segments[i] = new Segment;
+ }
+ }
+
+ int hashKey(int key) {
+ return key;
+ }
+
+
+
+int get(int key) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Get
+ interface_begin->interface_name = "Get";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__get(key);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Get
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Get_info* info = (Get_info*) malloc(sizeof(Get_info));
+ info->__RET__ = __RET__;
+ info->key = key;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Get
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__get(int key) {
+ ASSERT (key);
+ int hash = hashKey(key);
+
+ atomic<Entry*> *tab = table;
+ int index = hash & (capacity - 1);
+ atomic<Entry*> *first = &tab[index];
+ Entry *e;
+ int res = 0;
+
+
+
+ Entry *firstPtr = first->load(acquire);
+
+ e = firstPtr;
+ while (e != NULL) {
+ if (key, e->key) {
+
+ res = e->value.load(seq_cst);
+ /* Automatically generated code for commit point define check: GetReadValue1 */
+
+ if (res != 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "GetReadValue1";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (res != 0)
+ return res;
+ else
+ break;
+ }
+ e = e->next.load(relaxed);
+ }
+
+ Segment *seg = segments[hash & SEGMENT_MASK];
+ seg->lock();
+ Entry *newFirstPtr = first->load(relaxed);
+ /* Automatically generated code for commit point define check: GetReadEntry */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "GetReadEntry";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (e != NULL || firstPtr != newFirstPtr) {
+ e = newFirstPtr;
+ while (e != NULL) {
+ if (key == e->key) {
+ res = e->value.load(relaxed);
+ /* Automatically generated code for commit point define check: GetReadValue2 */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "GetReadValue2";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ seg->unlock(); return res;
+ }
+ e = e->next.load(relaxed);
+ }
+ }
+ seg->unlock(); return 0;
+ }
+
+
+int put(int key, int value) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Put
+ interface_begin->interface_name = "Put";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__put(key, value);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Put
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Put_info* info = (Put_info*) malloc(sizeof(Put_info));
+ info->__RET__ = __RET__;
+ info->key = key;
+ info->value = value;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Put
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__put(int key, int value) {
+ ASSERT (key && value);
+ int hash = hashKey(key);
+ Segment *seg = segments[hash & SEGMENT_MASK];
+ atomic<Entry*> *tab;
+
+ seg->lock(); tab = table;
+ int index = hash & (capacity - 1);
+
+ atomic<Entry*> *first = &tab[index];
+ Entry *e;
+ int oldValue = 0;
+
+ Entry *firstPtr = first->load(relaxed);
+ e = firstPtr;
+ while (e != NULL) {
+ if (key == e->key) {
+ oldValue = e->value.load(relaxed);
+
+
+ e->value.store(value, seq_cst);
+ /* Automatically generated code for commit point define check: PutUpdateValue */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "PutUpdateValue";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ seg->unlock(); return oldValue;
+ }
+ e = e->next.load(relaxed);
+ }
+
+ Entry *newEntry = new Entry(hash, key, value, firstPtr);
+
+
+ first->store(newEntry, release);
+ /* Automatically generated code for commit point define check: PutInsertValue */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 4;
+ cp_define_check->label_name = "PutInsertValue";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ seg->unlock(); return 0;
+ }
+};
+void** HashMap::func_ptr_table;
+hb_rule** HashMap::hb_rule_table;
+commutativity_rule** HashMap::commutativity_rule_table;
+IntegerMap * HashMap::__map;
+
+
+#endif
+
--- /dev/null
+#include <iostream>
+#include <threads.h>
+#include "hashmap.h"
+
+HashMap *table;
+
+void threadA(void *arg) {
+ table->put(1, 1);
+ printf("Thrd A: Put %d -> %d\n", 1, 1);
+ int r1 = table->get(2);
+ printf("Thrd A: Get %d\n", r1);
+}
+
+void threadB(void *arg) {
+ table->put(2, 2);
+ printf("Thrd B: Put %d -> %d\n", 2, 2);
+ int r2 = table->get(1);
+ printf("Thrd B: Get %d\n", r2);
+}
+
+int user_main(int argc, char *argv[]) {
+ thrd_t t1, t2;
+
+ table = new HashMap;
+
+ thrd_create(&t1, threadA, NULL);
+ thrd_create(&t2, threadB, NULL);
+ thrd_join(t1);
+ thrd_join(t2);
+
+ return 0;
+}
+
+
+
--- /dev/null
+#include <iostream>
+#include <threads.h>
+#include "hashmap.h"
+
+HashMap *table;
+
+void threadA(void *arg) {
+ table->put(1, 11);
+ printf("Thrd A: Put %d -> %d\n", 1, 11);
+ int r1 = table->get(2);
+ printf("Thrd A: Get %d\n", r1);
+}
+
+void threadB(void *arg) {
+ table->put(2, 22);
+ printf("Thrd B: Put %d -> %d\n", 2, 22);
+ int r2 = table->get(1);
+ printf("Thrd B: Get %d\n", r2);
+}
+
+int user_main(int argc, char *argv[]) {
+ thrd_t t1, t2;
+
+ table = new HashMap;
+ table->put(1, 1);
+ table->put(2, 2);
+
+ thrd_create(&t1, threadA, NULL);
+ thrd_create(&t2, threadB, NULL);
+ thrd_join(t1);
+ thrd_join(t2);
+
+ return 0;
+}
+
+
+
--- /dev/null
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+#include "librace.h"
+
+#define RW_LOCK_BIAS 0x00100000
+#define WRITE_LOCK_CMP RW_LOCK_BIAS
+
+typedef union {
+ atomic_int lock;
+} rwlock_t;
+
+
+
+
+
+
+
+/* All other user-defined structs */
+static bool writer_lock_acquired;
+static int reader_lock_cnt;
+/* All other user-defined functions */
+/* Definition of interface info struct: Write_Trylock */
+typedef struct Write_Trylock_info {
+int __RET__;
+rwlock_t * rw;
+} Write_Trylock_info;
+/* End of info struct definition: Write_Trylock */
+
+/* ID function of interface: Write_Trylock */
+inline static call_id_t Write_Trylock_id(void *info, thread_id_t __TID__) {
+ Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Trylock */
+
+/* Check action function of interface: Write_Trylock */
+inline static bool Write_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ if ( __RET__ == 1 ) writer_lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Write_Trylock */
+
+/* Definition of interface info struct: Read_Trylock */
+typedef struct Read_Trylock_info {
+int __RET__;
+rwlock_t * rw;
+} Read_Trylock_info;
+/* End of info struct definition: Read_Trylock */
+
+/* ID function of interface: Read_Trylock */
+inline static call_id_t Read_Trylock_id(void *info, thread_id_t __TID__) {
+ Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Trylock */
+
+/* Check action function of interface: Read_Trylock */
+inline static bool Read_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ if ( __RET__ ) reader_lock_cnt ++ ;
+ check_passed = __RET__ == ! writer_lock_acquired || ! __RET__;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Read_Trylock */
+
+/* Definition of interface info struct: Write_Lock */
+typedef struct Write_Lock_info {
+rwlock_t * rw;
+} Write_Lock_info;
+/* End of info struct definition: Write_Lock */
+
+/* ID function of interface: Write_Lock */
+inline static call_id_t Write_Lock_id(void *info, thread_id_t __TID__) {
+ Write_Lock_info* theInfo = (Write_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Lock */
+
+/* Check action function of interface: Write_Lock */
+inline static bool Write_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Lock_info* theInfo = (Write_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = ! writer_lock_acquired && reader_lock_cnt == 0;
+ if (!check_passed)
+ return false;
+ writer_lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Write_Lock */
+
+/* Definition of interface info struct: Write_Unlock */
+typedef struct Write_Unlock_info {
+rwlock_t * rw;
+} Write_Unlock_info;
+/* End of info struct definition: Write_Unlock */
+
+/* ID function of interface: Write_Unlock */
+inline static call_id_t Write_Unlock_id(void *info, thread_id_t __TID__) {
+ Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Unlock */
+
+/* Check action function of interface: Write_Unlock */
+inline static bool Write_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = reader_lock_cnt == 0 && writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ writer_lock_acquired = false ;
+ return true;
+}
+/* End of check action function: Write_Unlock */
+
+/* Definition of interface info struct: Read_Unlock */
+typedef struct Read_Unlock_info {
+rwlock_t * rw;
+} Read_Unlock_info;
+/* End of info struct definition: Read_Unlock */
+
+/* ID function of interface: Read_Unlock */
+inline static call_id_t Read_Unlock_id(void *info, thread_id_t __TID__) {
+ Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Unlock */
+
+/* Check action function of interface: Read_Unlock */
+inline static bool Read_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = reader_lock_cnt > 0 && ! writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ reader_lock_cnt -- ;
+ return true;
+}
+/* End of check action function: Read_Unlock */
+
+/* Definition of interface info struct: Read_Lock */
+typedef struct Read_Lock_info {
+rwlock_t * rw;
+} Read_Lock_info;
+/* End of info struct definition: Read_Lock */
+
+/* ID function of interface: Read_Lock */
+inline static call_id_t Read_Lock_id(void *info, thread_id_t __TID__) {
+ Read_Lock_info* theInfo = (Read_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Lock */
+
+/* Check action function of interface: Read_Lock */
+inline static bool Read_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Lock_info* theInfo = (Read_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = ! writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ reader_lock_cnt ++ ;
+ return true;
+}
+/* End of check action function: Read_Lock */
+
+#define INTERFACE_SIZE 6
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Lock_info *_info2 = (Read_Lock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition2(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition3(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition4(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition5(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition6(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition7(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition8(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition9(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Lock_info *_info2 = (Write_Lock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition10(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition11(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition12(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition13(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Lock_info *_info2 = (Write_Lock_info*) info2;
+ return ! _info1-> __RET__;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ writer_lock_acquired = false ;
+ reader_lock_cnt = 0 ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ return true;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 6 * 2);
+ func_ptr_table[2 * 3] = (void*) &Write_Trylock_id;
+ func_ptr_table[2 * 3 + 1] = (void*) &Write_Trylock_check_action;
+ func_ptr_table[2 * 2] = (void*) &Read_Trylock_id;
+ func_ptr_table[2 * 2 + 1] = (void*) &Read_Trylock_check_action;
+ func_ptr_table[2 * 1] = (void*) &Write_Lock_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Write_Lock_check_action;
+ func_ptr_table[2 * 5] = (void*) &Write_Unlock_id;
+ func_ptr_table[2 * 5 + 1] = (void*) &Write_Unlock_check_action;
+ func_ptr_table[2 * 4] = (void*) &Read_Unlock_id;
+ func_ptr_table[2 * 4 + 1] = (void*) &Read_Unlock_check_action;
+ func_ptr_table[2 * 0] = (void*) &Read_Lock_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Read_Lock_check_action;
+ /* Read_Unlock(true) -> Write_Lock(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 4; // Read_Unlock
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 1; // Write_Lock
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Read_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
+ struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit1->interface_num_before = 4; // Read_Unlock
+ hbConditionInit1->hb_condition_num_before = 0; //
+ hbConditionInit1->interface_num_after = 3; // Write_Trylock
+ hbConditionInit1->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
+ /* Write_Unlock(true) -> Write_Lock(true) */
+ struct hb_rule *hbConditionInit2 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit2->interface_num_before = 5; // Write_Unlock
+ hbConditionInit2->hb_condition_num_before = 0; //
+ hbConditionInit2->interface_num_after = 1; // Write_Lock
+ hbConditionInit2->hb_condition_num_after = 0; //
+ /* Write_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
+ struct hb_rule *hbConditionInit3 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit3->interface_num_before = 5; // Write_Unlock
+ hbConditionInit3->hb_condition_num_before = 0; //
+ hbConditionInit3->interface_num_after = 3; // Write_Trylock
+ hbConditionInit3->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
+ /* Write_Unlock(true) -> Read_Lock(true) */
+ struct hb_rule *hbConditionInit4 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit4->interface_num_before = 5; // Write_Unlock
+ hbConditionInit4->hb_condition_num_before = 0; //
+ hbConditionInit4->interface_num_after = 0; // Read_Lock
+ hbConditionInit4->hb_condition_num_after = 0; //
+ /* Write_Unlock(true) -> Read_Trylock(HB_Read_Trylock_Succ) */
+ struct hb_rule *hbConditionInit5 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit5->interface_num_before = 5; // Write_Unlock
+ hbConditionInit5->hb_condition_num_before = 0; //
+ hbConditionInit5->interface_num_after = 2; // Read_Trylock
+ hbConditionInit5->hb_condition_num_after = 2; // HB_Read_Trylock_Succ
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 6);
+ #define HB_RULE_TABLE_SIZE 6
+ hb_rule_table[0] = hbConditionInit0;
+ hb_rule_table[1] = hbConditionInit1;
+ hb_rule_table[2] = hbConditionInit2;
+ hb_rule_table[3] = hbConditionInit3;
+ hb_rule_table[4] = hbConditionInit4;
+ hb_rule_table[5] = hbConditionInit5;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 14);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 0;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 4;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition2;
+ commutativity_rule_table[2] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method2 . __RET__";
+ rule->condition = CommutativityCondition3;
+ commutativity_rule_table[3] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 4;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition4;
+ commutativity_rule_table[4] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition5;
+ commutativity_rule_table[5] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method2 . __RET__";
+ rule->condition = CommutativityCondition6;
+ commutativity_rule_table[6] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition7;
+ commutativity_rule_table[7] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition8;
+ commutativity_rule_table[8] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition9;
+ commutativity_rule_table[9] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 5;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition10;
+ commutativity_rule_table[10] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition11;
+ commutativity_rule_table[11] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 5;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition12;
+ commutativity_rule_table[12] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition13;
+ commutativity_rule_table[13] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 14;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+static inline int read_can_lock(rwlock_t *lock)
+{
+ return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0;
+}
+
+static inline int write_can_lock(rwlock_t *lock)
+{
+ return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS;
+}
+
+
+void __wrapper__read_lock(rwlock_t * rw);
+
+void read_lock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Read_Lock
+ interface_begin->interface_name = "Read_Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_lock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Read_Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_Lock_info* info = (Read_Lock_info*) malloc(sizeof(Read_Lock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Read_Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_lock(rwlock_t * rw)
+{
+
+
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Lock_Success_1 */
+
+ if (priorvalue > 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Read_Lock_Success_1";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ while (priorvalue <= 0) {
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
+ while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
+ thrd_yield();
+ }
+
+ priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Lock_Success_2 */
+
+ if (priorvalue > 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Read_Lock_Success_2";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+}
+
+
+void __wrapper__write_lock(rwlock_t * rw);
+
+void write_lock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Write_Lock
+ interface_begin->interface_name = "Write_Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_lock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Write_Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_Lock_info* info = (Write_Lock_info*) malloc(sizeof(Write_Lock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Write_Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_lock(rwlock_t * rw)
+{
+
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Write_Lock_Success_1 */
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "Write_Lock_Success_1";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ while (priorvalue != RW_LOCK_BIAS) {
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
+ while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
+ thrd_yield();
+ }
+
+ priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Write_Lock_Success_2 */
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "Write_Lock_Success_2";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+}
+
+int __wrapper__read_trylock(rwlock_t * rw);
+
+int read_trylock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 2; // Read_Trylock
+ interface_begin->interface_name = "Read_Trylock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__read_trylock(rw);
+ if (__RET__ == 1) {
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 2; // Read_Trylock
+ hb_condition->hb_condition_num = 2;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+ }
+
+ Read_Trylock_info* info = (Read_Trylock_info*) malloc(sizeof(Read_Trylock_info));
+ info->__RET__ = __RET__;
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 2; // Read_Trylock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__read_trylock(rwlock_t * rw)
+{
+
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for potential commit point: Potential_Read_Trylock_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 4;
+ potential_cp_define->label_name = "Potential_Read_Trylock_Point";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (priorvalue > 0) {
+ /* Automatically generated code for commit point define: Read_Trylock_Succ_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 5;
+ cp_define->label_name = "Read_Trylock_Succ_Point";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "Potential_Read_Trylock_Point";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return 1;
+ }
+ /* Automatically generated code for commit point define: Read_Trylock_Fail_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 6;
+ cp_define->label_name = "Read_Trylock_Fail_Point";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "Potential_Read_Trylock_Point";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
+ return 0;
+}
+
+int __wrapper__write_trylock(rwlock_t * rw);
+
+int write_trylock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 3; // Write_Trylock
+ interface_begin->interface_name = "Write_Trylock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__write_trylock(rw);
+ if (__RET__ == 1) {
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 3; // Write_Trylock
+ hb_condition->hb_condition_num = 1;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+ }
+
+ Write_Trylock_info* info = (Write_Trylock_info*) malloc(sizeof(Write_Trylock_info));
+ info->__RET__ = __RET__;
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 3; // Write_Trylock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__write_trylock(rwlock_t * rw)
+{
+
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for potential commit point: Potential_Write_Trylock_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 7;
+ potential_cp_define->label_name = "Potential_Write_Trylock_Point";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ /* Automatically generated code for commit point define: Write_Trylock_Succ_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 8;
+ cp_define->label_name = "Write_Trylock_Succ_Point";
+ cp_define->potential_cp_label_num = 7;
+ cp_define->potential_label_name = "Potential_Write_Trylock_Point";
+ cp_define->interface_num = 3;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return 1;
+ }
+ /* Automatically generated code for commit point define: Write_Trylock_Fail_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 9;
+ cp_define->label_name = "Write_Trylock_Fail_Point";
+ cp_define->potential_cp_label_num = 7;
+ cp_define->potential_label_name = "Potential_Write_Trylock_Point";
+ cp_define->interface_num = 3;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
+ return 0;
+}
+
+void __wrapper__read_unlock(rwlock_t * rw);
+
+void read_unlock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 4; // Read_Unlock
+ interface_begin->interface_name = "Read_Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_unlock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 4; // Read_Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_Unlock_info* info = (Read_Unlock_info*) malloc(sizeof(Read_Unlock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 4; // Read_Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_unlock(rwlock_t * rw)
+{
+
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
+ /* Automatically generated code for commit point define check: Read_Unlock_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 10;
+ cp_define_check->label_name = "Read_Unlock_Point";
+ cp_define_check->interface_num = 4;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+}
+
+void __wrapper__write_unlock(rwlock_t * rw);
+
+void write_unlock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 5; // Write_Unlock
+ interface_begin->interface_name = "Write_Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_unlock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 5; // Write_Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_Unlock_info* info = (Write_Unlock_info*) malloc(sizeof(Write_Unlock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 5; // Write_Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_unlock(rwlock_t * rw)
+{
+
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
+ /* Automatically generated code for commit point define check: Write_Unlock_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 11;
+ cp_define_check->label_name = "Write_Unlock_Point";
+ cp_define_check->interface_num = 5;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+
+}
+
+rwlock_t mylock;
+int shareddata;
+
+static void a(void *obj)
+{
+ read_lock(&mylock);
+ read_unlock(&mylock);
+
+ write_lock(&mylock);
+ shareddata = 47;
+ write_unlock(&mylock);
+}
+
+static void b(void *obj)
+{
+ if (read_trylock(&mylock) == 1) {
+ read_unlock(&mylock);
+ }
+
+ if (write_trylock(&mylock) == 1) {
+ write_unlock(&mylock);
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t1, t2;
+ atomic_init(&mylock.lock, RW_LOCK_BIAS);
+
+ thrd_create(&t1, (thrd_start_t)&a, NULL);
+ thrd_create(&t2, (thrd_start_t)&b, NULL);
+
+ thrd_join(t1);
+ thrd_join(t2);
+
+ return 0;
+}
+
--- /dev/null
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+#include "librace.h"
+
+#define RW_LOCK_BIAS 0x00100000
+#define WRITE_LOCK_CMP RW_LOCK_BIAS
+
+typedef union {
+ atomic_int lock;
+} rwlock_t;
+
+
+
+
+
+
+
+/* All other user-defined structs */
+static bool writer_lock_acquired;
+static int reader_lock_cnt;
+/* All other user-defined functions */
+/* Definition of interface info struct: Write_Trylock */
+typedef struct Write_Trylock_info {
+int __RET__;
+rwlock_t * rw;
+} Write_Trylock_info;
+/* End of info struct definition: Write_Trylock */
+
+/* ID function of interface: Write_Trylock */
+inline static call_id_t Write_Trylock_id(void *info, thread_id_t __TID__) {
+ Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Trylock */
+
+/* Check action function of interface: Write_Trylock */
+inline static bool Write_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ if ( __RET__ == 1 ) writer_lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Write_Trylock */
+
+/* Definition of interface info struct: Read_Trylock */
+typedef struct Read_Trylock_info {
+int __RET__;
+rwlock_t * rw;
+} Read_Trylock_info;
+/* End of info struct definition: Read_Trylock */
+
+/* ID function of interface: Read_Trylock */
+inline static call_id_t Read_Trylock_id(void *info, thread_id_t __TID__) {
+ Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Trylock */
+
+/* Check action function of interface: Read_Trylock */
+inline static bool Read_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ if ( __RET__ ) reader_lock_cnt ++ ;
+ check_passed = __RET__ == ! writer_lock_acquired || ! __RET__;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Read_Trylock */
+
+/* Definition of interface info struct: Write_Lock */
+typedef struct Write_Lock_info {
+rwlock_t * rw;
+} Write_Lock_info;
+/* End of info struct definition: Write_Lock */
+
+/* ID function of interface: Write_Lock */
+inline static call_id_t Write_Lock_id(void *info, thread_id_t __TID__) {
+ Write_Lock_info* theInfo = (Write_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Lock */
+
+/* Check action function of interface: Write_Lock */
+inline static bool Write_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Lock_info* theInfo = (Write_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = ! writer_lock_acquired && reader_lock_cnt == 0;
+ if (!check_passed)
+ return false;
+ writer_lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Write_Lock */
+
+/* Definition of interface info struct: Write_Unlock */
+typedef struct Write_Unlock_info {
+rwlock_t * rw;
+} Write_Unlock_info;
+/* End of info struct definition: Write_Unlock */
+
+/* ID function of interface: Write_Unlock */
+inline static call_id_t Write_Unlock_id(void *info, thread_id_t __TID__) {
+ Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Unlock */
+
+/* Check action function of interface: Write_Unlock */
+inline static bool Write_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = reader_lock_cnt == 0 && writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ writer_lock_acquired = false ;
+ return true;
+}
+/* End of check action function: Write_Unlock */
+
+/* Definition of interface info struct: Read_Unlock */
+typedef struct Read_Unlock_info {
+rwlock_t * rw;
+} Read_Unlock_info;
+/* End of info struct definition: Read_Unlock */
+
+/* ID function of interface: Read_Unlock */
+inline static call_id_t Read_Unlock_id(void *info, thread_id_t __TID__) {
+ Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Unlock */
+
+/* Check action function of interface: Read_Unlock */
+inline static bool Read_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = reader_lock_cnt > 0 && ! writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ reader_lock_cnt -- ;
+ return true;
+}
+/* End of check action function: Read_Unlock */
+
+/* Definition of interface info struct: Read_Lock */
+typedef struct Read_Lock_info {
+rwlock_t * rw;
+} Read_Lock_info;
+/* End of info struct definition: Read_Lock */
+
+/* ID function of interface: Read_Lock */
+inline static call_id_t Read_Lock_id(void *info, thread_id_t __TID__) {
+ Read_Lock_info* theInfo = (Read_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Lock */
+
+/* Check action function of interface: Read_Lock */
+inline static bool Read_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Lock_info* theInfo = (Read_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = ! writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ reader_lock_cnt ++ ;
+ return true;
+}
+/* End of check action function: Read_Lock */
+
+#define INTERFACE_SIZE 6
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Lock_info *_info2 = (Read_Lock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition2(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition3(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition4(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition5(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition6(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition7(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition8(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition9(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Lock_info *_info2 = (Write_Lock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition10(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition11(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition12(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition13(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Lock_info *_info2 = (Write_Lock_info*) info2;
+ return ! _info1-> __RET__;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ writer_lock_acquired = false ;
+ reader_lock_cnt = 0 ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ return true;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 6 * 2);
+ func_ptr_table[2 * 3] = (void*) &Write_Trylock_id;
+ func_ptr_table[2 * 3 + 1] = (void*) &Write_Trylock_check_action;
+ func_ptr_table[2 * 2] = (void*) &Read_Trylock_id;
+ func_ptr_table[2 * 2 + 1] = (void*) &Read_Trylock_check_action;
+ func_ptr_table[2 * 1] = (void*) &Write_Lock_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Write_Lock_check_action;
+ func_ptr_table[2 * 5] = (void*) &Write_Unlock_id;
+ func_ptr_table[2 * 5 + 1] = (void*) &Write_Unlock_check_action;
+ func_ptr_table[2 * 4] = (void*) &Read_Unlock_id;
+ func_ptr_table[2 * 4 + 1] = (void*) &Read_Unlock_check_action;
+ func_ptr_table[2 * 0] = (void*) &Read_Lock_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Read_Lock_check_action;
+ /* Read_Unlock(true) -> Write_Lock(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 4; // Read_Unlock
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 1; // Write_Lock
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Read_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
+ struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit1->interface_num_before = 4; // Read_Unlock
+ hbConditionInit1->hb_condition_num_before = 0; //
+ hbConditionInit1->interface_num_after = 3; // Write_Trylock
+ hbConditionInit1->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
+ /* Write_Unlock(true) -> Write_Lock(true) */
+ struct hb_rule *hbConditionInit2 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit2->interface_num_before = 5; // Write_Unlock
+ hbConditionInit2->hb_condition_num_before = 0; //
+ hbConditionInit2->interface_num_after = 1; // Write_Lock
+ hbConditionInit2->hb_condition_num_after = 0; //
+ /* Write_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
+ struct hb_rule *hbConditionInit3 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit3->interface_num_before = 5; // Write_Unlock
+ hbConditionInit3->hb_condition_num_before = 0; //
+ hbConditionInit3->interface_num_after = 3; // Write_Trylock
+ hbConditionInit3->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
+ /* Write_Unlock(true) -> Read_Lock(true) */
+ struct hb_rule *hbConditionInit4 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit4->interface_num_before = 5; // Write_Unlock
+ hbConditionInit4->hb_condition_num_before = 0; //
+ hbConditionInit4->interface_num_after = 0; // Read_Lock
+ hbConditionInit4->hb_condition_num_after = 0; //
+ /* Write_Unlock(true) -> Read_Trylock(HB_Read_Trylock_Succ) */
+ struct hb_rule *hbConditionInit5 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit5->interface_num_before = 5; // Write_Unlock
+ hbConditionInit5->hb_condition_num_before = 0; //
+ hbConditionInit5->interface_num_after = 2; // Read_Trylock
+ hbConditionInit5->hb_condition_num_after = 2; // HB_Read_Trylock_Succ
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 6);
+ #define HB_RULE_TABLE_SIZE 6
+ hb_rule_table[0] = hbConditionInit0;
+ hb_rule_table[1] = hbConditionInit1;
+ hb_rule_table[2] = hbConditionInit2;
+ hb_rule_table[3] = hbConditionInit3;
+ hb_rule_table[4] = hbConditionInit4;
+ hb_rule_table[5] = hbConditionInit5;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 14);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 0;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 4;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition2;
+ commutativity_rule_table[2] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method2 . __RET__";
+ rule->condition = CommutativityCondition3;
+ commutativity_rule_table[3] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 4;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition4;
+ commutativity_rule_table[4] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition5;
+ commutativity_rule_table[5] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method2 . __RET__";
+ rule->condition = CommutativityCondition6;
+ commutativity_rule_table[6] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition7;
+ commutativity_rule_table[7] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition8;
+ commutativity_rule_table[8] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition9;
+ commutativity_rule_table[9] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 5;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition10;
+ commutativity_rule_table[10] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition11;
+ commutativity_rule_table[11] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 5;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition12;
+ commutativity_rule_table[12] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition13;
+ commutativity_rule_table[13] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 14;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+static inline int read_can_lock(rwlock_t *lock)
+{
+ return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0;
+}
+
+static inline int write_can_lock(rwlock_t *lock)
+{
+ return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS;
+}
+
+
+void __wrapper__read_lock(rwlock_t * rw);
+
+void read_lock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Read_Lock
+ interface_begin->interface_name = "Read_Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_lock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Read_Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_Lock_info* info = (Read_Lock_info*) malloc(sizeof(Read_Lock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Read_Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_lock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Lock_Success_1 */
+
+ if (priorvalue > 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Read_Lock_Success_1";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ while (priorvalue <= 0) {
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
+ while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
+ thrd_yield();
+ }
+ priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Lock_Success_2 */
+
+ if (priorvalue > 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Read_Lock_Success_2";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+}
+
+
+void __wrapper__write_lock(rwlock_t * rw);
+
+void write_lock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Write_Lock
+ interface_begin->interface_name = "Write_Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_lock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Write_Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_Lock_info* info = (Write_Lock_info*) malloc(sizeof(Write_Lock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Write_Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_lock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Write_Lock_Success_1 */
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "Write_Lock_Success_1";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ while (priorvalue != RW_LOCK_BIAS) {
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
+ while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
+ thrd_yield();
+ }
+ priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Write_Lock_Success_2 */
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "Write_Lock_Success_2";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+}
+
+int __wrapper__read_trylock(rwlock_t * rw);
+
+int read_trylock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 2; // Read_Trylock
+ interface_begin->interface_name = "Read_Trylock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__read_trylock(rw);
+ if (__RET__ == 1) {
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 2; // Read_Trylock
+ hb_condition->hb_condition_num = 2;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+ }
+
+ Read_Trylock_info* info = (Read_Trylock_info*) malloc(sizeof(Read_Trylock_info));
+ info->__RET__ = __RET__;
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 2; // Read_Trylock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__read_trylock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for potential commit point: Potential_Read_Trylock_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 4;
+ potential_cp_define->label_name = "Potential_Read_Trylock_Point";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (priorvalue > 0) {
+ /* Automatically generated code for commit point define: Read_Trylock_Succ_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 5;
+ cp_define->label_name = "Read_Trylock_Succ_Point";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "Potential_Read_Trylock_Point";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return 1;
+ }
+ /* Automatically generated code for commit point define: Read_Trylock_Fail_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 6;
+ cp_define->label_name = "Read_Trylock_Fail_Point";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "Potential_Read_Trylock_Point";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
+ return 0;
+}
+
+int __wrapper__write_trylock(rwlock_t * rw);
+
+int write_trylock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 3; // Write_Trylock
+ interface_begin->interface_name = "Write_Trylock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__write_trylock(rw);
+ if (__RET__ == 1) {
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 3; // Write_Trylock
+ hb_condition->hb_condition_num = 1;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+ }
+
+ Write_Trylock_info* info = (Write_Trylock_info*) malloc(sizeof(Write_Trylock_info));
+ info->__RET__ = __RET__;
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 3; // Write_Trylock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__write_trylock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for potential commit point: Potential_Write_Trylock_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 7;
+ potential_cp_define->label_name = "Potential_Write_Trylock_Point";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ /* Automatically generated code for commit point define: Write_Trylock_Succ_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 8;
+ cp_define->label_name = "Write_Trylock_Succ_Point";
+ cp_define->potential_cp_label_num = 7;
+ cp_define->potential_label_name = "Potential_Write_Trylock_Point";
+ cp_define->interface_num = 3;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return 1;
+ }
+ /* Automatically generated code for commit point define: Write_Trylock_Fail_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 9;
+ cp_define->label_name = "Write_Trylock_Fail_Point";
+ cp_define->potential_cp_label_num = 7;
+ cp_define->potential_label_name = "Potential_Write_Trylock_Point";
+ cp_define->interface_num = 3;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
+ return 0;
+}
+
+void __wrapper__read_unlock(rwlock_t * rw);
+
+void read_unlock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 4; // Read_Unlock
+ interface_begin->interface_name = "Read_Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_unlock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 4; // Read_Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_Unlock_info* info = (Read_Unlock_info*) malloc(sizeof(Read_Unlock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 4; // Read_Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_unlock(rwlock_t * rw)
+{
+
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
+ /* Automatically generated code for commit point define check: Read_Unlock_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 10;
+ cp_define_check->label_name = "Read_Unlock_Point";
+ cp_define_check->interface_num = 4;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+}
+
+void __wrapper__write_unlock(rwlock_t * rw);
+
+void write_unlock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 5; // Write_Unlock
+ interface_begin->interface_name = "Write_Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_unlock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 5; // Write_Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_Unlock_info* info = (Write_Unlock_info*) malloc(sizeof(Write_Unlock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 5; // Write_Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_unlock(rwlock_t * rw)
+{
+
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
+ /* Automatically generated code for commit point define check: Write_Unlock_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 11;
+ cp_define_check->label_name = "Write_Unlock_Point";
+ cp_define_check->interface_num = 5;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+
+}
+
+rwlock_t mylock;
+int shareddata;
+
+static void a(void *obj)
+{
+ write_lock(&mylock);
+ shareddata = 47;
+ write_unlock(&mylock);
+}
+
+static void b(void *obj)
+{
+ if (read_trylock(&mylock)) {
+ read_unlock(&mylock);
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t1, t2;
+ atomic_init(&mylock.lock, RW_LOCK_BIAS);
+
+ thrd_create(&t1, (thrd_start_t)&a, NULL);
+ thrd_create(&t2, (thrd_start_t)&b, NULL);
+
+ thrd_join(t1);
+ thrd_join(t2);
+
+ return 0;
+}
+
--- /dev/null
+#include <stdio.h>
+#include <threads.h>
+#include <stdatomic.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+#include "librace.h"
+
+#define RW_LOCK_BIAS 0x00100000
+#define WRITE_LOCK_CMP RW_LOCK_BIAS
+
+typedef union {
+ atomic_int lock;
+} rwlock_t;
+
+
+
+
+
+
+
+/* All other user-defined structs */
+static bool writer_lock_acquired;
+static int reader_lock_cnt;
+/* All other user-defined functions */
+/* Definition of interface info struct: Write_Trylock */
+typedef struct Write_Trylock_info {
+int __RET__;
+rwlock_t * rw;
+} Write_Trylock_info;
+/* End of info struct definition: Write_Trylock */
+
+/* ID function of interface: Write_Trylock */
+inline static call_id_t Write_Trylock_id(void *info, thread_id_t __TID__) {
+ Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Trylock */
+
+/* Check action function of interface: Write_Trylock */
+inline static bool Write_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Trylock_info* theInfo = (Write_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ if ( __RET__ == 1 ) writer_lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Write_Trylock */
+
+/* Definition of interface info struct: Read_Trylock */
+typedef struct Read_Trylock_info {
+int __RET__;
+rwlock_t * rw;
+} Read_Trylock_info;
+/* End of info struct definition: Read_Trylock */
+
+/* ID function of interface: Read_Trylock */
+inline static call_id_t Read_Trylock_id(void *info, thread_id_t __TID__) {
+ Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Trylock */
+
+/* Check action function of interface: Read_Trylock */
+inline static bool Read_Trylock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Trylock_info* theInfo = (Read_Trylock_info*)info;
+ int __RET__ = theInfo->__RET__;
+ rwlock_t * rw = theInfo->rw;
+
+ if ( __RET__ ) reader_lock_cnt ++ ;
+ check_passed = __RET__ == ! writer_lock_acquired || ! __RET__;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Read_Trylock */
+
+/* Definition of interface info struct: Write_Lock */
+typedef struct Write_Lock_info {
+rwlock_t * rw;
+} Write_Lock_info;
+/* End of info struct definition: Write_Lock */
+
+/* ID function of interface: Write_Lock */
+inline static call_id_t Write_Lock_id(void *info, thread_id_t __TID__) {
+ Write_Lock_info* theInfo = (Write_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Lock */
+
+/* Check action function of interface: Write_Lock */
+inline static bool Write_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Lock_info* theInfo = (Write_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = ! writer_lock_acquired && reader_lock_cnt == 0;
+ if (!check_passed)
+ return false;
+ writer_lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Write_Lock */
+
+/* Definition of interface info struct: Write_Unlock */
+typedef struct Write_Unlock_info {
+rwlock_t * rw;
+} Write_Unlock_info;
+/* End of info struct definition: Write_Unlock */
+
+/* ID function of interface: Write_Unlock */
+inline static call_id_t Write_Unlock_id(void *info, thread_id_t __TID__) {
+ Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Write_Unlock */
+
+/* Check action function of interface: Write_Unlock */
+inline static bool Write_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_Unlock_info* theInfo = (Write_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = reader_lock_cnt == 0 && writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ writer_lock_acquired = false ;
+ return true;
+}
+/* End of check action function: Write_Unlock */
+
+/* Definition of interface info struct: Read_Unlock */
+typedef struct Read_Unlock_info {
+rwlock_t * rw;
+} Read_Unlock_info;
+/* End of info struct definition: Read_Unlock */
+
+/* ID function of interface: Read_Unlock */
+inline static call_id_t Read_Unlock_id(void *info, thread_id_t __TID__) {
+ Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Unlock */
+
+/* Check action function of interface: Read_Unlock */
+inline static bool Read_Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Unlock_info* theInfo = (Read_Unlock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = reader_lock_cnt > 0 && ! writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ reader_lock_cnt -- ;
+ return true;
+}
+/* End of check action function: Read_Unlock */
+
+/* Definition of interface info struct: Read_Lock */
+typedef struct Read_Lock_info {
+rwlock_t * rw;
+} Read_Lock_info;
+/* End of info struct definition: Read_Lock */
+
+/* ID function of interface: Read_Lock */
+inline static call_id_t Read_Lock_id(void *info, thread_id_t __TID__) {
+ Read_Lock_info* theInfo = (Read_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Read_Lock */
+
+/* Check action function of interface: Read_Lock */
+inline static bool Read_Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_Lock_info* theInfo = (Read_Lock_info*)info;
+ rwlock_t * rw = theInfo->rw;
+
+ check_passed = ! writer_lock_acquired;
+ if (!check_passed)
+ return false;
+ reader_lock_cnt ++ ;
+ return true;
+}
+/* End of check action function: Read_Lock */
+
+#define INTERFACE_SIZE 6
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Lock_info *_info2 = (Read_Lock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition2(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition3(void *info1, void *info2) {
+ Read_Lock_info *_info1 = (Read_Lock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition4(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Read_Unlock_info *_info2 = (Read_Unlock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition5(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition6(void *info1, void *info2) {
+ Read_Unlock_info *_info1 = (Read_Unlock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition7(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Read_Trylock_info *_info2 = (Read_Trylock_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition8(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition9(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Lock_info *_info2 = (Write_Lock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition10(void *info1, void *info2) {
+ Read_Trylock_info *_info1 = (Read_Trylock_info*) info1;
+ Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition11(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Trylock_info *_info2 = (Write_Trylock_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition12(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Unlock_info *_info2 = (Write_Unlock_info*) info2;
+ return ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition13(void *info1, void *info2) {
+ Write_Trylock_info *_info1 = (Write_Trylock_info*) info1;
+ Write_Lock_info *_info2 = (Write_Lock_info*) info2;
+ return ! _info1-> __RET__;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ writer_lock_acquired = false ;
+ reader_lock_cnt = 0 ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ return true;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 6 * 2);
+ func_ptr_table[2 * 3] = (void*) &Write_Trylock_id;
+ func_ptr_table[2 * 3 + 1] = (void*) &Write_Trylock_check_action;
+ func_ptr_table[2 * 2] = (void*) &Read_Trylock_id;
+ func_ptr_table[2 * 2 + 1] = (void*) &Read_Trylock_check_action;
+ func_ptr_table[2 * 1] = (void*) &Write_Lock_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Write_Lock_check_action;
+ func_ptr_table[2 * 5] = (void*) &Write_Unlock_id;
+ func_ptr_table[2 * 5 + 1] = (void*) &Write_Unlock_check_action;
+ func_ptr_table[2 * 4] = (void*) &Read_Unlock_id;
+ func_ptr_table[2 * 4 + 1] = (void*) &Read_Unlock_check_action;
+ func_ptr_table[2 * 0] = (void*) &Read_Lock_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Read_Lock_check_action;
+ /* Read_Unlock(true) -> Write_Lock(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 4; // Read_Unlock
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 1; // Write_Lock
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Read_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
+ struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit1->interface_num_before = 4; // Read_Unlock
+ hbConditionInit1->hb_condition_num_before = 0; //
+ hbConditionInit1->interface_num_after = 3; // Write_Trylock
+ hbConditionInit1->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
+ /* Write_Unlock(true) -> Write_Lock(true) */
+ struct hb_rule *hbConditionInit2 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit2->interface_num_before = 5; // Write_Unlock
+ hbConditionInit2->hb_condition_num_before = 0; //
+ hbConditionInit2->interface_num_after = 1; // Write_Lock
+ hbConditionInit2->hb_condition_num_after = 0; //
+ /* Write_Unlock(true) -> Write_Trylock(HB_Write_Trylock_Succ) */
+ struct hb_rule *hbConditionInit3 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit3->interface_num_before = 5; // Write_Unlock
+ hbConditionInit3->hb_condition_num_before = 0; //
+ hbConditionInit3->interface_num_after = 3; // Write_Trylock
+ hbConditionInit3->hb_condition_num_after = 1; // HB_Write_Trylock_Succ
+ /* Write_Unlock(true) -> Read_Lock(true) */
+ struct hb_rule *hbConditionInit4 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit4->interface_num_before = 5; // Write_Unlock
+ hbConditionInit4->hb_condition_num_before = 0; //
+ hbConditionInit4->interface_num_after = 0; // Read_Lock
+ hbConditionInit4->hb_condition_num_after = 0; //
+ /* Write_Unlock(true) -> Read_Trylock(HB_Read_Trylock_Succ) */
+ struct hb_rule *hbConditionInit5 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit5->interface_num_before = 5; // Write_Unlock
+ hbConditionInit5->hb_condition_num_before = 0; //
+ hbConditionInit5->interface_num_after = 2; // Read_Trylock
+ hbConditionInit5->hb_condition_num_after = 2; // HB_Read_Trylock_Succ
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 6);
+ #define HB_RULE_TABLE_SIZE 6
+ hb_rule_table[0] = hbConditionInit0;
+ hb_rule_table[1] = hbConditionInit1;
+ hb_rule_table[2] = hbConditionInit2;
+ hb_rule_table[3] = hbConditionInit3;
+ hb_rule_table[4] = hbConditionInit4;
+ hb_rule_table[5] = hbConditionInit5;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 14);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 0;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 4;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition2;
+ commutativity_rule_table[2] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method2 . __RET__";
+ rule->condition = CommutativityCondition3;
+ commutativity_rule_table[3] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 4;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition4;
+ commutativity_rule_table[4] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition5;
+ commutativity_rule_table[5] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 4;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method2 . __RET__";
+ rule->condition = CommutativityCondition6;
+ commutativity_rule_table[6] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 2;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition7;
+ commutativity_rule_table[7] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition8;
+ commutativity_rule_table[8] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition9;
+ commutativity_rule_table[9] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 5;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition10;
+ commutativity_rule_table[10] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 3;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition11;
+ commutativity_rule_table[11] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 5;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition12;
+ commutativity_rule_table[12] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__";
+ rule->condition = CommutativityCondition13;
+ commutativity_rule_table[13] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 14;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+static inline int read_can_lock(rwlock_t *lock)
+{
+ return atomic_load_explicit(&lock->lock, memory_order_relaxed) > 0;
+}
+
+static inline int write_can_lock(rwlock_t *lock)
+{
+ return atomic_load_explicit(&lock->lock, memory_order_relaxed) == RW_LOCK_BIAS;
+}
+
+
+void __wrapper__read_lock(rwlock_t * rw);
+
+void read_lock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Read_Lock
+ interface_begin->interface_name = "Read_Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_lock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Read_Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_Lock_info* info = (Read_Lock_info*) malloc(sizeof(Read_Lock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Read_Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_lock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Lock_Success_1 */
+
+ if (priorvalue > 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Read_Lock_Success_1";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ while (priorvalue <= 0) {
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
+ while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
+ thrd_yield();
+ }
+ priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Lock_Success_2 */
+
+ if (priorvalue > 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Read_Lock_Success_2";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+}
+
+
+void __wrapper__write_lock(rwlock_t * rw);
+
+void write_lock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Write_Lock
+ interface_begin->interface_name = "Write_Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_lock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Write_Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_Lock_info* info = (Write_Lock_info*) malloc(sizeof(Write_Lock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Write_Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_lock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Write_Lock_Success_1 */
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "Write_Lock_Success_1";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ while (priorvalue != RW_LOCK_BIAS) {
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
+ while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
+ thrd_yield();
+ }
+ priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for commit point define check: Write_Lock_Success_2 */
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "Write_Lock_Success_2";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+}
+
+int __wrapper__read_trylock(rwlock_t * rw);
+
+int read_trylock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 2; // Read_Trylock
+ interface_begin->interface_name = "Read_Trylock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__read_trylock(rw);
+ if (__RET__ == 1) {
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 2; // Read_Trylock
+ hb_condition->hb_condition_num = 2;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+ }
+
+ Read_Trylock_info* info = (Read_Trylock_info*) malloc(sizeof(Read_Trylock_info));
+ info->__RET__ = __RET__;
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 2; // Read_Trylock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__read_trylock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
+ /* Automatically generated code for potential commit point: Potential_Read_Trylock_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 4;
+ potential_cp_define->label_name = "Potential_Read_Trylock_Point";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (priorvalue > 0) {
+ /* Automatically generated code for commit point define: Read_Trylock_Succ_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 5;
+ cp_define->label_name = "Read_Trylock_Succ_Point";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "Potential_Read_Trylock_Point";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return 1;
+ }
+ /* Automatically generated code for commit point define: Read_Trylock_Fail_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 6;
+ cp_define->label_name = "Read_Trylock_Fail_Point";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "Potential_Read_Trylock_Point";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
+ return 0;
+}
+
+int __wrapper__write_trylock(rwlock_t * rw);
+
+int write_trylock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 3; // Write_Trylock
+ interface_begin->interface_name = "Write_Trylock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ int __RET__ = __wrapper__write_trylock(rw);
+ if (__RET__ == 1) {
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 3; // Write_Trylock
+ hb_condition->hb_condition_num = 1;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+ }
+
+ Write_Trylock_info* info = (Write_Trylock_info*) malloc(sizeof(Write_Trylock_info));
+ info->__RET__ = __RET__;
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 3; // Write_Trylock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+int __wrapper__write_trylock(rwlock_t * rw)
+{
+ int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+ /* Automatically generated code for potential commit point: Potential_Write_Trylock_Point */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 7;
+ potential_cp_define->label_name = "Potential_Write_Trylock_Point";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (priorvalue == RW_LOCK_BIAS) {
+ /* Automatically generated code for commit point define: Write_Trylock_Succ_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 8;
+ cp_define->label_name = "Write_Trylock_Succ_Point";
+ cp_define->potential_cp_label_num = 7;
+ cp_define->potential_label_name = "Potential_Write_Trylock_Point";
+ cp_define->interface_num = 3;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return 1;
+ }
+ /* Automatically generated code for commit point define: Write_Trylock_Fail_Point */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 9;
+ cp_define->label_name = "Write_Trylock_Fail_Point";
+ cp_define->potential_cp_label_num = 7;
+ cp_define->potential_label_name = "Potential_Write_Trylock_Point";
+ cp_define->interface_num = 3;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
+ return 0;
+}
+
+void __wrapper__read_unlock(rwlock_t * rw);
+
+void read_unlock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 4; // Read_Unlock
+ interface_begin->interface_name = "Read_Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_unlock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 4; // Read_Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_Unlock_info* info = (Read_Unlock_info*) malloc(sizeof(Read_Unlock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 4; // Read_Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_unlock(rwlock_t * rw)
+{
+
+ atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
+ /* Automatically generated code for commit point define check: Read_Unlock_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 10;
+ cp_define_check->label_name = "Read_Unlock_Point";
+ cp_define_check->interface_num = 4;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+}
+
+void __wrapper__write_unlock(rwlock_t * rw);
+
+void write_unlock(rwlock_t * rw) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 5; // Write_Unlock
+ interface_begin->interface_name = "Write_Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_unlock(rw);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 5; // Write_Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_Unlock_info* info = (Write_Unlock_info*) malloc(sizeof(Write_Unlock_info));
+ info->rw = rw;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 5; // Write_Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_unlock(rwlock_t * rw)
+{
+
+ atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
+ /* Automatically generated code for commit point define check: Write_Unlock_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 11;
+ cp_define_check->label_name = "Write_Unlock_Point";
+ cp_define_check->interface_num = 5;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+
+}
+
+rwlock_t mylock;
+int shareddata;
+
+static void a(void *obj)
+{
+ write_lock(&mylock);
+ shareddata = 47;
+ write_unlock(&mylock);
+}
+
+static void b(void *obj)
+{
+ if (write_trylock(&mylock)) {
+ shareddata = 47;
+ write_unlock(&mylock);
+ }
+
+ read_lock(&mylock);
+ read_unlock(&mylock);
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ thrd_t t1, t2;
+ atomic_init(&mylock.lock, RW_LOCK_BIAS);
+
+ thrd_create(&t1, (thrd_start_t)&a, NULL);
+ thrd_create(&t2, (thrd_start_t)&b, NULL);
+
+ thrd_join(t1);
+ thrd_join(t2);
+
+ return 0;
+}
+
--- /dev/null
+#include <stdio.h>
+#include <threads.h>
+
+#include "mcs-lock.h"
+
+
+#include "librace.h"
+
+struct mcs_mutex *mutex;
+static uint32_t shared;
+
+void threadA(void *arg)
+{
+ mcs_mutex::guard g(mutex);
+ shared = 17;
+ mutex->unlock(&g);
+ mutex->lock(&g);
+ }
+
+void threadB(void *arg)
+{
+ mcs_mutex::guard g(mutex);
+ mutex->unlock(&g);
+ mutex->lock(&g);
+ shared = 17;
+ }
+
+int user_main(int argc, char **argv)
+{
+ thrd_t A, B;
+
+ mutex = new mcs_mutex();
+
+ thrd_create(&A, &threadA, NULL);
+ thrd_create(&B, &threadB, NULL);
+ thrd_join(A);
+ thrd_join(B);
+ return 0;
+}
+
--- /dev/null
+
+#include <stdatomic.h>
+#include <unrelacy.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+struct mcs_node {
+ std::atomic<mcs_node *> next;
+ std::atomic<int> gate;
+
+ mcs_node() {
+ next.store(0);
+ gate.store(0);
+ }
+};
+
+
+struct mcs_mutex {
+public:
+ std::atomic<mcs_node *> m_tail;
+
+ mcs_mutex() {
+ __sequential_init();
+
+ m_tail.store( NULL );
+ }
+ ~mcs_mutex() {
+ }
+
+ class guard {
+ public:
+ mcs_mutex * m_t;
+ mcs_node m_node;
+ guard(mcs_mutex * t) : m_t(t) { t->lock(this); }
+ ~guard() { m_t->unlock(this); }
+ };
+
+/* All other user-defined structs */
+static bool _lock_acquired;
+/* All other user-defined functions */
+/* Definition of interface info struct: Unlock */
+typedef struct Unlock_info {
+guard * I;
+} Unlock_info;
+/* End of info struct definition: Unlock */
+
+/* ID function of interface: Unlock */
+inline static call_id_t Unlock_id(void *info, thread_id_t __TID__) {
+ Unlock_info* theInfo = (Unlock_info*)info;
+ guard * I = theInfo->I;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Unlock */
+
+/* Check action function of interface: Unlock */
+inline static bool Unlock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Unlock_info* theInfo = (Unlock_info*)info;
+ guard * I = theInfo->I;
+
+ check_passed = _lock_acquired == true;
+ if (!check_passed)
+ return false;
+ _lock_acquired = false ;
+ return true;
+}
+/* End of check action function: Unlock */
+
+/* Definition of interface info struct: Lock */
+typedef struct Lock_info {
+guard * I;
+} Lock_info;
+/* End of info struct definition: Lock */
+
+/* ID function of interface: Lock */
+inline static call_id_t Lock_id(void *info, thread_id_t __TID__) {
+ Lock_info* theInfo = (Lock_info*)info;
+ guard * I = theInfo->I;
+
+ call_id_t __ID__ = 0;
+ return __ID__;
+}
+/* End of ID function: Lock */
+
+/* Check action function of interface: Lock */
+inline static bool Lock_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Lock_info* theInfo = (Lock_info*)info;
+ guard * I = theInfo->I;
+
+ check_passed = _lock_acquired == false ;;
+ if (!check_passed)
+ return false;
+ _lock_acquired = true ;
+ return true;
+}
+/* End of check action function: Lock */
+
+#define INTERFACE_SIZE 2
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ _lock_acquired = false ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ return true;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
+ func_ptr_table[2 * 1] = (void*) &Unlock_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Unlock_check_action;
+ func_ptr_table[2 * 0] = (void*) &Lock_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Lock_check_action;
+ /* Unlock(true) -> Lock(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 1; // Unlock
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 0; // Lock
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
+ #define HB_RULE_TABLE_SIZE 1
+ hb_rule_table[0] = hbConditionInit0;
+ /* Init commutativity_rule_table */
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 0;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+
+void lock(guard * I) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Lock
+ interface_begin->interface_name = "Lock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__lock(I);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Lock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Lock_info* info = (Lock_info*) malloc(sizeof(Lock_info));
+ info->I = I;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Lock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__lock(guard * I) {
+ mcs_node * me = &(I->m_node);
+
+ me->next.store(NULL, std::mo_relaxed );
+ me->gate.store(1, std::mo_relaxed );
+
+
+
+ mcs_node * pred = m_tail.exchange(me, std::mo_acq_rel);
+ /* Automatically generated code for commit point define check: Lock_Enqueue_Point1 */
+
+ if (pred == NULL) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Lock_Enqueue_Point1";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if ( pred != NULL ) {
+
+ pred->next.store(me, std::mo_release );
+
+
+ rl::linear_backoff bo;
+ int my_gate = 1;
+ while (my_gate ) {
+
+ my_gate = me->gate.load(std::mo_acquire);
+ /* Automatically generated code for commit point define check: Lock_Enqueue_Point2 */
+
+ if (my_gate == 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Lock_Enqueue_Point2";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ thrd_yield();
+ }
+ }
+ }
+
+
+void unlock(guard * I) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Unlock
+ interface_begin->interface_name = "Unlock";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__unlock(I);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Unlock
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Unlock_info* info = (Unlock_info*) malloc(sizeof(Unlock_info));
+ info->I = I;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Unlock
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__unlock(guard * I) {
+ mcs_node * me = &(I->m_node);
+
+ mcs_node * next = me->next.load(std::mo_acquire);
+ if ( next == NULL )
+ {
+ mcs_node * tail_was_me = me;
+ bool success;
+
+
+ success = m_tail.compare_exchange_strong(
+ tail_was_me,NULL,std::mo_acq_rel);
+ /* Automatically generated code for commit point define check: Unlock_Point_Success_1 */
+
+ if (success == true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "Unlock_Point_Success_1";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (success) {
+
+ return;
+ }
+
+ rl::linear_backoff bo;
+ for(;;) {
+ next = me->next.load(std::mo_acquire);
+ if ( next != NULL )
+ break;
+ thrd_yield();
+ }
+ }
+
+
+
+ next->gate.store( 0, std::mo_release );
+ /* Automatically generated code for commit point define check: Unlock_Point_Success_2 */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "Unlock_Point_Success_2";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+};
+void** mcs_mutex::func_ptr_table;
+hb_rule** mcs_mutex::hb_rule_table;
+commutativity_rule** mcs_mutex::commutativity_rule_table;
+bool mcs_mutex::_lock_acquired;
+
+
--- /dev/null
+#include <inttypes.h>
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <librace.h>
+
+#include "mpmc-queue.h"
+
+void threadA(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
+{
+ int32_t *bin = queue->write_prepare();
+ *bin = 1;
+ printf("write_bin %d, val %d\n", bin, 1);
+ queue->write_publish(bin);
+}
+
+void threadB(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
+{
+ int32_t *bin;
+ while (bin = queue->read_fetch()) {
+ printf("Read: %d\n", *bin);
+ queue->read_consume(bin);
+ }
+}
+
+void threadC(struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> *queue)
+{
+ int32_t *bin = queue->write_prepare();
+ *bin = 1;
+ queue->write_publish(bin);
+
+ while (bin = queue->read_fetch()) {
+ printf("Read: %d\n", *bin);
+ queue->read_consume(bin);
+ }
+}
+
+#define MAXREADERS 3
+#define MAXWRITERS 3
+#define MAXRDWR 3
+
+#ifdef CONFIG_MPMC_READERS
+#define DEFAULT_READERS (CONFIG_MPMC_READERS)
+#else
+#define DEFAULT_READERS 2
+#endif
+
+#ifdef CONFIG_MPMC_WRITERS
+#define DEFAULT_WRITERS (CONFIG_MPMC_WRITERS)
+#else
+#define DEFAULT_WRITERS 2
+#endif
+
+#ifdef CONFIG_MPMC_RDWR
+#define DEFAULT_RDWR (CONFIG_MPMC_RDWR)
+#else
+#define DEFAULT_RDWR 0
+#endif
+
+int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS, rdwr = DEFAULT_RDWR;
+
+void print_usage()
+{
+ printf("Error: use the following options\n"
+ " -r <num> Choose number of reader threads\n"
+ " -w <num> Choose number of writer threads\n");
+ exit(EXIT_FAILURE);
+}
+
+void process_params(int argc, char **argv)
+{
+ const char *shortopts = "hr:w:";
+ int opt;
+ bool error = false;
+
+ while (!error && (opt = getopt(argc, argv, shortopts)) != -1) {
+ switch (opt) {
+ case 'h':
+ print_usage();
+ break;
+ case 'r':
+ readers = atoi(optarg);
+ break;
+ case 'w':
+ writers = atoi(optarg);
+ break;
+ default:
+ error = true;
+ break;
+ }
+ }
+
+ if (writers < 1 || writers > MAXWRITERS)
+ error = true;
+ if (readers < 1 || readers > MAXREADERS)
+ error = true;
+
+ if (error)
+ print_usage();
+}
+
+int user_main(int argc, char **argv)
+{
+ struct mpmc_boundq_1_alt<int32_t, sizeof(int32_t)> queue;
+ thrd_t A[MAXWRITERS], B[MAXREADERS], C[MAXRDWR];
+
+
+ printf("%d reader(s), %d writer(s)\n", readers, writers);
+
+#ifndef CONFIG_MPMC_NO_INITIAL_ELEMENT
+ printf("Adding initial element\n");
+ int32_t *bin = queue.write_prepare();
+ *bin, 17;
+ printf("init_write_bin %d, val %d\n", bin, 17);
+ queue.write_publish(bin);
+#endif
+
+ printf("Start threads\n");
+
+ for (int i = 0; i < writers; i++)
+ thrd_create(&A[i], (thrd_start_t)&threadA, &queue);
+ for (int i = 0; i < readers; i++)
+ thrd_create(&B[i], (thrd_start_t)&threadB, &queue);
+
+ for (int i = 0; i < rdwr; i++)
+ thrd_create(&C[i], (thrd_start_t)&threadC, &queue);
+
+ for (int i = 0; i < writers; i++)
+ thrd_join(A[i]);
+ for (int i = 0; i < readers; i++)
+ thrd_join(B[i]);
+ for (int i = 0; i < rdwr; i++)
+ thrd_join(C[i]);
+
+ printf("Threads complete\n");
+
+ return 0;
+}
+
--- /dev/null
+#include <stdatomic.h>
+#include <unrelacy.h>
+#include <common.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+
+
+template <typename t_element, size_t t_size>
+struct mpmc_boundq_1_alt
+{
+private:
+
+ unsigned int MASK;
+
+ t_element m_array[t_size];
+
+ atomic<unsigned int> m_rdwr;
+ atomic<unsigned int> m_read;
+ atomic<unsigned int> m_written;
+
+public:
+
+ mpmc_boundq_1_alt()
+ {
+ __sequential_init();
+
+ m_rdwr = 0;
+ m_read = 0;
+ m_written = 0;
+ MASK = 0x1; }
+
+
+/* All other user-defined structs */
+/* All other user-defined functions */
+/* Definition of interface info struct: Publish */
+typedef struct Publish_info {
+t_element * bin;
+} Publish_info;
+/* End of info struct definition: Publish */
+
+/* ID function of interface: Publish */
+inline static call_id_t Publish_id(void *info, thread_id_t __TID__) {
+ Publish_info* theInfo = (Publish_info*)info;
+ t_element * bin = theInfo->bin;
+
+ call_id_t __ID__ = ( call_id_t ) bin;
+ return __ID__;
+}
+/* End of ID function: Publish */
+
+/* Check action function of interface: Publish */
+inline static bool Publish_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Publish_info* theInfo = (Publish_info*)info;
+ t_element * bin = theInfo->bin;
+
+ return true;
+}
+/* End of check action function: Publish */
+
+/* Definition of interface info struct: Fetch */
+typedef struct Fetch_info {
+t_element * __RET__;
+} Fetch_info;
+/* End of info struct definition: Fetch */
+
+/* ID function of interface: Fetch */
+inline static call_id_t Fetch_id(void *info, thread_id_t __TID__) {
+ Fetch_info* theInfo = (Fetch_info*)info;
+ t_element * __RET__ = theInfo->__RET__;
+
+ call_id_t __ID__ = ( call_id_t ) __RET__;
+ return __ID__;
+}
+/* End of ID function: Fetch */
+
+/* Check action function of interface: Fetch */
+inline static bool Fetch_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Fetch_info* theInfo = (Fetch_info*)info;
+ t_element * __RET__ = theInfo->__RET__;
+
+ return true;
+}
+/* End of check action function: Fetch */
+
+/* Definition of interface info struct: Prepare */
+typedef struct Prepare_info {
+t_element * __RET__;
+} Prepare_info;
+/* End of info struct definition: Prepare */
+
+/* ID function of interface: Prepare */
+inline static call_id_t Prepare_id(void *info, thread_id_t __TID__) {
+ Prepare_info* theInfo = (Prepare_info*)info;
+ t_element * __RET__ = theInfo->__RET__;
+
+ call_id_t __ID__ = ( call_id_t ) __RET__;
+ return __ID__;
+}
+/* End of ID function: Prepare */
+
+/* Check action function of interface: Prepare */
+inline static bool Prepare_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Prepare_info* theInfo = (Prepare_info*)info;
+ t_element * __RET__ = theInfo->__RET__;
+
+ return true;
+}
+/* End of check action function: Prepare */
+
+/* Definition of interface info struct: Consume */
+typedef struct Consume_info {
+t_element * bin;
+} Consume_info;
+/* End of info struct definition: Consume */
+
+/* ID function of interface: Consume */
+inline static call_id_t Consume_id(void *info, thread_id_t __TID__) {
+ Consume_info* theInfo = (Consume_info*)info;
+ t_element * bin = theInfo->bin;
+
+ call_id_t __ID__ = ( call_id_t ) bin;
+ return __ID__;
+}
+/* End of ID function: Consume */
+
+/* Check action function of interface: Consume */
+inline static bool Consume_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Consume_info* theInfo = (Consume_info*)info;
+ t_element * bin = theInfo->bin;
+
+ return true;
+}
+/* End of check action function: Consume */
+
+#define INTERFACE_SIZE 4
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Prepare_info *_info1 = (Prepare_info*) info1;
+ Prepare_info *_info2 = (Prepare_info*) info2;
+ return _info1-> __RET__ != _info2-> __RET__ || ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Prepare_info *_info1 = (Prepare_info*) info1;
+ Publish_info *_info2 = (Publish_info*) info2;
+ return _info1-> __RET__ != _info2-> bin || ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition2(void *info1, void *info2) {
+ Prepare_info *_info1 = (Prepare_info*) info1;
+ Fetch_info *_info2 = (Fetch_info*) info2;
+ return _info1-> __RET__ != _info2-> __RET__ || ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition3(void *info1, void *info2) {
+ Prepare_info *_info1 = (Prepare_info*) info1;
+ Consume_info *_info2 = (Consume_info*) info2;
+ return _info1-> __RET__ != _info2-> bin || ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition4(void *info1, void *info2) {
+ Publish_info *_info1 = (Publish_info*) info1;
+ Publish_info *_info2 = (Publish_info*) info2;
+ return _info1-> bin != _info2-> bin;
+}
+inline static bool CommutativityCondition5(void *info1, void *info2) {
+ Publish_info *_info1 = (Publish_info*) info1;
+ Fetch_info *_info2 = (Fetch_info*) info2;
+ return _info1-> bin != _info2-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition6(void *info1, void *info2) {
+ Publish_info *_info1 = (Publish_info*) info1;
+ Consume_info *_info2 = (Consume_info*) info2;
+ return _info1-> bin != _info2-> bin;
+}
+inline static bool CommutativityCondition7(void *info1, void *info2) {
+ Fetch_info *_info1 = (Fetch_info*) info1;
+ Fetch_info *_info2 = (Fetch_info*) info2;
+ return _info1-> __RET__ != _info2-> __RET__ || ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+inline static bool CommutativityCondition8(void *info1, void *info2) {
+ Fetch_info *_info1 = (Fetch_info*) info1;
+ Consume_info *_info2 = (Consume_info*) info2;
+ return _info1-> __RET__ != _info2-> bin || ! _info1-> __RET__;
+}
+inline static bool CommutativityCondition9(void *info1, void *info2) {
+ Consume_info *_info1 = (Consume_info*) info1;
+ Consume_info *_info2 = (Consume_info*) info2;
+ return _info1-> bin != _info2-> bin;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ return true;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 4 * 2);
+ func_ptr_table[2 * 3] = (void*) &Publish_id;
+ func_ptr_table[2 * 3 + 1] = (void*) &Publish_check_action;
+ func_ptr_table[2 * 0] = (void*) &Fetch_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Fetch_check_action;
+ func_ptr_table[2 * 2] = (void*) &Prepare_id;
+ func_ptr_table[2 * 2 + 1] = (void*) &Prepare_check_action;
+ func_ptr_table[2 * 1] = (void*) &Consume_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Consume_check_action;
+ /* Consume(true) -> Prepare(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 1; // Consume
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 2; // Prepare
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Publish(true) -> Fetch(true) */
+ struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit1->interface_num_before = 3; // Publish
+ hbConditionInit1->hb_condition_num_before = 0; //
+ hbConditionInit1->interface_num_after = 0; // Fetch
+ hbConditionInit1->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 2);
+ #define HB_RULE_TABLE_SIZE 2
+ hb_rule_table[0] = hbConditionInit0;
+ hb_rule_table[1] = hbConditionInit1;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 10);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 2;
+ rule->rule = "_Method1 . __RET__ != _Method2 . __RET__ || ! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 3;
+ rule->rule = "_Method1 . __RET__ != _Method2 . bin || ! _Method1 . __RET__";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 0;
+ rule->rule = "_Method1 . __RET__ != _Method2 . __RET__ || ! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition2;
+ commutativity_rule_table[2] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 2;
+ rule->interface_num_after = 1;
+ rule->rule = "_Method1 . __RET__ != _Method2 . bin || ! _Method1 . __RET__";
+ rule->condition = CommutativityCondition3;
+ commutativity_rule_table[3] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 3;
+ rule->rule = "_Method1 . bin != _Method2 . bin";
+ rule->condition = CommutativityCondition4;
+ commutativity_rule_table[4] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 0;
+ rule->rule = "_Method1 . bin != _Method2 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition5;
+ commutativity_rule_table[5] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 3;
+ rule->interface_num_after = 1;
+ rule->rule = "_Method1 . bin != _Method2 . bin";
+ rule->condition = CommutativityCondition6;
+ commutativity_rule_table[6] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 0;
+ rule->rule = "_Method1 . __RET__ != _Method2 . __RET__ || ! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition7;
+ commutativity_rule_table[7] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 1;
+ rule->rule = "_Method1 . __RET__ != _Method2 . bin || ! _Method1 . __RET__";
+ rule->condition = CommutativityCondition8;
+ commutativity_rule_table[8] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 1;
+ rule->rule = "_Method1 . bin != _Method2 . bin";
+ rule->condition = CommutativityCondition9;
+ commutativity_rule_table[9] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 10;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+
+
+t_element * read_fetch() {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Fetch
+ interface_begin->interface_name = "Fetch";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ t_element * __RET__ = __wrapper__read_fetch();
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Fetch
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Fetch_info* info = (Fetch_info*) malloc(sizeof(Fetch_info));
+ info->__RET__ = __RET__;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Fetch
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+t_element * __wrapper__read_fetch() {
+ unsigned int rdwr = m_rdwr.load(mo_acquire);
+ /* Automatically generated code for potential commit point: Fetch_Potential_RW_Load */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 0;
+ potential_cp_define->label_name = "Fetch_Potential_RW_Load";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ unsigned int rd,wr;
+ for(;;) {
+ rd = (rdwr>>16) & MASK;
+ wr = rdwr & MASK;
+
+ if ( wr == rd ) {
+ /* Automatically generated code for commit point define: Fetch_RW_Load_Empty */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 1;
+ cp_define->label_name = "Fetch_RW_Load_Empty";
+ cp_define->potential_cp_label_num = 0;
+ cp_define->potential_label_name = "Fetch_Potential_RW_Load";
+ cp_define->interface_num = 0;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+
+ return false;
+ }
+
+
+ bool succ =
+ m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel);
+ /* Automatically generated code for commit point define check: Fetch_RW_RMW */
+
+ if (succ) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 2;
+ cp_define_check->label_name = "Fetch_RW_RMW";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (succ)
+ break;
+ else
+ thrd_yield();
+ }
+
+ rl::backoff bo;
+ while (true) {
+
+ int written = m_written.load(mo_acquire);
+ /* Automatically generated code for potential commit point: Fetch_Potential_W_Load */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 3;
+ potential_cp_define->label_name = "Fetch_Potential_W_Load";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if ((written & MASK) != wr) {
+ thrd_yield();
+ } else {
+ printf("Fetch: m_written=%d\n", written);
+ break;
+ }
+ }
+
+ /* Automatically generated code for commit point define: Fetch_W_Load */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 4;
+ cp_define->label_name = "Fetch_W_Load";
+ cp_define->potential_cp_label_num = 3;
+ cp_define->potential_label_name = "Fetch_Potential_W_Load";
+ cp_define->interface_num = 0;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+
+ t_element * p = & ( m_array[ rd % t_size ] );
+
+ return p;
+ }
+
+
+void read_consume(t_element * bin) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Consume
+ interface_begin->interface_name = "Consume";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__read_consume(bin);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Consume
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Consume_info* info = (Consume_info*) malloc(sizeof(Consume_info));
+ info->bin = bin;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Consume
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__read_consume(t_element * bin) {
+
+ m_read.fetch_add(1,mo_release);
+ /* Automatically generated code for commit point define check: Consume_R_RMW */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 5;
+ cp_define_check->label_name = "Consume_R_RMW";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+
+
+
+t_element * write_prepare() {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 2; // Prepare
+ interface_begin->interface_name = "Prepare";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ t_element * __RET__ = __wrapper__write_prepare();
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 2; // Prepare
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Prepare_info* info = (Prepare_info*) malloc(sizeof(Prepare_info));
+ info->__RET__ = __RET__;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 2; // Prepare
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+t_element * __wrapper__write_prepare() {
+ unsigned int rdwr = m_rdwr.load(mo_acquire);
+ /* Automatically generated code for potential commit point: Prepare_Potential_RW_Load */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 6;
+ potential_cp_define->label_name = "Prepare_Potential_RW_Load";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ unsigned int rd,wr;
+ for(;;) {
+ rd = (rdwr>>16) & MASK;
+ wr = rdwr & MASK;
+
+ if ( wr == ((rd + t_size)&MASK) ) {
+ /* Automatically generated code for commit point define: Prepare_RW_Load_Full */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 7;
+ cp_define->label_name = "Prepare_RW_Load_Full";
+ cp_define->potential_cp_label_num = 6;
+ cp_define->potential_label_name = "Prepare_Potential_RW_Load";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ return NULL;
+ }
+
+
+ bool succ = m_rdwr.compare_exchange_weak(rdwr,(rd<<16) |
+ ((wr+1)&MASK),mo_acq_rel);
+ /* Automatically generated code for commit point define check: Prepare_RW_RMW */
+
+ if (succ) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 8;
+ cp_define_check->label_name = "Prepare_RW_RMW";
+ cp_define_check->interface_num = 2;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (succ)
+ break;
+ else
+ thrd_yield();
+ }
+
+ rl::backoff bo;
+ while (true) {
+
+ int read = m_read.load(mo_acquire);
+ /* Automatically generated code for potential commit point: Prepare_Potential_R_Load */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 9;
+ potential_cp_define->label_name = "Prepare_Potential_R_Load";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if ((read & MASK) != rd)
+ thrd_yield();
+ else
+ break;
+ }
+
+ /* Automatically generated code for commit point define: Prepare_R_Load */
+
+ if (true) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 10;
+ cp_define->label_name = "Prepare_R_Load";
+ cp_define->potential_cp_label_num = 9;
+ cp_define->potential_label_name = "Prepare_Potential_R_Load";
+ cp_define->interface_num = 2;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+
+ t_element * p = & ( m_array[ wr % t_size ] );
+
+ return p;
+ }
+
+
+void write_publish(t_element * bin) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 3; // Publish
+ interface_begin->interface_name = "Publish";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__write_publish(bin);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 3; // Publish
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Publish_info* info = (Publish_info*) malloc(sizeof(Publish_info));
+ info->bin = bin;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 3; // Publish
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__write_publish(t_element * bin)
+ {
+
+ int tmp = m_written.fetch_add(1,mo_release);
+ /* Automatically generated code for commit point define check: Publish_W_RMW */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 11;
+ cp_define_check->label_name = "Publish_W_RMW";
+ cp_define_check->interface_num = 3;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ printf("publish: m_written=%d\n", tmp + 1);
+ }
+
+
+
+};
+template <typename t_element, size_t t_size>
+void** mpmc_boundq_1_alt<t_element, t_size>::func_ptr_table;
+template <typename t_element, size_t t_size>
+hb_rule** mpmc_boundq_1_alt<t_element, t_size>::hb_rule_table;
+template <typename t_element, size_t t_size>
+commutativity_rule** mpmc_boundq_1_alt<t_element, t_size>::commutativity_rule_table;
+
+
--- /dev/null
+#include <inttypes.h>
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <librace.h>
+
+#include "mpmc-queue.h"
+
+void threadA(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
+{
+ int32_t *bin;
+ bin = queue->write_prepare();
+ if (bin) {
+ *bin = 1;
+ printf("write_bin %d, val %d\n", bin, 1);
+ queue->write_publish(bin);
+ } else {
+ printf("write failed\n");
+ }
+}
+
+void threadB(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
+{
+ int32_t *bin;
+ bin = queue->read_fetch();
+ if (bin) {
+ printf("read_bin: %d, val %d\n", bin, *bin);
+ queue->read_consume(bin);
+ } else {
+ printf("Read failed\n");
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ struct mpmc_boundq_1_alt<int32_t, 2> queue;
+ thrd_t A, B;
+
+ printf("Adding initial element\n");
+ int32_t *bin;
+ bin = queue.write_prepare();
+ *bin = 17;
+ printf("init_write_bin %d, val %d\n", bin, 17);
+ queue.write_publish(bin);
+
+ bin = queue.write_prepare();
+ *bin = 27;
+ printf("init_write_bin %d, val %d\n", bin, 27);
+ queue.write_publish(bin);
+
+
+ printf("Start threads\n");
+
+ thrd_create(&A, (thrd_start_t)&threadA, &queue);
+ thrd_create(&B, (thrd_start_t)&threadB, &queue);
+
+ thrd_join(A);
+ thrd_join(B);
+ printf("Threads complete\n");
+
+ return 0;
+}
+
--- /dev/null
+#include <inttypes.h>
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <librace.h>
+
+#include "mpmc-queue.h"
+
+void threadA(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
+{
+ int32_t *bin;
+ bin = queue->write_prepare();
+ if (bin) {
+ *bin = 1;
+ printf("write_bin %d, val %d\n", bin, 1);
+ queue->write_publish(bin);
+ } else {
+ printf("write failed\n");
+ }
+}
+
+void threadB(struct mpmc_boundq_1_alt<int32_t, 2> *queue)
+{
+ int32_t *bin;
+ bin = queue->read_fetch();
+ if (bin) {
+ printf("read_bin: %d, val %d\n", bin, *bin);
+ queue->read_consume(bin);
+ } else {
+ printf("Read failed\n");
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ struct mpmc_boundq_1_alt<int32_t, 2> queue;
+ thrd_t A, B;
+
+ printf("Adding initial element\n");
+ int32_t *bin;
+ bin = queue.write_prepare();
+ *bin = 17;
+ printf("init_write_bin %d, val %d\n", bin, 17);
+ queue.write_publish(bin);
+
+ bin = queue.write_prepare();
+ *bin = 27;
+ printf("init_write_bin %d, val %d\n", bin, 27);
+ queue.write_publish(bin);
+
+
+ printf("Start threads\n");
+
+ thrd_create(&A, (thrd_start_t)&threadA, &queue);
+ thrd_create(&B, (thrd_start_t)&threadB, &queue);
+
+ thrd_join(A);
+ thrd_join(B);
+ printf("Threads complete\n");
+
+ return 0;
+}
+
--- /dev/null
+#include <inttypes.h>
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <librace.h>
+
+#include "mpmc-queue.h"
+
+void threadA(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
+{
+ int32_t *bin;
+
+
+ for (int i = 0; i < 1; i++) {
+ bin = queue->write_prepare();
+ if (bin) {
+ *bin = 1;
+ queue->write_publish(bin);
+ printf("write_bin %d, val %d\n", bin, 1);
+ } else {
+ printf("write failed\n");
+ }
+
+ bin = queue->read_fetch();
+ if (bin) {
+ printf("read_bin: %d, val %d\n", bin, *bin);
+ queue->read_consume(bin);
+ } else {
+ printf("read failed\n");
+ }
+ }
+
+}
+
+void threadB(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
+{
+ int32_t *bin;
+ for (int i = 0; i < 1; i++) {
+ bin = queue->read_fetch();
+ if (bin) {
+ printf("read_bin: %d, val %d\n", bin, *bin);
+ queue->read_consume(bin);
+ } else {
+ printf("read failed\n");
+ }
+ }
+
+
+}
+
+int user_main(int argc, char **argv)
+{
+ struct mpmc_boundq_1_alt<int32_t, 1> queue;
+ thrd_t A, A1, B;
+
+ printf("Adding initial element\n");
+ int32_t *bin;
+ for (int i = 0; i < 1; i++) {
+ printf("#%d, \n", i);
+ bin = queue.write_prepare();
+ *bin = 17;
+ printf("init_write_bin %d, val %d\n", bin, 17);
+ queue.write_publish(bin);
+
+ bin = queue.read_fetch();
+ if (bin) {
+ printf("init_read: %d, val %d\n", bin, *bin);
+ queue.read_consume(bin);
+ }
+ }
+
+ for (int i = 0; i < 3; i++) {
+
+ }
+
+ printf("Start threads\n");
+
+ thrd_create(&A, (thrd_start_t)&threadA, &queue);
+ thrd_create(&A1, (thrd_start_t)&threadA, &queue);
+ thrd_create(&B, (thrd_start_t)&threadB, &queue);
+
+ thrd_join(A);
+ thrd_join(A1);
+ thrd_join(B);
+ printf("Threads complete\n");
+
+ return 0;
+}
+
--- /dev/null
+#include <inttypes.h>
+#include <threads.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <librace.h>
+
+#include "mpmc-queue.h"
+
+void threadA(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
+{
+ int32_t *bin;
+
+
+ for (int i = 0; i < 1; i++) {
+ bin = queue->write_prepare();
+ if (bin) {
+ *bin = 1;
+ queue->write_publish(bin);
+ printf("write_bin %d, val %d\n", bin, 1);
+ } else {
+ printf("write failed\n");
+ }
+
+ bin = queue->read_fetch();
+ if (bin) {
+ printf("read_bin: %d, val %d\n", bin, *bin);
+ queue->read_consume(bin);
+ } else {
+ printf("read failed\n");
+ }
+ }
+
+}
+
+void threadB(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
+{
+ int32_t *bin;
+ for (int i = 0; i < 1; i++) {
+ bin = queue->read_fetch();
+ if (bin) {
+ printf("read_bin: %d, val %d\n", bin, *bin);
+ queue->read_consume(bin);
+ } else {
+ printf("read failed\n");
+ }
+ }
+
+
+}
+
+void threadC(struct mpmc_boundq_1_alt<int32_t, 1> *queue)
+{
+ int *bin;
+ bin = queue->write_prepare();
+ if (bin) {
+ *bin = 1;
+ queue->write_publish(bin);
+ printf("write_bin %d, val %d\n", bin, 1);
+ } else {
+ printf("write failed\n");
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ struct mpmc_boundq_1_alt<int32_t, 1> queue;
+ thrd_t A, A1, B, B1, C, C1;
+
+ printf("Adding initial element\n");
+ int32_t *bin;
+ for (int i = 0; i < 0; i++) {
+ printf("#%d, \n", i);
+ bin = queue.write_prepare();
+ *bin = 17;
+ printf("init_write_bin %d, val %d\n", bin, 17);
+ queue.write_publish(bin);
+
+ }
+
+ for (int i = 0; i < 3; i++) {
+
+ }
+
+ printf("Start threads\n");
+
+ thrd_create(&A, (thrd_start_t)&threadB, &queue);
+ thrd_create(&A1, (thrd_start_t)&threadC, &queue);
+ thrd_create(&B, (thrd_start_t)&threadB, &queue);
+ thrd_create(&B1, (thrd_start_t)&threadC, &queue);
+ thrd_create(&C, (thrd_start_t)&threadB, &queue);
+ thrd_create(&C1, (thrd_start_t)&threadC, &queue);
+
+ thrd_join(A);
+ thrd_join(A1);
+ thrd_join(B);
+ thrd_join(B1);
+ thrd_join(C);
+ thrd_join(C1);
+ printf("Threads complete\n");
+
+ return 0;
+}
+
include ../benchmarks.mk
-TESTNAME = main testcase1 testcase2
+TESTNAME = main testcase1 testcase2 testcase3
HEADERS = my_queue.h
OBJECTS = main.o my_queue.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)
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <threads.h>
+
+#include "my_queue.h"
+#include "model-assert.h"
+
+static int procs = 2;
+static queue_t *queue;
+static thrd_t *threads;
+static unsigned int *input;
+static unsigned int *output;
+static int num_threads;
+
+int get_thread_num()
+{
+ thrd_t curr = thrd_current();
+ int i;
+ for (i = 0; i < num_threads; i++)
+ if (curr.priv == threads[i].priv)
+ return i;
+ return -1;
+}
+
+bool succ1, succ2;
+
+static void main_task(void *param)
+{
+
+ unsigned int val;
+ int pid = *((int *)param);
+
+ if (pid % 2 == 0) {
+ input[0] = 17;
+ enqueue(queue, input[0]);
+ printf("Thrd %d Enqueue %d.\n", get_thread_num(), input[0]);
+
+ succ1 = dequeue(queue, &output[0]);
+ if (succ1)
+ printf("Thrd %d: Dequeue %d.\n", get_thread_num(), output[0]);
+ else
+ printf("Thrd %d: Dequeue NULL.\n", get_thread_num());
+
+ } else if (pid % 2 == 1) {
+ input[1] = 37;
+ enqueue(queue, input[1]);
+ printf("Thrd %d Enqueue %d.\n", get_thread_num(), input[1]);
+
+ succ2 = dequeue(queue, &output[1]);
+ if (succ2)
+ printf("Thrd %d: Dequeue %d.\n", get_thread_num(), output[1]);
+ else
+ printf("Thrd %d: Dequeue NULL.\n", get_thread_num());
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ int i;
+ int *param;
+ unsigned int in_sum = 0, out_sum = 0;
+
+ queue = calloc(1, sizeof(*queue));
+
+ num_threads = procs;
+ threads = malloc(num_threads * sizeof(thrd_t));
+ param = malloc(num_threads * sizeof(*param));
+ input = calloc(num_threads, sizeof(*input));
+ output = calloc(num_threads, sizeof(*output));
+
+ init_queue(queue, num_threads);
+ for (i = 0; i < num_threads; i++) {
+ param[i] = i;
+ thrd_create(&threads[i], main_task, ¶m[i]);
+ }
+ for (i = 0; i < num_threads; i++)
+ thrd_join(threads[i]);
+
+
+ free(param);
+ free(threads);
+ free(queue);
+
+ return 0;
+}
+
--- /dev/null
+#include <threads.h>
+#include <stdlib.h>
+#include "librace.h"
+#include "model-assert.h"
+
+#include "my_queue.h"
+
+#define relaxed memory_order_relaxed
+#define release memory_order_release
+#define acquire memory_order_acquire
+
+#define MAX_FREELIST 4
+#define INITIAL_FREE 3
+
+#define POISON_IDX 0x666
+
+static unsigned int (*free_lists)[MAX_FREELIST];
+
+
+static unsigned int new_node()
+{
+ int i;
+ int t = get_thread_num();
+ for (i = 0; i < MAX_FREELIST; i++) {
+ unsigned int node = free_lists[t][i];
+ if (node) {
+ free_lists[t][i] = 0;
+ return node;
+ }
+ }
+
+ return 0;
+}
+
+
+static void reclaim(unsigned int node)
+{
+ int i;
+ int t = get_thread_num();
+
+
+
+ for (i = 0; i < MAX_FREELIST; i++) {
+
+ unsigned int idx = free_lists[t][i];
+
+
+ if (idx == 0) {
+ store_32(&free_lists[t][i], node);
+ return;
+ }
+ }
+
+ }
+
+void init_queue(queue_t *q, int num_threads)
+{
+ int i, j;
+ for (i = 0; i < MAX_NODES; i++) {
+ atomic_init(&q->nodes[i].next, MAKE_POINTER(POISON_IDX, 0));
+ }
+
+
+
+ free_lists = malloc(num_threads * sizeof(*free_lists));
+ for (i = 0; i < num_threads; i++) {
+ for (j = 0; j < INITIAL_FREE; j++) {
+ free_lists[i][j] = 2 + i * MAX_FREELIST + j;
+ atomic_init(&q->nodes[free_lists[i][j]].next, MAKE_POINTER(POISON_IDX, 0));
+ }
+ }
+
+
+ atomic_init(&q->head, MAKE_POINTER(1, 0));
+ atomic_init(&q->tail, MAKE_POINTER(1, 0));
+ atomic_init(&q->nodes[1].next, MAKE_POINTER(0, 0));
+}
+
+
+void enqueue(queue_t * q, unsigned int val) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Enqueue
+ interface_begin->interface_name = "Enqueue";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__enqueue(q, val);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Enqueue
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Enqueue_info* info = (Enqueue_info*) malloc(sizeof(Enqueue_info));
+ info->q = q;
+ info->val = val;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Enqueue
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__enqueue(queue_t * q, unsigned int val)
+{
+ int success = 0;
+ unsigned int node;
+ pointer tail;
+ pointer next;
+ pointer tmp;
+
+ node = new_node();
+ q->nodes[node].value = val;
+ tmp = atomic_load_explicit(&q->nodes[node].next, relaxed);
+ set_ptr(&tmp, 0); atomic_store_explicit(&q->nodes[node].next, tmp, relaxed);
+
+ while (!success) {
+
+ /* Automatically generated code for commit point clear: Enqueue_Clear */
+
+ if (true) {
+ struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
+ cp_clear->label_name = "Enqueue_Clear";
+ cp_clear->label_num = 0;
+ struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_clear->type = CP_CLEAR;
+ annotation_cp_clear->annotation = cp_clear;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
+ }
+
+
+ tail = atomic_load_explicit(&q->tail, acquire);
+
+ next = atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire);
+ if (tail == atomic_load_explicit(&q->tail, relaxed)) {
+
+
+
+ if (get_ptr(next) == 0) { pointer value = MAKE_POINTER(node, get_count(next) + 1);
+
+ success = atomic_compare_exchange_strong_explicit(&q->nodes[get_ptr(tail)].next,
+ &next, value, release, relaxed);
+ /* Automatically generated code for commit point define check: EnqueueUpdateNext */
+
+ if (success) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "EnqueueUpdateNext";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ }
+ if (!success) {
+
+ unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire));
+ pointer value = MAKE_POINTER(ptr,
+ get_count(tail) + 1);
+
+ bool succ = false;
+ succ = atomic_compare_exchange_strong_explicit(&q->tail,
+ &tail, value, relaxed, relaxed);
+ if (succ) {
+ }
+ thrd_yield();
+ }
+ }
+ }
+
+ bool succ = atomic_compare_exchange_strong_explicit(&q->tail,
+ &tail,
+ MAKE_POINTER(node, get_count(tail) + 1),
+ release, relaxed);
+}
+
+
+bool dequeue(queue_t * q, int * retVal) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Dequeue
+ interface_begin->interface_name = "Dequeue";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ bool __RET__ = __wrapper__dequeue(q, retVal);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Dequeue
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Dequeue_info* info = (Dequeue_info*) malloc(sizeof(Dequeue_info));
+ info->__RET__ = __RET__;
+ info->q = q;
+ info->retVal = retVal;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Dequeue
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+bool __wrapper__dequeue(queue_t * q, int * retVal)
+{
+ unsigned int value = 0;
+ int success = 0;
+ pointer head;
+ pointer tail;
+ pointer next;
+
+ while (!success) {
+ /* Automatically generated code for commit point clear: Dequeue_Clear */
+
+ if (true) {
+ struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
+ cp_clear->label_name = "Dequeue_Clear";
+ cp_clear->label_num = 2;
+ struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_clear->type = CP_CLEAR;
+ annotation_cp_clear->annotation = cp_clear;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
+ }
+
+
+ head = atomic_load_explicit(&q->head, acquire);
+ /* Automatically generated code for commit point define check: DequeueReadHead */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 3;
+ cp_define_check->label_name = "DequeueReadHead";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+
+
+ tail = atomic_load_explicit(&q->tail, acquire);
+
+
+ next = atomic_load_explicit(&q->nodes[get_ptr(head)].next, acquire);
+ /* Automatically generated code for potential commit point: DequeueReadNext */
+
+ if (true) {
+ struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
+ potential_cp_define->label_num = 4;
+ potential_cp_define->label_name = "DequeueReadNext";
+ struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
+ annotation_potential_cp_define->annotation = potential_cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
+ }
+
+ if (atomic_load_explicit(&q->head, relaxed) == head) {
+ if (get_ptr(head) == get_ptr(tail)) {
+
+
+
+ if (get_ptr(next) == 0) { return false; }
+
+ bool succ = false;
+ succ = atomic_compare_exchange_strong_explicit(&q->tail,
+ &tail,
+ MAKE_POINTER(get_ptr(next), get_count(tail) + 1),
+ release, relaxed);
+ if (succ) {
+ }
+ thrd_yield();
+ } else {
+ value = q->nodes[get_ptr(next)].value;
+
+ success = atomic_compare_exchange_strong_explicit(&q->head,
+ &head,
+ MAKE_POINTER(get_ptr(next), get_count(head) + 1),
+ release, relaxed);
+ /* Automatically generated code for commit point define check: DequeueUpdateHead */
+
+ if (success) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 5;
+ cp_define_check->label_name = "DequeueUpdateHead";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+
+ /* Automatically generated code for commit point define: DequeueReadNextVerify */
+
+ if (success) {
+ struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
+ cp_define->label_num = 6;
+ cp_define->label_name = "DequeueReadNextVerify";
+ cp_define->potential_cp_label_num = 4;
+ cp_define->potential_label_name = "DequeueReadNext";
+ cp_define->interface_num = 1;
+ struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define->type = CP_DEFINE;
+ annotation_cp_define->annotation = cp_define;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
+ }
+
+ if (!success)
+ thrd_yield();
+ }
+ }
+ }
+ reclaim(get_ptr(head));
+ *retVal = value;
+ return true;
+}
+
--- /dev/null
+#ifndef _MY_QUEUE_H
+#define _MY_QUEUE_H
+
+#include <stdatomic.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+#define MAX_NODES 0xf
+
+typedef unsigned long long pointer;
+typedef atomic_ullong pointer_t;
+
+#define MAKE_POINTER(ptr, count) ((((pointer)count) << 32) | ptr)
+#define PTR_MASK 0xffffffffLL
+#define COUNT_MASK (0xffffffffLL << 32)
+
+static inline void set_count(pointer *p, unsigned int val) { *p = (*p & ~COUNT_MASK) | ((pointer)val << 32); }
+static inline void set_ptr(pointer *p, unsigned int val) { *p = (*p & ~PTR_MASK) | val; }
+static inline unsigned int get_count(pointer p) { return (p & COUNT_MASK) >> 32; }
+static inline unsigned int get_ptr(pointer p) { return p & PTR_MASK; }
+
+typedef struct node {
+ unsigned int value;
+ pointer_t next;
+} node_t;
+
+typedef struct {
+ pointer_t head;
+ pointer_t tail;
+ node_t nodes[MAX_NODES + 1];
+} queue_t;
+
+void init_queue(queue_t *q, int num_threads);
+
+/* All other user-defined structs */
+static IntegerList * __queue;
+/* All other user-defined functions */
+/* Definition of interface info struct: Dequeue */
+typedef struct Dequeue_info {
+bool __RET__;
+queue_t * q;
+int * retVal;
+} Dequeue_info;
+/* End of info struct definition: Dequeue */
+
+/* ID function of interface: Dequeue */
+inline static call_id_t Dequeue_id(void *info, thread_id_t __TID__) {
+ Dequeue_info* theInfo = (Dequeue_info*)info;
+ bool __RET__ = theInfo->__RET__;
+ queue_t * q = theInfo->q;
+ int * retVal = theInfo->retVal;
+
+ call_id_t __ID__ = __RET__ ? * retVal : 0;
+ return __ID__;
+}
+/* End of ID function: Dequeue */
+
+/* Check action function of interface: Dequeue */
+inline static bool Dequeue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Dequeue_info* theInfo = (Dequeue_info*)info;
+ bool __RET__ = theInfo->__RET__;
+ queue_t * q = theInfo->q;
+ int * retVal = theInfo->retVal;
+
+ int elem = 0 ;
+ if ( __RET__ ) {
+ elem = front ( __queue ) ;
+ pop_front ( __queue ) ;
+ }
+ check_passed = __RET__ ? * retVal == elem : true;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Dequeue */
+
+/* Definition of interface info struct: Enqueue */
+typedef struct Enqueue_info {
+queue_t * q;
+ unsigned int val;
+} Enqueue_info;
+/* End of info struct definition: Enqueue */
+
+/* ID function of interface: Enqueue */
+inline static call_id_t Enqueue_id(void *info, thread_id_t __TID__) {
+ Enqueue_info* theInfo = (Enqueue_info*)info;
+ queue_t * q = theInfo->q;
+ unsigned int val = theInfo->val;
+
+ call_id_t __ID__ = val;
+ return __ID__;
+}
+/* End of ID function: Enqueue */
+
+/* Check action function of interface: Enqueue */
+inline static bool Enqueue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Enqueue_info* theInfo = (Enqueue_info*)info;
+ queue_t * q = theInfo->q;
+ unsigned int val = theInfo->val;
+
+ push_back ( __queue , val ) ;
+ return true;
+}
+/* End of check action function: Enqueue */
+
+#define INTERFACE_SIZE 2
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Enqueue_info *_info1 = (Enqueue_info*) info1;
+ Dequeue_info *_info2 = (Dequeue_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Dequeue_info *_info1 = (Dequeue_info*) info1;
+ Dequeue_info *_info2 = (Dequeue_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ __queue = createIntegerList ( ) ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ if ( __queue ) destroyIntegerList ( __queue ) ;
+ return true ;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
+ func_ptr_table[2 * 1] = (void*) &Dequeue_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Dequeue_check_action;
+ func_ptr_table[2 * 0] = (void*) &Enqueue_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Enqueue_check_action;
+ /* Enqueue(true) -> Dequeue(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 0; // Enqueue
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 1; // Dequeue
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
+ #define HB_RULE_TABLE_SIZE 1
+ hb_rule_table[0] = hbConditionInit0;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 2);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 1;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 2;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+
+
+void __wrapper__enqueue(queue_t * q, unsigned int val);
+
+void __wrapper__enqueue(queue_t * q, unsigned int val) ;
+
+bool __wrapper__dequeue(queue_t * q, int * retVal);
+
+bool __wrapper__dequeue(queue_t * q, int * retVal) ;
+int get_thread_num();
+
+#endif
+
#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;
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");
}
}
--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <threads.h>
+
+#include "my_queue.h"
+#include "model-assert.h"
+
+static int procs = 3;
+static queue_t *queue;
+static thrd_t *threads;
+static unsigned int *input;
+static unsigned int *output;
+static int num_threads;
+
+int get_thread_num()
+{
+ thrd_t curr = thrd_current();
+ int i;
+ for (i = 0; i < num_threads; i++)
+ if (curr.priv == threads[i].priv)
+ return i;
+ return -1;
+}
+
+
+bool succ1, succ2;
+unsigned int output1, output2;
+
+static void main_task(void *param)
+{
+ int pid = *((int *)param);
+ if (pid % 4 == 0) {
+ output1 = 1;
+ succ1 = dequeue(queue, &output1);
+ if (succ1)
+ printf("Thrd 1: Dequeue %d.\n", output1);
+ else
+ printf("Thrd 1: Dequeue NULL.\n");
+ } else if (pid % 4 == 1) {
+ enqueue(queue, 1);
+ printf("Thrd 2: Enqueue %d.\n", 1);
+ } else if (pid % 4 == 2) {
+
+ output1 = 1;
+ succ1 = dequeue(queue, &output1);
+ if (succ1)
+ printf("Thrd 3: Dequeue %d.\n", output1);
+ else
+ printf("Thrd 3: Dequeue NULL.\n");
+ }
+}
+
+int user_main(int argc, char **argv)
+{
+ __sequential_init();
+
+ int i;
+ int *param;
+ unsigned int in_sum = 0, out_sum = 0;
+
+ queue = calloc(1, sizeof(*queue));
+
+ num_threads = procs;
+ threads = malloc(num_threads * sizeof(thrd_t));
+ param = malloc(num_threads * sizeof(*param));
+ input = calloc(num_threads, sizeof(*input));
+ output = calloc(num_threads, sizeof(*output));
+
+ init_queue(queue, num_threads);
+ for (i = 0; i < num_threads; i++) {
+ param[i] = i;
+ thrd_create(&threads[i], main_task, ¶m[i]);
+ }
+ for (i = 0; i < num_threads; i++)
+ thrd_join(threads[i]);
+
+
+ free(param);
+ free(threads);
+ free(queue);
+
+ return 0;
+}
+
--- /dev/null
+#include <atomic>
+#include <threads.h>
+#include <stdatomic.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+#include "librace.h"
+
+
+
+typedef struct Data {
+ int data1;
+ int data2;
+} Data;
+
+atomic<Data*> data;
+
+/* All other user-defined structs */
+static IntegerList * set;
+/* All other user-defined functions */
+inline static call_id_t getID ( int64_t d1 , int64_t d2 ) {
+return d1 + d2 ;
+}
+
+inline static bool print ( int64_t p ) {
+Data * d = ( Data * ) p ;
+model_print ( "Elem-> d1 = %d, d2 = %d\n" , d -> data1 , d -> data2 ) ;
+}
+bool equal ( int64_t p1 , int64_t p2 ) {
+if ( ! p1 || ! p2 ) return false ;
+Data * d1 = ( Data * ) p1 ;
+Data * d2 = ( Data * ) p2 ;
+if ( d1 -> data1 == d2 -> data1 && d1 -> data2 == d2 -> data2 ) {
+return true ;
+}
+else {
+return false ;
+}
+}
+
+inline static void _write ( int64_t d1 , int64_t d2 ) {
+Data * d = ( Data * ) MODEL_MALLOC ( sizeof ( Data ) ) ;
+d -> data1 = d1 ;
+d -> data2 = d2 ;
+push_back ( set , ( int64_t ) d ) ;
+}
+
+inline static bool _read ( Data * res ) {
+bool hasElem = has_elem_by_value ( set , ( int64_t ) res , & equal ) ;
+return hasElem ;
+}
+
+/* Definition of interface info struct: Write */
+typedef struct Write_info {
+Data * __RET__;
+int d1;
+int d2;
+} Write_info;
+/* End of info struct definition: Write */
+
+/* ID function of interface: Write */
+inline static call_id_t Write_id(void *info, thread_id_t __TID__) {
+ Write_info* theInfo = (Write_info*)info;
+ Data * __RET__ = theInfo->__RET__;
+ int d1 = theInfo->d1;
+ int d2 = theInfo->d2;
+
+ call_id_t __ID__ = getID ( d1 , d2 ) ;;
+ return __ID__;
+}
+/* End of ID function: Write */
+
+/* Check action function of interface: Write */
+inline static bool Write_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Write_info* theInfo = (Write_info*)info;
+ Data * __RET__ = theInfo->__RET__;
+ int d1 = theInfo->d1;
+ int d2 = theInfo->d2;
+
+ _write ( d1 , d2 ) ;
+ return true;
+}
+/* End of check action function: Write */
+
+/* Definition of interface info struct: Read */
+typedef struct Read_info {
+Data * __RET__;
+} Read_info;
+/* End of info struct definition: Read */
+
+/* ID function of interface: Read */
+inline static call_id_t Read_id(void *info, thread_id_t __TID__) {
+ Read_info* theInfo = (Read_info*)info;
+ Data * __RET__ = theInfo->__RET__;
+
+ call_id_t __ID__ = getID ( __RET__ -> data1 , __RET__ -> data2 );
+ return __ID__;
+}
+/* End of ID function: Read */
+
+/* Check action function of interface: Read */
+inline static bool Read_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Read_info* theInfo = (Read_info*)info;
+ Data * __RET__ = theInfo->__RET__;
+
+ check_passed = _read ( __RET__ ) ;;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Read */
+
+#define INTERFACE_SIZE 2
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Write_info *_info1 = (Write_info*) info1;
+ Read_info *_info2 = (Read_info*) info2;
+ return true;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ set = createIntegerList ( ) ;
+ Data * d = ( Data * ) MODEL_MALLOC ( sizeof ( Data ) ) ;
+ d -> data1 = 0 ;
+ d -> data2 = 0 ;
+ push_back ( set , ( int64_t ) d ) ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ if ( set ) destroyIntegerList ( set ) ;
+ return true ;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
+ func_ptr_table[2 * 1] = (void*) &Write_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Write_check_action;
+ func_ptr_table[2 * 0] = (void*) &Read_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Read_check_action;
+ /* Write(true) -> Read(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 1; // Write
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 0; // Read
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Write(true) -> Write(true) */
+ struct hb_rule *hbConditionInit1 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit1->interface_num_before = 1; // Write
+ hbConditionInit1->hb_condition_num_before = 0; //
+ hbConditionInit1->interface_num_after = 1; // Write
+ hbConditionInit1->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 2);
+ #define HB_RULE_TABLE_SIZE 2
+ hb_rule_table[0] = hbConditionInit0;
+ hb_rule_table[1] = hbConditionInit1;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 1);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 0;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 1;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+Data * __wrapper__read();
+
+Data * read() {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Read
+ interface_begin->interface_name = "Read";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ Data * __RET__ = __wrapper__read();
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Read
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Read_info* info = (Read_info*) malloc(sizeof(Read_info));
+ info->__RET__ = __RET__;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Read
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+Data * __wrapper__read() {
+
+ Data *res = data.load(memory_order_acquire);
+ /* Automatically generated code for commit point define check: Read_Success_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Read_Success_Point";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ return res;
+}
+
+Data * __wrapper__write(int d1, int d2);
+
+Data * write(int d1, int d2) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Write
+ interface_begin->interface_name = "Write";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ Data * __RET__ = __wrapper__write(d1, d2);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Write
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Write_info* info = (Write_info*) malloc(sizeof(Write_info));
+ info->__RET__ = __RET__;
+ info->d1 = d1;
+ info->d2 = d2;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Write
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+Data * __wrapper__write(int d1, int d2) {
+ bool succ = false;
+ Data *tmp = (Data*) malloc(sizeof(Data));
+ do {
+
+ Data *prev = data.load(memory_order_acquire);
+ tmp->data1 = d1;
+ tmp->data2 = d2;
+
+ succ = data.compare_exchange_strong(prev, tmp,
+ memory_order_release, memory_order_relaxed);
+ /* Automatically generated code for commit point define check: Write_Success_Point */
+
+ if (succ) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Write_Success_Point";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ } while (!succ);
+ return tmp;
+}
+
+
+void threadA(void *arg) {
+ write(1, 0);
+}
+
+void threadB(void *arg) {
+ write(0, 2);
+}
+
+void threadC(void *arg) {
+ write(2, 2);
+}
+
+void threadD(void *arg) {
+ Data *d = read();
+ printf("ThreadD: d1=%d, d2=%d\n", d->data1, d->data2);
+}
+
+int user_main(int argc, char **argv) {
+ __sequential_init();
+
+
+ thrd_t t1, t2, t3, t4;
+ Data *dataInit = (Data*) malloc(sizeof(Data));
+ dataInit->data1 = 0;
+ dataInit->data2 = 0;
+ atomic_init(&data, dataInit);
+
+ thrd_create(&t1, threadA, NULL);
+ thrd_create(&t2, threadB, NULL);
+ thrd_create(&t4, threadD, NULL);
+
+ thrd_join(t1);
+ thrd_join(t2);
+ thrd_join(t4);
+
+ return 0;
+}
+
--- /dev/null
+#ifndef _EVENTCOUNT_H
+#define _EVENTCOUNT_H
+
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+
+class eventcount
+{
+public:
+ eventcount() : waiters(0)
+ {
+ count = 0;
+ }
+
+ void signal_relaxed()
+ {
+ unsigned cmp = count.load(std::memory_order_relaxed);
+ signal_impl(cmp);
+ }
+
+ void signal()
+ {
+ unsigned cmp = count.fetch_add(0, std::memory_order_seq_cst);
+ signal_impl(cmp);
+ }
+
+ unsigned get()
+ {
+ unsigned cmp = count.fetch_or(0x80000000,
+std::memory_order_seq_cst);
+ return cmp & 0x7FFFFFFF;
+ }
+
+ void wait(unsigned cmp)
+ {
+ unsigned ec = count.load(std::memory_order_seq_cst);
+ if (cmp == (ec & 0x7FFFFFFF))
+ {
+ guard.lock($);
+ ec = count.load(std::memory_order_seq_cst);
+ if (cmp == (ec & 0x7FFFFFFF))
+ {
+ waiters += 1;
+ cv.wait(guard);
+ }
+ guard.unlock($);
+ }
+ }
+
+private:
+ std::atomic<unsigned> count;
+ rl::var<unsigned> waiters;
+ std::mutex guard;
+ std::condition_variable cv;
+
+ void signal_impl(unsigned cmp)
+ {
+ if (cmp & 0x80000000)
+ {
+ guard.lock($);
+ while (false == count.compare_exchange_weak(cmp,
+ (cmp + 1) & 0x7FFFFFFF, std::memory_order_relaxed));
+ unsigned w = waiters($);
+ waiters = 0;
+ guard.unlock($);
+ if (w)
+ cv.notify_all($);
+ }
+ }
+};
+
+#endif
+
--- /dev/null
+#ifndef _QUEUE_H
+#define _QUEUE_H
+
+#include <unrelacy.h>
+#include <atomic>
+
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
+#include "eventcount.h"
+
+
+template<typename T>
+class spsc_queue
+{
+
+public:
+
+
+ spsc_queue()
+ {
+
+ __sequential_init();
+
+
+ node* n = new node ();
+ head = n;
+ tail = n;
+ }
+
+ ~spsc_queue()
+ {
+ delete ((node*)head);
+ }
+
+/* All other user-defined structs */
+static IntegerList * __queue;
+/* All other user-defined functions */
+/* Definition of interface info struct: Dequeue */
+typedef struct Dequeue_info {
+T __RET__;
+} Dequeue_info;
+/* End of info struct definition: Dequeue */
+
+/* ID function of interface: Dequeue */
+inline static call_id_t Dequeue_id(void *info, thread_id_t __TID__) {
+ Dequeue_info* theInfo = (Dequeue_info*)info;
+ T __RET__ = theInfo->__RET__;
+
+ call_id_t __ID__ = __RET__ ? __RET__ : 0;
+ return __ID__;
+}
+/* End of ID function: Dequeue */
+
+/* Check action function of interface: Dequeue */
+inline static bool Dequeue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Dequeue_info* theInfo = (Dequeue_info*)info;
+ T __RET__ = theInfo->__RET__;
+
+ int elem = 0 ;
+ if ( __RET__ ) {
+ elem = front ( __queue ) ;
+ pop_front ( __queue ) ;
+ }
+ check_passed = __RET__ ? __RET__ == elem : true;
+ if (!check_passed)
+ return false;
+ return true;
+}
+/* End of check action function: Dequeue */
+
+/* Definition of interface info struct: Enqueue */
+typedef struct Enqueue_info {
+T data;
+} Enqueue_info;
+/* End of info struct definition: Enqueue */
+
+/* ID function of interface: Enqueue */
+inline static call_id_t Enqueue_id(void *info, thread_id_t __TID__) {
+ Enqueue_info* theInfo = (Enqueue_info*)info;
+ T data = theInfo->data;
+
+ call_id_t __ID__ = data;
+ return __ID__;
+}
+/* End of ID function: Enqueue */
+
+/* Check action function of interface: Enqueue */
+inline static bool Enqueue_check_action(void *info, call_id_t __ID__, thread_id_t __TID__) {
+ bool check_passed;
+ Enqueue_info* theInfo = (Enqueue_info*)info;
+ T data = theInfo->data;
+
+ push_back ( __queue , data ) ;
+ return true;
+}
+/* End of check action function: Enqueue */
+
+#define INTERFACE_SIZE 2
+static void** func_ptr_table;
+static hb_rule** hb_rule_table;
+static commutativity_rule** commutativity_rule_table;
+inline static bool CommutativityCondition0(void *info1, void *info2) {
+ Enqueue_info *_info1 = (Enqueue_info*) info1;
+ Dequeue_info *_info2 = (Dequeue_info*) info2;
+ return true;
+}
+inline static bool CommutativityCondition1(void *info1, void *info2) {
+ Dequeue_info *_info1 = (Dequeue_info*) info1;
+ Dequeue_info *_info2 = (Dequeue_info*) info2;
+ return ! _info1-> __RET__ || ! _info2-> __RET__;
+}
+
+/* Initialization of sequential varialbes */
+static void __SPEC_INIT__() {
+ __queue = createIntegerList ( ) ;
+}
+
+/* Cleanup routine of sequential variables */
+static bool __SPEC_CLEANUP__() {
+ if ( __queue ) destroyIntegerList ( __queue ) ;
+ return true ;
+}
+
+/* Define function for sequential code initialization */
+inline static void __sequential_init() {
+ /* Init func_ptr_table */
+ func_ptr_table = (void**) malloc(sizeof(void*) * 2 * 2);
+ func_ptr_table[2 * 1] = (void*) &Dequeue_id;
+ func_ptr_table[2 * 1 + 1] = (void*) &Dequeue_check_action;
+ func_ptr_table[2 * 0] = (void*) &Enqueue_id;
+ func_ptr_table[2 * 0 + 1] = (void*) &Enqueue_check_action;
+ /* Enqueue(true) -> Dequeue(true) */
+ struct hb_rule *hbConditionInit0 = (struct hb_rule*) malloc(sizeof(struct hb_rule));
+ hbConditionInit0->interface_num_before = 0; // Enqueue
+ hbConditionInit0->hb_condition_num_before = 0; //
+ hbConditionInit0->interface_num_after = 1; // Dequeue
+ hbConditionInit0->hb_condition_num_after = 0; //
+ /* Init hb_rule_table */
+ hb_rule_table = (hb_rule**) malloc(sizeof(hb_rule*) * 1);
+ #define HB_RULE_TABLE_SIZE 1
+ hb_rule_table[0] = hbConditionInit0;
+ /* Init commutativity_rule_table */
+ commutativity_rule_table = (commutativity_rule**) malloc(sizeof(commutativity_rule*) * 2);
+ commutativity_rule* rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 0;
+ rule->interface_num_after = 1;
+ rule->rule = "true";
+ rule->condition = CommutativityCondition0;
+ commutativity_rule_table[0] = rule;
+ rule = (commutativity_rule*) malloc (sizeof(commutativity_rule));
+ rule->interface_num_before = 1;
+ rule->interface_num_after = 1;
+ rule->rule = "! _Method1 . __RET__ || ! _Method2 . __RET__";
+ rule->condition = CommutativityCondition1;
+ commutativity_rule_table[1] = rule;
+ /* Pass init info, including function table info & HB rules & Commutativity Rules */
+ struct anno_init *anno_init = (struct anno_init*) malloc(sizeof(struct anno_init));
+ anno_init->init_func = (void_func_t) __SPEC_INIT__;
+ anno_init->cleanup_func = (cleanup_func_t) __SPEC_CLEANUP__;
+ anno_init->func_table = func_ptr_table;
+ anno_init->func_table_size = INTERFACE_SIZE;
+ anno_init->hb_rule_table = hb_rule_table;
+ anno_init->hb_rule_table_size = HB_RULE_TABLE_SIZE;
+ anno_init->commutativity_rule_table = commutativity_rule_table;
+ anno_init->commutativity_rule_table_size = 2;
+ struct spec_annotation *init = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ init->type = INIT;
+ init->annotation = anno_init;
+ cdsannotate(SPEC_ANALYSIS, init);
+
+}
+
+/* End of Global construct generation in class */
+
+
+
+
+void enqueue(T data) {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 0; // Enqueue
+ interface_begin->interface_name = "Enqueue";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ __wrapper__enqueue(data);
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 0; // Enqueue
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Enqueue_info* info = (Enqueue_info*) malloc(sizeof(Enqueue_info));
+ info->data = data;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 0; // Enqueue
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+}
+
+void __wrapper__enqueue(T data)
+ {
+ node* n = new node (data);
+
+ head->next.store(n, std::memory_order_release);
+ /* Automatically generated code for commit point define check: Enqueue_Point */
+
+ if (true) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 0;
+ cp_define_check->label_name = "Enqueue_Point";
+ cp_define_check->interface_num = 0;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ head = n;
+ ec.signal();
+ }
+
+T dequeue() {
+ /* Interface begins */
+ struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
+ interface_begin->interface_num = 1; // Dequeue
+ interface_begin->interface_name = "Dequeue";
+ struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_interface_begin->type = INTERFACE_BEGIN;
+ annotation_interface_begin->annotation = interface_begin;
+ cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
+ T __RET__ = __wrapper__dequeue();
+ struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
+ hb_condition->interface_num = 1; // Dequeue
+ hb_condition->hb_condition_num = 0;
+ struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_hb_condition->type = HB_CONDITION;
+ annotation_hb_condition->annotation = hb_condition;
+ cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
+
+ Dequeue_info* info = (Dequeue_info*) malloc(sizeof(Dequeue_info));
+ info->__RET__ = __RET__;
+ struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
+ interface_end->interface_num = 1; // Dequeue
+ interface_end->info = info;
+ struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annoation_interface_end->type = INTERFACE_END;
+ annoation_interface_end->annotation = interface_end;
+ cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
+ return __RET__;
+}
+
+T __wrapper__dequeue()
+ {
+ T data = try_dequeue();
+ while (0 == data)
+ {
+ int cmp = ec.get();
+ data = try_dequeue();
+ if (data)
+ break;
+ ec.wait(cmp);
+ data = try_dequeue();
+ if (data)
+ break;
+ }
+ return data;
+ }
+
+private:
+ struct node
+ {
+ std::atomic<node*> next;
+ T data;
+
+ node(T data = T())
+ : data(data)
+ {
+ next = 0;
+ }
+ };
+
+ node *head;
+ node *tail;
+
+
+
+ eventcount ec;
+
+ T try_dequeue()
+ {
+ node *t = tail;
+
+ node* n = t->next.load(std::memory_order_acquire);
+ /* Automatically generated code for commit point define check: Dequeue_Point */
+
+ if (n != 0) {
+ struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
+ cp_define_check->label_num = 1;
+ cp_define_check->label_name = "Dequeue_Point";
+ cp_define_check->interface_num = 1;
+ struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
+ annotation_cp_define_check->type = CP_DEFINE_CHECK;
+ annotation_cp_define_check->annotation = cp_define_check;
+ cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
+ }
+
+ if (0 == n)
+ return 0;
+ T data = n->data;
+ delete (t);
+ tail = n;
+ return data;
+ }
+};
+template<typename T>
+void** spsc_queue<T>::func_ptr_table;
+template<typename T>
+hb_rule** spsc_queue<T>::hb_rule_table;
+template<typename T>
+commutativity_rule** spsc_queue<T>::commutativity_rule_table;
+template<typename T>
+IntegerList * spsc_queue<T>::__queue;
+
+
+#endif
+
--- /dev/null
+#include <threads.h>
+
+#include "queue.h"
+
+spsc_queue<int> *q;
+
+ void thread(unsigned thread_index)
+ {
+ if (0 == thread_index)
+ {
+ q->enqueue(11);
+ }
+ else
+ {
+ int d = q->dequeue();
+ }
+ }
+
+int user_main(int argc, char **argv)
+{
+ thrd_t A, B;
+
+ q = new spsc_queue<int>();
+
+ thrd_create(&A, (thrd_start_t)&thread, (void *)0);
+ thrd_create(&B, (thrd_start_t)&thread, (void *)1);
+ thrd_join(A);
+ thrd_join(B);
+
+ delete q;
+
+ return 0;
+}
+
// 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]);