| 526 | } |
| 527 | |
| 528 | inline void Module::EmitPacket(Context *ctx, bess::Packet *pkt, |
| 529 | gate_idx_t ogate_idx) { |
| 530 | // Check if valid ogate is set |
| 531 | if (unlikely(ogates_.size() <= ogate_idx) || unlikely(!ogates_[ogate_idx])) { |
| 532 | DropPacket(ctx, pkt); |
| 533 | return; |
| 534 | } |
| 535 | |
| 536 | Task *task = ctx->task; |
| 537 | |
| 538 | // Put a packet into the ogate |
| 539 | bess::OGate *ogate = ogates_[ogate_idx]; |
| 540 | bess::IGate *igate = ogate->igate(); |
| 541 | bess::PacketBatch *batch = task->get_gate_batch(ogate); |
| 542 | if (!batch) { |
| 543 | if (!ogate->hooks().empty()) { |
| 544 | // Having separate batch to run ogate hooks |
| 545 | batch = task->AllocPacketBatch(); |
| 546 | task->set_gate_batch(ogate, batch); |
| 547 | ctx->gate_with_hook[ctx->gate_with_hook_cnt++] = ogate_idx; |
| 548 | } else { |
| 549 | // If no ogate hooks, just use next igate batch |
| 550 | batch = task->get_gate_batch(igate); |
| 551 | if (batch == nullptr) { |
| 552 | batch = task->AllocPacketBatch(); |
| 553 | task->AddToRun(igate, batch); |
| 554 | task->set_gate_batch(ogate, batch); |
| 555 | } else { |
| 556 | task->set_gate_batch(ogate, task->get_gate_batch(igate)); |
| 557 | } |
| 558 | ctx->gate_without_hook[ctx->gate_without_hook_cnt++] = ogate_idx; |
| 559 | } |
| 560 | } |
| 561 | |
| 562 | if (static_cast<size_t>(batch->cnt()) >= bess::PacketBatch::kMaxBurst) { |
| 563 | if (!ogate->hooks().empty()) { |
| 564 | for (auto &hook : ogate->hooks()) { |
| 565 | hook->ProcessBatch(task->get_gate_batch(ogate)); |
| 566 | } |
| 567 | task->AddToRun(igate, task->get_gate_batch(ogate)); |
| 568 | batch = task->AllocPacketBatch(); |
| 569 | task->set_gate_batch(ogate, batch); |
| 570 | } else { |
| 571 | // allocate a new batch and push |
| 572 | batch = task->AllocPacketBatch(); |
| 573 | task->set_gate_batch(ogate, batch); |
| 574 | task->AddToRun(igate, batch); |
| 575 | } |
| 576 | } |
| 577 | |
| 578 | batch->add(pkt); |
| 579 | } |
| 580 | |
| 581 | inline void Module::ProcessOGates(Context *ctx) { |
| 582 | Task *task = ctx->task; |
nothing calls this directly
no test coverage detected