The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
main.c
Go to the documentation of this file.
1 
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <math.h>
31 #include <string.h>
32 #include <setjmp.h>
33 
34 #include <core/core.h>
35 #include <arch/thread.h>
36 #include <statistics/statistics.h>
37 #include <gvt/ccgs.h>
38 #include <scheduler/binding.h>
39 #include <scheduler/scheduler.h>
40 #include <scheduler/process.h>
41 #include <gvt/gvt.h>
42 #include <mm/mm.h>
43 
44 #ifdef HAVE_CROSS_STATE
45 #include <mm/ecs.h>
46 #endif
47 
48 #include <serial/serial.h>
49 #include <communication/mpi.h>
50 
51 #define _INIT_FROM_MAIN
52 #include <core/init.h>
53 #undef _INIT_FROM_MAIN
54 
62 jmp_buf exit_jmp;
63 
67 static bool end_computing(void)
68 {
69 
70  // Did CCGS decide to terminate the simulation?
71  if (ccgs_can_halt_simulation()) {
72  return true;
73  }
74  // Termination detection based on passed (committed) simulation time
76  return true;
77  }
78  // If some KLT has encountered an error condition, we neatly shut down the simulation
79  if (simulation_error()) {
80  return true;
81  }
82 
83  if (user_requested_exit())
84  return true;
85 
86  return false;
87 }
88 
89 #ifdef HAVE_PREEMPTION
90 extern atomic_t preempt_count;
91 extern atomic_t overtick_platform;
92 extern atomic_t would_preempt;
93 #endif
94 
101 static void *main_simulation_loop(void *arg) __attribute__((noreturn));
102 static void *main_simulation_loop(void *arg)
103 {
104 
105  (void)arg;
106 
107  simtime_t my_time_barrier = -1.0;
108 
109 #ifdef HAVE_CROSS_STATE
110  lp_alloc_thread_init();
111 #endif
112 
113  // Do the initial (local) LP binding, then execute INIT at all (local) LPs
114  initialize_worker_thread();
115 
116 #ifdef HAVE_MPI
117  syncronize_all();
118 #endif
119 
120  // Notify the statistics subsystem that we are now starting the actual simulation
121  if (master_kernel() && master_thread()) {
123  printf("****************************\n"
124  "* Simulation Started *\n"
125  "****************************\n");
126  }
127 
128  if (setjmp(exit_jmp) != 0) {
129  goto leave_for_error;
130  }
131 
132  while (!end_computing()) {
133  // Recompute the LPs-thread binding
134  rebind_LPs();
135 
136 #ifdef HAVE_MPI
137  // Check whether we have new ingoing messages sent by remote instances
140 #endif
141  // Forward the messages from the kernel incoming message queue to the destination LPs
143 
144  // Activate one LP and process one event. Send messages produced during the events' execution
145  schedule();
146 
147  my_time_barrier = gvt_operations();
148 
149  // Only a master thread on master kernel prints the time barrier
150  if (master_kernel() && master_thread() && D_DIFFER(my_time_barrier, -1.0)) {
152 #ifdef HAVE_PREEMPTION
153  printf
154  ("TIME BARRIER %f - %d preemptions - %d in platform mode - %d would preempt\n",
155  my_time_barrier,
156  atomic_read(&preempt_count),
157  atomic_read(&overtick_platform),
158  atomic_read(&would_preempt));
159 #else
160  printf("TIME BARRIER %f\n", my_time_barrier);
161 
162 #endif
163 
164  fflush(stdout);
165  }
166  }
167 #ifdef HAVE_MPI
169 #endif
170  }
171 
172  leave_for_error:
174 
175  // If we're exiting due to an error, we neatly shut down the simulation
176  if (simulation_error()) {
177  simulation_shutdown(EXIT_FAILURE);
178  }
179  simulation_shutdown(EXIT_SUCCESS);
180 }
181 
190 int main(int argc, char **argv)
191 {
192 #ifdef HAVE_MPI
193  volatile int __wait = 0;
194  char hostname[256];
195 
196  if ((getenv("WGDB")) != NULL && *(getenv("WGDB")) == '1') {
197  gethostname(hostname, sizeof(hostname));
198  printf("PID %d on %s ready for attach\n", getpid(), hostname);
199  fflush(stdout);
200 
201  while (__wait == 0)
202  sleep(5);
203  }
204 #endif
205 
206  SystemInit(argc, argv);
207 
209  set_affinity(0);
210 
211  if (rootsim_config.serial) {
212  serial_simulation();
213  } else {
214 
215  // The number of locally required threads is now set. Detach them and then join the main simulation loop
216  if (!simulation_error()) {
217  if (n_cores > 1) {
219  }
220 
221  main_simulation_loop(NULL);
222  }
223  }
224 
225  return 0;
226 }
int prune_outgoing_queues(void)
Prune all outgoing queues.
Definition: wnd.c:225
void process_bottom_halves(void)
Definition: queues.c:132
void statistics_start(void)
Definition: statistics.c:286
Initialization routines.
jmp_buf exit_jmp
Definition: main.c:62
int verbose
Kernel verbose.
Definition: init.h:70
#define atomic_read(v)
Read operation on an atomic counter.
Definition: atomic.h:66
Core ROOT-Sim functionalities.
unsigned int n_cores
Total number of cores required for simulation.
Definition: core.c:61
simtime_t get_last_gvt(void)
Definition: gvt.c:179
simtime_t gvt_operations(void)
Definition: gvt.c:300
Statistics module.
The ROOT-Sim scheduler main module header.
Load sharing rules across worker threads.
Generic thread management facilities.
Consistent and Committed Global State.
void schedule(void)
Definition: scheduler.c:321
static void * main_simulation_loop(void *arg)
Definition: main.c:102
static bool end_computing(void)
Definition: main.c:67
double simtime_t
This defines the type with whom timestamps are represented.
Definition: ROOT-Sim.h:55
simulation_configuration rootsim_config
This global variable holds the configuration for the current simulation.
Definition: core.c:70
void SystemInit(int argc, char **argv)
Definition: init.c:401
Memory Manager main header.
Serial scheduler.
bool thread_barrier(barrier_t *b)
Definition: thread.c:200
int simulation_time
Wall-clock-time based termination predicate.
Definition: init.h:62
LP control blocks.
barrier_t all_thread_barrier
Barrier for all worker threads.
Definition: core.c:49
void create_threads(unsigned short int n, void *(*start_routine)(void *), void *arg)
Definition: thread.c:155
#define master_thread()
This macro expands to true if the current KLT is the master thread for the local kernel.
Definition: thread.h:155
#define D_DIFFER(a, b)
Difference condition for doubles.
Definition: core.h:98
MPI Support Module.
#define master_kernel()
This macro expands to true if the local kernel is the master kernel.
Definition: core.h:47
Global Virtual Time.
void receive_remote_msgs(void)
Receive remote messages.
Definition: mpi.c:208
void simulation_shutdown(int code)
Definition: core.c:178
void collect_termination(void)
Check if other kernels have reached the termination condition.
Definition: mpi.c:289
void rebind_LPs(void)
Definition: binding.c:252
void syncronize_all(void)
Syncronize all the kernels.
Definition: mpi.c:492
bool core_binding
Bind threads to specific core (reduce context switches and cache misses)
Definition: init.h:74
Event & Cross State Synchornization.
bool serial
If the simulation must be run serially.
Definition: init.h:72
static void set_affinity(int core)
Definition: thread.h:61
int main(int argc, char **argv)
Definition: main.c:190