ff3d42d4697354fa96985e9f457425a1957d3fdc
[cdsspec-compiler.git] / benchmark / ms-queue / my_queue.h
1 #ifndef _MY_QUEUE_H
2 #define _MY_QUEUE_H
3
4 #include <stdatomic.h>
5
6 #define MAX_NODES                       0xf
7
8 typedef unsigned long long pointer;
9 typedef atomic_ullong pointer_t;
10
11 #define MAKE_POINTER(ptr, count)        ((((pointer)count) << 32) | ptr)
12 #define PTR_MASK 0xffffffffLL
13 #define COUNT_MASK (0xffffffffLL << 32)
14
15 static inline void set_count(pointer *p, unsigned int val) { *p = (*p & ~COUNT_MASK) | ((pointer)val << 32); }
16 static inline void set_ptr(pointer *p, unsigned int val) { *p = (*p & ~PTR_MASK) | val; }
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
20 typedef struct node {
21         unsigned int value;
22         pointer_t next;
23 } node_t;
24
25 typedef struct {
26         pointer_t head;
27         pointer_t tail;
28         node_t nodes[MAX_NODES + 1];
29 } queue_t;
30
31 void init_queue(queue_t *q, int num_threads);
32
33 /**
34         @Begin
35         @Options:
36                 LANG = C;
37         @Global_define:
38                 @DeclareStruct:
39                 typedef struct tag_elem {
40                         call_id_t id;
41                         unsigned int data;
42                 } tag_elem_t;
43                 
44                 @DeclareVar:
45                 spec_list *__queue;
46                 id_tag_t *tag;
47                 @InitVar:
48                         __queue = new_spec_list();
49                         tag = new_id_tag(); // Beginning of available id
50                 @DefineFunc:
51                         tag_elem_t* new_tag_elem(call_id_t id, unsigned int data) {
52                                 tag_elem_t *e = (tag_elem_t*) CMODEL_MALLOC(sizeof(tag_elem_t));
53                                 e->id = id;
54                                 e->data = data;
55                                 return e;
56                         }
57                 @DefineFunc:
58                         void free_tag_elem(tag_elem_t *e) {
59                                 free(e);
60                         }
61                 @DefineFunc:
62                         call_id_t get_id(void *wrapper) {
63                                 return ((tag_elem_t*) wrapper)->id;
64                         }
65                 @DefineFunc:
66                         unsigned int get_data(void *wrapper) {
67                                 return ((tag_elem_t*) wrapper)->data;
68                         }
69         @Happens_before:
70                 # Only check the happens-before relationship according to the id of the
71                 # commit_point_set. For commit_point_set that has same ID, A -> B means
72                 # B happens after the previous A.
73                 Enqueue -> Dequeue
74         @End
75 */
76
77
78
79 /**
80         @Begin
81         @Interface: Enqueue
82         @Commit_point_set: Enqueue_Success_Point
83         @ID: get_and_inc(tag);
84         @Action:
85                 # __ID__ is an internal macro that refers to the id of the current
86                 # interface call
87                 tag_elem_t *elem = new_tag_elem(__ID__, val);
88                 push_back(__queue, elem);
89         @End
90 */
91 void enqueue(queue_t *q, unsigned int val);
92
93 /**
94         @Begin
95         @Interface: Dequeue
96         @Commit_point_set: Dequeue_Success_Point | Dequeue_Empty_Point
97         @ID: get_id(back(__queue))
98         @Action:
99                 unsigned int _Old_Val = get_data(front(__queue));
100                 pop_front(__queue);
101         @Post_check:
102                 _Old_Val == __RET__
103         @End
104 */
105 unsigned int dequeue(queue_t *q);
106 int get_thread_num();
107
108 #endif