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 #include "delayer.h"
00037
00038 Delayer::Delayer() : Connector(), last_sent(-100000), alloc_int(NULL),
00039 alloc_len(NULL), alloc_free(1), at_(*this),
00040 spike_int(NULL), spike_len(NULL), spike_free(1),
00041 st_(*this), target_free(1), th_ (*this), prev_h_(NULL), pkt_(NULL) {
00042 }
00043
00044 void Delayer::recv(Packet* p, Handler* h) {
00045 double now = Scheduler::instance().clock();
00046
00047 if (pkt_ != NULL) {
00048 printf("delayer not empty!\n");
00049 exit(1);
00050 }
00051
00052 prev_h_ = h;
00053 pkt_ = p;
00054
00055
00056 if (alloc_len && now - last_sent > alloc_int->value()) {
00057 alloc_free = 0;
00058 at_.resched(alloc_len->value());
00059 return;
00060 }
00061 try_send();
00062 }
00063
00064 void Delayer::try_send() {
00065 double now = Scheduler::instance().clock();
00066
00067 if (debug_)
00068 printf("now %f last_sent %f alloc_free %d target_free %d, spike_free %d\n",
00069 now, last_sent, alloc_free, target_free, spike_free);
00070
00071 if (!target_free || !alloc_free || !spike_free)
00072 return;
00073
00074 if (pkt_ && target_) {
00075 target_->recv(pkt_, &th_);
00076 last_sent = Scheduler::instance().clock();
00077 target_free = 0;
00078 pkt_ = NULL;
00079 }
00080 if (prev_h_)
00081 prev_h_->handle(&e);
00082 }
00083
00084 int Delayer::command(int argc, const char*const* argv) {
00085
00086 if (argc == 2 && !strcmp(argv[1],"block")
00087 && !spike_len
00088 ) {
00089 spike_free = 0;
00090 return (TCL_OK);
00091 }
00092 if (argc == 2 && !strcmp(argv[1],"unblock")
00093
00094 ) {
00095 spike_free = 1;
00096 try_send();
00097 return (TCL_OK);
00098 }
00099
00100 if (argc == 4 && !strcmp(argv[1],"alloc")) {
00101 alloc_int = (RandomVariable *)TclObject::lookup(argv[2]);
00102 alloc_len = (RandomVariable *)TclObject::lookup(argv[3]);
00103 return (TCL_OK);
00104 }
00105
00106 if (argc == 4 && !strcmp(argv[1],"spike")) {
00107 spike_int = (RandomVariable *)TclObject::lookup(argv[2]);
00108 spike_len = (RandomVariable *)TclObject::lookup(argv[3]);
00109 st_.sched(getNextSpikeInt());
00110 return (TCL_OK);
00111 }
00112 return Connector::command(argc, argv);
00113 }
00114
00115 void SpikeTimer::expire(Event*) {
00116
00117 if (delayer_.getSpike()) {
00118 delayer_.takeSpike();
00119 resched(delayer_.getNextSpikeLen());
00120 return;
00121 }
00122 delayer_.freeSpike();
00123 resched(delayer_.getNextSpikeInt());
00124 delayer_.try_send();
00125 }
00126
00127 void AllocTimer::expire(Event*) {
00128 delayer_.freeAlloc();
00129 delayer_.try_send();
00130
00131 }
00132
00133 void TargetHandler::handle(Event*) {
00134 delayer_.freeTarget();
00135 delayer_.try_send();
00136
00137 }
00138