LCOV - code coverage report
Current view: top level - ROOT-Sim/src/scheduler - process.c Hit Total Coverage
Test: doc-coverage.info Lines: 3 8 37.5 %
Date: 2020-01-30 11:31:10

          Line data    Source code
       1           1 : /**
       2             :  * @file scheduler/process.c
       3             :  *
       4             :  * @brief Generic LP management functions
       5             :  *
       6             :  * Generic LP management functions
       7             :  *
       8             :  * @copyright
       9             :  * Copyright (C) 2008-2019 HPDCS Group
      10             :  * https://hpdcs.github.io
      11             :  *
      12             :  * This file is part of ROOT-Sim (ROme OpTimistic Simulator).
      13             :  *
      14             :  * ROOT-Sim is free software; you can redistribute it and/or modify it under the
      15             :  * terms of the GNU General Public License as published by the Free Software
      16             :  * Foundation; only version 3 of the License applies.
      17             :  *
      18             :  * ROOT-Sim is distributed in the hope that it will be useful, but WITHOUT ANY
      19             :  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      20             :  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
      21             :  *
      22             :  * You should have received a copy of the GNU General Public License along with
      23             :  * ROOT-Sim; if not, write to the Free Software Foundation, Inc.,
      24             :  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      25             :  *
      26             :  * @author Alessandro Pellegrini
      27             :  * @author Francesco Quaglia
      28             :  *
      29             :  * @date December 14, 2017
      30             :  */
      31             : 
      32             : #include <limits.h>
      33             : 
      34             : #include <core/core.h>
      35             : #include <core/init.h>
      36             : #include <scheduler/process.h>
      37             : #include <scheduler/scheduler.h>
      38             : 
      39             : // TODO: see issue #121 to see how to make this ugly hack disappear
      40           0 : __thread unsigned int __lp_counter = 0;
      41           0 : __thread unsigned int __lp_bound_counter = 0;
      42             : 
      43             : /// Maintain LPs' simulation and execution states
      44           1 : struct lp_struct **lps_blocks = NULL;
      45             : 
      46             : /** Each KLT has a binding towards some LPs. This is the structure used
      47             :  *  to keep track of LPs currently being handled
      48             :  */
      49           1 : __thread struct lp_struct **lps_bound_blocks = NULL;
      50             : 
      51           0 : void initialize_binding_blocks(void)
      52             : {
      53             :         lps_bound_blocks =
      54             :             (struct lp_struct **)rsalloc(n_prc * sizeof(struct lp_struct *));
      55             :         bzero(lps_bound_blocks, sizeof(struct lp_struct *) * n_prc);
      56             : }
      57             : 
      58           0 : void initialize_lps(void)
      59             : {
      60             :         unsigned int i, j;
      61             :         unsigned int lid = 0;
      62             :         struct lp_struct *lp;
      63             :         unsigned int local = 0;
      64             :         GID_t gid;
      65             : 
      66             :         // First of all, determine what LPs should be locally hosted.
      67             :         // Only for them, we are creating struct lp_structs here.
      68             :         distribute_lps_on_kernels();
      69             : 
      70             :         // We now know how many LPs should be locally hosted. Prepare
      71             :         // the place for their control blocks.
      72             :         lps_blocks =
      73             :             (struct lp_struct **)rsalloc(n_prc * sizeof(struct lp_struct *));
      74             : 
      75             :         // We now iterate over all LP Gids. Everytime that we find an LP
      76             :         // which should be locally hosted, we create the local lp_struct
      77             :         // process control block.
      78             :         for (i = 0; i < n_prc_tot; i++) {
      79             :                 set_gid(gid, i);
      80             :                 if (find_kernel_by_gid(gid) != kid)
      81             :                         continue;
      82             : 
      83             :                 // Initialize the control block for the current lp
      84             :                 lp = (struct lp_struct *)rsalloc(sizeof(struct lp_struct));
      85             :                 bzero(lp, sizeof(struct lp_struct));
      86             :                 lps_blocks[local++] = lp;
      87             : 
      88             :                 if (local > n_prc) {
      89             :                         printf("reached local %d\n", local);
      90             :                         fflush(stdout);
      91             :                         abort();
      92             :                 }
      93             :                 // Initialize memory map
      94             :                 initialize_memory_map(lp);
      95             : 
      96             :                 // Allocate memory for the outgoing buffer
      97             :                 lp->outgoing_buffer.max_size = INIT_OUTGOING_MSG;
      98             :                 lp->outgoing_buffer.outgoing_msgs =
      99             :                     rsalloc(sizeof(msg_t *) * INIT_OUTGOING_MSG);
     100             : 
     101             :                 // Initialize bottom halves msg channel
     102             :                 lp->bottom_halves = init_channel();
     103             : 
     104             :                 // We sequentially assign lids, and use the current gid
     105             :                 lp->lid.to_int = lid++;
     106             :                 lp->gid = gid;
     107             : 
     108             :                 // Which version of OnGVT and ProcessEvent should we use?
     109             :                 if (rootsim_config.snapshot == SNAPSHOT_FULL) {
     110             :                         lp->OnGVT = &OnGVT_light;
     111             :                         lp->ProcessEvent = &ProcessEvent_light;
     112             :                 }               // TODO: add here an else for ISS
     113             : 
     114             :                 // Allocate LP stack
     115             :                 lp->stack = get_ult_stack(LP_STACK_SIZE);
     116             : 
     117             :                 // Set the initial checkpointing period for this LP.
     118             :                 // If the checkpointing period is fixed, this will not change during the
     119             :                 // execution. Otherwise, new calls to this function will (locally) update
     120             :                 // this.
     121             :                 set_checkpoint_period(lp, rootsim_config.ckpt_period);
     122             : 
     123             :                 // Initially, every LP is ready
     124             :                 lp->state = LP_STATE_READY;
     125             : 
     126             :                 // There is no current state layout at the beginning
     127             :                 lp->current_base_pointer = NULL;
     128             : 
     129             :                 // Initialize the queues
     130             :                 lp->queue_in = new_list(msg_t);
     131             :                 lp->queue_out = new_list(msg_hdr_t);
     132             :                 lp->queue_states = new_list(state_t);
     133             :                 lp->rendezvous_queue = new_list(msg_t);
     134             : 
     135             :                 // No event has been processed so far
     136             :                 lp->bound = NULL;
     137             : 
     138             :                 // We have no information about messages still to be delivered to this LP
     139             :                 lp->outgoing_buffer.min_in_transit = rsalloc(sizeof(simtime_t) * n_cores);
     140             :                 for (j = 0; j < n_cores; j++) {
     141             :                         lp->outgoing_buffer.min_in_transit[j] = INFTY;
     142             :                 }
     143             : 
     144             : #ifdef HAVE_CROSS_STATE
     145             :                 // No read/write dependencies open so far for the LP. The current lp is always opened
     146             :                 lp->ECS_index = 0;
     147             :                 lp->ECS_synch_table[0] = LidToGid(lp);       // LidToGid for distributed ECS
     148             : #endif
     149             : 
     150             :                 // Create User-Level Thread
     151             :                 context_create(&lp->context, LP_main_loop, NULL, lp->stack,
     152             :                                LP_STACK_SIZE);
     153             :         }
     154             : }
     155             : 
     156             : // This works only for locally-hosted LPs!
     157           0 : struct lp_struct *find_lp_by_gid(GID_t gid)
     158             : {
     159             :         foreach_lp(lp) {
     160             :                 if (lp->gid.to_int == gid.to_int)
     161             :                         return lp;
     162             :         }
     163             :         return NULL;
     164             : }

Generated by: LCOV version 1.14