Line data Source code
1 1 : /** 2 : * @file gvt/termination.c 3 : * 4 : * @brief Termination detection module 5 : * 6 : * SPDX-FileCopyrightText: 2008-2021 HPDCS Group <rootsim@googlegroups.com> 7 : * SPDX-License-Identifier: GPL-3.0-only 8 : */ 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 0 : _Atomic(nid_t) nodes_to_end; 17 : static _Atomic(rid_t) thr_to_end; 18 : static __thread uint64_t lps_to_end; 19 : static __thread simtime_t max_t; 20 : 21 : void termination_global_init(void) 22 : { 23 : atomic_store_explicit(&thr_to_end, n_threads, memory_order_relaxed); 24 : atomic_store_explicit(&nodes_to_end, n_nodes, memory_order_relaxed); 25 : } 26 : 27 0 : void termination_lp_init(void) 28 : { 29 : struct lp_ctx *this_lp = current_lp; 30 : bool term = CanEnd(this_lp - lps, current_lp->lib_ctx_p->state_s); 31 : lps_to_end += !term; 32 : this_lp->t_d = term * SIMTIME_MAX; 33 : } 34 : 35 0 : void termination_on_msg_process(simtime_t msg_time) 36 : { 37 : struct lp_ctx *this_lp = current_lp; 38 : if (this_lp->t_d) return; 39 : 40 : bool term = CanEnd(this_lp - lps, this_lp->lib_ctx_p->state_s); 41 : max_t = term ? max(msg_time, max_t) : max_t; 42 : this_lp->t_d = term * msg_time; 43 : lps_to_end -= term; 44 : } 45 : 46 0 : void termination_on_ctrl_msg(void) 47 : { 48 : atomic_fetch_sub_explicit(&nodes_to_end, 1U, memory_order_relaxed); 49 : } 50 : 51 0 : void termination_on_gvt(simtime_t current_gvt) 52 : { 53 : if (likely((lps_to_end || max_t >= current_gvt) && 54 : current_gvt < global_config.termination_time)) 55 : return; 56 : max_t = SIMTIME_MAX; 57 : unsigned t = atomic_fetch_sub_explicit(&thr_to_end, 1U, 58 : memory_order_relaxed); 59 : if (t == 1) 60 : mpi_control_msg_broadcast(MSG_CTRL_TERMINATION); 61 : } 62 : 63 0 : void termination_force(void) 64 : { 65 : nid_t i = atomic_load_explicit(&nodes_to_end, memory_order_relaxed); 66 : while (i--) 67 : mpi_control_msg_broadcast(MSG_CTRL_TERMINATION); 68 : } 69 : 70 0 : void termination_on_lp_rollback(simtime_t msg_time) 71 : { 72 : struct lp_ctx *this_lp = current_lp; 73 : simtime_t old_t = this_lp->t_d; 74 : bool keep = old_t < msg_time || old_t == SIMTIME_MAX; 75 : this_lp->t_d = keep * old_t; 76 : lps_to_end += !keep; 77 : }