[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Errors in compilation



Hey,
I copied the file to the ns-2.1b4 directory. Then I modified Makefile
to include stfq.o. Then I did a make depend. Then a make. The error
below happened during linking to get the ns executable.

Hope this info. helps help you solve my problem.

Thanks

--sudhir



On Thu, Nov 12, 1998 at 04:22:54PM +0800, Zhu Ming wrote:
> Hi,
> 
> How do you compile it? Do u provide enought source  during that
> compiler? 
> 
> 
> 
> On Thu, 12 Nov 1998, Sudhir Subramanian wrote:
> 
> > I tried to add a subclass of queue called stfq (to implement start
> > time fair queuing). When I compiled it, it gave the following error:
> > 
> > 
> > stfq.o: In function `StfqClass type_info function':
> > /v/hank/v61/manisha/ns-2.1b4/stfq.cc(.text+0x14): undefined reference to `Stfq::Handler virtual table'
> > /v/hank/v61/manisha/ns-2.1b4/stfq.cc(.text+0x18): undefined reference to `Stfq::Handler virtual table'
> > /v/hank/v61/manisha/ns-2.1b4/stfq.cc(.text+0x20): undefined reference to `Stfq virtual table'
> > /v/hank/v61/manisha/ns-2.1b4/stfq.cc(.text+0x24): undefined reference to `Stfq virtual table'
> > 
> > Could someone tell me what is the error.
> > 
> > Thanks
> > 
> > --sudhir
> > 
> > 
> > The code is attached below:
> > -------------------------------------------------------------------------------
> > #include <stdlib.h>
> > #include <string.h>
> > #include "queue.h"
> > 
> > #define MAXFLOW 32
> > 
> > class Stfq : public Queue {
> > public: 
> >   Stfq();
> >   virtual int command(int argc, const char*const* argv);
> >   Packet *deque(void);
> >   void enque(Packet *pkt);
> >   void recv(Packet* p, Handler* h);
> > protected:
> >   struct flowState {
> >     Queue* q_;
> >     //    Packet* hol_;   /* head-of-line packet for each flow */
> >     double finishTag_; /* Stfq finish tag for hol packet */
> >     double startTag_; /* Stfq finish tag for hol packet */
> >     //Handler* handler_;
> >     double weight;// dunno why I keep this!!
> >   } fs_[MAXFLOW];
> >   int active;
> >   double  max_finish_tag;
> > };
> > 
> > static class StfqClass : public TclClass {
> >  public:
> >   StfqClass() : TclClass("Queue/STFQ") {}
> >   TclObject* create(int, const char*const*) {
> >     return (new Stfq);
> >   }
> > } class_stfq;
> > 
> > Stfq::Stfq()
> > {
> >   for (int i = 0; i < MAXFLOW; ++i) {
> >     fs_[i].q_ = 0;
> >     fs_[i].hol_ = 0;
> >     fs_[i].finishTag_ = 0.;
> >     fs_[i].startTag_ = 0.;
> >   }
> >   active = -1;
> >   max_finish_tag = 0;
> > }
> > /*
> > int Stfq::command(int argc, const char*const* argv) {
> >   if (argc == 3) {
> >     if (!strcmp(argv[1], "weight")) {
> >       wt_ = atoi(argv[2]);
> >       return (TCL_OK);
> >     }
> >   }
> >   return Queue::command(argc, argv);
> > }
> > */
> > 
> > Packet* Stfq::deque(void){
> >     
> >   int packet_len;
> >   int i;
> > 
> >   for(i=0; i< MAXFLOW;i++){
> >     if(current == -1)
> >       fs_[i].start_tag = 0;
> >     else if(current == MAXFLOW)
> >       fs_[i].start_tag = max(max_finish_tag,fs_[i].finish_tag);
> >     else
> >       fs_[i].start_tag = max(fs_[i].finish_tag,fs_[current].start_tag);
> >     
> >     packet_len = fs_[i].q_->head_->datalen() + fs_[i].q_->head_->hdrlen_;
> > 
> >     fs_[i].finish_tag = fs_[i].start_tag + packet_len/fs_[i];
> >     
> >   }
> >    
> >   max_finish_tag = fs_[0].finish_tag;
> > 
> >   for(i=1;i<MAXFLOW;i++)
> >     if(fs_[i].finish_tag > max_finish_tag) max_finish_tag = fs_[i].finish_tag;
> >   
> >   int min_start_tag=fs_[0].start_tag;
> >   current = 0;
> > 
> >   for(i=1;i<MAXFLOW;i++)
> >     if(fs_[i].start_tag < min_start_tag){
> >       min_start_tag = fs_[i].start_tag;
> >       current = i;
> >     }
> > 
> >   return fs_[i].q_->deque();
> > }
> > 
> > void Stfq::enque(Packet*)
> > {
> >         /* should never be called because we override recv */
> >         abort();
> > }
> > 
> >    
> > void Stfq::recv(Packet* p, Handler* handler)
> > {
> >   hdr_ip* h = (hdr_ip*)p->access(off_ip_);
> >   int flowid = h->flowid();
> >   /* shouldn't be called when head-of-line is pending */
> >   if (flowid >= MAXFLOW || fs_[flowid].hol_ != 0)
> >     abort();
> >   
> >   /*
> >    * Put this packet at the head-of-line for its queue
> >    * and set up scheduling state according to the
> >    * standard fair-queueing "finish time" equation.
> >    */
> > 
> >   fs_[flowid].q_->enque();
> > 
> >   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) {
> >       blocked_ = 1;
> >       target_->recv(p, &qh_);
> >     }
> >   }
> > }
> > 
> > 
> > ----------------------------------------------------------------------------
> > 
>