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(pointer p) { return (p & COUNT_MASK) >> 32; }
18 static inline unsigned int get_ptr(pointer p) { return p & PTR_MASK; }
28 node_t nodes[MAX_NODES + 1];
31 static unsigned int new_node()
34 int t = get_thread_num();
35 for (i = 0; i < MAX_FREELIST; i++) {
36 unsigned int node = load_64(&free_lists[t][i]);
38 store_64(&free_lists[t][i], 0);
46 unsigned int nodeIdx = new_node();
47 node_t *node = &s->nodes[nodeIdx];
48 pointer oldTop = load_64(&s->top);
49 pointer newTop = MAKE_POINTER(nodeIdx, get_count(oldTop) + 1);
50 store_64(&node->next, oldTop);
51 rmw_64(CAS, &s->top, &oldTop, newTop);
54 void p0_no_macros(stack_t *s) {
55 unsigned int nodeIdx = new_node();
56 node_t *node = &s->nodes[nodeIdx];
57 pointer oldTop = load_64(&s->top);
58 pointer newTop = (pointer) (((((oldTop & COUNT_MASK) >> 32) + 1) << 32) | nodeIdx);
59 store_64(&node->next, oldTop);
60 rmw_64(CAS, &s->top, &oldTop, newTop);
64 pointer oldTop = load_64(&s->top), newTop, next;
66 if (get_ptr(oldTop) == 0)
68 node = &s->nodes[get_ptr(oldTop)];
70 next = load_64(&node->next);
71 newTop = MAKE_POINTER(get_ptr(next), get_count(oldTop) + 1);
73 rmw_64(CAS, &s->top, &oldTop, newTop);
77 int p1_no_macros(stack_t *s) {
78 pointer oldTop = load_64(&s->top), newTop, next;
80 if ((oldTop & PTR_MASK) == 0)
82 node = &s->nodes[oldTop & PTR_MASK];
84 next = load_64(&node->next);
85 newTop = (pointer) (((((oldTop & COUNT_MASK) >> 32) + 1) << 32) | (next & PTR_MASK));
87 rmw_64(CAS, &s->top, &oldTop, newTop);