Click
Loading...
Searching...
No Matches
batchelement.hh
1// -*- c-basic-offset: 4 -*-
2#ifndef CLICK_BATCHELEMENT_HH
3#define CLICK_BATCHELEMENT_HH
4#include <click/glue.hh>
5#include <click/vector.hh>
6#include <click/string.hh>
7#include <click/packet.hh>
8#include <click/handler.hh>
9#include <click/master.hh>
10#include <click/element.hh>
11#include <click/packet_anno.hh>
13
21CLICK_DECLS
22
23#ifdef HAVE_BATCH
24
25class PushToPushBatchVisitor;
26class BatchModePropagate;
27
28
29class BatchElement : public Element { public:
30 BatchElement();
31
32 ~BatchElement();
33
34 virtual PacketBatch* simple_action_batch(PacketBatch* batch) {
35 click_chatter("Warning in %s : simple_action_batch should be implemented."
36 " This element is useless, batch will be returned untouched.",name().c_str());
37 return batch;
38 }
39
40 virtual void push_batch(int port, PacketBatch* head) {
41 head = simple_action_batch(head);
42 if (head)
43 output_push_batch(port,head);
44 }
45
46 virtual PacketBatch* pull_batch(int port, unsigned max) {
47 PacketBatch* head = input_pull_batch(port,max);
48 if (head) {
49 head = simple_action_batch(head);
50 }
51 return head;
52 }
53
54 inline void checked_output_push_batch(int port, PacketBatch* batch) {
55 if ((unsigned) port < (unsigned) noutputs()) {
56#if BATCH_DEBUG
57 assert(in_batch_mode == BATCH_MODE_YES);
58#endif
59 output_push_batch(port,batch);
60 } else
61 batch->fast_kill();
62 }
63
64 inline void checked_output_push(int port, Packet* p)
65 {
66 if ((unsigned) port < (unsigned) noutputs()) {
67 if (in_batch_mode == BATCH_MODE_YES) {
68 output_push_batch(port,PacketBatch::make_from_packet(p));
69 } else {
70 _ports[1][port].push(p);
71 }
72 } else {
73 p->kill();
74 }
75 }
76
77 inline void
78 output_push_batch(int port, PacketBatch* batch) {
79 output(port).push_batch(batch);
80 }
81
82 inline void
83 output_push(int port, Packet* p) {
84 if (in_batch_mode == BATCH_MODE_YES) {
86 } else {
87 output(port).push(p);
88 }
89 }
90
91
92 inline PacketBatch*
93 input_pull_batch(int port, int max) {
94 return input(port).pull_batch(max);
95 }
96
97
98protected :
99
103 class BatchModePropagate : public RouterVisitor { public:
104 bool ispush;
105
106 BatchModePropagate() : ispush(true) {}
107
108 bool visit(Element *e, bool isoutput, int,
109 Element *, int, int);
110 };
111
115 class PushToPushBatchVisitor : public RouterVisitor { public:
116
117 PushToPushBatchVisitor(Element* origin);
118
119 bool visit(Element *, bool, int,
120 Element *, int, int);
121 Element* _origin;
122 };
123
124 friend class Router;
125};
126
127#define BATCH_ELEMENT_DEFINE_SIMPLE_ACTION_BATCH(T) \
128 PacketBatch* simple_action_batch(PacketBatch* batch) override {\
129 EXECUTE_FOR_EACH_PACKET_DROPPABLE(T::simple_action,batch,[](Packet*){});\
130 return batch;\
131 }
132
133#else
134#define BATCH_ELEMENT_DEFINE_SIMPLE_ACTION_BATCH(T)
135class BatchElement : public Element { public:
136 inline void checked_output_push_batch(int, PacketBatch*) {
137 click_chatter("Error : checked_output_push_batch called without batching being enabled");
138 assert(false);
139 }
140
141 inline void
142 output_push(int port, Packet* p) {
143 output(port).push(p);
144 }
145};
146#endif
147
159template <typename T, typename Base = BatchElement>
160class ClassifyElement : public Base { public:
161
162 void push(int, Packet *p) {
163 Base::checked_output_push(static_cast<T&>(*this).classify(p),p);
164 }
165
166#if HAVE_BATCH
167 void push_batch(int, PacketBatch *batch) {
168 CLASSIFY_EACH_PACKET(Base::noutputs() + 1, static_cast<T&>(*this).classify,batch,Base::checked_output_push_batch);
169 }
170#endif
171
172 private:
173 ClassifyElement(){};
174 friend T;
175};
176
177
186template <typename T>
187class SimpleBatchElement : public BatchElement { public:
188
189 void push(int port, Packet *p) override {
190 p = static_cast<T&>(*this).simple_action(p);
191 if (p)
192 output(port).push(p);
193 }
194
195 Packet* pull(int port) override {
196 Packet *p = input(port).pull();
197 if (p)
198 p = static_cast<T&>(*this).simple_action(p);
199 return p;
200 }
201
202#if HAVE_BATCH
203 void push_batch(int port, PacketBatch* head) override final {
204 head = static_cast<T&>(*this).simple_action_batch(head);
205 if (head)
206 output_push_batch(port,head);
207 }
208
209 PacketBatch* pull_batch(int port, unsigned max) override final {
210 PacketBatch* head = input_pull_batch(port,max);
211 if (head)
212 head = static_cast<T&>(*this).simple_action_batch(head);
213 return head;
214 }
215#endif
216
217 private:
219 friend T;
220
221};
222
223
236template <typename T>
237class SimpleElement : public BatchElement { public:
238
239 void push(int port, Packet *p) override {
240 p = static_cast<T&>(*this).simple_action(p);
241 if (p)
242 output(port).push(p);
243 }
244
245 Packet* pull(int port) override {
246 Packet *p = input(port).pull();
247 if (p)
248 p = static_cast<T&>(*this).simple_action(p);
249 return p;
250 }
251
252#if HAVE_BATCH
253 void push_batch(int port, PacketBatch* head) override {
254 head = _sm_action_batch(head);
255 if (head)
256 output(port).push_batch(head);
257 }
258
259 PacketBatch* pull_batch(int port, unsigned max) override final {
260 PacketBatch* head = input_pull_batch(port,max);
261 if (head)
262 head = _sm_action_batch(head);
263 return head;
264 }
265#endif
266
267 private:
268
269 inline PacketBatch* _sm_action_batch(PacketBatch* batch) {
270 EXECUTE_FOR_EACH_PACKET_DROPPABLE(static_cast<T&>(*this).simple_action, batch, [](Packet*){});
271 return batch;
272 }
273
274 SimpleElement(){};
275 friend T;
276
277};
278
279
280CLICK_ENDDECLS
281#endif
Definition batchelement.hh:160
void push(int, Packet *p)
Push packet p onto push input port.
Definition batchelement.hh:162
Packet * pull() const
Pull a packet over this port and return it.
Definition element.hh:841
void push(Packet *p) const
Push packet p over this port.
Definition element.hh:765
Base class for Click elements.
Definition element.hh:42
const Port & port(bool isoutput, int port) const
Return one of the element's ports.
Definition element.hh:566
String name() const
Return the element's name.
Definition element.cc:555
enum batch_mode in_batch_mode
Definition element.hh:382
const Port & output(int port) const
Return one of the element's output ports.
Definition element.hh:591
int noutputs() const
Return the number of output ports.
Definition element.hh:555
const Port & input(int port) const
Return one of the element's input ports.
Definition element.hh:579
void checked_output_push(int port, Packet *p) const
Push packet p to output port, or kill it if port is out of range.
Definition element.hh:1031
Definition packetbatch.hh:415
static PacketBatch * make_from_packet(Packet *p)
Definition packetbatch.hh:664
A network packet.
Definition packet.hh:68
void kill()
Delete this packet.
Definition packet.hh:1804
A router configuration.
Definition router.hh:28
Base class for router configuration visitors.
Definition routervisitor.hh:17
Definition batchelement.hh:187
void push(int port, Packet *p) override
Push packet p onto push input port.
Definition batchelement.hh:189
Packet * pull(int port) override
Pull a packet from pull output port.
Definition batchelement.hh:195
Definition batchelement.hh:237
Packet * pull(int port) override
Pull a packet from pull output port.
Definition batchelement.hh:245
void push(int port, Packet *p) override
Push packet p onto push input port.
Definition batchelement.hh:239
Click's Element class.
The Handler class for router handlers.
The Packet class models packets in Click.
Router configuration visitors for finding elements and ports.
Click's String class.
Click's vector container template.