@@ -592,32 +592,33 @@ void Module::RunSplit(const gate_idx_t *out_gates,
592592 gate_idx_t pending[bess::PacketBatch::kMaxBurst ];
593593 bess::PacketBatch batches[bess::PacketBatch::kMaxBurst ];
594594
595- bess::PacketBatch *splits = ctx.splits ();
595+ bess::PacketBatch ** splits = ctx.splits ();
596596
597- /* phase 1: collect unique ogates into pending[] */
597+ // phase 1: collect unique ogates into pending[] and add packets to local
598+ // batches, using splits to remember the association between an ogate and a
599+ // local batch
598600 for (int i = 0 ; i < cnt; i++) {
599601 bess::PacketBatch *batch;
600602 gate_idx_t ogate;
601603
602604 ogate = out_gates[i];
603- batch = &splits[ogate];
605+ batch = splits[ogate];
606+ if (!batch) {
607+ batch = splits[ogate] = &batches[num_pending];
608+ batch->clear ();
609+ pending[num_pending] = ogate;
610+ num_pending++;
611+ }
604612
605613 batch->add (*(p_pkt++));
606-
607- pending[num_pending] = ogate;
608- num_pending += (batch->cnt () == 1 );
609614 }
610615
611- /* phase 2: move batches to local stack , since it may be reentrant */
616+ // phase 2: clear splits , since it may be reentrant.
612617 for (int i = 0 ; i < num_pending; i++) {
613- bess::PacketBatch *batch;
614-
615- batch = &splits[pending[i]];
616- batches[i].Copy (batch);
617- batch->clear ();
618+ splits[pending[i]] = nullptr ;
618619 }
619620
620- /* phase 3: fire */
621+ // phase 3: fire
621622 for (int i = 0 ; i < num_pending; i++)
622623 RunChooseModule (pending[i], &batches[i]);
623624}
0 commit comments