📄 fc-queue.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* By Pablo Martin and Paula Ballester, * Strathclyde University, Glasgow. * June, 2003.*//* Copyright (c) 2003 Strathclyde University of Glasgow, Scotland. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code and binary code must contain * the above copyright notice, this list of conditions and the following * disclaimer. * * 2. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed at Strathclyde University of * Glasgow, Scotland. * * 3. The name of the University may not be used to endorse or promote * products derived from this software without specific prior written * permission. * STRATHCLYDE UNIVERSITY OF GLASGOW, MAKES NO REPRESENTATIONS * CONCERNING EITHER THE MERCHANTABILITY OF THIS SOFTWARE OR THE * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The software * is provided "as is" without express or implied warranty of any kind.*/#include "fc-queue.h"#include <stdio.h>#include <packet.h>/* Timers */void FCTimer::start(Packet *p, double time){ Scheduler &s = Scheduler::instance(); assert(busy_ == 0); busy_ = 1; paused_ = 0; stime = s.clock(); rtime = time; assert(rtime >= 0.0); s.schedule(this, p, rtime);} void FCTimer::stop(Packet *p){ Scheduler &s = Scheduler::instance(); assert(busy_); if(paused_ == 0) s.cancel((Event *)p); busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0;}void FCTimer::handle(Event *e){ busy_ = 0; paused_ = 0; stime = 0.0; rtime = 0.0; queue_->fcHandler(e);}/******************************** FCQueue *************************************/// TCL Classstatic class FCQueueClass : public TclClass {public: FCQueueClass() : TclClass("Queue/DropTail/FCQueue") {} TclObject* create(int, const char*const*) { return (new FCQueue); }} class_FCQueue;int FCQueue::verbose_ = {0};// ConstructorFCQueue::FCQueue() : DropTail(), qTimer_(this){ tti_ = TTI; // set tti_ to 10 ms int i; for (i=0; i<MAX_NUM_FLOWS; i++) { ifqc[i].flowid_ = -1; ifqc[i].bytes_per_tti_ = 0; ifqc[i].len = 0; } ip_ue_ = -1; bind("verbose_",&verbose_); intr = intr_ ; qTimer_.start((Packet *) (& intr_), 0); // start timer}int FCQueue::command(int argc, const char*const* argv){ return DropTail::command(argc, argv);}void FCQueue::recv(Packet* p, Handler*){ hdr_cmn *ch = HDR_CMN(p); if (ch->channel_t() == DTCH) { // if the packet is user data if (q_->length() < limit()) { // check if the queue is full q_->enque(p); // enque the packet } else drop(p); // queue full, drop the packet } else { target_->recv(p, this); // signalling } return;}// return position in ifqc[] for flowint FCQueue::get_pos(int flow){ int i; for (i=0; i<MAX_NUM_FLOWS; i++) { if (ifqc[i].flowid_ == flow){ return (i); // flow found } } return (-1); // not found}// register and de-register for a flowvoid FCQueue::reg(int flow, double l){ int id, len; id = get_pos(flow); if (l == 0) { // drop all the packets stored in the queue belonging to the flow len = q_->length(); while (len > 0) { Packet * prov = q_->deque(); struct hdr_ip *ihprov = HDR_IP(prov); if (ihprov->flowid()== ifqc[id].flowid_) { drop(prov); } else { q_->enque(prov); } --len; } ifqc[id].bytes_per_tti_ = 0; ifqc[id].flowid_ = -1; ifqc[id].len = 0; return; } if (id < 0) { // flow not registered, proceed to register for (id=0; id < MAX_NUM_UE; id++){ if (ifqc[id].flowid_ < 0) { ifqc[id].flowid_ = flow; break; } } } // update ifqc[] fields for the flow ifqc[id].bytes_per_tti_ = l; ifqc[id].len = 0; return;}// handler of FCTimer, executed each tti_void FCQueue::fcHandler(Event *e){ int l, pos; // Restart timer for next tti. qTimer_.start((Packet *)e, tti_); l = q_->length(); // take length of the queue while (l > 0) { // go through all the queue Packet * prov = q_->deque(); struct hdr_cmn *chprov = HDR_CMN(prov); struct hdr_ip *ihprov = HDR_IP(prov); pos = get_pos(ihprov->flowid()); if (ifqc[pos].len < ifqc[pos].bytes_per_tti_){ // allow to tx this packet if (verbose_) printf("UE %d at %f IFQ: ********** sending pkt of size: %d free len: %f and uid: %d bpertti %f\n", ip_ue_, NOW, chprov->size(), ifqc[pos].len, chprov->uid(), ifqc[pos].bytes_per_tti_); ifqc[pos].len += chprov->size(); // update len target_->recv(prov, this); // transmit the packet downwards } else { // enqueue again the packet q_->enque(prov); } --l; } // update len in each tti. for (pos=0; pos<MAX_NUM_FLOWS; pos++) { if ((ifqc[pos].flowid_ != -1) && (ifqc[pos].len > 0)) { ifqc[pos].len -= ifqc[pos].bytes_per_tti_; if (ifqc[pos].len < 0) ifqc[pos].len = 0; } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -