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