00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <tclcl.h>
00055
00056 #include "empftp.h"
00057
00058
00059 int EmpFtpTrafSession::LASTFILE_ = 1;
00060
00061
00062
00063 EmpFtpTrafSession::~EmpFtpTrafSession()
00064 {
00065
00066 if (nFile_ != curFile_) {
00067 fprintf(stderr, "done files %d != all files %d\n",
00068 nFile_, curFile_);
00069 abort();
00070 }
00071 if (status_ != TIMER_IDLE) {
00072 fprintf(stderr, "EmpFtpTrafSession must be idle when deleted.\n");
00073 abort();
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 }
00094
00095
00096
00097 void EmpFtpTrafSession::expire(Event *)
00098 {
00099
00100 if (curFile_ >= nFile_) return;
00101
00102 sendFile(LASTFILE_++, (int)ceil(rvFileSize_->value()));
00103
00104 if (mgr_->isdebug())
00105 printf("Session %d starting file %d, curfile %d \n",
00106 id_, LASTFILE_-1, curFile_);
00107
00108 }
00109
00110 void EmpFtpTrafSession::handle(Event *e)
00111 {
00112 TimerHandler::handle(e);
00113 if (curFile_ < nFile_) {
00114
00115
00116 curFile_++;
00117 sched(rvInterFile_->value());
00118 } else
00119 mgr_->doneSession(id_);
00120 }
00121
00122
00123 void EmpFtpTrafSession::sendFile(int file, int size)
00124 {
00125
00126 int wins = int(ceil(serverWin()->value()));
00127 int winc = int(ceil(clientWin()->value()));
00128 int window = (wins >= winc) ? wins : winc;
00129
00130
00131
00132 TcpAgent* stcp = mgr_->picktcp(window);
00133
00134 TcpSink* ssnk = mgr_->picksink();
00135
00136
00137 Tcl::instance().evalf("%s send-file %d %s %s %s %s %d %d",
00138 mgr_->name(), file, src_->name(),
00139 dst_->name(), stcp->name(), ssnk->name(), size, mgr_->color_);
00140
00141
00142
00143
00144
00145 if (mgr_->isdebug()) {
00146 printf("%d \t %d \t %d \t %g %d %d\n", size, file, id_,
00147 Scheduler::instance().clock(),
00148 src_->address(), dst_->address());
00149 printf("** Tcp agents %d, Tcp sinks %d\n", mgr_->nTcp(),mgr_->nSink());
00150 }
00151 }
00152
00153
00154 static class EmpFtpTrafPoolClass : public TclClass {
00155 public:
00156 EmpFtpTrafPoolClass() : TclClass("PagePool/EmpFtpTraf") {}
00157 TclObject* create(int, const char*const*) {
00158 return (new EmpFtpTrafPool());
00159 }
00160 } class_empwebtrafpool;
00161
00162 EmpFtpTrafPool::~EmpFtpTrafPool()
00163 {
00164 if (session_ != NULL) {
00165 for (int i = 0; i < nSession_; i++)
00166 delete session_[i];
00167 delete []session_;
00168 }
00169 if (server_ != NULL)
00170 delete []server_;
00171 if (client_ != NULL)
00172 delete []client_;
00173
00174 }
00175
00176 void EmpFtpTrafPool::delay_bind_init_all()
00177 {
00178 delay_bind_init_one("debug_");
00179 PagePool::delay_bind_init_all();
00180 }
00181
00182 int EmpFtpTrafPool::delay_bind_dispatch(const char *varName,const char *localName,
00183 TclObject *tracer)
00184 {
00185 if (delay_bind_bool(varName, localName, "debug_", &debug_, tracer))
00186 return TCL_OK;
00187 return PagePool::delay_bind_dispatch(varName, localName, tracer);
00188 }
00189
00190 EmpFtpTrafPool::EmpFtpTrafPool() :
00191 nSrc_(0), server_(NULL), session_(NULL), nClient_(0), client_(NULL),
00192 nTcp_(0), nSink_(0)
00193 {
00194 LIST_INIT(&tcpPool_);
00195 LIST_INIT(&sinkPool_);
00196 }
00197
00198 TcpAgent* EmpFtpTrafPool::picktcp(int win)
00199 {
00200
00201 TcpAgent* a = (TcpAgent*)detachHead(&tcpPool_);
00202 if (a == NULL) {
00203 Tcl& tcl = Tcl::instance();
00204 tcl.evalf("%s alloc-tcp %d", name(), win);
00205 a = (TcpAgent*)lookup_obj(tcl.result());
00206 if (a == NULL) {
00207 fprintf(stderr, "Failed to allocate a TCP agent\n");
00208 abort();
00209 }
00210 } else
00211 nTcp_--;
00212 return a;
00213 }
00214
00215 TcpSink* EmpFtpTrafPool::picksink()
00216 {
00217 TcpSink* a = (TcpSink*)detachHead(&sinkPool_);
00218 if (a == NULL) {
00219 Tcl& tcl = Tcl::instance();
00220 tcl.evalf("%s alloc-tcp-sink", name());
00221 a = (TcpSink*)lookup_obj(tcl.result());
00222 if (a == NULL) {
00223 fprintf(stderr, "Failed to allocate a TCP sink\n");
00224 abort();
00225 }
00226 } else
00227 nSink_--;
00228 return a;
00229 }
00230
00231 int EmpFtpTrafPool::command(int argc, const char*const* argv)
00232 {
00233 if (argc == 3) {
00234 if (strcmp(argv[1], "set-num-session") == 0) {
00235 if (session_ != NULL) {
00236 for (int i = 0; i < nSession_; i++)
00237 delete session_[i];
00238 delete []session_;
00239 }
00240 nSession_ = atoi(argv[2]);
00241 session_ = new EmpFtpTrafSession*[nSession_];
00242 memset(session_, 0, sizeof(EmpFtpTrafSession*)*nSession_);
00243 return (TCL_OK);
00244 } else if (strcmp(argv[1], "set-num-server-lan") == 0) {
00245 nSrcL_ = atoi(argv[2]);
00246 if (nSrcL_ > nSrc_) {
00247 fprintf(stderr, "Wrong server index %d\n", nSrcL_);
00248 return TCL_ERROR;
00249 }
00250 return (TCL_OK);
00251 } else if (strcmp(argv[1], "set-num-remote-client") == 0) {
00252 nClientL_ = atoi(argv[2]);
00253 if (nClientL_ > nClient_) {
00254 fprintf(stderr, "Wrong client index %d\n", nClientL_);
00255 return TCL_ERROR;
00256 }
00257 return (TCL_OK);
00258 } else if (strcmp(argv[1], "set-num-server") == 0) {
00259 nSrc_ = atoi(argv[2]);
00260 if (server_ != NULL)
00261 delete []server_;
00262 server_ = new Node*[nSrc_];
00263 return (TCL_OK);
00264 } else if (strcmp(argv[1], "set-num-client") == 0) {
00265 nClient_ = atoi(argv[2]);
00266 if (client_ != NULL)
00267 delete []client_;
00268 client_ = new Node*[nClient_];
00269 return (TCL_OK);
00270 }
00271 } else if (argc == 4) {
00272 if (strcmp(argv[1], "set-server") == 0) {
00273 Node* cli = (Node*)lookup_obj(argv[3]);
00274 if (cli == NULL)
00275 return (TCL_ERROR);
00276 int nc = atoi(argv[2]);
00277 if (nc >= nSrc_) {
00278 fprintf(stderr, "Wrong server index %d\n", nc);
00279 return TCL_ERROR;
00280 }
00281 server_[nc] = cli;
00282 return (TCL_OK);
00283 } else if (strcmp(argv[1], "set-client") == 0) {
00284 Node* s = (Node*)lookup_obj(argv[3]);
00285 if (s == NULL)
00286 return (TCL_ERROR);
00287 int n = atoi(argv[2]);
00288 if (n >= nClient_) {
00289 fprintf(stderr, "Wrong client index %d\n", n);
00290 return TCL_ERROR;
00291 }
00292 client_[n] = s;
00293 return (TCL_OK);
00294 } else if (strcmp(argv[1], "recycle") == 0) {
00295
00296
00297
00298 Agent* tcp = (Agent*)lookup_obj(argv[2]);
00299 Agent* snk = (Agent*)lookup_obj(argv[3]);
00300 nTcp_++, nSink_++;
00301 if ((tcp == NULL) || (snk == NULL))
00302 return (TCL_ERROR);
00303
00304 insertAgent(&tcpPool_, tcp);
00305 insertAgent(&sinkPool_, snk);
00306 return (TCL_OK);
00307 }
00308 } else if (argc == 12) {
00309 if (strcmp(argv[1], "create-session") == 0) {
00310
00311
00312
00313
00314
00315 int n = atoi(argv[2]);
00316 if ((n < 0)||(n >= nSession_)||(session_[n] != NULL)) {
00317 fprintf(stderr,"Invalid session index %d\n",n);
00318 return (TCL_ERROR);
00319 }
00320 int nfile = (int)strtod(argv[3], NULL);
00321 double lt = strtod(argv[4], NULL);
00322
00323 int flip = atoi(argv[10]);
00324 if ((flip < 0)||(flip > 1)) {
00325 fprintf(stderr,"Invalid I/O flag %d\n",flip);
00326 return (TCL_ERROR);
00327 }
00328
00329 color_ = atoi(argv[11]);
00330
00331 EmpFtpTrafSession* p =
00332 new EmpFtpTrafSession(this, nfile, n);
00333
00334 int res = lookup_rv(p->interFile(), argv[5]);
00335 res = (res == TCL_OK) ?
00336 lookup_rv(p->fileSize(), argv[6]) : TCL_ERROR;
00337 res = (res == TCL_OK) ?
00338 lookup_rv(p->serverSel(), argv[7]) : TCL_ERROR;
00339 res = (res == TCL_OK) ?
00340 lookup_rv(p->serverWin(), argv[8]) : TCL_ERROR;
00341 res = (res == TCL_OK) ?
00342 lookup_rv(p->clientWin(), argv[9]) : TCL_ERROR;
00343 if (res == TCL_ERROR) {
00344 delete p;
00345 fprintf(stderr, "Invalid random variable\n");
00346 return (TCL_ERROR);
00347 }
00348
00349 int cl, svr;
00350 if (flip == 1) {
00351 cl = int(floor(Random::uniform(0, nClientL_)));
00352 svr=0;
00353 } else {
00354 cl = int(floor(Random::uniform(nClientL_, nClient_)));
00355 svr= int(ceil(p->serverSel()->value()));
00356 }
00357 assert((cl >= 0) && (cl < nClient_));
00358 printf("%d %d\n",svr , nSrc_);
00359 assert((svr >= 0) && (svr < nSrc_));
00360 Node* c=client_[cl];
00361 Node* s=server_[svr];
00362
00363 p->setClient(c);
00364 p->setServer(s);
00365
00366 p->sched(lt);
00367 session_[n] = p;
00368
00369 return (TCL_OK);
00370 }
00371 }
00372 return PagePool::command(argc, argv);
00373 }
00374
00375