1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 *
4 * (C) 2001 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
6 */
7
8 #include "mpiimpl.h"
9
10 #undef FUNCNAME
11 #define FUNCNAME MPIR_Progress_wait_request
12 #undef FCNAME
13 #define FCNAME MPIU_QUOTE(FUNCNAME)
14 /*@
15 MPIR_Progress_wait_request
16
17 A helper routine that implements the very common case of running the progress
18 engine until the given request is complete.
19 @*/
MPIR_Progress_wait_request(MPID_Request * req)20 int MPIR_Progress_wait_request(MPID_Request *req)
21 {
22 int mpi_errno = MPI_SUCCESS;
23
24 if (!MPID_Request_is_complete(req))
25 {
26 MPID_Progress_state progress_state;
27
28 MPID_Progress_start(&progress_state);
29 while (!MPID_Request_is_complete(req))
30 {
31 mpi_errno = MPID_Progress_wait(&progress_state);
32 if (mpi_errno != MPI_SUCCESS)
33 {
34 /* --BEGIN ERROR HANDLING-- */
35 MPID_Progress_end(&progress_state);
36 if (mpi_errno) MPIU_ERR_POP(mpi_errno);
37 /* --END ERROR HANDLING-- */
38 }
39 }
40 MPID_Progress_end(&progress_state);
41 }
42 fn_fail: /* no special err handling at this level */
43 fn_exit:
44 return mpi_errno;
45 }
46
47 #undef FUNCNAME
48 #define FUNCNAME MPIR_Request_complete
49 #undef FCNAME
50 #define FCNAME MPIU_QUOTE(FUNCNAME)
51 /* Complete a request, saving the status data if necessary.
52 "active" has meaning only if the request is a persistent request; this
53 allows the completion routines to indicate that a persistent request
54 was inactive and did not require any extra completion operation.
55
56 If debugger information is being provided for pending (user-initiated)
57 send operations, the macros MPIR_SENDQ_FORGET will be defined to
58 call the routine MPIR_Sendq_forget; otherwise that macro will be a no-op.
59 The implementation of the MPIR_Sendq_xxx is in src/mpi/debugger/dbginit.c .
60 */
MPIR_Request_complete(MPI_Request * request,MPID_Request * request_ptr,MPI_Status * status,int * active)61 int MPIR_Request_complete(MPI_Request * request, MPID_Request * request_ptr,
62 MPI_Status * status, int * active)
63 {
64 int mpi_errno = MPI_SUCCESS;
65
66 *active = TRUE;
67 switch(request_ptr->kind)
68 {
69 case MPID_REQUEST_SEND:
70 {
71 if (status != MPI_STATUS_IGNORE)
72 {
73 status->cancelled = request_ptr->status.cancelled;
74 }
75 mpi_errno = request_ptr->status.MPI_ERROR;
76 /* FIXME: are Ibsend requests added to the send queue? */
77 MPIR_SENDQ_FORGET(request_ptr);
78 MPID_Request_release(request_ptr);
79 *request = MPI_REQUEST_NULL;
80 break;
81 }
82 case MPID_REQUEST_RECV:
83 {
84 MPIR_Request_extract_status(request_ptr, status);
85 mpi_errno = request_ptr->status.MPI_ERROR;
86 MPID_Request_release(request_ptr);
87 *request = MPI_REQUEST_NULL;
88 break;
89 }
90
91 case MPID_PREQUEST_SEND:
92 {
93 if (request_ptr->partner_request != NULL)
94 {
95 MPID_Request * prequest_ptr = request_ptr->partner_request;
96
97 /* reset persistent request to inactive state */
98 MPID_cc_set(&request_ptr->cc, 0);
99 request_ptr->cc_ptr = &request_ptr->cc;
100 request_ptr->partner_request = NULL;
101
102 if (prequest_ptr->kind != MPID_UREQUEST)
103 {
104 if (status != MPI_STATUS_IGNORE)
105 {
106 status->cancelled = prequest_ptr->status.cancelled;
107 }
108 mpi_errno = prequest_ptr->status.MPI_ERROR;
109 }
110 else
111 {
112 /* This is needed for persistent Bsend requests */
113 int rc;
114
115 rc = MPIR_Grequest_query(prequest_ptr);
116 if (mpi_errno == MPI_SUCCESS)
117 {
118 mpi_errno = rc;
119 }
120 if (status != MPI_STATUS_IGNORE)
121 {
122 status->cancelled = prequest_ptr->status.cancelled;
123 }
124 if (mpi_errno == MPI_SUCCESS)
125 {
126 mpi_errno = prequest_ptr->status.MPI_ERROR;
127 }
128 rc = MPIR_Grequest_free(prequest_ptr);
129 if (mpi_errno == MPI_SUCCESS)
130 {
131 mpi_errno = rc;
132 }
133 }
134
135 /* FIXME: MPIR_SENDQ_FORGET(request_ptr); -- it appears that
136 persistent sends are not currently being added to the send
137 queue. should they be, or should this release be
138 conditional? */
139 MPID_Request_release(prequest_ptr);
140 }
141 else
142 {
143 if (request_ptr->status.MPI_ERROR != MPI_SUCCESS)
144 {
145 /* if the persistent request failed to start then make the
146 error code available */
147 if (status != MPI_STATUS_IGNORE)
148 {
149 status->cancelled = FALSE;
150 }
151 mpi_errno = request_ptr->status.MPI_ERROR;
152 }
153 else
154 {
155 MPIR_Status_set_empty(status);
156 *active = FALSE;
157 }
158 }
159
160 break;
161 }
162
163 case MPID_PREQUEST_RECV:
164 {
165 if (request_ptr->partner_request != NULL)
166 {
167 MPID_Request * prequest_ptr = request_ptr->partner_request;
168
169 /* reset persistent request to inactive state */
170 MPID_cc_set(&request_ptr->cc, 0);
171 request_ptr->cc_ptr = &request_ptr->cc;
172 request_ptr->partner_request = NULL;
173
174 MPIR_Request_extract_status(prequest_ptr, status);
175 mpi_errno = prequest_ptr->status.MPI_ERROR;
176
177 MPID_Request_release(prequest_ptr);
178 }
179 else
180 {
181 MPIR_Status_set_empty(status);
182 /* --BEGIN ERROR HANDLING-- */
183 if (request_ptr->status.MPI_ERROR != MPI_SUCCESS)
184 {
185 /* if the persistent request failed to start then make the
186 error code available */
187 mpi_errno = request_ptr->status.MPI_ERROR;
188 }
189 else
190 {
191 *active = FALSE;
192 }
193 /* --END ERROR HANDLING-- */
194 }
195
196 break;
197 }
198
199 case MPID_UREQUEST:
200 {
201 int rc;
202
203 rc = MPIR_Grequest_query(request_ptr);
204 if (mpi_errno == MPI_SUCCESS)
205 {
206 mpi_errno = rc;
207 }
208 MPIR_Request_extract_status(request_ptr, status);
209 rc = MPIR_Grequest_free(request_ptr);
210 if (mpi_errno == MPI_SUCCESS)
211 {
212 mpi_errno = rc;
213 }
214
215 MPID_Request_release(request_ptr);
216 *request = MPI_REQUEST_NULL;
217
218 break;
219 }
220
221 case MPID_COLL_REQUEST:
222 {
223 MPIR_Request_extract_status(request_ptr, status);
224 MPID_Request_release(request_ptr);
225 *request = MPI_REQUEST_NULL;
226 break;
227 }
228
229 default:
230 {
231 /* --BEGIN ERROR HANDLING-- */
232 /* This should not happen */
233 MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
234 "**badcase %d", request_ptr->kind);
235 break;
236 /* --END ERROR HANDLING-- */
237 }
238 }
239
240 return mpi_errno;
241 }
242
243
244 #undef FUNCNAME
245 #define FUNCNAME MPIR_Request_get_error
246 #undef FCNAME
247 #define FCNAME MPIU_QUOTE(FUNCNAME)
248 /* FIXME: What is this routine for?
249 *
250 * [BRT] it is used by testall, although looking at testall now, I think the
251 * algorithm can be change slightly and eliminate the need for this routine
252 */
MPIR_Request_get_error(MPID_Request * request_ptr)253 int MPIR_Request_get_error(MPID_Request * request_ptr)
254 {
255 int mpi_errno = MPI_SUCCESS;
256
257 switch(request_ptr->kind)
258 {
259 case MPID_REQUEST_SEND:
260 case MPID_REQUEST_RECV:
261 case MPID_COLL_REQUEST:
262 {
263 mpi_errno = request_ptr->status.MPI_ERROR;
264 break;
265 }
266
267 case MPID_PREQUEST_SEND:
268 {
269 if (request_ptr->partner_request != NULL)
270 {
271 if (request_ptr->partner_request->kind == MPID_UREQUEST)
272 {
273 /* This is needed for persistent Bsend requests */
274 mpi_errno = MPIR_Grequest_query(
275 request_ptr->partner_request);
276 }
277 if (mpi_errno == MPI_SUCCESS)
278 {
279 mpi_errno = request_ptr->partner_request->status.MPI_ERROR;
280 }
281 }
282 else
283 {
284 mpi_errno = request_ptr->status.MPI_ERROR;
285 }
286
287 break;
288 }
289
290 case MPID_PREQUEST_RECV:
291 {
292 if (request_ptr->partner_request != NULL)
293 {
294 mpi_errno = request_ptr->partner_request->status.MPI_ERROR;
295 }
296 else
297 {
298 mpi_errno = request_ptr->status.MPI_ERROR;
299 }
300
301 break;
302 }
303
304 case MPID_UREQUEST:
305 {
306 int rc;
307
308 /* Note that we've acquired the thread private storage above */
309
310 switch (request_ptr->greq_fns->greq_lang)
311 {
312 case MPID_LANG_C:
313 #ifdef HAVE_CXX_BINDING
314 case MPID_LANG_CXX:
315 #endif
316 rc = (request_ptr->greq_fns->query_fn)(
317 request_ptr->greq_fns->grequest_extra_state,
318 &request_ptr->status);
319 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno,
320 MPI_ERR_OTHER,;, "**user", "**userquery %d", rc);
321 break;
322 #ifdef HAVE_FORTRAN_BINDING
323 case MPID_LANG_FORTRAN:
324 case MPID_LANG_FORTRAN90:
325 {
326 MPI_Fint ierr;
327 MPI_Fint is[sizeof(MPI_Status)/sizeof(int)];
328 ((MPIR_Grequest_f77_query_function*)(request_ptr->greq_fns->query_fn))(
329 request_ptr->greq_fns->grequest_extra_state, is,
330 &ierr );
331 rc = (int) ierr;
332 if (rc == MPI_SUCCESS)
333 PMPI_Status_f2c( is, &request_ptr->status );
334 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno,
335 MPI_ERR_OTHER,;, "**user", "**userquery %d", rc);
336 break;
337 }
338 #endif
339
340 default:
341 {
342 /* --BEGIN ERROR HANDLING-- */
343 /* This should not happen */
344 MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;,
345 "**badcase",
346 "**badcase %d", request_ptr->greq_fns->greq_lang);
347 break;
348 /* --END ERROR HANDLING-- */
349 }
350 }
351
352 break;
353 }
354
355 default:
356 {
357 /* --BEGIN ERROR HANDLING-- */
358 /* This should not happen */
359 MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
360 "**badcase %d", request_ptr->kind);
361 break;
362 /* --END ERROR HANDLING-- */
363 }
364 }
365
366 return mpi_errno;
367 }
368
369 #ifdef HAVE_FORTRAN_BINDING
370 /* Set the language type to Fortran for this (generalized) request */
MPIR_Grequest_set_lang_f77(MPI_Request greq)371 void MPIR_Grequest_set_lang_f77( MPI_Request greq )
372 {
373 MPID_Request *greq_ptr;
374
375 MPID_Request_get_ptr( greq, greq_ptr );
376
377 greq_ptr->greq_fns->greq_lang = MPID_LANG_FORTRAN;
378 }
379 #endif
380
381
382 #undef FUNCNAME
383 #define FUNCNAME MPIR_Grequest_cancel
384 #undef FCNAME
385 #define FCNAME MPIU_QUOTE(FUNCNAME)
MPIR_Grequest_cancel(MPID_Request * request_ptr,int complete)386 int MPIR_Grequest_cancel(MPID_Request * request_ptr, int complete)
387 {
388 int rc;
389 int mpi_errno = MPI_SUCCESS;
390
391 switch (request_ptr->greq_fns->greq_lang)
392 {
393 case MPID_LANG_C:
394 #ifdef HAVE_CXX_BINDING
395 case MPID_LANG_CXX:
396 #endif
397 rc = (request_ptr->greq_fns->cancel_fn)(
398 request_ptr->greq_fns->grequest_extra_state, complete);
399 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno,
400 MPI_ERR_OTHER,;, "**user", "**usercancel %d", rc);
401 break;
402 #ifdef HAVE_FORTRAN_BINDING
403 case MPID_LANG_FORTRAN:
404 case MPID_LANG_FORTRAN90:
405 {
406 MPI_Fint ierr;
407 MPI_Fint icomplete = complete;
408
409 ((MPIR_Grequest_f77_cancel_function *)(request_ptr->greq_fns->cancel_fn))(
410 request_ptr->greq_fns->grequest_extra_state, &icomplete, &ierr);
411 rc = (int) ierr;
412 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
413 {;}, "**user", "**usercancel %d", rc);
414 break;
415 }
416 #endif
417
418 default:
419 {
420 /* --BEGIN ERROR HANDLING-- */
421 /* This should not happen */
422 MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
423 "**badcase %d", request_ptr->greq_fns->greq_lang);
424 break;
425 /* --END ERROR HANDLING-- */
426 }
427 }
428
429 return mpi_errno;
430 }
431
432
433 #undef FUNCNAME
434 #define FUNCNAME MPIR_Grequest_query
435 #undef FCNAME
436 #define FCNAME MPIU_QUOTE(FUNCNAME)
MPIR_Grequest_query(MPID_Request * request_ptr)437 int MPIR_Grequest_query(MPID_Request * request_ptr)
438 {
439 int rc;
440 int mpi_errno = MPI_SUCCESS;
441
442 switch (request_ptr->greq_fns->greq_lang)
443 {
444 case MPID_LANG_C:
445 #ifdef HAVE_CXX_BINDING
446 case MPID_LANG_CXX:
447 #endif
448 rc = (request_ptr->greq_fns->query_fn)(request_ptr->greq_fns->grequest_extra_state,
449 &request_ptr->status);
450 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
451 {;}, "**user", "**userquery %d", rc);
452 break;
453 #ifdef HAVE_FORTRAN_BINDING
454 case MPID_LANG_FORTRAN:
455 case MPID_LANG_FORTRAN90:
456 {
457 MPI_Fint ierr;
458 MPI_Fint is[sizeof(MPI_Status)/sizeof(int)];
459 ((MPIR_Grequest_f77_query_function *)(request_ptr->greq_fns->query_fn))(
460 request_ptr->greq_fns->grequest_extra_state, is, &ierr );
461 rc = (int)ierr;
462 if (rc == MPI_SUCCESS)
463 PMPI_Status_f2c( is, &request_ptr->status );
464 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
465 {;}, "**user", "**userquery %d", rc);
466 }
467 break;
468 #endif
469 default:
470 {
471 /* --BEGIN ERROR HANDLING-- */
472 /* This should not happen */
473 MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN,;, "**badcase",
474 "**badcase %d", request_ptr->greq_fns->greq_lang);
475 break;
476 /* --END ERROR HANDLING-- */
477 }
478 }
479
480 return mpi_errno;
481 }
482
483
484 #undef FUNCNAME
485 #define FUNCNAME MPIR_Grequest_free
486 #undef FCNAME
487 #define FCNAME MPIU_QUOTE(FUNCNAME)
MPIR_Grequest_free(MPID_Request * request_ptr)488 int MPIR_Grequest_free(MPID_Request * request_ptr)
489 {
490 int rc;
491 int mpi_errno = MPI_SUCCESS;
492
493 switch (request_ptr->greq_fns->greq_lang)
494 {
495 case MPID_LANG_C:
496 #ifdef HAVE_CXX_BINDING
497 case MPID_LANG_CXX:
498 #endif
499 rc = (request_ptr->greq_fns->free_fn)(request_ptr->greq_fns->grequest_extra_state);
500 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
501 {;}, "**user", "**userfree %d", rc);
502 break;
503 #ifdef HAVE_FORTRAN_BINDING
504 case MPID_LANG_FORTRAN:
505 case MPID_LANG_FORTRAN90:
506 {
507 MPI_Fint ierr;
508
509 ((MPIR_Grequest_f77_free_function *)(request_ptr->greq_fns->free_fn))(
510 request_ptr->greq_fns->grequest_extra_state, &ierr);
511 rc = (int) ierr;
512 MPIU_ERR_CHKANDSTMT1((rc != MPI_SUCCESS), mpi_errno, MPI_ERR_OTHER,
513 {;}, "**user", "**userfree %d", rc);
514 break;
515 }
516 #endif
517
518 default:
519 {
520 /* --BEGIN ERROR HANDLING-- */
521 /* This should not happen */
522 MPIU_ERR_SETANDSTMT1(mpi_errno, MPI_ERR_INTERN, {;}, "**badcase",
523 "**badcase %d", request_ptr->greq_fns->greq_lang);
524 break;
525 /* --END ERROR HANDLING-- */
526 }
527 }
528
529 return mpi_errno;
530 }
531
532 /* MPIR_Grequest_progress_poke: Drives progess on generalized requests.
533 * Invokes poll_fn for each request in request_ptrs. Waits for completion of
534 * multiple requests if possible (all outstanding generalized requests are of
535 * same greq class) */
536 #undef FUNCNAME
537 #define FUNCNAME MPIR_Grequest_progress_poke
538 #undef FCNAME
539 #define FCNAME MPIU_QUOTE(FUNCNAME)
MPIR_Grequest_progress_poke(int count,MPID_Request ** request_ptrs,MPI_Status array_of_statuses[])540 int MPIR_Grequest_progress_poke(int count,
541 MPID_Request **request_ptrs,
542 MPI_Status array_of_statuses[] )
543 {
544 MPIX_Grequest_wait_function *wait_fn = NULL;
545 void ** state_ptrs;
546 int i, j, n_classes, n_native, n_greq;
547 int mpi_errno = MPI_SUCCESS;
548 MPIU_CHKLMEM_DECL(1);
549
550 MPIU_CHKLMEM_MALLOC(state_ptrs, void **, sizeof(void*) * count, mpi_errno, "state_ptrs");
551
552 /* This somewhat messy for-loop computes how many requests are native
553 * requests and how many are generalized requests, and how many generalized
554 * request classes those grequests are members of */
555 for (i=0, j=0, n_classes=1, n_native=0, n_greq=0; i< count; i++)
556 {
557 if (request_ptrs[i] == NULL || MPID_Request_is_complete(request_ptrs[i])) continue;
558 if (request_ptrs[i]->kind == MPID_UREQUEST)
559 {
560 n_greq += 1;
561 wait_fn = request_ptrs[i]->greq_fns->wait_fn;
562 state_ptrs[j] = request_ptrs[i]->greq_fns->grequest_extra_state;
563 j++;
564 if (i+1 < count) {
565 if (request_ptrs[i+1] == NULL ||
566 (request_ptrs[i]->greq_fns->greq_class !=
567 request_ptrs[i+1]->greq_fns->greq_class) )
568 n_classes += 1;
569 }
570 } else {
571 n_native += 1;
572 }
573 }
574
575 if (j > 0 && n_classes == 1 && wait_fn != NULL) {
576 mpi_errno = (wait_fn)(j, state_ptrs, 0, NULL);
577 } else {
578 for (i = 0; i< count; i++ )
579 {
580 if (request_ptrs[i] != NULL &&
581 request_ptrs[i]->kind == MPID_UREQUEST &&
582 !MPID_Request_is_complete(request_ptrs[i]) &&
583 request_ptrs[i]->greq_fns->poll_fn != NULL)
584 {
585 mpi_errno = (request_ptrs[i]->greq_fns->poll_fn)(request_ptrs[i]->greq_fns->grequest_extra_state, &(array_of_statuses[i]));
586 if (mpi_errno) MPIU_ERR_POP(mpi_errno);
587 }
588 }
589 }
590 fn_exit:
591 MPIU_CHKLMEM_FREEALL();
592 return mpi_errno;
593 fn_fail:
594 goto fn_exit;
595 }
596
597 /* MPIR_Grequest_wait: Waits until all generalized requests have
598 completed. This routine groups grequests by class and calls the
599 wait_fn on the whole class. */
600 #undef FUNCNAME
601 #define FUNCNAME MPIR_Grequest_waitall
602 #undef FCNAME
603 #define FCNAME MPIDI_QUOTE(FUNCNAME)
MPIR_Grequest_waitall(int count,MPID_Request * const * request_ptrs)604 int MPIR_Grequest_waitall(int count, MPID_Request * const * request_ptrs)
605 {
606 void ** state_ptrs;
607 int i;
608 int mpi_error = MPI_SUCCESS;
609 MPID_Progress_state progress_state;
610 MPIU_CHKLMEM_DECL(1);
611
612 MPIU_CHKLMEM_MALLOC(state_ptrs, void *, sizeof(void*)*count, mpi_error, "state_ptrs");
613
614 /* DISABLED CODE: The greq wait_fn function returns when ANY
615 of the requests completes, rather than all. Also, once a
616 greq has completed, you can't call wait on it again. So in
617 order to implement wait-all, we would need to rebuild the
618 state_ptrs array every time wait_fn completed. This would
619 then be an O(n^2) algorithm.
620
621 Until a waitall_fn is added for greqs, we'll call wait on
622 each greq individually. */
623 #if 0
624 MPIX_Grequest_wait_function *wait_fn = NULL;
625 int n_greq;
626 MPIX_Grequest_class curr_class;
627 /* loop over all requests, group greqs with the same class and
628 call wait_fn on the groups. (Only consecutive greqs with the
629 same class are being grouped) */
630 n_greq = 0;
631 for (i = 0; i < count; ++i)
632 {
633 /* skip over requests we're not interested in */
634 if (request_ptrs[i] == NULL || *request_ptrs[i]->cc_ptr == 0 || request_ptrs[i]->kind != MPID_UREQUEST)
635 continue;
636
637 if (n_greq == 0 || request_ptrs[i]->greq_fns->greq_class == curr_class)
638 {
639 /* if this is the first grequest of a group, or if it's the
640 same class as the last one, add its state to the list */
641 curr_class = request_ptrs[i]->greq_fns->greq_class;
642 wait_fn = request_ptrs[i]->greq_fns->wait_fn;
643 state_ptrs[n_greq] = request_ptrs[i]->greq_fns->grequest_extra_state;
644 ++n_greq;
645 }
646 else
647 {
648 /* greq with a new class: wait on the list of greqs we've
649 created, then start a new list*/
650 mpi_error = (wait_fn)(n_greq, state_ptrs, 0, NULL);
651 if (mpi_error) MPIU_ERR_POP(mpi_error);
652
653 curr_class = request_ptrs[i]->greq_fns->greq_class;
654 wait_fn = request_ptrs[i]->greq_fns->wait_fn;
655 state_ptrs[0] = request_ptrs[i]->greq_fns->grequest_extra_state;
656 n_greq = 1;
657 }
658 }
659
660 if (n_greq)
661 {
662 /* wait on the last group of greqs */
663 mpi_error = (wait_fn)(n_greq, state_ptrs, 0, NULL);
664 if (mpi_error) MPIU_ERR_POP(mpi_error);
665
666 }
667 #else
668 for (i = 0; i < count; ++i)
669 {
670 /* skip over requests we're not interested in */
671 if (request_ptrs[i] == NULL ||
672 MPID_Request_is_complete(request_ptrs[i]) ||
673 request_ptrs[i]->kind != MPID_UREQUEST ||
674 request_ptrs[i]->greq_fns->wait_fn == NULL)
675 {
676 continue;
677 }
678
679 mpi_error = (request_ptrs[i]->greq_fns->wait_fn)(1, &request_ptrs[i]->greq_fns->grequest_extra_state, 0, NULL);
680 if (mpi_error) MPIU_ERR_POP(mpi_error);
681 MPIU_Assert(MPID_Request_is_complete(request_ptrs[i]));
682 }
683
684 MPID_Progress_start(&progress_state);
685 for (i = 0; i < count; ++i)
686 {
687 if (request_ptrs[i] == NULL ||
688 MPID_Request_is_complete(request_ptrs[i]) ||
689 request_ptrs[i]->kind != MPID_UREQUEST)
690 {
691 continue;
692 }
693 /* We have a greq that doesn't have a wait function; some other
694 thread will cause completion via MPI_Grequest_complete(). Rather
695 than waste the time by simply yielding the processor to the
696 other thread, we'll make progress on regular requests too. The
697 progress engine should permit the other thread to run at some
698 point. */
699 while (!MPID_Request_is_complete(request_ptrs[i]))
700 {
701 mpi_error = MPID_Progress_wait(&progress_state);
702 if (mpi_error != MPI_SUCCESS)
703 {
704 /* --BEGIN ERROR HANDLING-- */
705 MPID_Progress_end(&progress_state);
706 goto fn_fail;
707 /* --END ERROR HANDLING-- */
708 }
709 }
710 }
711 MPID_Progress_end(&progress_state);
712 #endif
713
714 fn_exit:
715 MPIU_CHKLMEM_FREEALL();
716 return mpi_error;
717 fn_fail:
718 goto fn_exit;
719 }
720
721