source: CIVL/examples/experimental/por_bug.cvl

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.9 KB
RevLine 
[76d3d3a]1#include <stdlib.h>
2
3int global = 0;
4
5typedef struct _node Node;
6typedef struct _pqueue PQueue;
7
8struct _node
9{
10 int v;
11 int p;
12 int mthis;
13 int mnext;
14 Node* next;
15};
16
17struct _pqueue
18{
19 Node* head;
20 Node* tail;
21};
22
23
24Node* n_create(int val, int prior) {
25 Node* n = (Node*)malloc(sizeof(Node));
26 n->v = val;
27 n->p = prior;
28 n->mthis = 0;
29 n->mnext = 0;
30 n->next = NULL;
31 return n;
32}
33
34PQueue* pq_create() {
35 PQueue* q = (PQueue*)malloc(sizeof(PQueue));
36 q->head = n_create(-1, -100);
37 q->tail = n_create(-1, 100);
38 q->head->mnext = 0;
39 q->head->next = q->tail;
40 return q;
41}
42
43
44int comp_set(Node** ref, int* mref,
45 Node* exp, int mexp,
46 Node* new, int mnew) {
47 $atomic{
48 if (*ref == exp && *mref == mexp) {
49 *ref = new;
50 *mref = mnew;
51 return 1;
52 }
53 return 0;
54 }
55}
56
57int find(PQueue* q, Node* n, Node** preds, Node** succs) {
58 int marked = 0;
59 int snip;
60 Node* pred = NULL;
61 Node* curr = NULL;
62 Node* succ = NULL;
63retry:
64 while(1==1) {
65 pred = q->head;
66 curr = pred->next;
67 while(1==1) {
68 succ = curr->next;
69 marked = curr->mnext;
70 while(marked) {
71 if (comp_set(&(pred->next), &(pred->mnext),
72 curr, 0, succ, 0) == 0)
73 goto retry;
74 curr = pred->next;
75 succ = curr->next;
76 marked = curr->mnext;
77 }
78 if (curr->p < n->p) {
79 pred = curr;
80 curr = succ;
81 } else {
82 break;
83 }
84 }
85 preds[0] = pred;
86 succs[0] = curr;
87 if (curr->p == n->p) return 1;
88 else return 0;
89 }
90}
91
92int atom_comp_set(int* v, int vexp, int vnew) {
93 $atomic{
94 if (*v == vexp) {
95 *v = vnew;
96 return 1;
97 }
98 return 0;
99 }
100}
101
102Node* find_min(PQueue* q, int tid) {
103 int local = 0;
104 Node* curr = NULL;
105 Node* succ = NULL;
106 int marked;
107 curr = q->head->next;
108 while(curr != q->tail) {
109 $atomic {marked = curr->mthis;}
110 if (marked == 0) {
111 if (atom_comp_set(&(curr->mthis), 0, 1)) {
112#ifdef GLOBAL
113 global = 1;
114#else
115 local = 1;
116#endif
117 return curr;
118 }
119 } else {
120 curr = curr->next;
121 }
122 }
123 return NULL;
124}
125
126int add(PQueue* q, int val, int prior, int tid) {
127 Node* n = n_create(val, prior);
128 Node** preds = (Node**)malloc(sizeof(Node*));
129 Node** succs = (Node**)malloc(sizeof(Node*));
130 while(1==1) {
131 int found = find(q, n, preds, succs);
132 if (found == 1) {
133 return 0;
134 } else {
135 n->next = succs[0];
136 n->mnext = 0;
137 Node* pred = preds[0];
138 Node* succ = succs[0];
139 n->next = succ;
140 n->mnext = 0;
141 if (!comp_set(&(pred->next), &(pred->mnext), succ, 0, n, 0)) {
142 continue;
143 }
144 return 1;
145 }
146 }
147}
148
149int del(PQueue* q, int tid) {
150 Node* n = find_min(q, tid);
151
152 if(n == NULL) return -1;
153
154 Node* succ;
155 Node** preds = (Node**)malloc(sizeof(Node*));
156 Node** succs = (Node**)malloc(sizeof(Node*));
157 while(1==1) {
158 int found = find(q, n, preds, succs);
159 if (found == 0) {
160 return 0;
161 } else {
162 int marked = 0;
163 succ = n->next;
164 marked = n->mnext;
165 while(marked == 0) {
166 // attempt_mark(&(n->next), &(n->mnext), succ, 1);
167 comp_set(&(n->next), &(n->mnext), succ, n->mnext, succ, 1);
168 succ = n->next;
169 marked = n->mnext;
170 }
171 succ = n->next;
172 marked = n->mnext;
173 while(1==1) {
174 int imarked = comp_set(&(n->next), &(n->mnext), succ, 0, succ, 1);
175 succ = succs[0]->next;
176 marked = succs[0]->mnext;
177 if (imarked == 1) {
178 find(q, n, preds, succs);
179 return n->v;
180 } else if (marked == 1) {
181 return n->v;
182 }
183 }
184 }
185 }
186}
187
188int main() {
189 int res[2];
190 PQueue* q = pq_create();
191 add(q, 0, 2, 0);
192 $parfor(int tid: 1..3) {
193 if (tid == 1) {
194 $atomic {
195 add(q, 1, 1, tid);
196 add(q, 2, 3, tid);
197 }
198 } else {
199 res[tid-2] = del(q, tid);
200 }
201 }
202 $assert(res[0] != 2);
203}
Note: See TracBrowser for help on using the repository browser.