31 #ifndef __adevs_simulator_h_
32 #define __adevs_simulator_h_
33 #include "adevs_abstract_simulator.h"
34 #include "adevs_models.h"
35 #include "adevs_event_listener.h"
36 #include "adevs_sched.h"
37 #include "adevs_bag.h"
38 #include "adevs_set.h"
39 #include "object_pool.h"
55 template <
class X,
class T =
double>
class Simulator:
56 public AbstractSimulator<X,T>,
57 private Schedule<X,T>::ImminentVisitor
71 schedule(model,adevs_zero<T>());
79 return sched.minPriority();
122 schedule(model,adevs_zero<T>());
154 typedef enum { OUTPUT_OK, OUTPUT_NOT_OK, RESTORING_OUTPUT } OutputStatus;
159 LogicalProcess<X,T>* lp;
160 bool look_ahead, stop_forced;
161 OutputStatus out_flag;
162 Bag<Atomic<X,T>*> to_restore;
167 Bag<Event<X,T> > bogus_input;
171 Bag<Atomic<X,T>*> activated;
173 object_pool<Bag<X> > io_pool;
174 object_pool<Bag<Event<X,T> > > recv_pool;
176 Bag<Devs<X,T>*> added;
177 Bag<Devs<X,T>*> removed;
178 Set<Devs<X,T>*> next;
179 Set<Devs<X,T>*> prev;
181 struct bottom_to_top_depth_compare
183 bool operator()(
const Network<X,T>* m1,
const Network<X,T>* m2)
const
185 unsigned long int d1 = 0, d2 = 0;
187 const Network<X,T>* m = m1->getParent();
201 if (d1 == d2)
return m1 < m2;
206 struct top_to_bottom_depth_compare
208 bool operator()(
const Devs<X,T>* m1,
const Devs<X,T>* m2)
const
210 unsigned long int d1 = 0, d2 = 0;
212 const Network<X,T>* m = m1->getParent();
226 if (d1 == d2)
return m1 < m2;
231 std::set<Network<X,T>*,bottom_to_top_depth_compare> model_func_eval_set;
232 std::set<Devs<X,T>*,top_to_bottom_depth_compare> sorted_removed;
237 void schedule(Devs<X,T>* model, T t);
239 void route(Network<X,T>* parent, Devs<X,T>* src, X& x);
245 void inject_event(Atomic<X,T>* model, X& value);
250 void unschedule_model(Devs<X,T>* model);
256 void clean_up(Devs<X,T>* model);
263 void exec_event(Atomic<X,T>* model, T t);
267 void getAllChildren(Network<X,T>* model, Set<Devs<X,T>*>& s);
273 bool manage_lookahead_data(Atomic<X,T>* model);
277 void visit(Atomic<X,T>* model);
280 template <
class X,
class T>
281 void Simulator<X,T>::visit(Atomic<X,T>* model)
283 assert(model->y == NULL);
284 model->y = io_pool.make_obj();
286 if (model->x == NULL)
287 activated.insert(model);
290 model->output_func(*(model->y));
292 for (
typename Bag<X>::iterator y_iter = model->y->begin();
293 y_iter != model->y->end(); y_iter++)
295 route(model->getParent(),model,*y_iter);
299 template <
class X,
class T>
303 if (activated.empty() ==
false)
return;
305 sched.visitImminent(
this);
308 template <
class X,
class T>
312 if (t < sched.minPriority())
315 for (iter = activated.
begin(); iter != activated.
end(); iter++)
322 else if (t == sched.minPriority())
327 for (
typename Bag<
Event<X,T> >::iterator iter = input.begin();
328 iter != input.end(); iter++)
333 inject_event(amodel,(*iter).value);
337 route((*iter).model->typeIsNetwork(),(*iter).model,(*iter).value);
346 for (
typename Bag<
Atomic<X,T>*>::iterator iter = activated.begin();
347 iter != activated.end(); iter++)
357 if (model_func_eval_set.empty() ==
false)
359 while (!model_func_eval_set.empty())
361 Network<X,T>* network_model = *(model_func_eval_set.begin());
362 getAllChildren(network_model,prev);
366 model_func_eval_set.insert(network_model->
getParent());
368 getAllChildren(network_model,next);
369 model_func_eval_set.erase(network_model);
385 for (
typename Bag<
Devs<X,T>*>::iterator iter = added.begin();
386 iter != added.end(); iter++)
393 for (
typename Bag<
Devs<X,T>*>::iterator iter = removed.begin();
394 iter != removed.end(); iter++)
397 unschedule_model(*iter);
399 sorted_removed.insert(*iter);
404 while (!sorted_removed.empty())
407 Devs<X,T>* model_to_remove = *(sorted_removed.begin());
415 for (
typename Set<
Devs<X,T>*>::iterator iter = prev.begin();
416 iter != prev.end(); iter++)
418 sorted_removed.erase(*iter);
423 sorted_removed.erase(sorted_removed.begin());
425 delete model_to_remove;
428 assert(prev.empty());
429 assert(sorted_removed.empty());
433 for (
typename Bag<
Atomic<X,T>*>::iterator iter = activated.begin();
434 iter != activated.end(); iter++)
442 if (lps != NULL && lps->stop_forced)
449 template <
class X,
class T>
455 if (amodel->x != NULL)
458 io_pool.destroy_obj(amodel->x);
461 if (amodel->y != NULL)
465 io_pool.destroy_obj(amodel->y);
471 Set<Devs<X,T>*> components;
473 for (
typename Set<Devs<X,T>*>::iterator iter = components.begin();
474 iter != components.end(); iter++)
481 template <
class X,
class T>
482 void Simulator<X,T>::unschedule_model(Devs<X,T>* model)
484 if (model->typeIsAtomic() != NULL)
486 sched.schedule(model->typeIsAtomic(),adevs_inf<T>());
487 activated.erase(model->typeIsAtomic());
491 Set<Devs<X,T>*> components;
492 model->typeIsNetwork()->getComponents(components);
493 for (
typename Set<Devs<X,T>*>::iterator iter = components.begin();
494 iter != components.end(); iter++)
496 unschedule_model(*iter);
501 template <
class X,
class T>
502 void Simulator<X,T>::schedule(Devs<X,T>* model, T t)
504 Atomic<X,T>* a = model->typeIsAtomic();
509 if (dt < adevs_zero<T>())
511 exception err(
"Negative time advance",a);
514 if (dt == adevs_inf<T>())
515 sched.schedule(a,adevs_inf<T>());
517 sched.schedule(a,t+dt);
521 Set<Devs<X,T>*> components;
522 model->typeIsNetwork()->getComponents(components);
523 typename Set<Devs<X,T>*>::iterator iter = components.begin();
524 for (; iter != components.end(); iter++)
531 template <
class X,
class T>
532 void Simulator<X,T>::inject_event(Atomic<X,T>* model, X& value)
534 if (model->x == NULL)
536 if (model->y == NULL)
537 activated.insert(model);
538 model->x = io_pool.make_obj();
540 model->x->insert(value);
543 template <
class X,
class T>
544 void Simulator<X,T>::route(Network<X,T>* parent, Devs<X,T>* src, X& x)
547 if (parent != src && (lps == NULL || lps->out_flag != RESTORING_OUTPUT))
548 this->notify_output_listeners(src,x,sched.minPriority());
550 if (parent == NULL)
return;
552 Bag<Event<X,T> >* recvs = recv_pool.make_obj();
553 parent->route(x,src,*recvs);
555 Atomic<X,T>* amodel = NULL;
556 typename Bag<Event<X,T> >::iterator recv_iter = recvs->begin();
557 for (; recv_iter != recvs->end(); recv_iter++)
560 if (src == (*recv_iter).model)
562 exception err(
"Model tried to influence self",src);
569 amodel = (*recv_iter).model->typeIsAtomic();
573 if (lps == NULL || amodel->getProc() == lps->lp->getID())
574 inject_event(amodel,(*recv_iter).value);
576 else if (lps->out_flag != RESTORING_OUTPUT)
577 lps->lp->notifyInput(amodel,(*recv_iter).value);
580 else if ((*recv_iter).model == parent)
582 route(parent->getParent(),parent,(*recv_iter).value);
587 route((*recv_iter).model->typeIsNetwork(),
588 (*recv_iter).model,(*recv_iter).value);
592 recv_pool.destroy_obj(recvs);
595 template <
class X,
class T>
596 void Simulator<X,T>::exec_event(Atomic<X,T>* model, T t)
598 if (!manage_lookahead_data(model))
return;
600 if (model->x == NULL)
603 else if (model->y != NULL)
604 model->delta_conf(*(model->x));
607 model->delta_ext(t-model->tL,*(model->x));
609 this->notify_state_listeners(model,t);
611 if (model->model_transition() && model->getParent() != NULL)
613 model_func_eval_set.insert(model->getParent());
617 template <
class X,
class T>
618 void Simulator<X,T>::getAllChildren(Network<X,T>* model, Set<Devs<X,T>*>& s)
622 model->getComponents(tmp);
624 typename Set<Devs<X,T>*>::iterator iter;
625 for (iter = tmp.begin(); iter != tmp.end(); iter++)
627 if ((*iter)->typeIsNetwork() != NULL)
629 getAllChildren((*iter)->typeIsNetwork(),s);
633 for (iter = tmp.begin(); iter != tmp.end(); iter++)
639 template <
class X,
class T>
644 for (iter = activated.
begin(); iter != activated.
end(); iter++)
650 template <
class X,
class T>
654 lps =
new lp_support;
656 lps->look_ahead =
false;
657 lps->stop_forced =
false;
658 lps->out_flag = OUTPUT_OK;
661 template <
class X,
class T>
669 lps->look_ahead =
true;
670 if (!activated.empty())
671 lps->out_flag = OUTPUT_NOT_OK;
674 template <
class X,
class T>
680 template <
class X,
class T>
683 if (lps == NULL)
return;
685 for (; iter != lps->to_restore.
end(); iter++)
687 (*iter)->endLookahead();
688 schedule(*iter,(*iter)->tL_cp);
689 (*iter)->tL_cp = adevs_sentinel<T>();
690 assert((*iter)->x == NULL);
691 assert((*iter)->y == NULL);
693 lps->to_restore.clear();
694 assert(activated.empty());
695 if (lps->out_flag == OUTPUT_NOT_OK)
697 lps->out_flag = RESTORING_OUTPUT;
699 lps->out_flag = OUTPUT_OK;
701 lps->look_ahead =
false;
702 lps->stop_forced =
false;
705 template <
class X,
class T>
708 if (lps == NULL)
return true;
709 if (lps->look_ahead && model->tL_cp < adevs_zero<T>())
711 lps->to_restore.insert(model);
712 model->tL_cp = model->tL;
717 catch(method_not_supported_exception err)
719 lps->stop_forced =
true;
722 return !(lps->stop_forced);