#include <scheduler.h>
Inheritance diagram for CalendarScheduler:


Public Member Functions | |
| CalendarScheduler () | |
| ~CalendarScheduler () | |
| void | cancel (Event *) |
| void | insert (Event *) |
| Event * | lookup (scheduler_uid_t uid) |
| Event * | deque () |
| const Event * | head () |
| void | schedule (Handler *, Event *, double delay) |
| virtual void | run () |
| double | clock () const |
| virtual void | sync () |
| virtual double | start () |
| virtual void | reset () |
Static Public Member Functions | |
| Scheduler & | instance () |
Protected Member Functions | |
| virtual void | reinit (int nbuck, double bwidth, double start) |
| virtual void | resize (int newsize, double start) |
| virtual double | newwidth (int newsize) |
| void | dumpq () |
| void | dispatch (Event *) |
| void | dispatch (Event *, double) |
| int | command (int argc, const char *const *argv) |
Protected Attributes | |
| double | width_ |
| double | diff0_ |
| double | diff1_ |
| double | diff2_ |
| int | stat_qsize_ |
| int | nbuckets_ |
| int | lastbucket_ |
| int | top_threshold_ |
| int | bot_threshold_ |
| CalendarScheduler::Bucket * | buckets_ |
| int | qsize_ |
| double | clock_ |
| int | halted_ |
Static Protected Attributes | |
| Scheduler * | instance_ |
| scheduler_uid_t | uid_ = 1 |
Private Member Functions | |
| virtual void | insert2 (Event *) |
Private Attributes | |
| double | cal_clock_ |
|
|
Definition at line 582 of file scheduler.cc. References cal_clock_, and reinit().
00582 : cal_clock_(clock_) { 00583 reinit(4, 1.0, cal_clock_); 00584 } |
Here is the call graph for this function:

