//#ifndef tqueue_h //#define tqueue_h // bin queue for the fixed step method for NetCons and PreSyns. Splay tree // for others. // fifo for the NetCons and PreSyns with same delay. Splay tree for // others (especially SelfEvents). // note that most methods below assume a TQItem is in the splay tree // For the bin part, only insert_fifo, and remove make sense, // and forall_callback does the splay tree first and then the bin (so // not in time order) // The bin part assumes a fixed step method. #include #define COLLECT_TQueue_STATISTICS 1 struct SPTREE; class TQItemPool; class TQItem { public: TQItem(); virtual ~TQItem(); boolean check(); void clear(){}; public: void* data_; double t_; TQItem* left_; TQItem* right_; TQItem* parent_; int cnt_; // reused: -1 means it is in the splay tree, >=0 gives bin }; // helper class for the TQueue (SplayTBinQueue). class BinQ { public: BinQ(); virtual ~BinQ(); void enqueue(double tt, TQItem*); void shift(double tt) { assert(!bins_[qpt_]); tt_ = tt; if (++qpt_ >= nbin_) { qpt_ = 0; }} TQItem* top() { return bins_[qpt_]; } TQItem* dequeue(); double tbin() { return tt_; } // for iteration TQItem* first(); TQItem* next(TQItem*); void remove(TQItem*); void resize(int); #if COLLECT_TQueue_STATISTICS public: int nfenq, nfdeq, nfrem; #endif private: double tt_; // time at beginning of qpt_ interval int nbin_, qpt_; TQItem** bins_; }; class TQueue { public: TQueue(TQItemPool*, int mkmut = 0); virtual ~TQueue(); #if FAST_LEAST TQItem* least() {return least_;} #if USE_PTHREAD double least_t(){double tt; MUTLOCK; if (least_) { tt = least_->t_;}else{tt = 1e15;} MUTUNLOCK; return tt;} #else double least_t(){if (least_) { return least_->t_;}else{return 1e15;}} #endif #else TQItem* least(); // does not remove from TQueue double least_t(); #endif TQItem* atomic_dq(double til); TQItem* insert(double t, void* data); TQItem* enqueue_bin(double t, void* data); TQItem* dequeue_bin() { return binq_->dequeue(); } void shift_bin(double t) { ++nshift_; binq_->shift(t); } double tbin() { return binq_->tbin(); } TQItem* top() { return binq_->top(); } void release(TQItem*); TQItem* find(double t); void remove(TQItem*); void move(TQItem*, double tnew); void move_least(double tnew); void print(); void check(const char* errmess); void statistics(); void spike_stat(double*); void forall_callback(void (*)(const TQItem*, int)); int nshift_; void deleteitem(TQItem*); private: double least_t_nolock(){if (least_) { return least_->t_;}else{return 1e15;}} void move_least_nolock(double tnew); SPTREE* sptree_; BinQ* binq_; TQItem* least_; TQItemPool* tpool_; MUTDEC #if COLLECT_TQueue_STATISTICS unsigned long ninsert, nrem, nleast, nbal, ncmplxrem; unsigned long ncompare, nleastsrch, nfind, nfindsrch, nmove, nfastmove; #endif }; //#endif