-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/ch3u_recvq.c
-: 0:Graph:ch3u_recvq.gcno
-: 0:Data:ch3u_recvq.gcda
-: 0:Runs:4381
-: 0:Programs:1376
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: * (C) 2001 by Argonne National Laboratory.
-: 4: * See COPYRIGHT in top-level directory.
-: 5: */
-: 6:
-: 7:#include "mpidimpl.h"
-: 8:
-: 9:/* MPIDI_POSTED_RECV_ENQUEUE_HOOK(req): Notifies channel that req has
-: 10: been enqueued on the posted recv queue. Returns void. */
-: 11:#ifndef MPIDI_POSTED_RECV_ENQUEUE_HOOK
-: 12:#define MPIDI_POSTED_RECV_ENQUEUE_HOOK(req) do{}while(0)
-: 13:#endif
-: 14:/* MPIDI_POSTED_RECV_DEQUEUE_HOOK(req): Notifies channel that req has
-: 15: been dequeued from the posted recv queue. Returns non-zero if the
-: 16: channel has already matched the request; 0 otherwise. This happens
-: 17: when the channel supports shared-memory and network communication
-: 18: with a network capable of matching, and the same request is matched
-: 19: by the network and, e.g., shared-memory. When that happens the
-: 20: dequeue functions below should, either search for the next matching
-: 21: request, or report that no request was found. */
-: 22:#ifndef MPIDI_POSTED_RECV_DEQUEUE_HOOK
-: 23:#define MPIDI_POSTED_RECV_DEQUEUE_HOOK(req) 0
-: 24:#endif
-: 25:
-: 26:/* FIXME:
-: 27: * Recvq_lock/unlock removed because it is not needed for the SINGLE_CS
-: 28: * approach and we might want a different, non-lock-based approach in
-: 29: * a finer-grained thread-sync version. For example,
-: 30: * some routines can be implemented in a lock-free
-: 31: * fashion (because the user is required to guarantee non-conflicting
-: 32: * accesses, such as doing a probe and a receive that matches in different
-: 33: * threads).
-: 34: *
-: 35: * There are a lot of routines here. Do we really need them all?
-: 36: *
-: 37: * The search criteria can be implemented in a single 64 bit compare on
-: 38: * systems with efficient 64-bit operations. The rank and contextid can also
-: 39: * in many cases be combined into a single 32-bit word for the comparison
-: 40: * (in which case the message info should be stored in the queue in a
-: 41: * naturally aligned, 64-bit word.
-: 42: *
-: 43: */
-: 44:
-: 45:static MPID_Request * recvq_posted_head = 0;
-: 46:static MPID_Request * recvq_posted_tail = 0;
-: 47:static MPID_Request * recvq_unexpected_head = 0;
-: 48:static MPID_Request * recvq_unexpected_tail = 0;
-: 49:
-: 50:/* Export the location of the queue heads if debugger support is enabled.
-: 51: * This allows the queue code to rely on the local variables for the
-: 52: * queue heads while also exporting those variables to the debugger.
-: 53: * See src/mpi/debugger/dll_mpich2.c for how this is used to
-: 54: * access the message queues.
-: 55: */
-: 56:#ifdef HAVE_DEBUGGER_SUPPORT
-: 57:MPID_Request ** const MPID_Recvq_posted_head_ptr = &recvq_posted_head;
-: 58:MPID_Request ** const MPID_Recvq_unexpected_head_ptr = &recvq_unexpected_head;
-: 59:#endif
-: 60:
-: 61:/* If the MPIDI_Message_match structure fits into a pointer size, we
-: 62: * can directly work on it */
-: 63:/* MATCH_WITH_NO_MASK compares the match values without masking
-: 64: * them. This is useful for the case where there are no ANY_TAG or
-: 65: * ANY_SOURCE wild cards. */
-: 66:#define MATCH_WITH_NO_MASK(match1, match2) \
-: 67: ((sizeof(MPIDI_Message_match) == SIZEOF_VOID_P) ? ((match1).whole == (match2).whole) : \
-: 68: (((match1).parts.rank == (match2).parts.rank) && \
-: 69: ((match1).parts.tag == (match2).parts.tag) && \
-: 70: ((match1).parts.context_id == (match2).parts.context_id)))
-: 71:
-: 72:/* MATCH_WITH_LEFT_MASK compares the match values after masking only
-: 73: * the left field. This is useful for the case where the right match
-: 74: * is a part of the unexpected queue and has no ANY_TAG or ANY_SOURCE
-: 75: * wild cards, but the left match might have them. */
-: 76:#define MATCH_WITH_LEFT_MASK(match1, match2, mask) \
-: 77: ((sizeof(MPIDI_Message_match) == SIZEOF_VOID_P) ? \
-: 78: (((match1).whole & (mask).whole) == (match2).whole) : \
-: 79: ((((match1).parts.rank & (mask).parts.rank) == (match2).parts.rank) && \
-: 80: (((match1).parts.tag & (mask).parts.tag) == (match2).parts.tag) && \
-: 81: ((match1).parts.context_id == (match2).parts.context_id)))
-: 82:
-: 83:/* This is the most general case where both matches have to be
-: 84: * masked. Both matches are masked with the same value. There doesn't
-: 85: * seem to be a need for two different masks at this time. */
-: 86:#define MATCH_WITH_LEFT_RIGHT_MASK(match1, match2, mask) \
-: 87: ((sizeof(MPIDI_Message_match) == SIZEOF_VOID_P) ? \
-: 88: (((match1).whole & (mask).whole) == ((match2).whole & (mask).whole)) : \
-: 89: ((((match1).parts.rank & (mask).parts.rank) == ((match2).parts.rank & (mask).parts.rank)) && \
-: 90: (((match1).parts.tag & (mask).parts.tag) == ((match2).parts.tag & (mask).parts.tag)) && \
-: 91: ((match1).parts.context_id == (match2).parts.context_id)))
-: 92:
-: 93:
-: 94:/* FIXME: If this routine is only used by probe/iprobe, then we don't need
-: 95: to set the cancelled field in status (only set for nonblocking requests) */
-: 96:/*
-: 97: * MPIDI_CH3U_Recvq_FU()
-: 98: *
-: 99: * Search for a matching request in the unexpected receive queue. Return
-: 100: * true if one is found, false otherwise. If the status arguement is
-: 101: * not MPI_STATUS_IGNORE, return information about the request in that
-: 102: * parameter. This routine is used by mpid_probe and mpid_iprobe.
-: 103: *
-: 104: * Multithread - As this is a read-only routine, it need not
-: 105: * require an external critical section (careful organization of the
-: 106: * queue updates would not even require a critical section within this
-: 107: * routine). However, this routine is used both from within the progress
-: 108: * engine and from without it. To make that work with the current
-: 109: * design for MSGQUEUE and the brief-global mode, the critical section
-: 110: * is *outside* of this routine.
-: 111: *
-: 112: * This routine is used only in mpid_iprobe and mpid_probe
-: 113: *
-: 114: */
-: 115:#undef FUNCNAME
-: 116:#define FUNCNAME MPIDI_CH3U_Recvq_FU
-: 117:#undef FCNAME
-: 118:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 119:int MPIDI_CH3U_Recvq_FU(int source, int tag, int context_id, MPI_Status *s)
26176341: 120:{
-: 121: MPID_Request * rreq;
26176341: 122: int found = 0;
-: 123: MPIDI_Message_match match, mask;
-: 124: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_RECVQ_FU);
-: 125:
-: 126: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_RECVQ_FU);
-: 127:
26176341: 128: rreq = recvq_unexpected_head;
-: 129:
26176341: 130: match.parts.context_id = context_id;
26176341: 131: match.parts.tag = tag;
26176341: 132: match.parts.rank = source;
-: 133:
26176341: 134: if (tag != MPI_ANY_TAG && source != MPI_ANY_SOURCE) {
51633859: 135: while (rreq != NULL) {
25819552: 136: if (MATCH_WITH_NO_MASK(rreq->dev.match, match))
1096: 137: break;
25818456: 138: rreq = rreq->dev.next;
-: 139: }
-: 140: }
-: 141: else {
360938: 142: mask.parts.context_id = mask.parts.rank = mask.parts.tag = ~0;
360938: 143: if (tag == MPI_ANY_TAG)
108520: 144: match.parts.tag = mask.parts.tag = 0;
360938: 145: if (source == MPI_ANY_SOURCE)
300830: 146: match.parts.rank = mask.parts.rank = 0;
-: 147:
504787: 148: while (rreq != NULL) {
145757: 149: if (MATCH_WITH_LEFT_MASK(rreq->dev.match, match, mask))
1908: 150: break;
143849: 151: rreq = rreq->dev.next;
-: 152: }
-: 153: }
-: 154:
-: 155: /* Save the information about the request before releasing the
-: 156: queue */
26176341: 157: if (rreq) {
3004: 158: if (s != MPI_STATUS_IGNORE) {
-: 159: /* Avoid setting "extra" fields like MPI_ERROR */
2990: 160: s->MPI_SOURCE = rreq->status.MPI_SOURCE;
2990: 161: s->MPI_TAG = rreq->status.MPI_TAG;
2990: 162: s->count = rreq->status.count;
2990: 163: s->cancelled = rreq->status.cancelled;
-: 164: }
3004: 165: found = 1;
-: 166: }
-: 167:
|
-: 168: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_RECVQ_FU);
|
26176341: 169: return found;
-: 170:}
-: 171:
-: 172:/*
-: 173: * MPIDI_CH3U_Recvq_FDU()
-: 174: *
-: 175: * Find a request in the unexpected queue and dequeue it; otherwise return NULL.
-: 176: *
-: 177: * Multithread - This routine must be atomic (since it dequeues a
-: 178: * request). However, once the request is dequeued, no other thread can
-: 179: * see it, so this routine provides its own atomicity.
-: 180: *
-: 181: * This routine is used only in the case of send_cancel. However, it is used both
-: 182: * within mpid_send_cancel and within a packet handler.
-: 183: */
-: 184:#undef FUNCNAME
-: 185:#define FUNCNAME MPIDI_CH3U_Recvq_FDU
-: 186:#undef FCNAME
-: 187:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 188:MPID_Request * MPIDI_CH3U_Recvq_FDU(MPI_Request sreq_id,
-: 189: MPIDI_Message_match * match)
475: 190:{
-: 191: MPID_Request * rreq;
-: 192: MPID_Request * prev_rreq;
-: 193: MPID_Request * cur_rreq;
-: 194: MPID_Request * matching_prev_rreq;
-: 195: MPID_Request * matching_cur_rreq;
-: 196: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_RECVQ_FDU);
-: 197:
-: 198: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_RECVQ_FDU);
-: 199:
475: 200: matching_prev_rreq = NULL;
475: 201: matching_cur_rreq = NULL;
475: 202: prev_rreq = NULL;
-: 203:
-: 204: /* Note that since this routine is used only in the case of send_cancel,
-: 205: there can be only one match if at all. */
-: 206: /* FIXME: Why doesn't this exit after it finds the first match? */
475: 207: cur_rreq = recvq_unexpected_head;
1417: 208: while (cur_rreq != NULL) {
467: 209: if (cur_rreq->dev.sender_req_id == sreq_id &&
-: 210: (MATCH_WITH_NO_MASK(cur_rreq->dev.match, *match))) {
467: 211: matching_prev_rreq = prev_rreq;
467: 212: matching_cur_rreq = cur_rreq;
-: 213: }
467: 214: prev_rreq = cur_rreq;
467: 215: cur_rreq = cur_rreq->dev.next;
-: 216: }
-: 217:
475: 218: if (matching_cur_rreq != NULL) {
467: 219: if (matching_prev_rreq != NULL) {
|
#####: 220: matching_prev_rreq->dev.next = matching_cur_rreq->dev.next;
-: 221: }
-: 222: else {
|
467: 223: recvq_unexpected_head = matching_cur_rreq->dev.next;
-: 224: }
-: 225:
467: 226: if (matching_cur_rreq->dev.next == NULL) {
467: 227: recvq_unexpected_tail = matching_prev_rreq;
-: 228: }
-: 229:
467: 230: rreq = matching_cur_rreq;
-: 231: }
-: 232: else {
8: 233: rreq = NULL;
-: 234: }
-: 235:
|
-: 236: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_RECVQ_FDU);
|
475: 237: return rreq;
-: 238:}
-: 239:
-: 240:
-: 241:/*
-: 242: * MPIDI_CH3U_Recvq_FDU_or_AEP()
-: 243: *
-: 244: * Atomically find a request in the unexpected queue and dequeue it, or
-: 245: * allocate a new request and enqueue it in the posted queue
-: 246: *
-: 247: * Multithread - This routine must be called from within a MSGQUEUE
-: 248: * critical section. If a request is allocated, it must not release
-: 249: * the MSGQUEUE until the request is completely valid, as another thread
-: 250: * may then find it and dequeue it.
-: 251: *
-: 252: * This routine is used in mpid_irecv and mpid_recv.
-: 253: *
-: 254: */
-: 255:#undef FUNCNAME
-: 256:#define FUNCNAME MPIDI_CH3U_Recvq_FDU_or_AEP
-: 257:#undef FCNAME
-: 258:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 259:MPID_Request * MPIDI_CH3U_Recvq_FDU_or_AEP(int source, int tag,
-: 260: int context_id, MPID_Comm *comm, void *user_buf,
-: 261: int user_count, MPI_Datatype datatype, int * foundp)
15581986: 262:{
-: 263: int found;
-: 264: MPID_Request *rreq, *prev_rreq;
-: 265: MPIDI_Message_match match;
-: 266: MPIDI_Message_match mask;
-: 267: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_RECVQ_FDU_OR_AEP);
-: 268:
-: 269: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_RECVQ_FDU_OR_AEP);
-: 270:
-: 271: /* Optimize this loop for an empty unexpected receive queue */
15581986: 272: rreq = recvq_unexpected_head;
15581986: 273: if (rreq) {
2390401: 274: prev_rreq = NULL;
-: 275:
2390401: 276: match.parts.context_id = context_id;
2390401: 277: match.parts.tag = tag;
2390401: 278: match.parts.rank = source;
-: 279:
2390401: 280: if (tag != MPI_ANY_TAG && source != MPI_ANY_SOURCE) {
-: 281: do {
2543137: 282: if (MATCH_WITH_NO_MASK(rreq->dev.match, match)) {
1613498: 283: if (prev_rreq != NULL) {
165399: 284: prev_rreq->dev.next = rreq->dev.next;
-: 285: }
-: 286: else {
1448099: 287: recvq_unexpected_head = rreq->dev.next;
-: 288: }
-: 289:
1613498: 290: if (rreq->dev.next == NULL) {
1436113: 291: recvq_unexpected_tail = prev_rreq;
-: 292: }
-: 293:
1613498: 294: rreq->comm = comm;
1613498: 295: MPIR_Comm_add_ref(comm);
1613498: 296: rreq->dev.user_buf = user_buf;
1613498: 297: rreq->dev.user_count = user_count;
1613498: 298: rreq->dev.datatype = datatype;
1613498: 299: found = TRUE;
1613498: 300: goto lock_exit;
-: 301: }
929639: 302: prev_rreq = rreq;
929639: 303: rreq = rreq->dev.next;
929639: 304: } while (rreq);
-: 305: }
-: 306: else {
176862: 307: mask.parts.context_id = mask.parts.rank = mask.parts.tag = ~0;
176862: 308: if (tag == MPI_ANY_TAG)
141385: 309: match.parts.tag = mask.parts.tag = 0;
176862: 310: if (source == MPI_ANY_SOURCE)
69984: 311: match.parts.rank = mask.parts.rank = 0;
-: 312:
-: 313: do {
210858: 314: if (MATCH_WITH_LEFT_MASK(rreq->dev.match, match, mask)) {
122679: 315: if (prev_rreq != NULL) {
22601: 316: prev_rreq->dev.next = rreq->dev.next;
-: 317: }
-: 318: else {
100078: 319: recvq_unexpected_head = rreq->dev.next;
-: 320: }
122679: 321: if (rreq->dev.next == NULL) {
91077: 322: recvq_unexpected_tail = prev_rreq;
-: 323: }
122679: 324: rreq->comm = comm;
122679: 325: MPIR_Comm_add_ref(comm);
122679: 326: rreq->dev.user_buf = user_buf;
122679: 327: rreq->dev.user_count = user_count;
122679: 328: rreq->dev.datatype = datatype;
122679: 329: found = TRUE;
122679: 330: goto lock_exit;
-: 331: }
88179: 332: prev_rreq = rreq;
88179: 333: rreq = rreq->dev.next;
88179: 334: } while (rreq);
-: 335: }
-: 336: }
-: 337:
-: 338: /* A matching request was not found in the unexpected queue, so we
-: 339: need to allocate a new request and add it to the posted queue */
-: 340: {
13845809: 341: int mpi_errno=0;
13845809: 342: MPIDI_Request_create_rreq( rreq, mpi_errno,
-: 343: found = FALSE;goto lock_exit );
13845809: 344: rreq->dev.match.parts.tag = tag;
13845809: 345: rreq->dev.match.parts.rank = source;
13845809: 346: rreq->dev.match.parts.context_id = context_id;
-: 347:
-: 348: /* Added a mask for faster search on 64-bit capable
-: 349: * platforms */
13845809: 350: rreq->dev.mask.parts.context_id = ~0;
13845809: 351: if (rreq->dev.match.parts.rank == MPI_ANY_SOURCE)
136519: 352: rreq->dev.mask.parts.rank = 0;
-: 353: else
13709290: 354: rreq->dev.mask.parts.rank = ~0;
13845809: 355: if (rreq->dev.match.parts.tag == MPI_ANY_TAG)
270599: 356: rreq->dev.mask.parts.tag = 0;
-: 357: else
13575210: 358: rreq->dev.mask.parts.tag = ~0;
-: 359:
13845809: 360: rreq->comm = comm;
13845809: 361: MPIR_Comm_add_ref(comm);
13845809: 362: rreq->dev.user_buf = user_buf;
13845809: 363: rreq->dev.user_count = user_count;
13845809: 364: rreq->dev.datatype = datatype;
13845809: 365: rreq->dev.next = NULL;
13845809: 366: if (recvq_posted_tail != NULL) {
1493282: 367: recvq_posted_tail->dev.next = rreq;
-: 368: }
-: 369: else {
12352527: 370: recvq_posted_head = rreq;
-: 371: }
13845809: 372: recvq_posted_tail = rreq;
-: 373: MPIDI_POSTED_RECV_ENQUEUE_HOOK(rreq);
-: 374: }
-: 375:
13845809: 376: found = FALSE;
-: 377:
15581986: 378: lock_exit:
-: 379:
15581986: 380: *foundp = found;
-: 381:
|
-: 382: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_RECVQ_FDU_OR_AEP);
|
15581986: 383: return rreq;
-: 384:}
-: 385:
-: 386:
-: 387:/*
-: 388: * MPIDI_CH3U_Recvq_DP()
-: 389: *
-: 390: * Given an existing request, dequeue that request from the posted queue, or
-: 391: * return NULL if the request was not in the posted queued
-: 392: *
-: 393: * Multithread - This routine is atomic
-: 394: */
-: 395:#undef FUNCNAME
-: 396:#define FUNCNAME MPIDI_CH3U_Recvq_DP
-: 397:#undef FCNAME
-: 398:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 399:int MPIDI_CH3U_Recvq_DP(MPID_Request * rreq)
2293: 400:{
-: 401: int found;
-: 402: MPID_Request * cur_rreq;
-: 403: MPID_Request * prev_rreq;
-: 404: int dequeue_failed;
-: 405: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_RECVQ_DP);
-: 406:
-: 407: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_RECVQ_DP);
-: 408:
2293: 409: found = FALSE;
2293: 410: prev_rreq = NULL;
-: 411:
-: 412: MPIU_THREAD_CS_ENTER(MSGQUEUE,);
2293: 413: cur_rreq = recvq_posted_head;
4591: 414: while (cur_rreq != NULL) {
2281: 415: if (cur_rreq == rreq) {
2276: 416: if (prev_rreq != NULL) {
3: 417: prev_rreq->dev.next = cur_rreq->dev.next;
-: 418: }
-: 419: else {
2273: 420: recvq_posted_head = cur_rreq->dev.next;
-: 421: }
2276: 422: if (cur_rreq->dev.next == NULL) {
226: 423: recvq_posted_tail = prev_rreq;
-: 424: }
-: 425: /* Notify channel that rreq has been dequeued and check if
-: 426: it has already matched rreq, fail if so */
2276: 427: dequeue_failed = MPIDI_POSTED_RECV_DEQUEUE_HOOK(rreq);
2276: 428: if (!dequeue_failed)
2276: 429: found = TRUE;
-: 430: break;
-: 431: }
-: 432:
5: 433: prev_rreq = cur_rreq;
5: 434: cur_rreq = cur_rreq->dev.next;
-: 435: }
-: 436:
-: 437: MPIU_THREAD_CS_EXIT(MSGQUEUE,);
-: 438:
|
-: 439: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_RECVQ_DP);
|
2293: 440: return found;
-: 441:}
-: 442:
-: 443:/*
-: 444: * MPIDI_CH3U_Recvq_FDP_or_AEU()
-: 445: *
-: 446: * Locate a request in the posted queue and dequeue it, or allocate a new
-: 447: * request and enqueue it in the unexpected queue
-: 448: *
-: 449: * Multithread - This routine must be called from within a MSGQUEUE
-: 450: * critical section. If a request is allocated, it must not release
-: 451: * the MSGQUEUE until the request is completely valid, as another thread
-: 452: * may then find it and dequeue it.
-: 453: *
-: 454: * This routine is used in ch3u_eager, ch3u_eagersync, ch3u_handle_recv_pkt,
-: 455: * ch3u_rndv, and mpidi_isend_self. Routines within the progress engine
-: 456: * will need to be careful to avoid nested critical sections.
-: 457: *
-: 458: * FIXME: Currently, the routines called from within the progress engine
-: 459: * do not use the MSGQUEUE CS, because in the brief-global mode, that
-: 460: * simply uses the global_mutex .
-: 461: */
-: 462:#undef FUNCNAME
-: 463:#define FUNCNAME MPIDI_CH3U_Recvq_FDP_or_AEU
-: 464:#undef FCNAME
-: 465:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 466:MPID_Request * MPIDI_CH3U_Recvq_FDP_or_AEU(MPIDI_Message_match * match,
-: 467: int * foundp)
15580176: 468:{
-: 469: int found;
-: 470: MPID_Request * rreq;
-: 471: MPID_Request * prev_rreq;
-: 472: int channel_matched;
-: 473: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_RECVQ_FDP_OR_AEU);
-: 474:
-: 475: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_RECVQ_FDP_OR_AEU);
-: 476:
15580176: 477: top_loop:
15580176: 478: prev_rreq = NULL;
-: 479:
15580176: 480: rreq = recvq_posted_head;
-: 481:
33083715: 482: while (rreq != NULL) {
15766895: 483: if (MATCH_WITH_LEFT_RIGHT_MASK(rreq->dev.match, *match, rreq->dev.mask)) {
13843532: 484: if (prev_rreq != NULL) {
264450: 485: prev_rreq->dev.next = rreq->dev.next;
-: 486: }
-: 487: else {
13579082: 488: recvq_posted_head = rreq->dev.next;
-: 489: }
13843532: 490: if (rreq->dev.next == NULL) {
12569669: 491: recvq_posted_tail = prev_rreq;
-: 492: }
-: 493:
-: 494: /* give channel a chance to match the request, try again if so */
13843532: 495: channel_matched = MPIDI_POSTED_RECV_DEQUEUE_HOOK(rreq);
13843532: 496: if (channel_matched)
|
#####: 497: goto top_loop;
-: 498:
|
13843532: 499: found = TRUE;
13843532: 500: goto lock_exit;
-: 501: }
1923363: 502: prev_rreq = rreq;
1923363: 503: rreq = rreq->dev.next;
-: 504: }
-: 505:
-: 506: /* A matching request was not found in the posted queue, so we
-: 507: need to allocate a new request and add it to the unexpected queue */
-: 508: {
1736644: 509: int mpi_errno=0;
1736644: 510: MPIDI_Request_create_rreq( rreq, mpi_errno,
-: 511: found=FALSE;goto lock_exit );
1736644: 512: rreq->dev.recv_pending_count = 1;
1736644: 513: rreq->dev.match = *match;
1736644: 514: rreq->dev.next = NULL;
1736644: 515: if (recvq_unexpected_tail != NULL) {
369338: 516: recvq_unexpected_tail->dev.next = rreq;
-: 517: }
-: 518: else {
1367306: 519: recvq_unexpected_head = rreq;
-: 520: }
1736644: 521: recvq_unexpected_tail = rreq;
-: 522: }
-: 523:
1736644: 524: found = FALSE;
-: 525:
15580176: 526: lock_exit:
-: 527:
15580176: 528: *foundp = found;
-: 529:
|
-: 530: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_RECVQ_FDP_OR_AEU);
|
15580176: 531: return rreq;
-: 532:}
-: 533:
|
-: 534:/* --BEGIN ERROR HANDLING-- */
-: 535:/* pretty prints tag, returns out for calling convenience */
-: 536:static char *tag_val_to_str(int tag, char *out, int max)
#####: 537:{
#####: 538: if (tag == MPI_ANY_TAG) {
#####: 539: MPIU_Strncpy(out, "MPI_ANY_TAG", max);
-: 540: }
-: 541: else {
#####: 542: MPIU_Snprintf(out, max, "%d", tag);
-: 543: }
#####: 544: return out;
-: 545:}
-: 546:
-: 547:/* pretty prints rank, returns out for calling convenience */
-: 548:static char *rank_val_to_str(int rank, char *out, int max)
#####: 549:{
#####: 550: if (rank == MPI_ANY_SOURCE) {
#####: 551: MPIU_Strncpy(out, "MPI_ANY_SOURCE", max);
-: 552: }
-: 553: else {
#####: 554: MPIU_Snprintf(out, max, "%d", rank);
-: 555: }
#####: 556: return out;
-: 557:}
-: 558:
-: 559:/* satisfy the compiler */
-: 560:void MPIDI_CH3U_Dbg_print_recvq(FILE *stream);
-: 561:
-: 562:/* This function can be called by a debugger to dump the recvq state to the
-: 563: * given stream. */
-: 564:#undef FUNCNAME
-: 565:#define FUNCNAME MPIDI_CH3U_Dbg_print_recvq
-: 566:#undef FCNAME
-: 567:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 568:void MPIDI_CH3U_Dbg_print_recvq(FILE *stream)
#####: 569:{
-: 570: MPID_Request * rreq;
-: 571: int i;
-: 572: char tag_buf[128];
-: 573: char rank_buf[128];
-: 574:
#####: 575: fprintf(stream, "========================================\n");
#####: 576: fprintf(stream, "MPI_COMM_WORLD ctx=%#x rank=%d\n", MPIR_Process.comm_world->context_id, MPIR_Process.comm_world->rank);
#####: 577: fprintf(stream, "MPI_COMM_SELF ctx=%#x\n", MPIR_Process.comm_self->context_id);
#####: 578: if (MPIR_Process.comm_parent) {
#####: 579: fprintf(stream, "MPI_COMM_PARENT ctx=%#x recvctx=%#x\n",
-: 580: MPIR_Process.comm_self->context_id,
-: 581: MPIR_Process.comm_parent->recvcontext_id);
-: 582: }
-: 583: else {
#####: 584: fprintf(stream, "MPI_COMM_PARENT (NULL)\n");
-: 585: }
-: 586:
#####: 587: fprintf(stream, "CH3 Posted RecvQ:\n");
#####: 588: rreq = recvq_posted_head;
#####: 589: i = 0;
#####: 590: while (rreq != NULL) {
#####: 591: fprintf(stream, "..[%d] rreq=%p ctx=%#x rank=%s tag=%s\n", i, rreq,
-: 592: rreq->dev.match.parts.context_id,
-: 593: rank_val_to_str(rreq->dev.match.parts.rank, rank_buf, sizeof(rank_buf)),
-: 594: tag_val_to_str(rreq->dev.match.parts.tag, tag_buf, sizeof(tag_buf)));
#####: 595: ++i;
#####: 596: rreq = rreq->dev.next;
-: 597: }
-: 598:
#####: 599: fprintf(stream, "CH3 Unexpected RecvQ:\n");
#####: 600: rreq = recvq_unexpected_head;
#####: 601: i = 0;
#####: 602: while (rreq != NULL) {
#####: 603: fprintf(stream, "..[%d] rreq=%p ctx=%#x rank=%s tag=%s\n", i, rreq,
-: 604: rreq->dev.match.parts.context_id,
-: 605: rank_val_to_str(rreq->dev.match.parts.rank, rank_buf, sizeof(rank_buf)),
-: 606: tag_val_to_str(rreq->dev.match.parts.tag, tag_buf, sizeof(tag_buf)));
#####: 607: fprintf(stream, ".. status.src=%s status.tag=%s\n",
-: 608: rank_val_to_str(rreq->status.MPI_SOURCE, rank_buf, sizeof(rank_buf)),
-: 609: tag_val_to_str(rreq->status.MPI_TAG, tag_buf, sizeof(tag_buf)));
#####: 610: ++i;
#####: 611: rreq = rreq->dev.next;
-: 612: }
#####: 613: fprintf(stream, "========================================\n");
#####: 614:}
-: 615:/* --END ERROR HANDLING-- */
-: 616:
-: 617:/* returns the number of elements in the unexpected queue */
-: 618:#undef FUNCNAME
-: 619:#define FUNCNAME MPIDI_CH3U_Recvq_count_unexp
-: 620:#undef FCNAME
-: 621:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 622:int MPIDI_CH3U_Recvq_count_unexp(void)
|
#####: 623:{
#####: 624: int count = 0;
#####: 625: MPID_Request *req = recvq_unexpected_head;
-: 626:
#####: 627: while (req)
-: 628: {
#####: 629: ++count;
#####: 630: req = req->dev.next;
-: 631: }
-: 632:
#####: 633: return count;
-: 634:}
|