The ROme OpTimistic Simulator  3.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
lp.c
Go to the documentation of this file.
1 
11 #include <lp/lp.h>
12 
13 #include <core/sync.h>
14 #include <gvt/fossil.h>
15 
16 __thread uint64_t lp_id_first;
17 __thread uint64_t lp_id_end;
18 
19 __thread struct lp_ctx *current_lp;
20 struct lp_ctx *lps;
22 
23 #define lp_start_id_compute(trd) \
24 __extension__({ \
25  lp_id_t _g = (trd) * n_lps_node / n_threads; \
26  while (_g && lid_to_rid(_g) >= (trd)) \
27  --_g; \
28  while (lid_to_rid(_g) < (trd)) \
29  ++_g; \
30  _g; \
31 })
32 
33 static void lp_iterator_init(void)
34 {
35  lp_id_first = lp_start_id_compute(rid);
36  lp_id_end = lp_start_id_compute(rid + 1);
37 }
38 
39 void lp_global_init(void)
40 {
41  uint64_t lps_offset = nid * n_lps / n_nodes;
42  n_lps_node = ((nid + 1) * n_lps) / n_nodes - lps_offset;
43 
44  lps = mm_alloc(sizeof(*lps) * n_lps_node);
45  lps -= lps_offset;
46 
47  if (n_lps_node < n_threads) {
48  log_log(
49  LOG_WARN,
50  "The simulation will run with %u threads instead of the available %u",
51  n_lps_node,
52  n_threads
53  );
55  }
56 }
57 
58 void lp_global_fini(void)
59 {
60  uint64_t lps_offset = nid * n_lps / n_nodes;
61  lps += lps_offset;
62 
63  mm_free(lps);
64 }
65 
66 void lp_init(void)
67 {
68  lp_iterator_init();
69 
70  for (uint64_t i = lp_id_first; i < lp_id_end; ++i) {
71  current_lp = &lps[i];
72 
73  model_allocator_lp_init();
74  current_lp->lib_ctx_p = malloc_mt(sizeof(*current_lp->lib_ctx_p));
75  lib_lp_init_pr();
77  termination_lp_init();
78  }
79 }
80 
81 void lp_fini(void)
82 {
83  if (sync_thread_barrier()) {
84  uint64_t lps_offset = nid * n_lps / n_nodes;
85  for (uint64_t i = 0; i < n_lps_node ; ++i) {
86  current_lp = &lps[i + lps_offset];
88  }
89  }
90 
92 
93  for (uint64_t i = lp_id_first; i < lp_id_end; ++i) {
94  current_lp = &lps[i];
95 
97  lib_lp_fini_pr();
98  model_allocator_lp_fini();
99  }
100 
101  current_lp = NULL;
102 }
103 
104 lp_id_t lp_id_get_mt(void)
105 {
106  return current_lp - lps;
107 }
108 
109 struct lib_ctx *lib_ctx_get_mt(void)
110 {
111  return current_lp->lib_ctx_p;
112 }
nid
nid_t nid
The node identifier of the node.
Definition: core.c:20
sync.h
Easier Synchronization primitives.
n_lps
lp_id_t n_lps
The total number of LPs in the simulation.
Definition: core.c:13
mm_alloc
void * mm_alloc(size_t mem_size)
A version of the stdlib malloc() used internally.
Definition: mm.h:26
process_lp_init
void process_lp_init(void)
Initializes the processing module in the current LP.
Definition: process.c:66
n_threads
rid_t n_threads
The total number of MPI nodes in the simulation.
Definition: core.c:15
lp_ctx
A complete LP context.
Definition: lp.h:21
log_log
#define log_log(lvl,...)
Produces a log.
Definition: log.h:49
n_lps_node
lp_id_t n_lps_node
The total number of LPs hosted in the node.
Definition: lp.c:21
lp.h
LP construction functions.
lp_ctx::lib_ctx_p
struct lib_ctx * lib_ctx_p
The additional libraries context of this LP.
Definition: lp.h:25
rid
__thread rid_t rid
The identifier of the thread.
Definition: core.c:16
sync_thread_barrier
bool sync_thread_barrier(void)
Synchronizes threads on a barrier.
Definition: sync.c:19
mm_free
void mm_free(void *ptr)
A version of the stdlib free() used internally.
Definition: mm.h:61
fossil.h
Housekeeping operations.
process_lp_fini
void process_lp_fini(void)
Finalizes the processing module in the current LP.
Definition: process.c:98
lib_ctx
Definition: lib.h:17
lp_id_t
uint64_t lp_id_t
Used to uniquely identify LPs in the simulation.
Definition: core.h:75
LOG_WARN
#define LOG_WARN
The logging level reserved to unexpected, non deal breaking conditions.
Definition: log.h:31
process_lp_deinit
void process_lp_deinit(void)
Deinitializes the LP by calling the model's DEINIT handler.
Definition: process.c:88