This source file includes following definitions.
- ompi_mtl_portals4_recv_block_progress
- ompi_mtl_portals4_recv_short_block_alloc
- ompi_mtl_portals4_recv_short_block_free
- ompi_mtl_portals4_activate_block
- ompi_mtl_portals4_recv_short_init
- ompi_mtl_portals4_recv_short_fini
- ompi_mtl_portals4_recv_short_link
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "ompi_config.h"
22
23 #include "ompi/constants.h"
24
25 #include "mtl_portals4.h"
26 #include "mtl_portals4_recv_short.h"
27
28
29 OBJ_CLASS_INSTANCE(ompi_mtl_portals4_recv_short_block_t,
30 opal_list_item_t,
31 NULL, NULL);
32
33 static inline int ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block);
34 static int ompi_mtl_portals4_recv_short_block_free(ompi_mtl_portals4_recv_short_block_t *block);
35
36 static int
37 ompi_mtl_portals4_recv_block_progress(ptl_event_t *ev,
38 ompi_mtl_portals4_base_request_t* ptl_base_request)
39 {
40 int ret = OMPI_SUCCESS;
41 ompi_mtl_portals4_recv_short_request_t *ptl_request =
42 (ompi_mtl_portals4_recv_short_request_t*) ptl_base_request;
43 ompi_mtl_portals4_recv_short_block_t *block = ptl_request->block;
44
45 switch (ev->type) {
46 case PTL_EVENT_AUTO_FREE:
47 OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
48 switch (block->status) {
49 case BLOCK_STATUS_ACTIVATED:
50 block->status = BLOCK_STATUS_WAITING_UNLINK;
51 ompi_mtl_portals4.active_recv_short_blocks--;
52 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
53 OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
54 "mtl:portals4 PTL_EVENT_AUTO_FREE received before PTL_EVENT_AUTO_UNLINK"));
55 break;
56
57 case BLOCK_STATUS_WAITING_FREE:
58 if (OPAL_UNLIKELY(block->release_on_free)) {
59 opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
60 &block->base);
61 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
62 ret = ompi_mtl_portals4_recv_short_block_free(block);
63 } else {
64 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
65 ret = ompi_mtl_portals4_activate_block(block);
66 }
67 break;
68
69 default:
70 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
71 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
72 "%s:%d: Bad status (%d) when receiving PTL_EVENT_AUTO_FREE",
73 __FILE__, __LINE__, block->status);
74 break;
75 }
76
77 break;
78
79 case PTL_EVENT_AUTO_UNLINK:
80 block->me_h = PTL_INVALID_HANDLE;
81 OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
82 switch (block->status) {
83 case BLOCK_STATUS_ACTIVATED:
84 block->status = BLOCK_STATUS_WAITING_FREE;
85 ompi_mtl_portals4.active_recv_short_blocks--;
86 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
87 break;
88
89 case BLOCK_STATUS_WAITING_UNLINK:
90 if (OPAL_UNLIKELY(block->release_on_free)) {
91 opal_list_remove_item(&ompi_mtl_portals4.recv_short_blocks,
92 &block->base);
93 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
94 ret = ompi_mtl_portals4_recv_short_block_free(block);
95 } else {
96 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
97 OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
98 "mtl:portals4 PTL_EVENT_AUTO_UNLINK received after PTL_EVENT_AUTO_FREE"));
99 ret = ompi_mtl_portals4_activate_block(block);
100 }
101 break;
102
103 default:
104 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
105 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
106 "%s:%d: Bad status (%d) when receiving PTL_EVENT_AUTO_UNLINK",
107 __FILE__, __LINE__, block->status);
108 break;
109 }
110
111 break;
112
113 case PTL_EVENT_LINK:
114 OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
115 switch (block->status) {
116 case BLOCK_STATUS_WAITING_LINK:
117 block->status = BLOCK_STATUS_ACTIVATED;
118 ompi_mtl_portals4.active_recv_short_blocks++;
119 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
120 break;
121
122 default:
123 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
124 opal_output_verbose(1, ompi_mtl_base_framework.framework_output,
125 "%s:%d: Bad status (%d) when receiving PTL_EVENT_LINK",
126 __FILE__, __LINE__, block->status);
127 break;
128 }
129
130 break;
131
132 default:
133 OPAL_OUTPUT_VERBOSE((50, ompi_mtl_base_framework.framework_output,
134 "Other EVENT %d, hdr_data = %lx", ev->type, (long unsigned) ev->hdr_data));
135 break;
136 }
137
138 return ret;
139 }
140
141
142 static ompi_mtl_portals4_recv_short_block_t*
143 ompi_mtl_portals4_recv_short_block_alloc(bool release_on_free)
144 {
145 ompi_mtl_portals4_recv_short_block_t *block;
146
147 block = OBJ_NEW(ompi_mtl_portals4_recv_short_block_t);
148 block->start = malloc(ompi_mtl_portals4.recv_short_size);
149 block->status = BLOCK_STATUS_INACTIVE;
150 if (block->start == NULL) return NULL;
151
152 block->me_h = PTL_INVALID_HANDLE;
153 block->request.block = block;
154 block->request.super.type = portals4_req_recv_short;
155 block->request.super.event_callback = ompi_mtl_portals4_recv_block_progress;
156 block->release_on_free = release_on_free;
157
158 return block;
159 }
160
161
162 static int
163 ompi_mtl_portals4_recv_short_block_free(ompi_mtl_portals4_recv_short_block_t *block)
164 {
165 if (PTL_INVALID_HANDLE != block->me_h) {
166 PtlMEUnlink(block->me_h);
167 block->me_h = PTL_INVALID_HANDLE;
168 }
169
170 if (NULL != block->start) {
171 free(block->start);
172 block->start = NULL;
173 }
174
175 OBJ_RELEASE(block);
176
177 return OMPI_SUCCESS;
178 }
179
180
181 static inline int
182 ompi_mtl_portals4_activate_block(ompi_mtl_portals4_recv_short_block_t *block)
183 {
184 ptl_match_bits_t match_bits = MTL_PORTALS4_SHORT_MSG;
185 ptl_match_bits_t ignore_bits;
186 ptl_me_t me;
187 int ret;
188
189 ignore_bits = MTL_PORTALS4_CONTEXT_MASK | MTL_PORTALS4_SOURCE_MASK | MTL_PORTALS4_TAG_MASK;
190
191 me.start = block->start;
192 me.length = ompi_mtl_portals4.recv_short_size;
193 me.ct_handle = PTL_CT_NONE;
194 me.min_free = ompi_mtl_portals4.short_limit;
195 me.uid = ompi_mtl_portals4.uid;
196 me.options =
197 PTL_ME_OP_PUT |
198 PTL_ME_EVENT_COMM_DISABLE |
199 PTL_ME_MANAGE_LOCAL |
200 PTL_ME_MAY_ALIGN;
201 if (ompi_mtl_portals4.use_logical) {
202 me.match_id.rank = PTL_RANK_ANY;
203 } else {
204 me.match_id.phys.nid = PTL_NID_ANY;
205 me.match_id.phys.pid = PTL_PID_ANY;
206 }
207 me.match_bits = match_bits;
208 me.ignore_bits = ignore_bits;
209
210 OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
211 block->status = BLOCK_STATUS_WAITING_LINK;
212 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
213
214 ret = PtlMEAppend(ompi_mtl_portals4.ni_h,
215 ompi_mtl_portals4.recv_idx,
216 &me,
217 PTL_OVERFLOW_LIST,
218 &block->request,
219 &block->me_h);
220 if (OPAL_LIKELY(ret == PTL_OK)) {
221 ret = OMPI_SUCCESS;
222 } else {
223 ret = ompi_mtl_portals4_get_error(ret);
224 }
225
226 return ret;
227 }
228
229
230 int
231 ompi_mtl_portals4_recv_short_init(void)
232 {
233 int ret = OMPI_SUCCESS;
234 uint32_t i;
235
236 OBJ_CONSTRUCT(&ompi_mtl_portals4.short_block_mutex, opal_mutex_t);
237 OBJ_CONSTRUCT(&(ompi_mtl_portals4.recv_short_blocks), opal_list_t);
238
239
240 for (i = 0 ; i < ompi_mtl_portals4.recv_short_num ; ++i) {
241 ompi_mtl_portals4_recv_short_block_t *block =
242 ompi_mtl_portals4_recv_short_block_alloc(false);
243 if (OPAL_UNLIKELY(NULL == block)) {
244 return OMPI_ERR_OUT_OF_RESOURCE;
245 }
246 opal_list_append(&ompi_mtl_portals4.recv_short_blocks,
247 &block->base);
248 ret = ompi_mtl_portals4_activate_block(block);
249 }
250
251 return ret;
252 }
253
254
255 int
256 ompi_mtl_portals4_recv_short_fini(void)
257 {
258 opal_list_item_t *item;
259 int ret = OMPI_SUCCESS;
260
261 OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
262 while (NULL != (item = opal_list_remove_first(&ompi_mtl_portals4.recv_short_blocks))) {
263 ompi_mtl_portals4_recv_short_block_t *block =
264 (ompi_mtl_portals4_recv_short_block_t*) item;
265 ret = ompi_mtl_portals4_recv_short_block_free(block);
266 ompi_mtl_portals4.active_recv_short_blocks--;
267 }
268 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
269
270 return ret;
271 }
272
273
274 int
275 ompi_mtl_portals4_recv_short_link(int count)
276 {
277 int ret = OMPI_SUCCESS;
278 int active = ompi_mtl_portals4.active_recv_short_blocks;
279 int i;
280
281 if (active < count) {
282 for (i = 0 ; i < (count - active) ; ++i) {
283 ompi_mtl_portals4_recv_short_block_t *block =
284 ompi_mtl_portals4_recv_short_block_alloc(true);
285 if (NULL == block) {
286 return OMPI_ERR_OUT_OF_RESOURCE;
287 }
288 OPAL_THREAD_LOCK(&ompi_mtl_portals4.short_block_mutex);
289 opal_list_append(&ompi_mtl_portals4.recv_short_blocks,
290 &block->base);
291 OPAL_OUTPUT_VERBOSE((10, ompi_mtl_base_framework.framework_output,
292 "recv_short_link: total=%d active=%d",
293 (int) opal_list_get_size(&ompi_mtl_portals4.recv_short_blocks), ompi_mtl_portals4.active_recv_short_blocks));
294 OPAL_THREAD_UNLOCK(&ompi_mtl_portals4.short_block_mutex);
295 ret = ompi_mtl_portals4_activate_block(block);
296 }
297 }
298
299 return ret;
300 }