0e2fb2b269f7212f8c0d078784d65fce14d4a090
[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                         model_print("init_list\n");
41             tag = new_id_tag(); // Beginning of available id
42                 @Cleanup:
43                         if (__deque) {
44                                 //free_spec_list(__deque);
45                                 model_print("free_list\n");
46                         }
47                         if (tag)
48                                 free_id_tag(tag);
49         @DefineFunc:
50             tag_elem_t* new_tag_elem(call_id_t id, int data) {
51                 tag_elem_t *e = (tag_elem_t*) CMODEL_MALLOC(sizeof(tag_elem_t));
52                 e->id = id;
53                 e->data = data;
54                 return e;
55             }
56         @DefineFunc:
57             call_id_t get_id(void *wrapper) {
58                                 tag_elem_t *res = (tag_elem_t*) wrapper;
59                                 if (res == NULL) {
60                                         //model_print("wrong id here\n");
61                                         return 0;
62                                 }
63                 return res->id;
64             }
65         @DefineFunc:
66             int get_data(void *wrapper) {
67                                 tag_elem_t *res = (tag_elem_t*) wrapper;
68                 return res->data;
69             }
70     @Happens_before:
71         Push -> Steal
72                 Push -> Take
73     @End
74 */
75
76
77 Deque * create();
78 void resize(Deque *q);
79
80 /**
81     @Begin
82     @Interface: Take 
83     //@Commit_point_set: Take_Read_Bottom | Take_CAS_Top | Take_Additional_Point
84     @Commit_point_set: Take_Read_Bottom | Take_Additional_Point
85     @ID: __RET__ == EMPTY ? DEFAULT_CALL_ID : get_id(back(__deque))
86     @Action:
87         int _Old_Val = EMPTY;
88                 if (__RET__ != EMPTY) {
89                         if (size(__deque) > 0) {
90                                 _Old_Val = get_data(back(__deque));
91                         pop_back(__deque);
92                         }       
93                 }
94     @Post_check:
95         _Old_Val == __RET__
96     @End
97 */
98 int take(Deque *q);
99
100 /**
101     @Begin
102     @Interface: Push 
103     @Commit_point_set: Push_Update_Bottom 
104     @ID: get_and_inc(tag);
105     @Action:
106         tag_elem_t *elem = new_tag_elem(__ID__, x);
107         push_back(__deque, elem);
108     @End
109 */
110 void push(Deque *q, int x);
111
112 /**
113     @Begin
114     @Interface: Steal 
115     //@Commit_point_set: Steal_Read_Bottom | Steal_CAS_Top | Steal_Additional_Point
116     @Commit_point_set: Steal_Read_Bottom | Steal_Additional_Point
117     @ID: (__RET__ == EMPTY || __RET__ == ABORT) ? DEFAULT_CALL_ID : get_id(front(__deque))
118     @Action:
119         int _Old_Val = EMPTY;
120                 if (__RET__ != EMPTY && __RET__ != ABORT) {
121                         if (size(__deque) > 0) {
122                                 _Old_Val = get_data(front(__deque));
123                                 pop_front(__deque);
124                         }
125                 }
126     @Post_check:
127         _Old_Val == __RET__ || __RET__ == EMPTY || __RET__ == ABORT
128     @End
129 */
130 int steal(Deque *q);
131
132 #endif