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_uint thr_to_end; 17 0 : atomic_int nodes_to_end; 18 : 19 0 : static __thread uint64_t lps_to_end; 20 0 : static __thread simtime_t max_t; 21 : 22 0 : 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 0 : 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 0 : 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 0 : void termination_on_ctrl_msg(void) 48 : { 49 : atomic_fetch_sub_explicit(&nodes_to_end, 1U, memory_order_relaxed); 50 : } 51 : 52 0 : 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 63 : mpi_control_msg_broadcast(MSG_CTRL_TERMINATION); 64 : #endif 65 : } 66 : } 67 : } 68 : 69 0 : 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--) 75 : mpi_control_msg_broadcast(MSG_CTRL_TERMINATION); 76 : #endif 77 : } 78 : 79 : 80 0 : 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 : }