|
|
Definition at line 586 of file scheduler.cc. References buckets_, qsize_, and stat_qsize_.
00586 {
00587 // XXX free events?
00588 delete [] buckets_;
00589 qsize_ = 0;
00590 stat_qsize_ = 0;
00591 }
|
|
|
Implements Scheduler. Definition at line 892 of file scheduler.cc. References buckets_, CALENDAR_HASH, CalendarScheduler::Bucket::count_, CalendarScheduler::Bucket::list_, Event::next_, Event::prev_, qsize_, stat_qsize_, Event::time_, and Event::uid_.
00893 {
00894 if (e->uid_ <= 0) // event not in queue
00895 return;
00896
00897 int i = CALENDAR_HASH(e->time_);
00898
00899 assert(e->prev_->next_ == e);
00900 assert(e->next_->prev_ == e);
00901
00902 if (e->next_ == e ||
00903 (e->next_->time_ != e->time_ &&
00904 (e->prev_->time_ != e->time_))) {
00905 --stat_qsize_;
00906 assert(stat_qsize_ >= 0);
00907 --buckets_[i].count_;
00908 assert(buckets_[i].count_ >= 0);
00909 }
00910
00911 if (e->next_ == e) {
00912 assert(buckets_[i].list_ == e);
00913 buckets_[i].list_ = 0;
00914 } else {
00915 e->next_->prev_ = e->prev_;
00916 e->prev_->next_ = e->next_;
00917 if (buckets_[i].list_ == e)
00918 buckets_[i].list_ = e->next_;
00919 }
00920
00921 if (buckets_[i].count_ == 0)
00922 assert(buckets_[i].list_ == 0);
00923
00924 e->uid_ = -e->uid_;
00925 e->next_ = e->prev_ = NULL;
00926
00927 --qsize_;
00928
00929 return;
00930 }
|
|
|
||||||||||||
|
Definition at line 188 of file scheduler.cc. References at_handler, Scheduler::cancel(), Scheduler::clock(), MemTrace::diff(), Scheduler::dumpq(), Scheduler::halted_, Scheduler::instance_, Scheduler::lookup(), AtEvent::proc_, Scheduler::reset(), Scheduler::run(), Scheduler::schedule(), STRTOUID, Event::uid_, and UID_PRINTF_FORMAT.
00189 {
00190 Tcl& tcl = Tcl::instance();
00191 if (instance_ == 0)
00192 instance_ = this;
00193 if (argc == 2) {
00194 if (strcmp(argv[1], "run") == 0) {
00195 /* set global to 0 before calling object reset methods */
00196 reset(); // sets clock to zero
00197 run();
00198 return (TCL_OK);
00199 } else if (strcmp(argv[1], "now") == 0) {
00200 sprintf(tcl.buffer(), "%.17g", clock());
00201 tcl.result(tcl.buffer());
00202 return (TCL_OK);
00203 } else if (strcmp(argv[1], "resume") == 0) {
00204 halted_ = 0;
00205 run();
00206 return (TCL_OK);
00207 } else if (strcmp(argv[1], "halt") == 0) {
00208 halted_ = 1;
00209 return (TCL_OK);
00210
00211 } else if (strcmp(argv[1], "clearMemTrace") == 0) {
00212 #ifdef MEMDEBUG_SIMULATIONS
00213 extern MemTrace *globalMemTrace;
00214 if (globalMemTrace)
00215 globalMemTrace->diff("Sim.");
00216 #endif
00217 return (TCL_OK);
00218 } else if (strcmp(argv[1], "is-running") == 0) {
00219 sprintf(tcl.buffer(), "%d", !halted_);
00220 return (TCL_OK);
00221 } else if (strcmp(argv[1], "dumpq") == 0) {
00222 if (!halted_) {
00223 fprintf(stderr, "Scheduler: dumpq only allowed while halted\n");
00224 tcl.result("0");
00225 return (TCL_ERROR);
00226 }
00227 dumpq();
00228 return (TCL_OK);
00229 }
00230 } else if (argc == 3) {
00231 if (strcmp(argv[1], "at") == 0 ||
00232 strcmp(argv[1], "cancel") == 0) {
00233 Event* p = lookup(STRTOUID(argv[2]));
00234 if (p != 0) {
00235 /*XXX make sure it really is an atevent*/
00236 cancel(p);
00237 AtEvent* ae = (AtEvent*)p;
00238 delete ae;
00239 }
00240 } else if (strcmp(argv[1], "at-now") == 0) {
00241 const char* proc = argv[2];
00242
00243 // "at [$ns now]" may not work because of tcl's
00244 // string number resolution
00245 AtEvent* e = new AtEvent;
00246 int n = strlen(proc);
00247 e->proc_ = new char[n + 1];
00248 strcpy(e->proc_, proc);
00249 schedule(&at_handler, e, 0);
00250 sprintf(tcl.buffer(), UID_PRINTF_FORMAT, e->uid_);
00251 tcl.result(tcl.buffer());
00252 }
00253 return (TCL_OK);
00254 } else if (argc == 4) {
00255 if (strcmp(argv[1], "at") == 0) {
00256 /* t < 0 means relative time: delay = -t */
00257 double delay, t = atof(argv[2]);
00258 const char* proc = argv[3];
00259
00260 AtEvent* e = new AtEvent;
00261 int n = strlen(proc);
00262 e->proc_ = new char[n + 1];
00263 strcpy(e->proc_, proc);
00264 delay = (t < 0) ? -t : t - clock();
00265 if (delay < 0) {
00266 tcl.result("can't schedule command in past");
00267 return (TCL_ERROR);
00268 }
00269 schedule(&at_handler, e, delay);
00270 sprintf(tcl.buffer(), UID_PRINTF_FORMAT, e->uid_);
00271 tcl.result(tcl.buffer());
00272 return (TCL_OK);
00273 }
00274 }
00275 return (TclObject::command(argc, argv));
00276 }
|
Here is the call graph for this function:

