-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfakelflist.c
122 lines (106 loc) · 2.57 KB
/
fakelflist.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <lflist.h>
#ifdef FAKELOCKFREE
#include <list.h>
#include <atomics.h>
#include <pthread.h>
static
void lock_lflist(lflist *l){
fuzz_atomics();
pthread_mutex_lock((pthread_mutex_t *) &l->mut);
}
static
void unlock_lflist(lflist *l){
fuzz_atomics();
pthread_mutex_unlock((pthread_mutex_t *) &l->mut);
}
flref flref_of(flanchor *a){
return (flref){a, a->gen};
}
flanchor *flptr(flref a){
return a.ptr;
}
/* TODO: lock_lflist may segfault in segalloc. As with lflist, need
validity bits. */
err (lflist_del)(flx a, type *t){
(void) t;
lflist *l;
while(1){
l = a.ptr->host;
if(!l || a.ptr->gen != a.gen)
return -1;
lock_lflist(l);
if(a.ptr->host == l)
break;
unlock_lflist(l);
}
if(a.ptr->gen != a.gen)
return unlock_lflist(l), -1;
list_del(&a.ptr->lanc, &l->l);
assert(a.ptr->host == l);
a.ptr->host = NULL;
unlock_lflist(l);
return 0;
}
flx (lflist_unenq)(lflist *l, type *t){
lock_lflist(l);
flx rlx = (flx){};
flanchor *r = cof(list_deq(&l->l), flanchor, lanc);
if(r){
rlx = (flx){r, r->gen};
assert(r->host == l);
r->host = NULL;
muste(linref_up(r, t));
}
unlock_lflist(l);
return rlx;
}
flx (lflist_deq)(lflist *l, type *t){
lock_lflist(l);
flx rlx = (flx){};
flanchor *r = cof(list_deq(&l->l), flanchor, lanc);
if(r){
rlx = (flx){r, r->gen};
assert(r->host == l);
r->host = NULL;
muste(linref_up(r, t));
}
unlock_lflist(l);
return rlx;
}
err (lflist_enq)(flx a, lflist *l, type *t){
return lflist_enq_cas(a.gen + 1, a, l, t);
}
err (lflist_enq_cas)(uptr ng, flx a, lflist *l, type *t){
(void) t;
if(a.ptr->gen != a.gen)
return -1;
lock_lflist(l);
if(!cas2_won(((stx){ng, l}), &a.ptr->stx, (&(stx){a.gen, NULL})))
return unlock_lflist(l), -1;
list_enq(&a.ptr->lanc, &l->l);
assert(a.ptr->host == l);
assert(a.ptr->gen == ng);
unlock_lflist(l);
return 0;
}
err (lflist_jam)(flx a, type *t){
return lflist_del_cas(a.gen + 1, a, t);
}
err (lflist_del_cas)(uptr ng, flx a, type *t){
for(stx ax = a.ptr->stx;;){
if(ax.gen != a.gen)
return -1;
if(ax.host){
lflist_del(a, t);
ax = a.ptr->stx;
continue;
}
if(cas2_won(((stx){ng, NULL}), &a.ptr->stx, &ax))
return 0;
}
}
void flanc_ordered_init(uptr g, flanchor *a){
*a = (flanchor) FLANCHOR_GEN(g);
}
void lflist_report_profile(void){}
#endif