3
3
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4
4
* University Research and Technology
5
5
* Corporation. All rights reserved.
6
- * Copyright (c) 2004-2016 The University of Tennessee and The University
6
+ * Copyright (c) 2004-2017 The University of Tennessee and The University
7
7
* of Tennessee Research Foundation. All rights
8
8
* reserved.
9
9
* Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
@@ -66,7 +66,7 @@ OBJ_CLASS_INSTANCE( mca_pml_ob1_recv_frag_t,
66
66
*/
67
67
68
68
/**
69
- * Append a unexpected descriptor to a queue. This function will allocate and
69
+ * Append an unexpected descriptor to a queue. This function will allocate and
70
70
* initialize the fragment (if necessary) and then will add it to the specified
71
71
* queue. The allocated fragment is not returned to the caller.
72
72
*/
@@ -82,21 +82,92 @@ append_frag_to_list(opal_list_t *queue, mca_btl_base_module_t *btl,
82
82
opal_list_append (queue , (opal_list_item_t * )frag );
83
83
}
84
84
85
+ /**
86
+ * Append an unexpected descriptor to an ordered queue. This function will allocate and
87
+ * initialize the fragment (if necessary) and then will add it to the specified
88
+ * queue respecting the sequence number. The allocated fragment is not returned to the caller.
89
+ */
90
+ static void
91
+ append_frag_to_ordered_list (opal_list_t * queue , mca_btl_base_module_t * btl ,
92
+ mca_pml_ob1_match_hdr_t * hdr , mca_btl_base_segment_t * segments ,
93
+ size_t num_segments , mca_pml_ob1_recv_frag_t * frag )
94
+ {
95
+ mca_pml_ob1_recv_frag_t * tmpfrag ;
96
+ mca_pml_ob1_match_hdr_t * tmphdr ;
97
+
98
+ if (NULL == frag ) {
99
+ MCA_PML_OB1_RECV_FRAG_ALLOC (frag );
100
+ MCA_PML_OB1_RECV_FRAG_INIT (frag , hdr , segments , num_segments , btl );
101
+ }
102
+
103
+ if ( opal_list_is_empty (queue ) ) { /* no pending fragments yet */
104
+ opal_list_append (queue , (opal_list_item_t * )frag );
105
+ return ;
106
+ }
107
+ /* Shortcut for sequence number earlier than the first fragment in the list */
108
+ tmpfrag = (mca_pml_ob1_recv_frag_t * )opal_list_get_first (queue );
109
+ tmphdr = & tmpfrag -> hdr .hdr_match ;
110
+ assert (hdr -> hdr_seq != tmphdr -> hdr_seq );
111
+ if ( hdr -> hdr_seq < tmphdr -> hdr_seq ) {
112
+ opal_list_prepend (queue , (opal_list_item_t * )frag );
113
+ return ;
114
+ }
115
+ /* Shortcut for sequence number later than the last fragment in the list */
116
+ tmpfrag = (mca_pml_ob1_recv_frag_t * )opal_list_get_last (queue );
117
+ tmphdr = & tmpfrag -> hdr .hdr_match ;
118
+ if ( hdr -> hdr_seq > tmphdr -> hdr_seq ) {
119
+ opal_list_append (queue , (opal_list_item_t * )frag );
120
+ return ;
121
+ }
122
+ /* For all other cases (sequence number missing in the list) */
123
+ OPAL_LIST_FOREACH (tmpfrag , queue , mca_pml_ob1_recv_frag_t ) {
124
+ tmphdr = & tmpfrag -> hdr .hdr_match ;
125
+ if ( hdr -> hdr_seq < tmphdr -> hdr_seq ) {
126
+ opal_list_insert_pos (queue , (opal_list_item_t * )tmpfrag ,
127
+ (opal_list_item_t * ) frag );
128
+ return ;
129
+ }
130
+ }
131
+ }
132
+
85
133
/**
86
134
* Match incoming recv_frags against posted receives.
87
135
* Supports out of order delivery.
88
136
*
89
- * @param frag_header (IN) Header of received recv_frag.
90
- * @param frag_desc (IN) Received recv_frag descriptor.
91
- * @param match_made (OUT) Flag indicating wether a match was made.
92
- * @param additional_matches (OUT ) List of additional matches
137
+ * @param hdr (IN) Header of received recv_frag.
138
+ * @param segments (IN) Received recv_frag descriptor.
139
+ * @param num_segments (IN) Flag indicating wether a match was made.
140
+ * @param type (IN ) Type of the message header.
93
141
* @return OMPI_SUCCESS or error status on failure.
94
142
*/
95
143
static int mca_pml_ob1_recv_frag_match ( mca_btl_base_module_t * btl ,
96
144
mca_pml_ob1_match_hdr_t * hdr ,
97
145
mca_btl_base_segment_t * segments ,
98
146
size_t num_segments ,
99
- int type );
147
+ int type );
148
+
149
+ /**
150
+ * Match incoming frags against posted receives. If frag is not NULL then we assume
151
+ * it is already local and that it can be released upon completion.
152
+ * Supports out of order delivery.
153
+ *
154
+ * @param comm_ptr (IN) Communicator where the message has been received
155
+ * @param proc (IN) Proc for which we have received the message.
156
+ * @param hdr (IN) Header of received recv_frag.
157
+ * @param segments (IN) Received recv_frag descriptor.
158
+ * @param num_segments (IN) Flag indicating wether a match was made.
159
+ * @param type (IN) Type of the message header.
160
+ * @return OMPI_SUCCESS or error status on failure.
161
+ */
162
+ static int
163
+ mca_pml_ob1_recv_frag_match_proc ( mca_btl_base_module_t * btl ,
164
+ ompi_communicator_t * comm_ptr ,
165
+ mca_pml_ob1_comm_proc_t * proc ,
166
+ mca_pml_ob1_match_hdr_t * hdr ,
167
+ mca_btl_base_segment_t * segments ,
168
+ size_t num_segments ,
169
+ int type ,
170
+ mca_pml_ob1_recv_frag_t * frag );
100
171
101
172
static mca_pml_ob1_recv_request_t *
102
173
match_one (mca_btl_base_module_t * btl ,
@@ -105,6 +176,19 @@ match_one(mca_btl_base_module_t *btl,
105
176
mca_pml_ob1_comm_proc_t * proc ,
106
177
mca_pml_ob1_recv_frag_t * frag );
107
178
179
+ static mca_pml_ob1_recv_frag_t * check_cantmatch_for_match (mca_pml_ob1_comm_proc_t * proc )
180
+ {
181
+ mca_pml_ob1_recv_frag_t * frag = NULL ;
182
+
183
+ frag = (mca_pml_ob1_recv_frag_t * )opal_list_get_first (& proc -> frags_cant_match );
184
+ if ( (opal_list_get_end (& proc -> frags_cant_match ) != (opal_list_item_t * )frag ) &&
185
+ (frag -> hdr .hdr_match .hdr_seq == proc -> expected_sequence ) ) {
186
+ opal_list_remove_item (& proc -> frags_cant_match , (opal_list_item_t * )frag );
187
+ return frag ;
188
+ }
189
+ return NULL ;
190
+ }
191
+
108
192
void mca_pml_ob1_recv_frag_callback_match (mca_btl_base_module_t * btl ,
109
193
mca_btl_base_tag_t tag ,
110
194
mca_btl_base_descriptor_t * des ,
@@ -177,7 +261,7 @@ void mca_pml_ob1_recv_frag_callback_match(mca_btl_base_module_t* btl,
177
261
PERUSE_TRACE_MSG_EVENT (PERUSE_COMM_MSG_ARRIVED , comm_ptr ,
178
262
hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
179
263
180
- append_frag_to_list (& proc -> frags_cant_match , btl ,
264
+ append_frag_to_ordered_list (& proc -> frags_cant_match , btl ,
181
265
hdr , segments , num_segments , NULL );
182
266
OB1_MATCHING_UNLOCK (& comm -> matching_lock );
183
267
return ;
@@ -198,7 +282,7 @@ void mca_pml_ob1_recv_frag_callback_match(mca_btl_base_module_t* btl,
198
282
* generation until we reach the correct sequence number.
199
283
*/
200
284
PERUSE_TRACE_MSG_EVENT (PERUSE_COMM_SEARCH_POSTED_Q_BEGIN , comm_ptr ,
201
- hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
285
+ hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
202
286
203
287
match = match_one (btl , hdr , segments , num_segments , comm_ptr , proc , NULL );
204
288
@@ -261,8 +345,18 @@ void mca_pml_ob1_recv_frag_callback_match(mca_btl_base_module_t* btl,
261
345
/* don't need a rmb as that is for checking */
262
346
recv_request_pml_complete (match );
263
347
}
348
+ if (0 != opal_list_get_size (& proc -> frags_cant_match )) {
349
+ mca_pml_ob1_recv_frag_t * frag ;
350
+ OB1_MATCHING_LOCK (& comm -> matching_lock );
351
+ if ((frag = check_cantmatch_for_match (proc ))) {
352
+ mca_pml_ob1_recv_frag_match_proc (frag -> btl , comm_ptr , proc , & frag -> hdr .hdr_match ,
353
+ frag -> segments , frag -> num_segments ,
354
+ hdr -> hdr_common .hdr_type , frag );
355
+ } else {
356
+ OB1_MATCHING_UNLOCK (& comm -> matching_lock );
357
+ }
358
+ }
264
359
return ;
265
-
266
360
slow_path :
267
361
OB1_MATCHING_UNLOCK (& comm -> matching_lock );
268
362
mca_pml_ob1_recv_frag_match (btl , hdr , segments ,
@@ -605,31 +699,6 @@ match_one(mca_btl_base_module_t *btl,
605
699
} while (true);
606
700
}
607
701
608
- static mca_pml_ob1_recv_frag_t * check_cantmatch_for_match (mca_pml_ob1_comm_proc_t * proc )
609
- {
610
- mca_pml_ob1_recv_frag_t * frag ;
611
-
612
- /* search the list for a fragment from the send with sequence
613
- * number next_msg_seq_expected
614
- */
615
- for (frag = (mca_pml_ob1_recv_frag_t * )opal_list_get_first (& proc -> frags_cant_match );
616
- frag != (mca_pml_ob1_recv_frag_t * )opal_list_get_end (& proc -> frags_cant_match );
617
- frag = (mca_pml_ob1_recv_frag_t * )opal_list_get_next (frag ))
618
- {
619
- mca_pml_ob1_match_hdr_t * hdr = & frag -> hdr .hdr_match ;
620
- /*
621
- * If the message has the next expected seq from that proc...
622
- */
623
- if (hdr -> hdr_seq != proc -> expected_sequence )
624
- continue ;
625
-
626
- opal_list_remove_item (& proc -> frags_cant_match , (opal_list_item_t * )frag );
627
- return frag ;
628
- }
629
-
630
- return NULL ;
631
- }
632
-
633
702
/**
634
703
* RCS/CTS receive side matching
635
704
*
@@ -669,10 +738,8 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
669
738
/* local variables */
670
739
uint16_t next_msg_seq_expected , frag_msg_seq ;
671
740
ompi_communicator_t * comm_ptr ;
672
- mca_pml_ob1_recv_request_t * match = NULL ;
673
741
mca_pml_ob1_comm_t * comm ;
674
742
mca_pml_ob1_comm_proc_t * proc ;
675
- mca_pml_ob1_recv_frag_t * frag = NULL ;
676
743
677
744
/* communicator pointer */
678
745
comm_ptr = ompi_comm_lookup (hdr -> hdr_ctx );
@@ -691,14 +758,13 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
691
758
comm = (mca_pml_ob1_comm_t * )comm_ptr -> c_pml_comm ;
692
759
693
760
/* source sequence number */
694
- frag_msg_seq = hdr -> hdr_seq ;
695
761
proc = mca_pml_ob1_peer_lookup (comm_ptr , hdr -> hdr_src );
696
762
697
- /**
698
- * We generate the MSG_ARRIVED event as soon as the PML is aware of a matching
699
- * fragment arrival. Independing if it is received on the correct order or not.
700
- * This will allow the tools to figure out if the messages are not received in the
701
- * correct order (if multiple network interfaces).
763
+ /* We generate the MSG_ARRIVED event as soon as the PML is aware
764
+ * of a matching fragment arrival. Independing if it is received
765
+ * on the correct order or not. This will allow the tools to
766
+ * figure out if the messages are not received in the correct
767
+ * order (if multiple network interfaces).
702
768
*/
703
769
PERUSE_TRACE_MSG_EVENT (PERUSE_COMM_MSG_ARRIVED , comm_ptr ,
704
770
hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
@@ -712,38 +778,68 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
712
778
*/
713
779
OB1_MATCHING_LOCK (& comm -> matching_lock );
714
780
781
+ frag_msg_seq = hdr -> hdr_seq ;
715
782
/* get sequence number of next message that can be processed */
716
783
next_msg_seq_expected = (uint16_t )proc -> expected_sequence ;
717
784
if (OPAL_UNLIKELY (frag_msg_seq != next_msg_seq_expected ))
718
785
goto wrong_seq ;
719
786
787
+ return mca_pml_ob1_recv_frag_match_proc (btl , comm_ptr , proc , hdr , segments , num_segments ,
788
+ type , NULL );
789
+ wrong_seq :
790
+ /*
791
+ * This message comes after the next expected, so it
792
+ * is ahead of sequence. Save it for later.
793
+ */
794
+ append_frag_to_ordered_list (& proc -> frags_cant_match , btl , hdr , segments ,
795
+ num_segments , NULL );
796
+ OB1_MATCHING_UNLOCK (& comm -> matching_lock );
797
+ return OMPI_SUCCESS ;
798
+ }
799
+
800
+ /**
801
+ * This function should be called with the comm lock help, but upon it's return
802
+ * the mutex will be released.
803
+ */
804
+ static int
805
+ mca_pml_ob1_recv_frag_match_proc ( mca_btl_base_module_t * btl ,
806
+ ompi_communicator_t * comm_ptr ,
807
+ mca_pml_ob1_comm_proc_t * proc ,
808
+ mca_pml_ob1_match_hdr_t * hdr ,
809
+ mca_btl_base_segment_t * segments ,
810
+ size_t num_segments ,
811
+ int type ,
812
+ mca_pml_ob1_recv_frag_t * frag )
813
+ {
814
+ /* local variables */
815
+ mca_pml_ob1_comm_t * comm = (mca_pml_ob1_comm_t * )comm_ptr -> c_pml_comm ;
816
+ mca_pml_ob1_recv_request_t * match = NULL ;
817
+
720
818
/*
721
819
* This is the sequence number we were expecting,
722
- * so we can try matching it to already posted
723
- * receives.
820
+ * so we can try matching it to already posted receives.
724
821
*/
725
822
726
- out_of_order_match :
823
+ out_of_order_match :
727
824
/* We're now expecting the next sequence number. */
728
825
proc -> expected_sequence ++ ;
729
826
730
- /**
731
- * We generate the SEARCH_POSTED_QUEUE only when the message is received
732
- * in the correct sequence. Otherwise, we delay the event generation until
733
- * we reach the correct sequence number.
827
+ /* We generate the SEARCH_POSTED_QUEUE only when the message is
828
+ * received in the correct sequence. Otherwise, we delay the event
829
+ * generation until we reach the correct sequence number.
734
830
*/
735
831
PERUSE_TRACE_MSG_EVENT (PERUSE_COMM_SEARCH_POSTED_Q_BEGIN , comm_ptr ,
736
- hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
832
+ hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
737
833
738
834
match = match_one (btl , hdr , segments , num_segments , comm_ptr , proc , frag );
739
835
740
- /**
741
- * The match is over. We generate the SEARCH_POSTED_Q_END here, before going
742
- * into the mca_pml_ob1_check_cantmatch_for_match so we can make a difference
743
- * for the searching time for all messages.
836
+ /* The match is over. We generate the SEARCH_POSTED_Q_END here,
837
+ * before going into the mca_pml_ob1_check_cantmatch_for_match so
838
+ * we can make a difference for the searching time for all
839
+ * messages.
744
840
*/
745
841
PERUSE_TRACE_MSG_EVENT (PERUSE_COMM_SEARCH_POSTED_Q_END , comm_ptr ,
746
- hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
842
+ hdr -> hdr_src , hdr -> hdr_tag , PERUSE_RECV );
747
843
748
844
/* release matching lock before processing fragment */
749
845
OB1_MATCHING_UNLOCK (& comm -> matching_lock );
@@ -767,7 +863,7 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
767
863
768
864
/*
769
865
* Now that new message has arrived, check to see if
770
- * any fragments on the c_c_frags_cant_match list
866
+ * any fragments on the frags_cant_match list
771
867
* may now be used to form new matchs
772
868
*/
773
869
if (OPAL_UNLIKELY (opal_list_get_size (& proc -> frags_cant_match ) > 0 )) {
@@ -783,15 +879,6 @@ static int mca_pml_ob1_recv_frag_match( mca_btl_base_module_t *btl,
783
879
OB1_MATCHING_UNLOCK (& comm -> matching_lock );
784
880
}
785
881
786
- return OMPI_SUCCESS ;
787
- wrong_seq :
788
- /*
789
- * This message comes after the next expected, so it
790
- * is ahead of sequence. Save it for later.
791
- */
792
- append_frag_to_list (& proc -> frags_cant_match , btl , hdr , segments ,
793
- num_segments , NULL );
794
- OB1_MATCHING_UNLOCK (& comm -> matching_lock );
795
882
return OMPI_SUCCESS ;
796
883
}
797
884
0 commit comments