00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __adevs_simulator_h_
00021 #define __adevs_simulator_h_
00022 #include "adevs_abstract_simulator.h"
00023 #include "adevs_models.h"
00024 #include "adevs_event_listener.h"
00025 #include "adevs_sched.h"
00026 #include "adevs_bag.h"
00027 #include "adevs_set.h"
00028 #include "object_pool.h"
00029 #include "adevs_lp.h"
00030 #include <cassert>
00031 #include <cstdlib>
00032 #include <iostream>
00033 #include <vector>
00034
00035 namespace adevs
00036 {
00037
00044 template <class X> class Simulator:
00045 public AbstractSimulator<X>
00046 {
00047 public:
00054 Simulator(Devs<X>* model):
00055 AbstractSimulator<X>(),lp(NULL)
00056 {
00057 schedule(model,0.0);
00058 }
00063 double nextEventTime()
00064 {
00065 return sched.minPriority();
00066 }
00068 void execNextEvent()
00069 {
00070 computeNextOutput();
00071 computeNextState(bogus_input,sched.minPriority());
00072 }
00074 void execUntil(double tend)
00075 {
00076 while (nextEventTime() <= tend && nextEventTime() < DBL_MAX)
00077 execNextEvent();
00078 }
00084 void computeNextOutput();
00093 void computeNextState(Bag<Event<X> >& input, double t);
00099 ~Simulator();
00104 void addModel(Atomic<X>* model)
00105 {
00106 schedule(model,0.0);
00107 }
00112 Simulator(LogicalProcess<X>* lp):
00113 AbstractSimulator<X>(),lp(lp)
00114 {
00115 }
00116 private:
00117
00118 LogicalProcess<X>* lp;
00119
00120 Bag<Event<X> > bogus_input;
00121
00122 Schedule<X> sched;
00123
00124 Bag<Atomic<X>*> imm;
00125
00126 Bag<Atomic<X>*> activated;
00127
00128 object_pool<Bag<X> > io_pool;
00129 object_pool<Bag<Event<X> > > recv_pool;
00130
00131 Set<Devs<X>*> added;
00132 Set<Devs<X>*> removed;
00133 Set<Devs<X>*> next;
00134 Set<Devs<X>*> prev;
00135
00136 struct bottom_to_top_depth_compare
00137 {
00138 bool operator()(const Network<X>* m1, const Network<X>* m2) const
00139 {
00140 unsigned long int d1 = 0, d2 = 0;
00141
00142 const Network<X>* m = m1->getParent();
00143 while (m != NULL)
00144 {
00145 d1++;
00146 m = m->getParent();
00147 }
00148
00149 m = m2->getParent();
00150 while (m != NULL)
00151 {
00152 d2++;
00153 m = m->getParent();
00154 }
00155
00156 if (d1 == d2) return m1 < m2;
00157
00158 return d1 > d2;
00159 }
00160 };
00161 struct top_to_bottom_depth_compare
00162 {
00163 bool operator()(const Devs<X>* m1, const Devs<X>* m2) const
00164 {
00165 unsigned long int d1 = 0, d2 = 0;
00166
00167 const Network<X>* m = m1->getParent();
00168 while (m != NULL)
00169 {
00170 d1++;
00171 m = m->getParent();
00172 }
00173
00174 m = m2->getParent();
00175 while (m != NULL)
00176 {
00177 d2++;
00178 m = m->getParent();
00179 }
00180
00181 if (d1 == d2) return m1 < m2;
00182
00183 return d1 < d2;
00184 }
00185 };
00186 std::set<Network<X>*,bottom_to_top_depth_compare> model_func_eval_set;
00187 std::set<Devs<X>*,top_to_bottom_depth_compare> sorted_removed;
00192 void schedule(Devs<X>* model, double t);
00194 void route(Network<X>* parent, Devs<X>* src, X& x);
00199 void inject_event(Atomic<X>* model, X& value);
00204 void unschedule_model(Devs<X>* model);
00210 void clean_up(Devs<X>* model);
00216 void exec_event(Atomic<X>* model, bool internal, double t);
00220 void getAllChildren(Network<X>* model, Set<Devs<X>*>& s);
00221 };
00222
00223 template <class X>
00224 void Simulator<X>::computeNextOutput()
00225 {
00226
00227 if (imm.empty() == false) return;
00228
00229 sched.getImminent(imm);
00230
00231
00232 for (typename Bag<Atomic<X>*>::iterator imm_iter = imm.begin();
00233 imm_iter != imm.end(); imm_iter++)
00234 {
00235 Atomic<X>* model = *imm_iter;
00236
00237 if (model->y == NULL)
00238 {
00239 model->y = io_pool.make_obj();
00240 model->output_func(*(model->y));
00241
00242 for (typename Bag<X>::iterator y_iter = model->y->begin();
00243 y_iter != model->y->end(); y_iter++)
00244 {
00245 route(model->getParent(),model,*y_iter);
00246 }
00247 }
00248 }
00249 }
00250
00251 template <class X>
00252 void Simulator<X>::computeNextState(Bag<Event<X> >& input, double t)
00253 {
00254
00255 if (t < sched.minPriority())
00256 {
00257 typename Bag<Atomic<X>*>::iterator iter;
00258 for (iter = activated.begin(); iter != activated.end(); iter++)
00259 {
00260 clean_up(*iter);
00261 }
00262 activated.clear();
00263 for (iter = imm.begin(); iter != imm.end(); iter++)
00264 {
00265 clean_up(*iter);
00266 }
00267 imm.clear();
00268 }
00269
00270 else if (t == sched.minPriority() && imm.empty())
00271 {
00272 computeNextOutput();
00273 }
00274
00275 for (typename Bag<Event<X> >::iterator iter = input.begin();
00276 iter != input.end(); iter++)
00277 {
00278 Atomic<X>* amodel = (*iter).model->typeIsAtomic();
00279 if (amodel != NULL)
00280 {
00281 inject_event(amodel,(*iter).value);
00282 }
00283 else
00284 {
00285 route((*iter).model->typeIsNetwork(),(*iter).model,(*iter).value);
00286 }
00287 }
00288
00289
00290
00291
00292
00293
00294 for (typename Bag<Atomic<X>*>::iterator iter = imm.begin();
00295 iter != imm.end(); iter++)
00296 {
00297 exec_event(*iter,true,t);
00298 }
00299 for (typename Bag<Atomic<X>*>::iterator iter = activated.begin();
00300 iter != activated.end(); iter++)
00301 {
00302 exec_event(*iter,false,t);
00303 }
00310 if (model_func_eval_set.empty() == false)
00311 {
00312 while (!model_func_eval_set.empty())
00313 {
00314 Network<X>* network_model = *(model_func_eval_set.begin());
00315 getAllChildren(network_model,prev);
00316 if (network_model->model_transition() && network_model->getParent() != NULL)
00317 {
00318 model_func_eval_set.insert(network_model->getParent());
00319 }
00320 getAllChildren(network_model,next);
00321 model_func_eval_set.erase(network_model);
00322 }
00323
00324 set_assign_union(added,set_difference(next,prev));
00325
00326 set_assign_union(removed,set_difference(prev,next));
00327 next.clear();
00328 prev.clear();
00329
00330 Set<Devs<X>*> moved(set_intersect(removed,added));
00331 for (typename Set<Devs<X>*>::iterator iter = moved.begin();
00332 iter != moved.end(); iter++)
00333 {
00334 typename Set<Devs<X>*>::iterator iter_tmp = added.find(*iter);
00335 if (iter_tmp != added.end()) added.erase(iter_tmp);
00336 iter_tmp = removed.find(*iter);
00337 if (iter_tmp != removed.end()) removed.erase(iter_tmp);
00338 }
00345 for (typename Set<Devs<X>*>::iterator iter = added.begin();
00346 iter != added.end(); iter++)
00347 {
00348 schedule(*iter,t);
00349 }
00350
00351 added.clear();
00352
00353 for (typename Set<Devs<X>*>::iterator iter = removed.begin();
00354 iter != removed.end(); iter++)
00355 {
00356 clean_up(*iter);
00357 unschedule_model(*iter);
00358 sorted_removed.insert(*iter);
00359 }
00360
00361 removed.clear();
00362
00363 while (!sorted_removed.empty())
00364 {
00365
00366 Devs<X>* model_to_remove = *(sorted_removed.begin());
00371 if (model_to_remove->typeIsNetwork() != NULL)
00372 {
00373 getAllChildren(model_to_remove->typeIsNetwork(),removed);
00374 for (typename Set<Devs<X>*>::iterator iter = removed.begin();
00375 iter != removed.end(); iter++)
00376 {
00377 sorted_removed.erase(*iter);
00378 }
00379 removed.clear();
00380 }
00381
00382 sorted_removed.erase(sorted_removed.begin());
00383
00384 delete model_to_remove;
00385 }
00386
00387 assert(removed.empty());
00388 assert(sorted_removed.empty());
00389 }
00390
00391
00392 for (typename Bag<Atomic<X>*>::iterator iter = imm.begin();
00393 iter != imm.end(); iter++)
00394 {
00395 clean_up(*iter);
00396 schedule(*iter,t);
00397 }
00398 for (typename Bag<Atomic<X>*>::iterator iter = activated.begin();
00399 iter != activated.end(); iter++)
00400 {
00401 clean_up(*iter);
00402 schedule(*iter,t);
00403 }
00404
00405 imm.clear();
00406 activated.clear();
00407 }
00408
00409 template <class X>
00410 void Simulator<X>::clean_up(Devs<X>* model)
00411 {
00412 Atomic<X>* amodel = model->typeIsAtomic();
00413 if (amodel != NULL)
00414 {
00415 amodel->active = false;
00416 if (amodel->x != NULL)
00417 {
00418 amodel->x->clear();
00419 io_pool.destroy_obj(amodel->x);
00420 amodel->x = NULL;
00421 }
00422 if (amodel->y != NULL)
00423 {
00424 amodel->gc_output(*(amodel->y));
00425 amodel->y->clear();
00426 io_pool.destroy_obj(amodel->y);
00427 amodel->y = NULL;
00428 }
00429 }
00430 else
00431 {
00432 Set<Devs<X>*> components;
00433 model->typeIsNetwork()->getComponents(components);
00434 for (typename Set<Devs<X>*>::iterator iter = components.begin();
00435 iter != components.end(); iter++)
00436 {
00437 clean_up(*iter);
00438 }
00439 }
00440 }
00441
00442 template <class X>
00443 void Simulator<X>::unschedule_model(Devs<X>* model)
00444 {
00445 if (model->typeIsAtomic() != NULL)
00446 {
00447 sched.schedule(model->typeIsAtomic(),DBL_MAX);
00448 imm.erase(model->typeIsAtomic());
00449 activated.erase(model->typeIsAtomic());
00450 }
00451 else
00452 {
00453 Set<Devs<X>*> components;
00454 model->typeIsNetwork()->getComponents(components);
00455 for (typename Set<Devs<X>*>::iterator iter = components.begin();
00456 iter != components.end(); iter++)
00457 {
00458 unschedule_model(*iter);
00459 }
00460 }
00461 }
00462
00463 template <class X>
00464 void Simulator<X>::schedule(Devs<X>* model, double t)
00465 {
00466 Atomic<X>* a = model->typeIsAtomic();
00467 if (a != NULL)
00468 {
00469 a->tL = t;
00470 double dt = a->ta();
00471 if (dt < 0.0)
00472 {
00473 exception err("Negative time advance",a);
00474 throw err;
00475 }
00476 if (dt == DBL_MAX)
00477 sched.schedule(a,DBL_MAX);
00478 else
00479 sched.schedule(a,t+dt);
00480 }
00481 else
00482 {
00483 Set<Devs<X>*> components;
00484 model->typeIsNetwork()->getComponents(components);
00485 typename Set<Devs<X>*>::iterator iter = components.begin();
00486 for (; iter != components.end(); iter++)
00487 {
00488 schedule(*iter,t);
00489 }
00490 }
00491 }
00492
00493 template <class X>
00494 void Simulator<X>::inject_event(Atomic<X>* model, X& value)
00495 {
00496 if (model->active == false)
00497 {
00498 model->active = true;
00499 activated.insert(model);
00500 }
00501 if (model->x == NULL)
00502 {
00503 model->x = io_pool.make_obj();
00504 }
00505 model->x->insert(value);
00506 }
00507
00508 template <class X>
00509 void Simulator<X>::route(Network<X>* parent, Devs<X>* src, X& x)
00510 {
00511
00512 if (parent != src)
00513 notify_output_listeners(src,x,sched.minPriority());
00514
00515 if (parent == NULL) return;
00516
00517 Bag<Event<X> >* recvs = recv_pool.make_obj();
00518 parent->route(x,src,*recvs);
00519
00520 Atomic<X>* amodel = NULL;
00521 typename Bag<Event<X> >::iterator recv_iter = recvs->begin();
00522 for (; recv_iter != recvs->end(); recv_iter++)
00523 {
00524
00525 if (src == (*recv_iter).model)
00526 {
00527 exception err("Model tried to influence self",src);
00528 throw err;
00529 }
00534 amodel = (*recv_iter).model->typeIsAtomic();
00535 if (amodel != NULL)
00536 {
00537
00538 if (lp == NULL || amodel->getProc() == lp->getID())
00539 inject_event(amodel,(*recv_iter).value);
00540
00541 else lp->notifyInput(amodel,(*recv_iter).value);
00542 }
00543
00544 else if ((*recv_iter).model == parent)
00545 {
00546 route(parent->getParent(),parent,(*recv_iter).value);
00547 }
00548
00549 else
00550 {
00551 route((*recv_iter).model->typeIsNetwork(),
00552 (*recv_iter).model,(*recv_iter).value);
00553 }
00554 }
00555 recvs->clear();
00556 recv_pool.destroy_obj(recvs);
00557 }
00558
00559 template <class X>
00560 void Simulator<X>::exec_event(Atomic<X>* model, bool internal, double t)
00561 {
00562
00563 if (model->x == NULL)
00564 {
00565 model->delta_int();
00566 }
00567 else if (internal)
00568 {
00569 model->delta_conf(*(model->x));
00570 }
00571 else
00572 {
00573 model->delta_ext(t-model->tL,*(model->x));
00574 }
00575
00576 notify_state_listeners(model,t);
00577
00578 if (model->model_transition() && model->getParent() != NULL)
00579 {
00580 model_func_eval_set.insert(model->getParent());
00581 }
00582 }
00583
00584 template <class X>
00585 void Simulator<X>::getAllChildren(Network<X>* model, Set<Devs<X>*>& s)
00586 {
00587 Set<Devs<X>*> tmp;
00588
00589 model->getComponents(tmp);
00590
00591 typename Set<Devs<X>*>::iterator iter;
00592 for (iter = tmp.begin(); iter != tmp.end(); iter++)
00593 {
00594 if ((*iter)->typeIsNetwork() != NULL)
00595 {
00596 getAllChildren((*iter)->typeIsNetwork(),s);
00597 }
00598 }
00599
00600 for (iter = tmp.begin(); iter != tmp.end(); iter++)
00601 {
00602 s.insert(*iter);
00603 }
00604 }
00605
00606 template <class X>
00607 Simulator<X>::~Simulator()
00608 {
00609
00610 typename Bag<Atomic<X>*>::iterator imm_iter;
00611 for (imm_iter = imm.begin(); imm_iter != imm.end(); imm_iter++)
00612 {
00613 clean_up(*imm_iter);
00614 }
00615 for (imm_iter = activated.begin(); imm_iter != activated.end(); imm_iter++)
00616 {
00617 clean_up(*imm_iter);
00618 }
00619 }
00620
00621 }
00622
00623 #endif