|
|
Implements Scheduler. Definition at line 763 of file scheduler.cc. References bot_threshold_, buckets_, cal_clock_, CalendarScheduler::Bucket::count_, head(), lastbucket_, CalendarScheduler::Bucket::list_, nbuckets_, Event::next_, Event::prev_, qsize_, resize(), stat_qsize_, and Event::time_. Referenced by RealTimeScheduler::run().
00764 {
00765 Event *e = const_cast<Event *>(head());
00766
00767 if (!e)
00768 return 0;
00769
00770 int l = lastbucket_;
00771
00772 // update stats and unlink
00773 if (e->next_ == e || e->next_->time_ != e->time_) {
00774 --stat_qsize_;
00775 //assert(stat_qsize_ >= 0);
00776 --buckets_[l].count_;
00777 //assert(buckets_[l].count_ >= 0);
00778
00779 }
00780 --qsize_;
00781
00782 if (e->next_ == e)
00783 buckets_[l].list_ = 0;
00784 else {
00785 e->next_->prev_ = e->prev_;
00786 e->prev_->next_ = e->next_;
00787 buckets_[l].list_ = e->next_;
00788 }
00789
00790 e->next_ = e->prev_ = NULL;
00791
00792
00793 //if (buckets_[l].count_ == 0)
00794 // assert(buckets_[l].list_ == 0);
00795
00796 if (stat_qsize_ < bot_threshold_) {
00797 resize(nbuckets_ >> 1, cal_clock_);
00798 }
00799
00800 return e;
00801 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 140 of file scheduler.cc. References abort(), Scheduler::clock_, Handler::handle(), Event::handler_, and Event::uid_.
|
Here is the call graph for this function:

|
|
Definition at line 153 of file scheduler.cc. References Event::time_. Referenced by RealTimeScheduler::run(), and Scheduler::run().
|
|
|
Definition at line 279 of file scheduler.cc. References Scheduler::clock(), Scheduler::deque(), Event::handler_, Event::time_, Event::uid_, and UID_PRINTF_FORMAT. Referenced by Scheduler::command().
|
Here is the call graph for this function:

|
|
Implements Scheduler. Definition at line 701 of file scheduler.cc. References buckets_, cal_clock_, lastbucket_, CalendarScheduler::Bucket::list_, nbuckets_, qsize_, and Event::time_. Referenced by deque(), insert(), insert2(), lookup(), and RealTimeScheduler::run().
00702 {
00703 if (qsize_ == 0)
00704 return NULL;
00705
00706 int l, i = lastbucket_;
00707 int lastbucket_dec = (lastbucket_) ? lastbucket_ - 1 : nbuckets_ - 1;
00708 double diff;
00709 Event *e, *min_e = NULL;
00710 #define CAL_DEQUEUE(x) \
00711 do { \
00712 if ((e = buckets_[i].list_) != NULL) { \
00713 diff = e->time_ - cal_clock_; \
00714 if (diff < diff##x##_) { \
00715 l = i; \
00716 goto found_l; \
00717 } \
00718 if (min_e == NULL || min_e->time_ > e->time_) { \
00719 min_e = e; \
00720 l = i; \
00721 } \
00722 } \
00723 if (++i == nbuckets_) i = 0; \
00724 } while (0)
00725
00726 // CAL_DEQUEUE applied successively will find the event to
00727 // dequeue (within one year) and keep track of the
00728 // minimum-priority event seen so far; the argument controls
00729 // the criteria used to decide whether the event should be
00730 // considered `within one year'. Importantly, the number of
00731 // buckets should not be less than 4.
00732 CAL_DEQUEUE(0);
00733 CAL_DEQUEUE(1);
00734 for (; i != lastbucket_dec; ) {
00735 CAL_DEQUEUE(2);
00736 }
00737 // one last bucket is left unchecked - take the minimum
00738 // [could have done CAL_DEQUEUE(3) with diff3_ = bwidth*(nbuck*3/2-1)]
00739 e = buckets_[i].list_;
00740 if (min_e != NULL &&
00741 (e == NULL || min_e->time_ < e->time_))
00742 e = min_e;
00743 else {
00744 //assert(e);
00745 l = i;
00746 }
00747 found_l:
00748 //assert(buckets_[l].count_ >= 0);
00749 //assert(buckets_[l].list_ == e);
00750
00751 /* l is the index of the bucket to dequeue, e is the event */
00752 /*
00753 * still want to advance lastbucket_ and cal_clock_ to save
00754 * time when deque() follows.
00755 */
00756 lastbucket_ = l;
00757 cal_clock_ = e->time_;
00758
00759 return e;
00760 }
|
|
|
Implements Scheduler. Definition at line 594 of file scheduler.cc. References buckets_, cal_clock_, CALENDAR_HASH, head(), lastbucket_, CalendarScheduler::Bucket::list_, nbuckets_, Event::next_, Event::prev_, qsize_, resize(), stat_qsize_, Event::time_, and top_threshold_.
00595 {
00596 int i;
00597 if (cal_clock_ > e->time_) {
00598 // may happen in RT scheduler
00599 cal_clock_ = e->time_;
00600 i = lastbucket_ = CALENDAR_HASH(cal_clock_);
00601 } else
00602 i = CALENDAR_HASH(e->time_);
00603
00604 Event *head = buckets_[i].list_;
00605 Event *before=0;
00606
00607 if (!head) {
00608 buckets_[i].list_ = e;
00609 e->next_ = e->prev_ = e;
00610 ++stat_qsize_;
00611 ++buckets_[i].count_;
00612 } else {
00613 bool newhead;
00614 if (e->time_ >= head->prev_->time_) {
00615 // insert at the tail
00616 before = head;
00617 newhead = false;
00618 } else {
00619 // insert event in time sorted order, FIFO for sim-time events
00620 for (before = head; e->time_ >= before->time_; before = before->next_)
00621 ;
00622 newhead = (before == head);
00623 }
00624
00625 e->next_ = before;
00626 e->prev_ = before->prev_;
00627 before->prev_ = e;
00628 e->prev_->next_ = e;
00629 if (newhead) {
00630 buckets_[i].list_ = e;
00631 //assert(e->time_ <= e->next_->time_);
00632 }
00633 //assert(e->prev_ != e);
00634 if (e->prev_->time_ != e->time_) {
00635 // unique timing
00636 ++stat_qsize_;
00637 ++buckets_[i].count_;
00638 }
00639 }
00640 ++qsize_;
00641 //assert(e == buckets_[i].list_ || e->prev_->time_ <= e->time_);
00642 //assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
00643
00644 if (stat_qsize_ > top_threshold_) {
00645 resize(nbuckets_ << 1, cal_clock_);
00646 return;
00647 }
00648 }
|
Here is the call graph for this function:

|
|
Definition at line 651 of file scheduler.cc. References buckets_, CALENDAR_HASH, head(), CalendarScheduler::Bucket::list_, Event::next_, Event::prev_, qsize_, stat_qsize_, and Event::time_. Referenced by resize().
00652 {
00653 // Same as insert, but for inserts e *before* any same-time-events, if
00654 // there should be any. Since it is used only by CalendarScheduler::newwidth(),
00655 // some important checks present in insert() need not be performed.
00656
00657 int i = CALENDAR_HASH(e->time_);
00658 Event *head = buckets_[i].list_;
00659 Event *before=0;
00660 if (!head) {
00661 buckets_[i].list_ = e;
00662 e->next_ = e->prev_ = e;
00663 ++stat_qsize_;
00664 ++buckets_[i].count_;
00665 } else {
00666 bool newhead;
00667 if (e->time_ > head->prev_->time_) { //strict LIFO, so > and not >=
00668 // insert at the tail
00669 before = head;
00670 newhead = false;
00671 } else {
00672 // insert event in time sorted order, LIFO for sim-time events
00673 for (before = head; e->time_ > before->time_; before = before->next_)
00674 ;
00675 newhead = (before == head);
00676 }
00677
00678 e->next_ = before;
00679 e->prev_ = before->prev_;
00680 before->prev_ = e;
00681 e->prev_->next_ = e;
00682 if (newhead) {
00683 buckets_[i].list_ = e;
00684 //assert(e->time_ <= e->next_->time_);
00685 }
00686
00687 if (e != e->next_ && e->next_->time_ != e->time_) {
00688 // unique timing
00689 ++stat_qsize_;
00690 ++buckets_[i].count_;
00691 }
00692 }
00693 //assert(e == buckets_[i].list_ || e->prev_->time_ <= e->time_);
00694 //assert(e == buckets_[i].list_->prev_ || e->next_->time_ >= e->time_);
00695
00696 ++qsize_;
00697 // no need to check resizing
00698 }
|
Here is the call graph for this function:

|
|
|
Implements Scheduler. Definition at line 933 of file scheduler.cc. References buckets_, head(), CalendarScheduler::Bucket::list_, nbuckets_, Event::next_, and Event::uid_.
|
Here is the call graph for this function:

|
|
Definition at line 862 of file scheduler.cc. References buckets_, CalendarScheduler::Bucket::count_, nbuckets_, and width_. Referenced by resize().
00863 {
00864 int i;
00865 short max_bucket = 0; // index of the fullest bucket
00866 for (i = 1; i < nbuckets_; ++i) {
00867 if (buckets_[i].count_ > buckets_[max_bucket].count_)
00868 max_bucket = i;
00869 }
00870 int nsamples = buckets_[max_bucket].count_;
00871
00872 if (nsamples <= 4) return width_;
00873
00874 double nw = buckets_[max_bucket].list_->prev_->time_
00875 - buckets_[max_bucket].list_->time_;
00876 assert(nw > 0);
00877
00878 nw /= ((newsize < nsamples) ? newsize : nsamples); // min (newsize, nsamples)
00879 nw *= 4.0;
00880
00881 return nw;
00882 }
|
|
||||||||||||||||
|
Definition at line 804 of file scheduler.cc. References bot_threshold_, buckets_, CALENDAR_HASH, diff0_, diff1_, diff2_, lastbucket_, nbuckets_, qsize_, stat_qsize_, top_threshold_, and width_. Referenced by CalendarScheduler(), and resize().
00805 {
00806 buckets_ = new Bucket[nbuck];
00807
00808 memset(buckets_, 0, sizeof(Bucket)*nbuck); //faster than ctor
00809
00810 width_ = bwidth;
00811 nbuckets_ = nbuck;
00812 qsize_ = 0;
00813 stat_qsize_ = 0;
00814
00815 lastbucket_ = CALENDAR_HASH(start);
00816
00817 diff0_ = bwidth*nbuck/2;
00818 diff1_ = diff0_ + bwidth;
00819 diff2_ = bwidth*nbuck;
00820 //diff3_ = bwidth*(nbuck*3/2-1);
00821
00822 bot_threshold_ = (nbuck >> 1) - 2;
00823 top_threshold_ = (nbuck << 1);
00824 }
|
|
|
Reimplemented in RealTimeScheduler. Definition at line 182 of file scheduler.cc. References Scheduler::clock_, and SCHED_START. Referenced by Scheduler::command().
00183 {
00184 clock_ = SCHED_START;
00185 }
|
|
||||||||||||
|
Definition at line 827 of file scheduler.cc. References buckets_, insert2(), CalendarScheduler::Bucket::list_, nbuckets_, newwidth(), Event::next_, Event::prev_, and reinit(). Referenced by deque(), and insert().
00828 {
00829 double bwidth = newwidth(newsize);
00830
00831 if (newsize < 4)
00832 newsize = 4;
00833
00834 Bucket *oldb = buckets_;
00835 int oldn = nbuckets_;
00836
00837 reinit(newsize, bwidth, start);
00838
00839 // copy events to new buckets
00840 int i;
00841
00842 for (i = 0; i < oldn; ++i) {
00843 // we can do inserts faster, if we use insert2, but to
00844 // preserve FIFO, we have to start from the end of
00845 // each bucket and use insert2
00846 if (oldb[i].list_) {
00847 Event *tail = oldb[i].list_->prev_;
00848 Event *e = tail;
00849 do {
00850 Event* ep = e->prev_;
00851 e->next_ = e->prev_ = 0;
00852 insert2(e);
00853 e = ep;
00854 } while (e != tail);
00855 }
00856 }
00857 delete [] oldb;
00858 }
|
Here is the call graph for this function:

|
|
Reimplemented in RealTimeScheduler. Definition at line 118 of file scheduler.cc. References Scheduler::deque(), Scheduler::dispatch(), Scheduler::halted_, and Scheduler::instance_. Referenced by Scheduler::command().
00119 {
00120 instance_ = this;
00121 Event *p;
00122 /*
00123 * The order is significant: if halted_ is checked later,
00124 * event p could be lost when the simulator resumes.
00125 * Patch by Thomas Kaemer <Thomas.Kaemer@eas.iis.fhg.de>.
00126 */
00127 while (!halted_ && (p = deque())) {
00128 dispatch(p, p->time_);
00129 }
00130 }
|
Here is the call graph for this function:

|
||||||||||||||||
Here is the call graph for this function:

|
|
Definition at line 94 of file scheduler.h. References SCHED_START.
00094 { // start time
00095 return SCHED_START;
00096 }
|
|
|
Reimplemented in RealTimeScheduler. Definition at line 93 of file scheduler.h. Referenced by TapAgent::dispatch().
00093 {};
|
|
|
Definition at line 163 of file scheduler.h. |
|
|
Referenced by cancel(), deque(), head(), insert(), insert2(), lookup(), newwidth(), reinit(), resize(), and ~CalendarScheduler(). |
|
|
Definition at line 178 of file scheduler.h. Referenced by CalendarScheduler(), deque(), head(), and insert(). |
|
|
Definition at line 105 of file scheduler.h. Referenced by Scheduler::clock(), Scheduler::dispatch(), RealTimeScheduler::reset(), Scheduler::reset(), RealTimeScheduler::run(), Scheduler::schedule(), and RealTimeScheduler::sync(). |
|
|
Definition at line 157 of file scheduler.h. Referenced by reinit(). |
|
|
Definition at line 157 of file scheduler.h. Referenced by reinit(). |
|
|
Definition at line 157 of file scheduler.h. Referenced by reinit(). |
|
|
Definition at line 106 of file scheduler.h. Referenced by Scheduler::command(), RealTimeScheduler::run(), and Scheduler::run(). |
|
|
Definition at line 55 of file scheduler.cc. Referenced by Scheduler::command(), RealTimeScheduler::run(), Scheduler::run(), and Scheduler::~Scheduler(). |
|
|
Definition at line 161 of file scheduler.h. |
|
|
Definition at line 160 of file scheduler.h. Referenced by deque(), head(), insert(), lookup(), newwidth(), reinit(), and resize(). |
|
|
Definition at line 170 of file scheduler.h. Referenced by cancel(), deque(), head(), insert(), insert2(), reinit(), and ~CalendarScheduler(). |
|
|
Definition at line 159 of file scheduler.h. Referenced by cancel(), deque(), insert(), insert2(), reinit(), and ~CalendarScheduler(). |
|
|
Definition at line 162 of file scheduler.h. |
|
|
Definition at line 56 of file scheduler.cc. Referenced by Scheduler::schedule(). |
|
|
Definition at line 156 of file scheduler.h. Referenced by newwidth(), and reinit(). |
1.3.3