4 #include "model-assert.h"
8 #define relaxed memory_order_relaxed
9 #define release memory_order_release
10 #define acquire memory_order_acquire
12 #define MAX_FREELIST 4
13 #define INITIAL_FREE 3
15 #define POISON_IDX 0x666
17 static unsigned int (*free_lists)[MAX_FREELIST];
20 static unsigned int new_node()
23 int t = get_thread_num();
24 for (i = 0; i < MAX_FREELIST; i++) {
25 unsigned int node = free_lists[t][i];
36 static void reclaim(unsigned int node)
39 int t = get_thread_num();
43 for (i = 0; i < MAX_FREELIST; i++) {
45 unsigned int idx = free_lists[t][i];
49 store_32(&free_lists[t][i], node);
56 void init_queue(queue_t *q, int num_threads)
59 for (i = 0; i < MAX_NODES; i++) {
60 atomic_init(&q->nodes[i].next, MAKE_POINTER(POISON_IDX, 0));
65 free_lists = malloc(num_threads * sizeof(*free_lists));
66 for (i = 0; i < num_threads; i++) {
67 for (j = 0; j < INITIAL_FREE; j++) {
68 free_lists[i][j] = 2 + i * MAX_FREELIST + j;
69 atomic_init(&q->nodes[free_lists[i][j]].next, MAKE_POINTER(POISON_IDX, 0));
74 atomic_init(&q->head, MAKE_POINTER(1, 0));
75 atomic_init(&q->tail, MAKE_POINTER(1, 0));
76 atomic_init(&q->nodes[1].next, MAKE_POINTER(0, 0));
80 void enqueue(queue_t * q, unsigned int val) {
81 /* Interface begins */
82 struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
83 interface_begin->interface_num = 0; // Enqueue
84 interface_begin->interface_name = "Enqueue";
85 struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
86 annotation_interface_begin->type = INTERFACE_BEGIN;
87 annotation_interface_begin->annotation = interface_begin;
88 cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
89 __wrapper__enqueue(q, val);
90 struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
91 hb_condition->interface_num = 0; // Enqueue
92 hb_condition->hb_condition_num = 0;
93 struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
94 annotation_hb_condition->type = HB_CONDITION;
95 annotation_hb_condition->annotation = hb_condition;
96 cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
98 Enqueue_info* info = (Enqueue_info*) malloc(sizeof(Enqueue_info));
101 struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
102 interface_end->interface_num = 0; // Enqueue
103 interface_end->info = info;
104 struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
105 annoation_interface_end->type = INTERFACE_END;
106 annoation_interface_end->annotation = interface_end;
107 cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
110 void __wrapper__enqueue(queue_t * q, unsigned int val)
119 q->nodes[node].value = val;
120 tmp = atomic_load_explicit(&q->nodes[node].next, relaxed);
121 set_ptr(&tmp, 0); atomic_store_explicit(&q->nodes[node].next, tmp, relaxed);
125 /* Automatically generated code for commit point clear: Enqueue_Clear */
128 struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
129 cp_clear->label_name = "Enqueue_Clear";
130 cp_clear->label_num = 0;
131 struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
132 annotation_cp_clear->type = CP_CLEAR;
133 annotation_cp_clear->annotation = cp_clear;
134 cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
138 tail = atomic_load_explicit(&q->tail, acquire);
140 next = atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire);
141 if (tail == atomic_load_explicit(&q->tail, relaxed)) {
145 if (get_ptr(next) == 0) { pointer value = MAKE_POINTER(node, get_count(next) + 1);
147 success = atomic_compare_exchange_strong_explicit(&q->nodes[get_ptr(tail)].next,
148 &next, value, release, relaxed);
149 /* Automatically generated code for commit point define check: EnqueueUpdateNext */
152 struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
153 cp_define_check->label_num = 1;
154 cp_define_check->label_name = "EnqueueUpdateNext";
155 cp_define_check->interface_num = 0;
156 struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
157 annotation_cp_define_check->type = CP_DEFINE_CHECK;
158 annotation_cp_define_check->annotation = cp_define_check;
159 cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
165 unsigned int ptr = get_ptr(atomic_load_explicit(&q->nodes[get_ptr(tail)].next, acquire));
166 pointer value = MAKE_POINTER(ptr,
167 get_count(tail) + 1);
170 succ = atomic_compare_exchange_strong_explicit(&q->tail,
171 &tail, value, relaxed, relaxed);
179 bool succ = atomic_compare_exchange_strong_explicit(&q->tail,
181 MAKE_POINTER(node, get_count(tail) + 1),
186 bool dequeue(queue_t * q, int * retVal) {
187 /* Interface begins */
188 struct anno_interface_begin *interface_begin = (struct anno_interface_begin*) malloc(sizeof(struct anno_interface_begin));
189 interface_begin->interface_num = 1; // Dequeue
190 interface_begin->interface_name = "Dequeue";
191 struct spec_annotation *annotation_interface_begin = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
192 annotation_interface_begin->type = INTERFACE_BEGIN;
193 annotation_interface_begin->annotation = interface_begin;
194 cdsannotate(SPEC_ANALYSIS, annotation_interface_begin);
195 bool __RET__ = __wrapper__dequeue(q, retVal);
196 struct anno_hb_condition *hb_condition = (struct anno_hb_condition*) malloc(sizeof(struct anno_hb_condition));
197 hb_condition->interface_num = 1; // Dequeue
198 hb_condition->hb_condition_num = 0;
199 struct spec_annotation *annotation_hb_condition = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
200 annotation_hb_condition->type = HB_CONDITION;
201 annotation_hb_condition->annotation = hb_condition;
202 cdsannotate(SPEC_ANALYSIS, annotation_hb_condition);
204 Dequeue_info* info = (Dequeue_info*) malloc(sizeof(Dequeue_info));
205 info->__RET__ = __RET__;
207 info->retVal = retVal;
208 struct anno_interface_end *interface_end = (struct anno_interface_end*) malloc(sizeof(struct anno_interface_end));
209 interface_end->interface_num = 1; // Dequeue
210 interface_end->info = info;
211 struct spec_annotation *annoation_interface_end = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
212 annoation_interface_end->type = INTERFACE_END;
213 annoation_interface_end->annotation = interface_end;
214 cdsannotate(SPEC_ANALYSIS, annoation_interface_end);
218 bool __wrapper__dequeue(queue_t * q, int * retVal)
220 unsigned int value = 0;
227 /* Automatically generated code for commit point clear: Dequeue_Clear */
230 struct anno_cp_clear *cp_clear = (struct anno_cp_clear*) malloc(sizeof(struct anno_cp_clear));
231 cp_clear->label_name = "Dequeue_Clear";
232 cp_clear->label_num = 2;
233 struct spec_annotation *annotation_cp_clear = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
234 annotation_cp_clear->type = CP_CLEAR;
235 annotation_cp_clear->annotation = cp_clear;
236 cdsannotate(SPEC_ANALYSIS, annotation_cp_clear);
240 head = atomic_load_explicit(&q->head, acquire);
241 /* Automatically generated code for commit point define check: DequeueReadHead */
244 struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
245 cp_define_check->label_num = 3;
246 cp_define_check->label_name = "DequeueReadHead";
247 cp_define_check->interface_num = 1;
248 struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
249 annotation_cp_define_check->type = CP_DEFINE_CHECK;
250 annotation_cp_define_check->annotation = cp_define_check;
251 cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
257 tail = atomic_load_explicit(&q->tail, acquire);
260 next = atomic_load_explicit(&q->nodes[get_ptr(head)].next, acquire);
261 /* Automatically generated code for potential commit point: DequeueReadNext */
264 struct anno_potential_cp_define *potential_cp_define = (struct anno_potential_cp_define*) malloc(sizeof(struct anno_potential_cp_define));
265 potential_cp_define->label_num = 4;
266 potential_cp_define->label_name = "DequeueReadNext";
267 struct spec_annotation *annotation_potential_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
268 annotation_potential_cp_define->type = POTENTIAL_CP_DEFINE;
269 annotation_potential_cp_define->annotation = potential_cp_define;
270 cdsannotate(SPEC_ANALYSIS, annotation_potential_cp_define);
273 if (atomic_load_explicit(&q->head, relaxed) == head) {
274 if (get_ptr(head) == get_ptr(tail)) {
278 if (get_ptr(next) == 0) { return false; }
281 succ = atomic_compare_exchange_strong_explicit(&q->tail,
283 MAKE_POINTER(get_ptr(next), get_count(tail) + 1),
289 value = q->nodes[get_ptr(next)].value;
291 success = atomic_compare_exchange_strong_explicit(&q->head,
293 MAKE_POINTER(get_ptr(next), get_count(head) + 1),
295 /* Automatically generated code for commit point define check: DequeueUpdateHead */
298 struct anno_cp_define_check *cp_define_check = (struct anno_cp_define_check*) malloc(sizeof(struct anno_cp_define_check));
299 cp_define_check->label_num = 5;
300 cp_define_check->label_name = "DequeueUpdateHead";
301 cp_define_check->interface_num = 1;
302 struct spec_annotation *annotation_cp_define_check = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
303 annotation_cp_define_check->type = CP_DEFINE_CHECK;
304 annotation_cp_define_check->annotation = cp_define_check;
305 cdsannotate(SPEC_ANALYSIS, annotation_cp_define_check);
309 /* Automatically generated code for commit point define: DequeueReadNextVerify */
312 struct anno_cp_define *cp_define = (struct anno_cp_define*) malloc(sizeof(struct anno_cp_define));
313 cp_define->label_num = 6;
314 cp_define->label_name = "DequeueReadNextVerify";
315 cp_define->potential_cp_label_num = 4;
316 cp_define->potential_label_name = "DequeueReadNext";
317 cp_define->interface_num = 1;
318 struct spec_annotation *annotation_cp_define = (struct spec_annotation*) malloc(sizeof(struct spec_annotation));
319 annotation_cp_define->type = CP_DEFINE;
320 annotation_cp_define->annotation = cp_define;
321 cdsannotate(SPEC_ANALYSIS, annotation_cp_define);
329 reclaim(get_ptr(head));