16 atomic_uint thr_to_end;
17 atomic_int nodes_to_end;
19 static __thread uint64_t lps_to_end;
22 void termination_global_init(
void)
24 atomic_store_explicit(&thr_to_end,
n_threads, memory_order_relaxed);
25 atomic_store_explicit(&nodes_to_end, n_nodes, memory_order_relaxed);
28 void termination_lp_init(
void)
30 struct lp_ctx *this_lp = current_lp;
31 bool term = CanEnd(this_lp - lps, current_lp->
lib_ctx_p->state_s);
36 void termination_on_msg_process(
simtime_t msg_time)
38 struct lp_ctx *this_lp = current_lp;
39 if (this_lp->
t_d)
return;
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;
47 void termination_on_ctrl_msg(
void)
49 atomic_fetch_sub_explicit(&nodes_to_end, 1U, memory_order_relaxed);
52 void termination_on_gvt(
simtime_t current_gvt)
54 if (
unlikely((!lps_to_end && max_t < current_gvt) ||
57 unsigned t = atomic_fetch_sub_explicit(&thr_to_end, 1U,
58 memory_order_relaxed) - 1;
60 atomic_fetch_sub_explicit(&nodes_to_end, 1U,
61 memory_order_relaxed);
69 void termination_force(
void)
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);
80 void termination_on_lp_rollback(
simtime_t msg_time)
82 struct lp_ctx *this_lp = current_lp;
84 bool keep = old_t < msg_time || old_t ==
SIMTIME_MAX;
85 this_lp->
t_d = keep * old_t;