📄 stridesched.hh
字号:
// -*- c-basic-offset: 4 -*-#ifndef CLICK_STRIDESCHED_HH#define CLICK_STRIDESCHED_HH#include <click/element.hh>#include <click/task.hh>#include <click/notifier.hh>CLICK_DECLS/* * =c * StrideSched(TICKETS0, ..., TICKETSI<N-1>) * =s scheduling * pulls from stride-scheduled inputs * =d * Has one output and N inputs. Performs simple packet-based stride * scheduling, assigning TICKETSI<i> to input I<i> for each input. * * Each time a pull comes in on the output, it pulls on its inputs in the order * specified by the stride scheduling queue, until all inputs have been tried * or one produces a packet. If an input does not produce a packet, it is not * tried again in the current round (for the current pull on the output) even * if it has a very short stride. This minimizes overhead and ensures that * an input that produces a packet, if any, is found as soon as possible, * consistently with the stride scheduler ordering. * * The inputs usually come from Queues or other pull schedulers. * StrideSched uses notification to avoid pulling from empty inputs. * * =h tickets0...ticketsI<N-1> read/write * Returns or sets the number of tickets for each input port. * * =a PrioSched, RoundRobinSched, DRRSched, StrideSwitch */class StrideSched : public Element { public: StrideSched(); ~StrideSched(); const char *class_name() const { return "StrideSched"; } const char *port_count() const { return "1-/1"; } const char *processing() const { return PULL; } const char *flags() const { return "S0"; } int configure(Vector<String> &conf, ErrorHandler *); bool can_live_reconfigure() const { return true; } int initialize(ErrorHandler *); void cleanup(CleanupStage); void add_handlers(); enum { STRIDE1 = 1U<<16, MAX_TICKETS = 1U<<15 }; int tickets(int) const; int set_tickets(int, int, ErrorHandler *); Packet *pull(int port); protected: struct Client { Client **_pprev; Client *_next; unsigned _pass; unsigned _stride; int _tickets; NotifierSignal _signal; Client() : _pprev(0), _next(0), _pass(0), _stride(0), _tickets(-1) { } void set_tickets(int t) { _tickets = t; _stride = t ? STRIDE1 / t : 0; } void stride() { _pass += _stride; } void insert(Client **list) { _pprev = list; while ((_next = *_pprev) && PASS_GT(_pass, _next->_pass)) _pprev = &_next->_next; *_pprev = this; if (_next) _next->_pprev = &_next; } void remove() { if ((*_pprev = _next)) _next->_pprev = _pprev; } }; Client *_all; Client *_list; int nclients() const { return input_is_pull(0) ? ninputs() : noutputs(); } static String read_handler(Element *, void *);};CLICK_ENDDECLS#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -