1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 /*
7  * This is code for handling unordered delivery of packets.  It is currently
8  * unused but saved for reference.
9  */
10 
11 #if defined(MPIDI_CH3_MSGS_UNORDERED)
12 int MPIDI_CH3U_Handle_unordered_recv_pkt(MPIDI_VC_t * vc, MPIDI_CH3_Pkt_t * pkt);
13 #define MPIDI_CH3U_Handle_unordered_recv_pkt MPIDI_CH3U_Handle_recv_pkt
14 #else
15 #define MPIDI_CH3U_Handle_ordered_recv_pkt MPIDI_CH3U_Handle_recv_pkt
16 #endif
17 
18 #if defined(MPIDI_CH3_MSGS_UNORDERED)
19 
20 #define MPIDI_CH3U_Pkt_send_container_alloc() (MPL_malloc(sizeof(MPIDI_CH3_Pkt_send_container_t), MPL_MEM_BUFFER))
21 #define MPIDI_CH3U_Pkt_send_container_free(pc_) MPL_free(pc_)
22 
MPIDI_CH3U_Handle_unordered_recv_pkt(MPIDI_VC_t * vc,MPIDI_CH3_Pkt_t * pkt,MPIR_Request ** rreqp)23 int MPIDI_CH3U_Handle_unordered_recv_pkt(MPIDI_VC_t *vc, MPIDI_CH3_Pkt_t * pkt,
24 					 MPIR_Request ** rreqp)
25 {
26     int mpi_errno = MPI_SUCCESS;
27     MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDI_CH3U_HANDLE_UNORDERED_RECV_PKT);
28 
29     MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDI_CH3U_HANDLE_UNORDERED_RECV_PKT);
30 
31     /* FIXME: This should probably be *rreqp = NULL? */
32     rreqp = NULL;
33 
34     switch(pkt->type)
35     {
36 	case MPIDI_CH3_PKT_EAGER_SEND:
37 	case MPIDI_CH3_PKT_EAGER_SYNC_SEND:
38 	case MPIDI_CH3_PKT_READY_SEND:
39 	case MPIDI_CH3_PKT_RNDV_REQ_TO_SEND:
40 	{
41 	    MPIDI_CH3_Pkt_send_t * send_pkt = (MPIDI_CH3_Pkt_send_t *) pkt;
42 	    MPIDI_CH3_Pkt_send_container_t * pc_cur;
43 	    MPIDI_CH3_Pkt_send_container_t * pc_last;
44 
45 	    MPL_DBG_MSG(MPIDI_CH3_DBG_OTHER,VERBOSE,
46 			 "received (potentially) out-of-order send pkt");
47 	    MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_OTHER,VERBOSE,(MPL_DBG_FDEST,
48 	          "rank=%d, tag=%d, context=%d seqnum=%d",
49 		  send_pkt->match.rank, send_pkt->match.tag,
50 		  send_pkt->match.context_id, send_pkt->seqnum));
51 	    MPL_DBG_MSG_FMAT(MPIDI_CH3_DBG_OTHER,VERBOSE,(MPL_DBG_FDEST,
52               "vc - seqnum_send=%d seqnum_recv=%d reorder_msg_queue=0x%08lx",
53 	      vc->seqnum_send, vc->seqnum_recv,
54 	      (unsigned long) vc->msg_reorder_queue));
55 
56 	    if (send_pkt->seqnum == vc->seqnum_recv)
57 	    {
58 		mpi_errno = MPIDI_CH3U_Handle_ordered_recv_pkt(vc, pkt, rreqp);
59 		/* --BEGIN ERROR HANDLING-- */
60 		if (mpi_errno != MPI_SUCCESS)
61 		{
62 		    goto fn_exit;
63 		}
64 		/* --END ERROR HANDLING-- */
65 		vc->seqnum_recv++;
66 		pc_cur = vc->msg_reorder_queue;
67 		while(pc_cur != NULL && vc->seqnum_recv == pc_cur->pkt.seqnum)
68 		{
69 		    pkt = (MPIDI_CH3_Pkt_t *) &pc_cur->pkt;
70 		    mpi_errno = MPIDI_CH3U_Handle_ordered_recv_pkt(vc, pkt, rreqp);
71 		    /* --BEGIN ERROR HANDLING-- */
72 		    if (mpi_errno != MPI_SUCCESS)
73 		    {
74 			mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, __func__, __LINE__, MPI_ERR_OTHER,
75 							 "**ch3|pktordered", 0);
76 			goto fn_exit;
77 		    }
78 		    /* --END ERROR HANDLING-- */
79 		    vc->seqnum_recv++;
80 		    pc_last = pc_cur;
81 		    pc_cur = pc_cur->next;
82 		    MPIDI_CH3U_Pkt_send_container_free(pc_last);
83 		}
84 		vc->msg_reorder_queue = pc_cur;
85 	    }
86 	    else
87 	    {
88 		MPIDI_CH3_Pkt_send_container_t * pc_new;
89 
90 		/* allocate container and copy packet */
91 		pc_new = MPIDI_CH3U_Pkt_send_container_alloc();
92 		/* --BEGIN ERROR HANDLING-- */
93 		if (pc_new == NULL)
94 		{
95 		    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, __func__, __LINE__, MPI_ERR_OTHER,
96 						     "**ch3|nopktcontainermem", 0);
97 		    goto fn_exit;
98 		}
99 		/* --END ERROR HANDLING-- */
100 		pc_new->pkt = *send_pkt;
101 
102 		/* insert packet into reorder queue */
103 		pc_last = NULL;
104 		pc_cur = vc->msg_reorder_queue;
105 		while (pc_cur != NULL)
106 		{
107 		    /* the current recv seqnum is subtracted from both the
108 		       seqnums prior to comparision so as to remove any wrap
109 		       around effects. */
110 		    if (pc_new->pkt.seqnum - vc->seqnum_recv <
111 			pc_cur->pkt.seqnum - vc->seqnum_recv)
112 		    {
113 			break;
114 		    }
115 
116 		    pc_last = pc_cur;
117 		    pc_cur = pc_cur->next;
118 		}
119 
120 		if (pc_last == NULL)
121 		{
122 		    pc_new->next = pc_cur;
123 		    vc->msg_reorder_queue = pc_new;
124 		}
125 		else
126 		{
127 		    pc_new->next = pc_cur;
128 		    pc_last->next = pc_new;
129 		}
130 	    }
131 
132 	    break;
133 	}
134 
135 	case MPIDI_CH3_PKT_CANCEL_SEND_REQ:
136 	{
137 	    /* --BEGIN ERROR HANDLING-- */
138 	    /* FIXME: processing send cancel requests requires that we be
139 	       aware of pkts in the reorder queue */
140 	    mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, __func__, __LINE__, MPI_ERR_OTHER,
141 					     "**ch3|ooocancelreq", 0);
142 	    goto fn_exit;
143 	    break;
144 	    /* --END ERROR HANDLING-- */
145 	}
146 
147 	default:
148 	{
149 	    mpi_errno = MPIDI_CH3U_Handle_ordered_recv_pkt(vc, pkt, rreqp);
150 	    break;
151 	}
152     }
153 
154   fn_exit:
155     MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDI_CH3U_HANDLE_UNORDERED_RECV_PKT);
156     return mpi_errno;
157 }
158 #endif /* defined(MPIDI_CH3_MSGS_UNORDERED) */
159