The ROme OpTimistic Simulator  3.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
termination.c
Go to the documentation of this file.
1 
9 #include <gvt/termination.h>
10 
11 #include <core/init.h>
12 #include <distributed/mpi.h>
13 #include <gvt/gvt.h>
14 #include <lp/lp.h>
15 
16 atomic_uint thr_to_end;
17 atomic_int nodes_to_end;
18 
19 static __thread uint64_t lps_to_end;
20 static __thread simtime_t max_t;
21 
22 void termination_global_init(void)
23 {
24  atomic_store_explicit(&thr_to_end, n_threads, memory_order_relaxed);
25  atomic_store_explicit(&nodes_to_end, n_nodes, memory_order_relaxed);
26 }
27 
28 void termination_lp_init(void)
29 {
30  struct lp_ctx *this_lp = current_lp;
31  bool term = CanEnd(this_lp - lps, current_lp->lib_ctx_p->state_s);
32  lps_to_end += !term;
33  this_lp->t_d = term * SIMTIME_MAX;
34 }
35 
36 void termination_on_msg_process(simtime_t msg_time)
37 {
38  struct lp_ctx *this_lp = current_lp;
39  if (this_lp->t_d) return;
40 
41  bool term = CanEnd(this_lp - lps, this_lp->lib_ctx_p->state_s);
42  max_t = term ? max(msg_time, max_t) : max_t;
43  this_lp->t_d = term * msg_time;
44  lps_to_end -= term;
45 }
46 
47 void termination_on_ctrl_msg(void)
48 {
49  atomic_fetch_sub_explicit(&nodes_to_end, 1U, memory_order_relaxed);
50 }
51 
52 void termination_on_gvt(simtime_t current_gvt)
53 {
54  if (unlikely((!lps_to_end && max_t < current_gvt) ||
55  current_gvt >= global_config.termination_time)) {
56  max_t = SIMTIME_MAX;
57  unsigned t = atomic_fetch_sub_explicit(&thr_to_end, 1U,
58  memory_order_relaxed) - 1;
59  if (!t) {
60  atomic_fetch_sub_explicit(&nodes_to_end, 1U,
61  memory_order_relaxed);
62 #ifdef ROOTSIM_MPI
64 #endif
65  }
66  }
67 }
68 
69 void termination_force(void)
70 {
71  nid_t i = atomic_load_explicit(&nodes_to_end, memory_order_relaxed);
72  atomic_fetch_sub_explicit(&nodes_to_end, i, memory_order_relaxed);
73 #ifdef ROOTSIM_MPI
74  while (i--)
76 #endif
77 }
78 
79 
80 void termination_on_lp_rollback(simtime_t msg_time)
81 {
82  struct lp_ctx *this_lp = current_lp;
83  simtime_t old_t = this_lp->t_d;
84  bool keep = old_t < msg_time || old_t == SIMTIME_MAX;
85  this_lp->t_d = keep * old_t;
86  lps_to_end += !keep;
87 }
simtime_t
double simtime_t
The type used to represent logical time in the simulation.
Definition: core.h:62
nid_t
int nid_t
Used to identify MPI nodes in a distributed environment.
Definition: core.h:79
simulation_configuration::termination_time
simtime_t termination_time
The target termination logical time.
Definition: init.h:22
n_threads
rid_t n_threads
The total number of MPI nodes in the simulation.
Definition: core.c:15
lp_ctx
A complete LP context.
Definition: lp.h:21
SIMTIME_MAX
#define SIMTIME_MAX
The maximum value of the logical simulation time, semantically never.
Definition: core.h:64
termination.h
Termination detection module.
mpi_control_msg_broadcast
void mpi_control_msg_broadcast(enum msg_ctrl_tag ctrl)
Sends a platform control message to all the other nodes.
Definition: mpi.c:180
init.h
Initialization routines.
lp.h
LP construction functions.
mpi.h
MPI Support Module.
lp_ctx::lib_ctx_p
struct lib_ctx * lib_ctx_p
The additional libraries context of this LP.
Definition: lp.h:25
MSG_CTRL_TERMINATION
@ MSG_CTRL_TERMINATION
Used in broadcast to signal that local LPs can terminate.
Definition: mpi.h:29
unlikely
#define unlikely(exp)
Optimize the branch as likely not taken.
Definition: core.h:59
global_config
struct simulation_configuration global_config
The configuration filled in by init_args_parse()
Definition: init.c:27
gvt.h
Global Virtual Time.
lp_ctx::t_d
simtime_t t_d
The termination time of this LP, handled by the termination module.
Definition: lp.h:23