📄 webtraf.cc.svn-base
字号:
/* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- *////* * webtraf.cc * Copyright (C) 1999 by the University of Southern California * $Id: webtraf.cc,v 1.30 2005/09/18 23:33:35 tomh Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * * The copyright of this module includes the following * linking-with-specific-other-licenses addition: * * In addition, as a special exception, the copyright holders of * this module give you permission to combine (via static or * dynamic linking) this module with free software programs or * libraries that are released under the GNU LGPL and with code * included in the standard release of ns-2 under the Apache 2.0 * license or under otherwise-compatible licenses with advertising * requirements (or modified versions of such code, with unchanged * license). You may copy and distribute such a system following the * terms of the GNU GPL for this module and the licenses of the * other code concerned, provided that you include the source code of * that other code when and as the GNU GPL requires distribution of * source code. * * Note that people who make modified versions of this module * are not obligated to grant this special exception for their * modified versions; it is their choice whether to do so. The GNU * General Public License gives permission to release a modified * version without this exception; this exception also makes it * possible to release a modified version which carries forward this * exception. * *///// Incorporation Polly's web traffic module into the PagePool framework//// $Header: /nfs/jade/vint/CVSROOT/ns-2/webcache/webtraf.cc,v 1.30 2005/09/18 23:33:35 tomh Exp $#include "config.h"#include <tclcl.h>#include <iostream>#include "node.h"#include "pagepool.h"#include "webtraf.h"// Data structures that are specific to this web traffic model and // should not be used outside this file.//// - WebTrafPage// - WebTrafObjectclass WebPage : public TimerHandler {public: WebPage(int id, WebTrafSession* sess, int nObj, Node* dst) : id_(id), sess_(sess), nObj_(nObj), curObj_(0), doneObj_(0), dst_(dst) {} virtual ~WebPage() {} inline void start() { // Call expire() and schedule the next one if needed status_ = TIMER_PENDING; handle(&event_); } inline int id() const { return id_; } Node* dst() { return dst_; } void doneObject() { if (++doneObj_ >= nObj_) { //printf("doneObject: %g %d %d \n", Scheduler::instance().clock(), doneObj_, nObj_); sess_->donePage((void*)this); } } inline int curObj() const { return curObj_; } inline int doneObj() const { return doneObj_; }private: virtual void expire(Event* = 0) { // Launch a request. Make sure size is not 0! if (curObj_ >= nObj_) return; sess_->launchReq(this, LASTOBJ_++, (int)ceil(sess_->objSize()->value())); if (sess_->mgr()->isdebug()) printf("Session %d launched page %d obj %d\n", sess_->id(), id_, curObj_); } virtual void handle(Event *e) { // XXX Note when curObj_ == nObj_, we still schedule the timer // once, but we do not actually send out requests. This extra // schedule is only meant to be a hint to wait for the last // request to finish, then we will ask our parent to delete // this page. // if (curObj_ <= nObj_) { // // Polly Huang: Wed Nov 21 18:18:51 CET 2001 // With explicit doneObject() upcalls from the tcl // space, we don't need to play this trick anymore. if (curObj_ < nObj_) { // If this is not the last object, schedule the next // one. Otherwise stop and tell session to delete me. TimerHandler::handle(e); curObj_++; // Kun-chan Lan: Mon Feb 11 10:12:27 PST 2002 // Don't schedule another one when curObj_ = nObj_ // otherwise the page might already have been deleted // before the next one is up and cause seg fault // in the case of larger interObj()->value() // sched(sess_->interObj()->value()); if (curObj_ < nObj_) sched(sess_->interObj()->value()); } } int id_; WebTrafSession* sess_; int nObj_, curObj_, doneObj_; Node* dst_; static int LASTOBJ_;};int WebPage::LASTOBJ_ = 1;int WebTrafSession::LASTPAGE_ = 1;// ConstructorWebTrafSession::WebTrafSession(WebTrafPool *mgr, Node *src, int np, int id, int ftcp_, int recycle_p) : rvInterPage_(NULL), rvPageSize_(NULL), rvInterObj_(NULL), rvObjSize_(NULL), mgr_(mgr), src_(src), nPage_(np), curPage_(0), donePage_(0), id_(id), interPageOption_(1), fulltcp_(0) { fulltcp_ = ftcp_; recycle_page_ = recycle_p;}// XXX Must delete this after all pages are done!!WebTrafSession::~WebTrafSession() { if (donePage_ != curPage_) { fprintf(stderr, "done pages %d != all pages %d\n", donePage_, curPage_); abort(); } if (status_ != TIMER_IDLE) { fprintf(stderr, "WebTrafSession must be idle when deleted.\n"); abort(); } // Recycle the objects of page level attributes if needed // Reuse these objects may save memory for large simulations--xuanc if (recycle_page_) { if (rvInterPage_ != NULL) Tcl::instance().evalf("delete %s", rvInterPage_->name()); if (rvPageSize_ != NULL) Tcl::instance().evalf("delete %s", rvPageSize_->name()); if (rvInterObj_ != NULL) Tcl::instance().evalf("delete %s", rvInterObj_->name()); if (rvObjSize_ != NULL) Tcl::instance().evalf("delete %s", rvObjSize_->name()); }}void WebTrafSession::donePage(void* ClntData) { WebPage* pg = (WebPage*)ClntData; if (mgr_->isdebug()) printf("Session %d done page %d\n", id_, pg->id()); if (pg->doneObj() != pg->curObj()) { fprintf(stderr, "done objects %d != all objects %d\n", pg->doneObj(), pg->curObj()); abort(); } delete pg; // If all pages are done, tell my parent to delete myself // if (++donePage_ >= nPage_) mgr_->doneSession(id_); else if (interPageOption_) { // Polly Huang: Wed Nov 21 18:23:30 CET 2001 // add inter-page time option // inter-page time = end of a page to the start of the next sched(rvInterPage_->value()); // printf("donePage: %g %d %d\n", Scheduler::instance().clock(), donePage_, curPage_); }}// Launch the current pagevoid WebTrafSession::expire(Event *){ // Pick destination for this page Node* dst = mgr_->pickdst(); // Make sure page size is not 0! WebPage* pg = new WebPage(LASTPAGE_++, this, (int)ceil(rvPageSize_->value()), dst); if (mgr_->isdebug()) printf("Session %d starting page %d, curpage %d\n", id_, LASTPAGE_-1, curPage_); pg->start();}void WebTrafSession::handle(Event *e){ // If I haven't scheduled all my pages, do the next one TimerHandler::handle(e); ++curPage_; // XXX Notice before each page is done, it will schedule itself // one more time, this makes sure that this session will not be // deleted after the above call. Thus the following code will not // be executed in the context of a deleted object. // // Polly Huang: Wed Nov 21 18:23:30 CET 2001 // add inter-page time option // inter-page time = inter-page-start time // If the interPageOption_ is not set, the XXX Notice above applies. if (!interPageOption_) { if (curPage_ < nPage_) { sched(rvInterPage_->value()); // printf("schedule: %g %d %d\n", Scheduler::instance().clock(), donePage_, curPage_); } }}// Launch a request for a particular objectvoid WebTrafSession::launchReq(void* ClntData, int obj, int size) { mgr_->launchReq(src_, ClntData, obj, size);}static class WebTrafPoolClass : public TclClass {public: WebTrafPoolClass() : TclClass("PagePool/WebTraf") { } TclObject* create(int, const char*const*) { return (new WebTrafPool()); }} class_webtrafpool;WebTrafPool::~WebTrafPool(){ if (session_ != NULL) { for (int i = 0; i < nSession_; i++) delete session_[i]; delete []session_; } if (server_ != NULL) delete []server_; if (client_ != NULL) delete []client_; // XXX Destroy tcpPool_ and sinkPool_ ?}void WebTrafPool::delay_bind_init_all(){ delay_bind_init_one("debug_"); PagePool::delay_bind_init_all();}int WebTrafPool::delay_bind_dispatch(const char *varName,const char *localName, TclObject *tracer){ if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer)) return TCL_OK; return PagePool::delay_bind_dispatch(varName, localName, tracer);}// By default we use constant request interval and page sizeWebTrafPool::WebTrafPool() : session_(NULL), nServer_(0), server_(NULL), nClient_(0), client_(NULL), nTcp_(0), nSink_(0), fulltcp_(0), recycle_page_(0){ bind("fulltcp_", &fulltcp_); bind("recycle_page_", &recycle_page_); bind("dont_recycle_", &dont_recycle_); // Debo asimflag_=0; LIST_INIT(&tcpPool_); LIST_INIT(&sinkPool_); dbTcp_a = dbTcp_r = dbTcp_cr = 0;}TcpAgent* WebTrafPool::picktcp(){ TcpAgent* a = (TcpAgent*)detachHead(&tcpPool_); if (a == NULL) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s alloc-tcp", name()); a = (TcpAgent*)lookup_obj(tcl.result()); if (a == NULL) { fprintf(stderr, "Failed to allocate a TCP agent\n"); abort(); } } else nTcp_--; a->set_apptype(PT_HTTP); //printf("A# %d\n", dbTcp_a++); return a;}TcpSink* WebTrafPool::picksink(){ TcpSink* a = (TcpSink*)detachHead(&sinkPool_); if (a == NULL) { Tcl& tcl = Tcl::instance(); tcl.evalf("%s alloc-tcp-sink", name()); a = (TcpSink*)lookup_obj(tcl.result()); if (a == NULL) { fprintf(stderr, "Failed to allocate a TCP sink\n"); abort(); } } else nSink_--; a->set_apptype(PT_HTTP);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -