2 #include "libinterface.h"
4 /* atomic */ int flag1, flag2;
9 #define MAX_FREELIST 4 /* Each thread can own up to MAX_FREELIST free nodes */
10 static unsigned int (*free_lists)[MAX_FREELIST];
12 typedef /* atomic */ unsigned long long pointer_t;
13 typedef unsigned long long pointer;
14 #define MAKE_POINTER(ptr, count) ((((pointer)count) << 32) | ptr)
15 #define COUNT_MASK (0xffffffffLL << 32)
16 #define PTR_MASK 0xffffffffLL
17 static inline unsigned int get_count(MCID _mp, pointer p, MCID * retval) { *retval = MCID_NODEP;
18 return (p & COUNT_MASK) >> 32; }
19 static inline unsigned int get_ptr(MCID _mp, pointer p, MCID * retval) { *retval = MCID_NODEP;
20 return p & PTR_MASK; }
30 node_t nodes[MAX_NODES + 1];
33 static unsigned int new_node(MCID * retval)
36 int t = get_thread_num(); // should be thrd_current but that's not guaranteed to be an array index
38 for (i = 0; i < MAX_FREELIST; i++) {
39 void * _p1 = &free_lists[t][i]; MCID _mp1 = MC2_function_id(8, 2, sizeof(_p1), t, i, _p1);
40 MCID _mnode; _mnode=MC2_nextOpLoad(_mp1); unsigned int node = load_64(p1);
44 MCID _cond0_m = MC2_function_id(1, 1, sizeof(_cond0), _cond0, _mnode);
46 _br0 = MC2_branchUsesID(_mnode, 1, 2, true);
47 MC2_nextOpStore(_mfree_lists, MCID_NODEP);
48 store_64(&free_lists[t][i], 0);
53 } else { _br0 = MC2_branchUsesID(_mnode, 0, 2, true); MC2_merge(_br0);
61 void p0(MCID _ms, stack_t *s) {
63 unsigned int nodeIdx = new_node(&_rv0);
64 MCID _mnode; node_t *node = &s->nodes[nodeIdx]; // why is this not load_64'd?
65 MCID _moldTop; _moldTop=MC2_nextOpLoadOffset(_ms, MC2_OFFSET(stack_t *, top)); pointer oldTop = load_64(&s->top);
67 pointer newTop = MAKE_POINTER(nodeIdx, get_count(oldTop) + 1);
68 _fn0 = MC2_function_id(4, 2, sizeof (newTop), (uint64_t)newTop, _moldTop, _rv0);
69 MC2_nextOpStoreOffset(_mnode, MC2_OFFSET(node_t *, next), _moldTop);
70 store_64(&node->next, oldTop);
71 MCID _rmw0 = MC2_nextRMWOffset(_ms, MC2_OFFSET(stack_t *, top), MCID_NODEP, _rv1);
72 rmw_64(CAS, &s->top, &oldTop, newTop);
75 void p0_no_macros(MCID _ms, stack_t *s) {
77 unsigned int nodeIdx = new_node(&_rv2);
78 MCID _mnode; node_t *node = &s->nodes[nodeIdx];
79 MCID _moldTop; _moldTop=MC2_nextOpLoadOffset(_ms, MC2_OFFSET(stack_t *, top)); pointer oldTop = load_64(&s->top);
80 MCID _fn1; pointer newTop = (pointer) (((((oldTop & COUNT_MASK) >> 32) + 1) << 32) | nodeIdx);
81 _fn1 = MC2_function_id(5, 2, sizeof (newTop), (uint64_t)newTop, _moldTop, _rv2);
82 MC2_nextOpStoreOffset(_mnode, MC2_OFFSET(node_t *, next), _moldTop);
83 store_64(&node->next, oldTop);
84 MCID _rmw1 = MC2_nextRMWOffset(_ms, MC2_OFFSET(stack_t *, top), MCID_NODEP, _fn1);
85 rmw_64(CAS, &s->top, &oldTop, newTop);
88 int p1(MCID _ms, stack_t *s, MCID * retval) {
89 MCID _mnext; MCID _fn2; MCID _moldTop; _moldTop=MC2_nextOpLoadOffset(_ms, MC2_OFFSET(stack_t *, top)); pointer oldTop = load_64(&s->top), newTop, next;
93 int _cond1 = get_ptr(oldTop) == 0;
94 MCID _cond1_m = MC2_function_id(2, 1, sizeof(_cond1), _cond1, _moldTop);
97 _br1 = MC2_branchUsesID(_cond1_m, 1, 2, true);
99 else { _br1 = MC2_branchUsesID(_cond1_m, 0, 2, true); MC2_merge(_br1);
101 node = &s->nodes[get_ptr(MCID_NODEP, oldTop, &_rv3)]; // why is this not load_64'd?
103 _mnext=MC2_nextOpLoadOffset(_mnode, MC2_OFFSET(node_t *, next)), next = load_64(&node->next);
106 newTop = MAKE_POINTER(get_ptr(next), get_count(oldTop) + 1);
107 MCID _mnewTop = MC2_function_id(9, 2, sizeof (newTop), (uint64_t)newTop, get_ptr(next), get_count(oldTop) + 1);
109 MCID _rmw2 = MC2_nextRMWOffset(_ms, MC2_OFFSET(stack_t *, top), MCID_NODEP, _fn2);
110 rmw_64(CAS, &s->top, &oldTop, newTop);
111 *retval = MCID_NODEP;
115 int p1_no_macros(MCID _ms, stack_t *s, MCID * retval) {
116 MCID _mnext; MCID _fn3; MCID _moldTop; _moldTop=MC2_nextOpLoadOffset(_ms, MC2_OFFSET(stack_t *, top)); pointer oldTop = load_64(&s->top), newTop, next;
120 int _cond2 = (oldTop & 4294967295LL) == 0;
121 MCID _cond2_m = MC2_function_id(3, 1, sizeof(_cond2), _cond2, _moldTop);
123 *retval = MCID_NODEP;
124 _br2 = MC2_branchUsesID(_cond2_m, 1, 2, true);
126 else { _br2 = MC2_branchUsesID(_cond2_m, 0, 2, true); MC2_merge(_br2);
127 }node = &s->nodes[oldTop & PTR_MASK];
129 _mnext=MC2_nextOpLoadOffset(_mnode, MC2_OFFSET(node_t *, next)), next = load_64(&node->next);
130 newTop = (pointer) (((((oldTop & COUNT_MASK) >> 32) + 1) << 32) | (next & PTR_MASK));
131 _fn3 = MC2_function_id(7, 3, sizeof (newTop), (uint64_t)newTop, _fn3, _mnext, _moldTop);
133 MCID _rmw3 = MC2_nextRMWOffset(_ms, MC2_OFFSET(stack_t *, top), MCID_NODEP, _fn3);
134 rmw_64(CAS, &s->top, &oldTop, newTop);
135 *retval = MCID_NODEP;