Commit state of repository at time of OOPSLA 2015 submission.
[satcheck.git] / clang / test / bitops_unannotated.c
1 #include <stdbool.h>
2 #include "libinterface.h"
3
4 /* atomic */ int flag1, flag2;
5
6 #define true 1
7 #define false 0
8 #define NULL 0
9 #define MAX_FREELIST 4 /* Each thread can own up to MAX_FREELIST free nodes */
10 static unsigned int (*free_lists)[MAX_FREELIST];
11
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; }
19 #define MAX_NODES                       0xf
20
21 typedef struct node {
22         unsigned int value;
23         pointer_t next;
24 } node_t;
25
26 typedef struct {
27         pointer_t top;
28         node_t nodes[MAX_NODES + 1];
29 } stack_t;
30
31 static unsigned int new_node()
32 {
33         int i;
34         int t = get_thread_num();
35         for (i = 0; i < MAX_FREELIST; i++) {
36                 unsigned int node = load_64(&free_lists[t][i]);
37                 if (node) {
38                         store_64(&free_lists[t][i], 0);
39                         return node;
40                 }
41         }
42         return 0;
43 }
44
45 void p0(stack_t *s) {
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);
52 }
53
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);
61 }
62
63 int p1(stack_t *s) {
64         pointer oldTop = load_64(&s->top), newTop, next;
65         node_t *node;
66         if (get_ptr(oldTop) == 0)
67                 return 0;
68         node = &s->nodes[get_ptr(oldTop)];
69              
70         next = load_64(&node->next);
71         newTop = MAKE_POINTER(get_ptr(next), get_count(oldTop) + 1);
72              
73         rmw_64(CAS, &s->top, &oldTop, newTop);
74         return 0;
75 }
76
77 int p1_no_macros(stack_t *s) {
78         pointer oldTop = load_64(&s->top), newTop, next;
79         node_t *node;
80         if ((oldTop & PTR_MASK) == 0)
81                 return 0;
82         node = &s->nodes[oldTop & PTR_MASK];
83              
84         next = load_64(&node->next);
85         newTop = (pointer) (((((oldTop & COUNT_MASK) >> 32) + 1) << 32) | (next & PTR_MASK));
86              
87         rmw_64(CAS, &s->top, &oldTop, newTop);
88         return 0;
89 }