📄 queue.cc
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *//* * Copyright (c) 1996-1997 The Regents of the University of California. * 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 must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Network Research * Group at Lawrence Berkeley National Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic const char rcsid[] = "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/queue/queue.cc,v 1.25 2002/01/01 00:04:53 sfloyd Exp $ (LBL)";#endif#include "queue.h"#include <stdio.h>//JUNGMIN#include "mac-802_11.h"//end of JUNGMIN//#define MAXIMUM_NEIGHBOR 64void PacketQueue::remove(Packet* target){ for (Packet *pp= 0, *p= head_; p; pp= p, p= p->next_) { if (p == target) { if (!pp) deque(); else { if (p == tail_) tail_= pp; pp->next_= p->next_; --len_; bytes_ -= hdr_cmn::access(p)->size(); } return; } } fprintf(stderr, "PacketQueue:: remove() couldn't find target\n"); abort();}/* * Remove packet pkt located after packet prev on the queue. Either p or prev * could be NULL. If prev is NULL then pkt must be the head of the queue. */void PacketQueue::remove(Packet* pkt, Packet *prev) //XXX: screwy{ if (pkt) { if (head_ == pkt) PacketQueue::deque(); /* decrements len_ internally */ else { prev->next_ = pkt->next_; if (tail_ == pkt) tail_ = prev; --len_; bytes_ -= hdr_cmn::access(pkt)->size(); } } return;}//JUNGMINint PacketQueue::BuildQState(int* q_array, int size){ //printf("PacketQueue::BuildQState called len_: %d\n", len_); int i; Packet* tp; struct hdr_mac802_11* dh; int dst; int nodecount = 0; //First reset the array for(i=0; i < size; i++) { q_array[i] = 0; } for(i=0; i < len_; i++) { tp = lookup(i); dh = HDR_MAC802_11(tp); dst = ETHER_ADDR(dh->dh_da); if(dst == -1) continue; //update the q state! if(q_array[dst] == 0) nodecount++; q_array[dst]++; } return nodecount;}//end of JUNGMINvoid QueueHandler::handle(Event*){ queue_.resume();}//JUNGMINQueue::Queue() : Connector(), blocked_(0), unblock_on_resume_(1), qh_(*this), pq_(0), atim_window_(0), wmac_(0), pre_atim_max_(0), pre_atim_iter_(0), pre_atim_(0) /* temporarily NULL *///end of JUNGMIN{ bind("limit_", &qlim_); bind_bool("blocked_", &blocked_); bind_bool("unblock_on_resume_", &unblock_on_resume_);//JUNGMIN ResetQInfo();//end of JUNGMIN}void Queue::recv(Packet* p, Handler*){ int dest; struct hdr_mac802_11* dh = HDR_MAC802_11(p); enque(p);//JUNGMIN if (atim_window_ == 1) { if(!blocked_) { //must block the queue since already one packet is //waiting to be sent. It's just blocked by the //ATIM window. blocked_ = 1; } return; } if (!blocked_) { /* * We're not blocked. Get a packet and send it on. * We perform an extra check because the queue * might drop the packet even if it was * previously empty! (e.g., RED can do this.) */ p = deque(); if (p != 0) { //if it is near the beacon, don't send the packet if(wmac_->NearBeacon(p, 0)) { ReturnPacket(p); return; } //end of implementation blocked_ = 1; target_->recv(p, &qh_); } }//end of JUNGMIN}void Queue::updateStats(int queuesize){ double now = Scheduler::instance().clock(); double newtime = now - total_time_; if (newtime > 0.0) { double oldave = true_ave_; double oldtime = total_time_; double newtime = now - total_time_; true_ave_ = (oldtime * oldave + newtime * queuesize) /now; total_time_ = now; }}//JUNGMINvoid Queue::ResetQInfo(){ for(int i=0; i<MAX_NODES; i++) { q_state_[i] = 0; }}int Queue::ExtractMaximum(int *q_array){ int maximum_node = -1; int maximum_node_var = 0; int q_empty = 0; int i; for(i=0; i<MAX_NODES; i++) { if(q_array[i] > maximum_node_var) { maximum_node = i; q_empty = 1; } } if(q_empty == 0) return -1; //danger of seg fault q_array[i] = 0; return maximum_node;}void Queue::SetATIMWindow(){ atim_window_ = 1; return;}void Queue::StartSendingATIM(){ pre_atim_ = 1; //Build the Queue State and start sending ATIM pre_atim_max_ = BuildQState(q_state_, MAX_NODES); pre_atim_iter_ = 0; if(pre_atim_iter_ < pre_atim_max_) { int dest = ExtractMaximum(q_state_); if(dest == -1) { printf("dest = -1! Something's wrong!\n"); return; } else { wmac_->sendATIM(dest, &qh_); } pre_atim_iter_++; } else { pre_atim_ = 0; }}void Queue::ContinueSendingATIM(){ //Build the Queue State and start sending ATIM if(pre_atim_iter_ < pre_atim_max_) { int dest = ExtractMaximum(q_state_); if(dest == -1) { printf("dest = -1! Something's wrong!\n"); return; } else { wmac_->sendATIM(dest, &qh_); } pre_atim_iter_++; } else { pre_atim_ = 0; }}void Queue::ResetATIMWindow(int status){ atim_window_ = 0; if(status == 1) resume();}void Queue::resume(){ //If the queue is backlogged, send the packet immediately. if (atim_window_ == 1) { //status: pre_atim_ (only) if(pre_atim_ == 1) { ContinueSendingATIM(); } return; } Packet* p = deque(); if (p != 0) { //if it is near beacon, don't send the packet if(wmac_->NearBeacon(p, 1)) { //printf("[%d] %lf: Returning PACKET TO QUEUE DOWN from resume, queue size: %d\n", wmac_->addr(), NOW, length()); ReturnPacket(p); return; } //end of implementation target_->recv(p, &qh_); } else { if (unblock_on_resume_) blocked_ = 0; else blocked_ = 1; }}void Queue::reset(){ Packet* p; total_time_ = 0.0; true_ave_ = 0.0; while ((p = deque()) != 0) drop(p);}void Queue::set_wmac(Mac802_11* m){ wmac_ = m;}//end of JUNGMIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -