Arax -8d09c51940345c86062e8ef2427c705ae66e5926
A Runtime Framework for Decoupling Applications from Heterogeneous Accelerators
Loading...
Searching...
No Matches
queue.c
Go to the documentation of this file.
1
13
14#include "queue.h"
15#include <stddef.h>
16#include <stdio.h>
17#include <stdint.h>
18#include <string.h>
19#include "utils/arax_assert.h"
20#include <limits.h>
21
22#define COMPILER_BARRIER() asm volatile ("" : : : "memory")
23
24#ifdef __GNUC__
25#define UNLIKELY(cond) __builtin_expect(cond, 0)
26#define LIKELY(cond) __builtin_expect(cond, 1)
27#else /* ifdef __GNUC__ */
28#define UNLIKELY(cond) (cond)
29#define LIKELY(cond) (cond)
30#endif /* ifdef __GNUC__ */
31
32#ifndef UTILS_QUEUE_MPMC
33// No spinlock, so define spin functions to nop
34#define utils_spinlock_init(V)
35#define utils_spinlock_lock(V)
36#define utils_spinlock_unlock(V)
37#endif
38
40{
41 arax_assert(!( UTILS_QUEUE_CAPACITY & (UTILS_QUEUE_CAPACITY - 1) ) );
42
43 /* Zero memory */
44 memset(buff, 0, sizeof(struct queue) );
45
46 utils_spinlock_init(&(((utils_queue_s *) buff)->lock));
47
48 return (utils_queue_s *) buff;
49}
50
52{
53 register int used_slots;
54
55 used_slots = q->bottom - q->top;
56
57 if (used_slots < 0)
58 used_slots += UINT16_MAX + 1;
59
60 return (unsigned int) used_slots;
61}
62
64{
65 register uint16_t t, b;
66 register int i;
67 void *ret_val = 0;
68
69 arax_assert(q);
70
71 /* Only one thief can succeed in the following critical section */
72 t = q->top;
73 b = q->bottom;
74
75 /* If it is empty */
76 if (b == t)
77 goto RETURN;
78
79 /* Get the top element */
80 i = t & (UTILS_QUEUE_CAPACITY - 1);
81 ret_val = q->entries[i];
82 if (!__sync_bool_compare_and_swap(&q->top, t, t + 1) )
83 ret_val = 0;
84
85RETURN:
86 return ret_val;
87}
88
89void* utils_queue_push(utils_queue_s *q, void *data)
90{
91 uint16_t b, t;
92 int i;
93
94 arax_assert(data);
95 arax_assert(q);
96
97 utils_spinlock_lock(&(q->lock));
98
99 b = q->bottom;
100 t = q->top;
101
102 int used_slots = b - t;
103
104 if (used_slots < 0)
105 used_slots += UINT16_MAX + 1;
106
107 /* If there is no more space */
108 if (used_slots == UTILS_QUEUE_CAPACITY) {
109 data = 0;
110 goto RETURN;
111 }
112
113 i = b & (UTILS_QUEUE_CAPACITY - 1);
114 q->entries[i] = data;
115 __sync_synchronize();
116 q->bottom = b + 1;
117
118 /* printf("b=%u t=%u\n", ++b, t);
119 * arax_assert(((b >> 7) == (t >> 7)) || ((b & (UTILS_QUEUE_CAPACITY-1)) <= (t & (UTILS_QUEUE_CAPACITY)))); */
120
121RETURN:
122 utils_spinlock_unlock(&(q->lock));
123 return data;
124} /* utils_queue_push */
125
127{
128 register uint16_t t, b;
129 register int i;
130
131 /* Only one thief can succeed in the following critical section */
132 t = q->top;
133 b = q->bottom;
134
135 /* If it is empty */
136 if (b == t)
137 return 0;
138
139 i = t & (UTILS_QUEUE_CAPACITY - 1);
140
141 return q->entries[i];
142}
#define arax_assert(EXPR)
Definition arax_assert.h:7
struct queue utils_queue_s
Definition queue.h:30
#define utils_spinlock_lock(V)
Definition queue.c:35
#define utils_spinlock_init(V)
Definition queue.c:34
utils_queue_s * utils_queue_init(void *buff)
Definition queue.c:39
unsigned int utils_queue_used_slots(utils_queue_s *q)
Definition queue.c:51
void * utils_queue_peek(utils_queue_s *q)
Definition queue.c:126
#define utils_spinlock_unlock(V)
Definition queue.c:36
void * utils_queue_pop(utils_queue_s *q)
Definition queue.c:63
void * utils_queue_push(utils_queue_s *q, void *data)
Definition queue.c:89
Definition queue.h:16
void * entries[UTILS_QUEUE_CAPACITY]
Definition queue.h:18