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