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 #include "systemclocktypes.h"
00027 #include "systemclock.h"
00028 #include "simulationmember.h"
00029 #include "helper.h"
00030 #include "application.h"
00031 #include "avrerror.h"
00032
00033 #include "signal.h"
00034 #include <assert.h>
00035
00036 using namespace std;
00037
00038
00039 template<typename Key, typename Value>
00040 MinHeap<Key, Value>::MinHeap()
00041 {
00042 this->reserve(10);
00043 }
00044
00045 template<typename Key, typename Value>
00046 void MinHeap<Key, Value>::RemoveMinimum()
00047 {
00048 assert(!this->empty());
00049 Key k = this->back().first;
00050 Value v = this->back().second;
00051 RemoveMinimumAndInsert(k, v);
00052 this->pop_back();
00053 }
00054
00055 template<typename Key, typename Value>
00056 bool MinHeap<Key, Value>::ContainsValue(Value v) const
00057 {
00058 for(unsigned i = 0; i < this->size(); i++)
00059 {
00060 std::pair<Key,Value> item = (*this)[i];
00061 if(item.second == v)
00062 return true;
00063 }
00064 return false;
00065 }
00066
00067 template<typename Key, typename Value>
00068 void MinHeap<Key, Value>::Insert(Key k, Value v)
00069 {
00070 resize(this->size()+1);
00071 for(unsigned i = this->size();;) {
00072 unsigned parent = i/2;
00073 if(parent == 0 || (*this)[parent-1].first < k) {
00074 (*this)[i-1].first = k;
00075 (*this)[i-1].second = v;
00076 return;
00077 }
00078 Key k_temp = (*this)[parent-1].first;
00079 Value v_temp = (*this)[parent-1].second;
00080 (*this)[i-1].first = k_temp;
00081 (*this)[i-1].second = v_temp;
00082 i = parent;
00083 }
00084 }
00085
00086 template<typename Key, typename Value>
00087 void MinHeap<Key, Value>::RemoveMinimumAndInsert(Key k, Value v)
00088 {
00089 assert(!this->empty());
00090 unsigned i = 1;
00091 for(;;) {
00092 unsigned left = 2*i;
00093 unsigned right = 2*i + 1;
00094 unsigned smallest = i;
00095 if(left-1 < this->size() && (*this)[left-1].first < k)
00096 smallest = left;
00097 if(right-1 < this->size() && (*this)[right-1].first < k)
00098 smallest = right;
00099 if(smallest == i) {
00100 (*this)[smallest-1].first = k;
00101 (*this)[smallest-1].second = v;
00102 return;
00103 }
00104 Key k_temp = (*this)[smallest-1].first;
00105 Value v_temp = (*this)[smallest-1].second;
00106 (*this)[smallest-1].first = k;
00107 (*this)[smallest-1].second = v;
00108 k = k_temp;
00109 v = v_temp;
00110 i = smallest;
00111 }
00112 }
00113
00114
00115 SystemClock::SystemClock() {
00116 static int no = 0;
00117 currentTime = 0;
00118 no++;
00119 if(no > 1)
00120 avr_error("Crazy problem: Second instance of SystemClock created!");
00121 }
00122
00123 void SystemClock::SetTraceModeForAllMembers(int trace_on) {
00124 MinHeap<SystemClockOffset, SimulationMember *>::iterator mi;
00125 for(mi = syncMembers.begin(); mi != syncMembers.end(); mi++)
00126 {
00127 AvrDevice* core = dynamic_cast<AvrDevice*>( mi->second );
00128 if(core != NULL)
00129 core->trace_on = trace_on;
00130 }
00131 }
00132
00133
00134 void SystemClock::Add(SimulationMember *dev) {
00135 syncMembers.Insert(currentTime, dev);
00136 }
00137
00138 void SystemClock::AddAsyncMember(SimulationMember *dev) {
00139 asyncMembers.push_back(dev);
00140 }
00141
00142 int SystemClock::Step(bool &untilCoreStepFinished) {
00143
00144 int res = 0;
00145
00146
00147 static vector<SimulationMember*>::iterator ami;
00148 static vector<SimulationMember*>::iterator amiEnd;
00149
00150 if(syncMembers.begin() != syncMembers.end()) {
00151
00152 SimulationMember * core = syncMembers.begin()->second;
00153 currentTime = syncMembers.begin()->first;
00154 SystemClockOffset nextStepIn_ns = -1;
00155
00156
00157 res = core->Step(untilCoreStepFinished, &nextStepIn_ns);
00158
00159 if(nextStepIn_ns == 0) {
00160 nextStepIn_ns = 1 + (syncMembers.IsEmpty() ? currentTime : syncMembers.front().first);
00161 } else if(nextStepIn_ns > 0)
00162 nextStepIn_ns += currentTime;
00163
00164
00165
00166 if(nextStepIn_ns > 0)
00167 syncMembers.RemoveMinimumAndInsert(nextStepIn_ns, core);
00168 else
00169 syncMembers.RemoveMinimum();
00170
00171
00172 amiEnd = asyncMembers.end();
00173 for(ami = asyncMembers.begin(); ami != amiEnd; ami++) {
00174 bool untilCoreStepFinished = false;
00175 (*ami)->Step(untilCoreStepFinished, 0);
00176 }
00177 }
00178
00179 return res;
00180 }
00181
00182 void SystemClock::Rescedule(SimulationMember *sm, SystemClockOffset newTime) {
00183 MinHeap<SystemClockOffset, SimulationMember *>::iterator ii;
00184
00185 for(ii=syncMembers.begin(); ii != syncMembers.end(); ii++) {
00186 if(ii->second == sm) {
00187 syncMembers.erase(ii);
00188 break;
00189 }
00190 }
00191
00192 syncMembers.Insert(newTime+currentTime+1, sm);
00193 }
00194
00195 volatile int breakMessage = false;
00196
00197 void OnBreak(int s) {
00198 signal(SIGINT, SIG_DFL);
00199 signal(SIGTERM, SIG_DFL);
00200 breakMessage = true;
00201 }
00202
00203 void SystemClock::stop() {
00204 breakMessage = true;
00205 }
00206
00207 void SystemClock::ResetClock(void) {
00208 asyncMembers.clear();
00209 syncMembers.clear();
00210 currentTime = 0;
00211 }
00212
00213 void SystemClock::Endless() {
00214 int steps = 0;
00215
00216 signal(SIGINT, OnBreak);
00217 signal(SIGTERM, OnBreak);
00218
00219 while(breakMessage == false) {
00220 steps++;
00221 bool untilCoreStepFinished = false;
00222 Step(untilCoreStepFinished);
00223 }
00224
00225 cout << "SystemClock::Endless stopped" << endl;
00226 cout << "number of cpu cycles simulated: " << dec << steps << endl;
00227 Application::GetInstance()->PrintResults();
00228 }
00229
00230
00231 void SystemClock::Run(SystemClockOffset maxRunTime) {
00232 int steps = 0;
00233
00234 signal(SIGINT, OnBreak);
00235 signal(SIGTERM, OnBreak);
00236
00237 while((breakMessage== false) &&
00238 (SystemClock::Instance().GetCurrentTime() < maxRunTime)) {
00239 steps++;
00240 bool untilCoreStepFinished =false;
00241 Step(untilCoreStepFinished);
00242 }
00243
00244 cout << endl << "Ran too long. Terminated after " << maxRunTime;
00245 cout << " simulated nanoseconds." << endl;
00246
00247 Application::GetInstance()->PrintResults();
00248 }
00249
00250 int SystemClock::RunTimeRange(SystemClockOffset timeRange) {
00251 int res = 0;
00252 bool untilCoreStepFinished;
00253
00254 signal(SIGINT, OnBreak);
00255 signal(SIGTERM, OnBreak);
00256
00257 timeRange += SystemClock::Instance().GetCurrentTime();
00258 while((breakMessage == false) && (SystemClock::Instance().GetCurrentTime() < timeRange)) {
00259 untilCoreStepFinished = false;
00260 res = Step(untilCoreStepFinished);
00261 if(res != 0)
00262 break;
00263 }
00264
00265 return res;
00266 }
00267
00268 SystemClock& SystemClock::Instance() {
00269 static SystemClock obj;
00270 return obj;
00271 }
00272