7d2df9f18e1732d7e2909cf5ec89faaa7b9afd0b
[cdsspec-compiler.git] / benchmark / chase-lev-deque-bugfix / deque.h
1 #ifndef DEQUE_H
2 #define DEQUE_H
3
4 #include <spec_lib.h>
5 #include <stdlib.h>
6 #include <cdsannotate.h>
7 #include <specannotation.h>
8 #include <model_memory.h>
9 #include "common.h"
10
11 typedef struct {
12         atomic_size_t size;
13         atomic_int buffer[];
14 } Array;
15
16 typedef struct {
17         atomic_size_t top, bottom;
18         atomic_uintptr_t array; /* Atomic(Array *) */
19 } Deque;
20
21 #define EMPTY 0xffffffff
22 #define ABORT 0xfffffffe
23
24 /**
25     @Begin
26     @Options:
27         LANG = C;
28     @Global_define:
29         @DeclareStruct:
30         typedef struct tag_elem {
31             call_id_t id;
32             int data;
33         } tag_elem_t;
34         
35         @DeclareVar:
36         spec_list *__deque;
37         id_tag_t *tag;
38         @InitVar:
39             __deque= new_spec_list();
40             tag = new_id_tag(); // Beginning of available id
41         @DefineFunc:
42             tag_elem_t* new_tag_elem(call_id_t id, int data) {
43                 tag_elem_t *e = (tag_elem_t*) CMODEL_MALLOC(sizeof(tag_elem_t));
44                 e->id = id;
45                 e->data = data;
46                 return e;
47             }
48         @DefineFunc:
49             call_id_t get_id(void *wrapper) {
50                                 tag_elem_t *res = (tag_elem_t*) wrapper;
51                                 if (res == NULL) {
52                                         //model_print("wrong id here\n");
53                                         return 0;
54                                 }
55                 return res->id;
56             }
57         @DefineFunc:
58             int get_data(void *wrapper) {
59                                 tag_elem_t *res = (tag_elem_t*) wrapper;
60                 return res->data;
61             }
62     @Happens_before:
63         Push -> Steal
64                 Push -> Take
65     @End
66 */
67
68
69 Deque * create();
70 void resize(Deque *q);
71
72 /**
73     @Begin
74     @Interface: Take 
75     //@Commit_point_set: Take_Read_Bottom | Take_CAS_Top | Take_Additional_Point
76     @Commit_point_set: Take_Read_Bottom | Take_Additional_Point
77     @ID: __RET__ == EMPTY ? DEFAULT_CALL_ID : get_id(back(__deque))
78     @Action:
79         int _Old_Val = EMPTY;
80                 if (__RET__ != EMPTY) {
81                         if (size(__deque) > 0) {
82                                 _Old_Val = get_data(back(__deque));
83                         pop_back(__deque);
84                         }       
85                 }
86     @Post_check:
87         _Old_Val == __RET__
88     @End
89 */
90 int take(Deque *q);
91
92 /**
93     @Begin
94     @Interface: Push 
95     @Commit_point_set: Push_Update_Bottom 
96     @ID: get_and_inc(tag);
97     @Action:
98         tag_elem_t *elem = new_tag_elem(__ID__, x);
99         push_back(__deque, elem);
100     @End
101 */
102 void push(Deque *q, int x);
103
104 /**
105     @Begin
106     @Interface: Steal 
107     //@Commit_point_set: Steal_Read_Bottom | Steal_CAS_Top | Steal_Additional_Point
108     @Commit_point_set: Steal_Read_Bottom | Steal_Additional_Point
109     @ID: (__RET__ == EMPTY || __RET__ == ABORT) ? DEFAULT_CALL_ID : get_id(front(__deque))
110     @Action:
111         int _Old_Val = EMPTY;
112                 if (__RET__ != EMPTY && __RET__ != ABORT) {
113                         if (size(__deque) > 0) {
114                                 _Old_Val = get_data(front(__deque));
115                                 pop_front(__deque);
116                         }
117                 }
118     @Post_check:
119         _Old_Val == __RET__ || __RET__ == EMPTY || __RET__ == ABORT
120     @End
121 */
122 int steal(Deque *q);
123
124 #endif