📄 stridesched.cc
字号:
// -*- c-basic-offset: 4 -*-/* * stridesched.{cc,hh} -- stride scheduler * Max Poletto, Eddie Kohler * * Copyright (c) 2000 Massachusetts Institute of Technology * Copyright (c) 2003 International Computer Science Institute * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "stridesched.hh"#include <click/confparse.hh>#include <click/straccum.hh>#include <click/error.hh>CLICK_DECLSStrideSched::StrideSched() : _all(0), _list(0){}StrideSched::~StrideSched(){}intStrideSched::configure(Vector<String> &conf, ErrorHandler *errh){ if (conf.size() != nclients()) return errh->error("need %d arguments, one per %s port", nclients(), (processing() == PULL ? "input" : "output")); bool first = !_all; if (first && !(_all = new Client[nclients()])) return errh->error("out of memory"); int before = errh->nerrors(); for (int i = 0; i < conf.size(); i++) { int v; if (!cp_integer(conf[i], &v)) errh->error("argument %d should be number of tickets (integer)", i); else if (v < 0) errh->error("argument %d (number of tickets) must be >= 0", i); else { if (v > MAX_TICKETS) { errh->warning("input %d's tickets reduced to %d", i, MAX_TICKETS); v = MAX_TICKETS; } _all[i].set_tickets(v); if (first) _all[i].stride(); } } // insert into reverse order so they're run in forward order on ties _list = 0; for (int i = nclients() - 1; i >= 0; i--) if (_all[i]._tickets) _all[i].insert(&_list); return (errh->nerrors() == before ? 0 : -1);}intStrideSched::initialize(ErrorHandler *){ if (input_is_push(0)) for (int i = 0; i < nclients(); ++i) _all[i]._signal = Notifier::upstream_empty_signal(this, i, 0); return 0;}voidStrideSched::cleanup(CleanupStage){ delete[] _all;}Packet *StrideSched::pull(int){ // go over list until we find a packet, striding as we go Client *stridden = _list, *c; Packet *p = 0; for (c = _list; c && !p; c = c->_next) { if (c->_signal) p = input(c - _all).pull(); c->stride(); } // remove stridden portion from list if ((_list = c)) c->_pprev = &_list; // reinsert stridden portion into list while (stridden != c) { Client *next = stridden->_next; stridden->insert(&_list); stridden = next; } return p;}intStrideSched::tickets(int port) const{ if ((unsigned) port < (unsigned) nclients()) return _all[port]._tickets; else return -1;}intStrideSched::set_tickets(int port, int tickets, ErrorHandler *errh){ if ((unsigned) port >= (unsigned) nclients()) return errh->error("port %d out of range", port); else if (tickets < 0) return errh->error("number of tickets must be >= 0"); else if (tickets > MAX_TICKETS) { errh->warning("port %d's tickets reduced to %d", port, MAX_TICKETS); tickets = MAX_TICKETS; } int old_tickets = _all[port]._tickets; _all[port].set_tickets(tickets); if (tickets == 0 && old_tickets != 0) _all[port].remove(); else if (tickets != 0 && old_tickets == 0) { _all[port]._pass = (_list ? _list->_pass + _all[port]._stride : 0); _all[port].insert(&_list); } return 0;}static Stringread_tickets_handler(Element *e, void *thunk){ StrideSched *ss = (StrideSched *)e; int port = (intptr_t)thunk; return String(ss->tickets(port));}static intwrite_tickets_handler(const String &s, Element *e, void *thunk, ErrorHandler *errh){ StrideSched *ss = (StrideSched *)e; int port = (intptr_t)thunk; int tickets; if (!cp_integer(s, &tickets)) return errh->error("tickets value must be integer"); else return ss->set_tickets(port, tickets, errh);}StringStrideSched::read_handler(Element *e, void *){ StrideSched *ss = static_cast<StrideSched *>(e); StringAccum sa; for (int i = 0; i < ss->nclients(); i++) sa << (i ? ", " : "") << ss->_all[i]._tickets; return sa.take_string();}voidStrideSched::add_handlers(){ // beware: StrideSwitch inherits from StrideSched for (intptr_t i = 0; i < nclients(); i++) { String s = "tickets" + String(i); add_read_handler(s, read_tickets_handler, (void *)i); add_write_handler(s, write_tickets_handler, (void *)i); } add_read_handler("config", read_handler); set_handler_flags("config", 0, Handler::CALM);}CLICK_ENDDECLSEXPORT_ELEMENT(StrideSched)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -