changes with lines of spec counted
[cdsspec-compiler.git] / benchmark / chase-lev-deque-bugfix / deque.h
index bc670e7ef1e540d56b2e043fe1b11b48f396b91a..837df898e421b8a8f038dd5d0c4dd1fd59b2b1ba 100644 (file)
@@ -1,6 +1,13 @@
 #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[];
@@ -11,12 +18,110 @@ typedef struct {
        atomic_uintptr_t array; /* Atomic(Array *) */
 } Deque;
 
+#define EMPTY 0xffffffff
+#define ABORT 0xfffffffe
+
+/**
+    @Begin
+    @Options:
+        LANG = C;
+    @Global_define:
+        @DeclareStruct:
+        typedef struct tag_elem {
+            call_id_t id;
+            int data;
+        } tag_elem_t;
+        
+        @DeclareVar:
+        spec_list *__deque;
+        id_tag_t *tag;
+        @InitVar:
+            __deque = new_spec_list();
+                       //model_print("init_list\n");
+            tag = new_id_tag(); // Beginning of available id
+               //@Cleanup:
+                       //if (__deque) {
+                               //free_spec_list(__deque);
+                               //model_print("free_list\n");
+                       //}
+                       //if (tag)
+                               //free_id_tag(tag);
+        @DefineFunc:
+            tag_elem_t* new_tag_elem(call_id_t id, int data) {
+                tag_elem_t *e = (tag_elem_t*) CMODEL_MALLOC(sizeof(tag_elem_t));
+                e->id = id;
+                e->data = data;
+                return e;
+            }
+        @DefineFunc:
+            call_id_t get_id(void *wrapper) {
+                               //tag_elem_t *res = (tag_elem_t*) wrapper;
+                               return res == NULL ? 0 : ((tag_elem_t*) wrapper)->id;
+                               //if (res == NULL) {
+                                       //model_print("wrong id here\n");
+                                       //return 0;
+                               //}
+                //return res->id;
+            }
+        @DefineFunc:
+            int get_data(void *wrapper) {
+                               //tag_elem_t *res = (tag_elem_t*) wrapper;
+                //return res->data;
+                               return ((tag_elem_t*) wrapper)->data;
+            }
+    @Happens_before:
+        Push -> Steal
+               Push -> Take
+    @End
+*/
+
+
 Deque * create();
-int take(Deque *q);
 void resize(Deque *q);
+
+/**
+    @Begin
+    @Interface: Take 
+    //@Commit_point_set: Take_Read_Bottom | Take_CAS_Top | Take_Additional_Point
+    @Commit_point_set: Take_Read_Bottom | Take_Additional_Point
+    @ID: __RET__ == EMPTY ? DEFAULT_CALL_ID : get_id(back(__deque))
+    @Action:
+        int _Old_Val = EMPTY;
+               if (__RET__ != EMPTY && size(__deque) > 0) {
+                       _Old_Val = get_data(back(__deque));
+               pop_back(__deque);
+               }
+    @Post_check: _Old_Val == __RET__
+    @End
+*/
+int take(Deque *q);
+
+/**
+    @Begin
+    @Interface: Push 
+    @Commit_point_set: Push_Update_Bottom 
+    @ID: get_and_inc(tag);
+    @Action: push_back(__deque, new_tag_elem(__ID__, x));
+    @End
+*/
 void push(Deque *q, int x);
 
-#define EMPTY 0xffffffff
-#define ABORT 0xfffffffe
+/**
+    @Begin
+    @Interface: Steal 
+    //@Commit_point_set: Steal_Read_Bottom | Steal_CAS_Top | Steal_Additional_Point
+    @Commit_point_set: Steal_Read_Bottom | Steal_Additional_Point
+    @ID: (__RET__ == EMPTY || __RET__ == ABORT) ? DEFAULT_CALL_ID : get_id(front(__deque))
+    @Action:
+        int _Old_Val = EMPTY;
+               if (__RET__ != EMPTY && __RET__ != ABORT && size(__deque) > 0) {
+                       _Old_Val = get_data(front(__deque));
+                       pop_front(__deque);
+               }
+    @Post_check:
+        _Old_Val == __RET__ || __RET__ == EMPTY || __RET__ == ABORT
+    @End
+*/
+int steal(Deque *q);
 
 #endif