1 #ifndef TPL_SIM_AGENT_GRAPH_H
2 #define TPL_SIM_AGENT_GRAPH_H
8 #include <tpl_concurrent_graph.H>
9 #include <tpl_dynBinHeap.H>
12 using namespace Aleph;
27 template <
typename Arc_Agents,
typename Node_Agents,
typename Agent>
38 Sim_Event(
const long & _curr_time) : actual_time(_curr_time)
40 to_be_destroyed =
false;
45 bool operator < (
const Sim_Event & event)
const
47 return actual_time >
event.actual_time;
50 virtual void execute_event(
void * graph)
55 domain_error(
"Debe sobreescribir este método en una clase derivada");
63 return op1->actual_time < op2->actual_time;
69 typedef void (*Transit) (
void *,
void *);
80 typedef Agent_Info Agent_Type;
82 Sim_Agent(Agent_Info agent_info, Transit _transit,
long actual_time)
83 :
Sim_Event(actual_time), info (agent_info), transit(_transit)
94 Agent_Info & get_info()
99 virtual void execute_event (
void * graph)
103 transit(graph,
this);
108 template <
typename Agents_Node_Info>
112 typedef Concurrent_Node<Agents_Node_Info> Parent_Node;
113 typedef Agents_Node_Info Node_Type;
120 template <
typename Agents_Arc_Info>
121 struct Sim_Agent_Arc :
public Concurrent_Arc<Agents_Arc_Info> {
123 typedef Concurrent_Arc<Agents_Arc_Info> Parent_Arc;
124 typedef Agents_Arc_Info Arc_Type;
129 template <
typename Node,
typename Arc,
typename Agent >
134 typedef Node Node_Class;
135 typedef Arc Arc_Class;
136 typedef typename Node::Node_Type Node_Type;
137 typedef typename Arc::Arc_Type Arc_Type;
138 typedef typename Agent::Agent_Type Agent_Type;
144 pthread_mutex_t sch_mutex;
145 pthread_mutex_t suspend_mutex;
146 pthread_cond_t sch_cond;
147 pthread_cond_t suspend_cond;
151 Update_Callback update_callback;
166 Node * get_agent_node_location (
Agent * agent)
170 return static_cast<Node*
>(agent->location);
175 void set_agent_node_location (
Agent * agent, Node * node)
177 agent->location_link.del();
178 agent->in_node =
true;
179 agent->location = node;
180 node->agent_list.append(&agent->location_link);
183 Arc * get_agent_arc_location (
Agent * agent)
187 return static_cast<Arc*
>(agent->location);
192 void set_agent_arc_location(
Agent * agent, Arc * arc)
194 agent->location_link.del();
195 agent->in_node =
false;
196 agent->location = arc;
197 arc->agent_list.append(&agent->location_link);
200 bool is_agent_in_node (
Agent * agent)
202 return agent->in_node;
205 Agent * get_first_agent ()
207 if(get_num_agents() == 0)
208 throw std::range_error(
"Graph has not agents ");
209 return Agent::agent_link_to_Sim_Agent(&*agent_list.get_next());
212 void remove_agent (
Agent * agent)
214 agent->agent_link.del();
215 agent->location_link.del();
220 void clear_agent_list()
222 Agent * agent = NULL;
225 agent = Agent::agent_link_to_Sim_Agent(it.get_current());
235 threads = (pthread_t*)malloc(num_threads *
sizeof(pthread_t));
236 init_mutex(sch_mutex);
237 init_mutex(suspend_mutex);
238 pthread_cond_init(&suspend_cond, NULL);
239 pthread_cond_init(&sch_cond, NULL);
247 destroy_mutex(sch_mutex);
248 destroy_mutex(suspend_mutex);
249 pthread_cond_destroy(&suspend_cond);
250 pthread_cond_destroy(&sch_cond);
254 Agent * create_agent_in_node(Agent_Type agent_info,
void (*funcptr) (
void *,
void *), Node * node,
long activation_time)
256 Agent * agent =
new Agent ( agent_info, funcptr, activation_time );
257 set_agent_node_location(agent, node);
258 agent_list.append(&agent->agent_link);
260 schedule_event(agent);
264 Agent * create_agent_in_arc(Agent_Type agent_info,
void (*funcptr) (
void *,
void *), Arc * arc,
long activation_time)
266 Agent * agent =
new Agent( agent_info, funcptr, activation_time );
267 set_agent_arc_location(agent, arc);
268 agent_list.append(&agent->agent_link);
270 schedule_event(agent);
274 template <
class Equal>
275 Agent * search_agent(
const Agent_Type & agent)
277 Agent * result = NULL;
280 result = Agent::agent_link_to_Sim_Agent(it.get_current());
281 if (Equal() (result->get_info(), agent))
289 Agent * search_agent(
const Agent_Type & agent)
291 return search_agent<Aleph::equal_to<Agent_Type> >(agent);
296 for (
unsigned int i = 0; i < thread_count; i++)
298 int result = pthread_create(&threads[i] , NULL, Sim_Agent_Graph::run,
this);
301 cout<<
" Thread "<<i<<endl;
308 if (get_status() == SUSPENDED)
313 for (
unsigned int i = 0; i < thread_count; i++)
315 pthread_join(threads[i] , NULL);
321 CRITICAL_SECTION(sch_mutex);
325 void set_status(
int value)
327 CRITICAL_SECTION(sch_mutex);
333 set_status(SUSPENDED);
339 pthread_cond_broadcast(&suspend_cond);
349 events_heap.insert(event);
352 void set_update_callback(Update_Callback fnct)
354 update_callback = fnct;
357 long get_actual_time()
362 void set_callback_rate(
long rate)
364 callback_rate = rate;
367 long get_callback_rate()
369 return callback_rate();
372 static void * run(
void * cookie)
376 while (graph->get_status() != STOPPED)
378 while (graph->get_status() == SUSPENDED)
380 pthread_mutex_lock(&graph->suspend_mutex);
381 pthread_cond_wait(&graph->suspend_cond, &graph->suspend_mutex);
382 pthread_mutex_unlock(&graph->suspend_mutex);
385 if (graph->events_heap.is_empty())
390 Sim_Event * next_event = graph->events_heap.getMin();
392 graph->actual_time = next_event->actual_time;
393 next_event->execute_event(graph);
398 if (next_event->to_be_destroyed)
409 while (!events_heap.is_empty())
411 Sim_Event * next_event = events_heap.getMin();
413 actual_time = next_event->actual_time;
414 next_event->execute_event(
this);
415 if (next_event->to_be_destroyed)
Definition: tpl_concurrent_graph.H:22
Definition: tpl_sim_agent_graph.H:21
#define LINKNAME_TO_TYPE(type_name, link_name)
Definition: dlink.H:741
Iterador sobre enlaces.
Definition: dlink.H:437
Definition: tpl_sim_agent_graph.H:30
const size_t & get_num_agents() const
Definition: tpl_sim_agent_graph.H:164
Definition: tpl_sim_agent_graph.H:28
Definition: tpl_sim_agent_graph.H:23
Definition: tpl_dynBinHeap.H:26
Definition: tpl_sim_agent_graph.H:59
bool has_current() const
Retorna true si iterador aún tiene elemento actual.
Definition: dlink.H:554
Definition: tpl_agent_graph.H:22
Sim_Agent_Graph(const size_t &num_threads)
Definition: tpl_sim_agent_graph.H:233
Definition: tpl_sim_agent_graph.H:25