This source file includes following definitions.
- virtual2relative
- virtual2relativepeer
- relative2virtual
- vader_fifo_read
- vader_fifo_init
- vader_fifo_write
- vader_fifo_write_ep
- vader_fifo_write_back
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #ifndef MCA_BTL_VADER_FIFO_H
27 #define MCA_BTL_VADER_FIFO_H
28
29 #include "btl_vader.h"
30 #include "btl_vader_endpoint.h"
31 #include "btl_vader_frag.h"
32
33 #define vader_item_compare_exchange(x, y, z) opal_atomic_compare_exchange_strong_ptr ((opal_atomic_intptr_t *) (x), (intptr_t *) (y), (intptr_t) (z))
34
35 #if SIZEOF_VOID_P == 8
36 #define vader_item_swap(x, y) opal_atomic_swap_64((opal_atomic_int64_t *)(x), (int64_t)(y))
37
38 #define MCA_BTL_VADER_OFFSET_MASK 0xffffffffll
39 #define MCA_BTL_VADER_OFFSET_BITS 32
40 #define MCA_BTL_VADER_BITNESS 64
41 #else
42 #define vader_item_swap(x, y) opal_atomic_swap_32((opal_atomic_int32_t *)(x), (int32_t)(y))
43
44 #define MCA_BTL_VADER_OFFSET_MASK 0x00ffffffl
45 #define MCA_BTL_VADER_OFFSET_BITS 24
46 #define MCA_BTL_VADER_BITNESS 32
47 #endif
48
49 typedef opal_atomic_intptr_t atomic_fifo_value_t;
50 typedef intptr_t fifo_value_t;
51
52 #define VADER_FIFO_FREE ((fifo_value_t)-2)
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 typedef struct vader_fifo_t {
70 atomic_fifo_value_t fifo_head;
71 atomic_fifo_value_t fifo_tail;
72 opal_atomic_int32_t fbox_available;
73 } vader_fifo_t;
74
75
76 #define MCA_BTL_VADER_FIFO_SIZE 128
77
78
79
80
81
82
83
84
85
86
87
88 static inline fifo_value_t virtual2relative (char *addr)
89 {
90 return (fifo_value_t) ((intptr_t) (addr - mca_btl_vader_component.my_segment)) | ((fifo_value_t)MCA_BTL_VADER_LOCAL_RANK << MCA_BTL_VADER_OFFSET_BITS);
91 }
92
93 static inline fifo_value_t virtual2relativepeer (struct mca_btl_base_endpoint_t *endpoint, char *addr)
94 {
95 return (fifo_value_t) ((intptr_t) (addr - endpoint->segment_base)) | ((fifo_value_t)endpoint->peer_smp_rank << MCA_BTL_VADER_OFFSET_BITS);
96 }
97
98 static inline void *relative2virtual (fifo_value_t offset)
99 {
100 return (void *)(intptr_t)((offset & MCA_BTL_VADER_OFFSET_MASK) + mca_btl_vader_component.endpoints[offset >> MCA_BTL_VADER_OFFSET_BITS].segment_base);
101 }
102
103 #include "btl_vader_fbox.h"
104
105
106
107
108
109
110
111
112
113
114
115
116
117 static inline mca_btl_vader_hdr_t *vader_fifo_read (vader_fifo_t *fifo, struct mca_btl_base_endpoint_t **ep)
118 {
119 mca_btl_vader_hdr_t *hdr;
120 fifo_value_t value;
121
122 if (VADER_FIFO_FREE == fifo->fifo_head) {
123 return NULL;
124 }
125
126 opal_atomic_rmb ();
127
128 value = fifo->fifo_head;
129
130 *ep = &mca_btl_vader_component.endpoints[value >> MCA_BTL_VADER_OFFSET_BITS];
131 hdr = (mca_btl_vader_hdr_t *) relative2virtual (value);
132
133 fifo->fifo_head = VADER_FIFO_FREE;
134
135 assert (hdr->next != value);
136
137 if (OPAL_UNLIKELY(VADER_FIFO_FREE == hdr->next)) {
138 opal_atomic_rmb();
139
140 if (!vader_item_compare_exchange (&fifo->fifo_tail, &value, VADER_FIFO_FREE)) {
141 while (VADER_FIFO_FREE == hdr->next) {
142 opal_atomic_rmb ();
143 }
144
145 fifo->fifo_head = hdr->next;
146 }
147 } else {
148 fifo->fifo_head = hdr->next;
149 }
150
151 opal_atomic_wmb ();
152 return hdr;
153 }
154
155 static inline void vader_fifo_init (vader_fifo_t *fifo)
156 {
157
158
159
160 fifo->fifo_head = VADER_FIFO_FREE;
161 fifo->fifo_tail = VADER_FIFO_FREE;
162 fifo->fbox_available = mca_btl_vader_component.fbox_max;
163 mca_btl_vader_component.my_fifo = fifo;
164 }
165
166 static inline void vader_fifo_write (vader_fifo_t *fifo, fifo_value_t value)
167 {
168 fifo_value_t prev;
169
170 opal_atomic_wmb ();
171 prev = vader_item_swap (&fifo->fifo_tail, value);
172 opal_atomic_rmb ();
173
174 assert (prev != value);
175
176 if (OPAL_LIKELY(VADER_FIFO_FREE != prev)) {
177 mca_btl_vader_hdr_t *hdr = (mca_btl_vader_hdr_t *) relative2virtual (prev);
178 hdr->next = value;
179 } else {
180 fifo->fifo_head = value;
181 }
182
183 opal_atomic_wmb ();
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 static inline bool vader_fifo_write_ep (mca_btl_vader_hdr_t *hdr, struct mca_btl_base_endpoint_t *ep)
198 {
199 fifo_value_t rhdr = virtual2relative ((char *) hdr);
200 if (ep->fbox_out.buffer) {
201
202
203 opal_atomic_wmb ();
204 return mca_btl_vader_fbox_sendi (ep, 0xfe, &rhdr, sizeof (rhdr), NULL, 0);
205 }
206 mca_btl_vader_try_fbox_setup (ep, hdr);
207 hdr->next = VADER_FIFO_FREE;
208 vader_fifo_write (ep->fifo, rhdr);
209
210 return true;
211 }
212
213
214
215
216
217
218
219
220
221
222
223
224 static inline void vader_fifo_write_back (mca_btl_vader_hdr_t *hdr, struct mca_btl_base_endpoint_t *ep)
225 {
226 hdr->next = VADER_FIFO_FREE;
227 vader_fifo_write(ep->fifo, virtual2relativepeer (ep, (char *) hdr));
228 }
229
230 #endif