This source file includes following definitions.
- mca_pml_bsend_alloc_segment
- mca_pml_base_bsend_init
- mca_pml_base_bsend_fini
- mca_pml_base_bsend_attach
- mca_pml_base_bsend_detach
- mca_pml_base_bsend_request_start
- mca_pml_base_bsend_request_alloc
- mca_pml_base_bsend_request_alloc_buf
- mca_pml_base_bsend_request_free
- mca_pml_base_bsend_request_fini
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 #include "ompi_config.h"
27 #include "opal/threads/mutex.h"
28 #include "opal/threads/condition.h"
29 #include "ompi/datatype/ompi_datatype.h"
30 #include "opal/mca/allocator/base/base.h"
31 #include "opal/mca/allocator/allocator.h"
32 #include "ompi/mca/pml/pml.h"
33 #include "ompi/mca/pml/base/pml_base_request.h"
34 #include "ompi/mca/pml/base/pml_base_sendreq.h"
35 #include "ompi/mca/pml/base/pml_base_bsend.h"
36 #include "opal/mca/mpool/mpool.h"
37
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 static opal_mutex_t mca_pml_bsend_mutex;
43 static opal_condition_t mca_pml_bsend_condition;
44 static mca_allocator_base_component_t* mca_pml_bsend_allocator_component;
45 static mca_allocator_base_module_t* mca_pml_bsend_allocator;
46 static size_t mca_pml_bsend_usersize;
47 unsigned char *mca_pml_bsend_userbase=NULL;
48 unsigned char *mca_pml_bsend_base = NULL;
49 unsigned char *mca_pml_bsend_addr = NULL;
50 static size_t mca_pml_bsend_size;
51 static size_t mca_pml_bsend_count;
52 static size_t mca_pml_bsend_pagesz;
53 static int mca_pml_bsend_pagebits;
54 static opal_atomic_int32_t mca_pml_bsend_init = 0;
55
56
57 extern char *ompi_pml_base_bsend_allocator_name;
58
59
60
61
62 static void* mca_pml_bsend_alloc_segment(void *ctx, size_t *size_inout)
63 {
64 void *addr;
65 size_t size = *size_inout;
66 if(mca_pml_bsend_addr + size > mca_pml_bsend_base + mca_pml_bsend_size) {
67 return NULL;
68 }
69
70 size = mca_pml_bsend_size - (mca_pml_bsend_addr - mca_pml_bsend_base);
71 addr = mca_pml_bsend_addr;
72 mca_pml_bsend_addr += size;
73 *size_inout = size;
74 return addr;
75 }
76
77
78
79
80 int mca_pml_base_bsend_init(bool thread_safe)
81 {
82 size_t tmp;
83
84 if(OPAL_THREAD_ADD_FETCH32(&mca_pml_bsend_init, 1) > 1)
85 return OMPI_SUCCESS;
86
87
88 OBJ_CONSTRUCT(&mca_pml_bsend_mutex, opal_mutex_t);
89 OBJ_CONSTRUCT(&mca_pml_bsend_condition, opal_condition_t);
90
91
92 if(NULL == (mca_pml_bsend_allocator_component = mca_allocator_component_lookup(ompi_pml_base_bsend_allocator_name))) {
93 return OMPI_ERR_BUFFER;
94 }
95
96
97 tmp = mca_pml_bsend_pagesz = sysconf(_SC_PAGESIZE);
98 mca_pml_bsend_pagebits = 0;
99 while( tmp != 0 ) {
100 tmp >>= 1;
101 mca_pml_bsend_pagebits++;
102 }
103 return OMPI_SUCCESS;
104 }
105
106
107
108
109
110 int mca_pml_base_bsend_fini(void)
111 {
112 if(OPAL_THREAD_ADD_FETCH32(&mca_pml_bsend_init,-1) > 0)
113 return OMPI_SUCCESS;
114
115 if(NULL != mca_pml_bsend_allocator)
116 mca_pml_bsend_allocator->alc_finalize(mca_pml_bsend_allocator);
117 mca_pml_bsend_allocator = NULL;
118
119 OBJ_DESTRUCT(&mca_pml_bsend_condition);
120 OBJ_DESTRUCT(&mca_pml_bsend_mutex);
121 return OMPI_SUCCESS;
122 }
123
124
125
126
127
128 int mca_pml_base_bsend_attach(void* addr, int size)
129 {
130 int align;
131
132 bool thread_safe = ompi_mpi_thread_multiple;
133 if(NULL == addr || size <= 0) {
134 return OMPI_ERR_BUFFER;
135 }
136
137
138 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
139 if(NULL != mca_pml_bsend_allocator) {
140 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
141 return OMPI_ERR_BUFFER;
142 }
143
144
145 mca_pml_bsend_allocator = mca_pml_bsend_allocator_component->allocator_init(thread_safe, mca_pml_bsend_alloc_segment, NULL, NULL);
146 if(NULL == mca_pml_bsend_allocator) {
147 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
148 return OMPI_ERR_BUFFER;
149 }
150
151
152
153
154
155 mca_pml_bsend_userbase = (unsigned char*)addr;
156 mca_pml_bsend_usersize = size;
157
158
159
160
161 align = sizeof(void *) - ((size_t)addr & (sizeof(void *) - 1));
162
163
164 mca_pml_bsend_base = (unsigned char *)addr + align;
165 mca_pml_bsend_addr = (unsigned char *)addr + align;
166 mca_pml_bsend_size = size - align;
167 mca_pml_bsend_count = 0;
168 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
169 return OMPI_SUCCESS;
170 }
171
172
173
174
175 int mca_pml_base_bsend_detach(void* addr, int* size)
176 {
177 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
178
179
180 if(NULL == mca_pml_bsend_allocator) {
181 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
182 return OMPI_ERR_BUFFER;
183 }
184
185
186 while(mca_pml_bsend_count != 0)
187 opal_condition_wait(&mca_pml_bsend_condition, &mca_pml_bsend_mutex);
188
189
190 mca_pml_bsend_allocator->alc_finalize(mca_pml_bsend_allocator);
191 mca_pml_bsend_allocator = NULL;
192
193
194 if(NULL != addr)
195 *((void**)addr) = mca_pml_bsend_userbase;
196 if(NULL != size)
197 *size = (int)mca_pml_bsend_usersize;
198
199
200 mca_pml_bsend_userbase = NULL;
201 mca_pml_bsend_usersize = 0;
202 mca_pml_bsend_base = NULL;
203 mca_pml_bsend_addr = NULL;
204 mca_pml_bsend_size = 0;
205 mca_pml_bsend_count = 0;
206 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
207 return OMPI_SUCCESS;
208 }
209
210
211
212
213
214
215 int mca_pml_base_bsend_request_start(ompi_request_t* request)
216 {
217 mca_pml_base_send_request_t* sendreq = (mca_pml_base_send_request_t*)request;
218 struct iovec iov;
219 unsigned int iov_count;
220 size_t max_data;
221 int rc;
222
223 if(sendreq->req_bytes_packed > 0) {
224
225
226 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
227 if(NULL == mca_pml_bsend_addr) {
228 sendreq->req_addr = NULL;
229 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
230 return OMPI_ERR_BUFFER;
231 }
232
233
234 sendreq->req_addr = mca_pml_bsend_allocator->alc_alloc(
235 mca_pml_bsend_allocator, sendreq->req_bytes_packed, 0);
236 if(NULL == sendreq->req_addr) {
237
238 sendreq->req_base.req_pml_complete = true;
239 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
240 return OMPI_ERR_BUFFER;
241 }
242
243 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
244
245
246
247
248 iov.iov_base = (IOVBASE_TYPE*)sendreq->req_addr;
249 iov.iov_len = sendreq->req_bytes_packed;
250 iov_count = 1;
251 max_data = iov.iov_len;
252 if((rc = opal_convertor_pack( &sendreq->req_base.req_convertor,
253 &iov,
254 &iov_count,
255 &max_data )) < 0) {
256 return OMPI_ERROR;
257 }
258
259
260 opal_convertor_prepare_for_send( &sendreq->req_base.req_convertor, &(ompi_mpi_packed.dt.super),
261 max_data, sendreq->req_addr );
262
263 mca_pml_bsend_count++;
264 }
265
266 return OMPI_SUCCESS;
267 }
268
269
270
271
272
273
274 int mca_pml_base_bsend_request_alloc(ompi_request_t* request)
275 {
276 mca_pml_base_send_request_t* sendreq = (mca_pml_base_send_request_t*)request;
277
278 assert( sendreq->req_bytes_packed > 0 );
279
280
281 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
282 if(NULL == mca_pml_bsend_addr) {
283 sendreq->req_addr = NULL;
284 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
285 return OMPI_ERR_BUFFER;
286 }
287
288
289 sendreq->req_addr = mca_pml_bsend_allocator->alc_alloc(
290 mca_pml_bsend_allocator, sendreq->req_bytes_packed, 0);
291 if(NULL == sendreq->req_addr) {
292
293 sendreq->req_base.req_pml_complete = true;
294 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
295
296
297 opal_progress();
298 return OMPI_ERR_BUFFER;
299 }
300
301
302 mca_pml_bsend_count++;
303 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
304
305 return OMPI_SUCCESS;
306 }
307
308
309
310
311
312 void* mca_pml_base_bsend_request_alloc_buf( size_t length )
313 {
314 void* buf = NULL;
315
316 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
317 if(NULL == mca_pml_bsend_addr) {
318 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
319 return NULL;
320 }
321
322
323 buf = mca_pml_bsend_allocator->alc_alloc(
324 mca_pml_bsend_allocator, length, 0);
325 if(NULL == buf) {
326
327 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
328
329
330 opal_progress();
331 return NULL;
332 }
333
334
335 mca_pml_bsend_count++;
336 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
337
338 return buf;
339 }
340
341
342
343
344
345 int mca_pml_base_bsend_request_free(void* addr)
346 {
347
348 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
349
350
351 mca_pml_bsend_allocator->alc_free(mca_pml_bsend_allocator, addr);
352
353
354 if(--mca_pml_bsend_count == 0)
355 opal_condition_signal(&mca_pml_bsend_condition);
356
357 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
358 return OMPI_SUCCESS;
359 }
360
361
362
363
364
365
366 int mca_pml_base_bsend_request_fini(ompi_request_t* request)
367 {
368 mca_pml_base_send_request_t* sendreq = (mca_pml_base_send_request_t*)request;
369 if(sendreq->req_bytes_packed == 0 ||
370 sendreq->req_addr == NULL ||
371 sendreq->req_addr == sendreq->req_base.req_addr)
372 return OMPI_SUCCESS;
373
374
375 OPAL_THREAD_LOCK(&mca_pml_bsend_mutex);
376
377
378 mca_pml_bsend_allocator->alc_free(mca_pml_bsend_allocator, (void *)sendreq->req_addr);
379 sendreq->req_addr = sendreq->req_base.req_addr;
380
381
382 if(--mca_pml_bsend_count == 0)
383 opal_condition_signal(&mca_pml_bsend_condition);
384
385 OPAL_THREAD_UNLOCK(&mca_pml_bsend_mutex);
386 return OMPI_SUCCESS;
387 }
388
389