The ROme OpTimistic Simulator  3.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
msg_allocator.c
Go to the documentation of this file.
1 
11 #include <mm/msg_allocator.h>
12 
13 #include <core/core.h>
14 #include <datatypes/array.h>
15 #include <gvt/gvt.h>
16 
17 static __thread dyn_array(struct lp_msg *) free_list = {0};
18 static __thread dyn_array(struct lp_msg *) free_gvt_list = {0};
19 
20 void msg_allocator_init(void)
21 {
22  array_init(free_list);
23  array_init(free_gvt_list);
24 }
25 
26 void msg_allocator_fini(void)
27 {
28  while(!array_is_empty(free_list)){
29  mm_free(array_pop(free_list));
30  }
31  array_fini(free_list);
32 
33  while(!array_is_empty(free_gvt_list)){
34  mm_free(array_pop(free_gvt_list));
35  }
36  array_fini(free_gvt_list);
37 }
38 
39 struct lp_msg* msg_allocator_alloc(unsigned payload_size)
40 {
41  struct lp_msg *ret;
42  if(unlikely(payload_size > BASE_PAYLOAD_SIZE)){
43  ret = mm_alloc(
44  offsetof(struct lp_msg, extra_pl) +
45  (payload_size - BASE_PAYLOAD_SIZE)
46  );
47  ret->pl_size = payload_size;
48  return ret;
49  }
50  if(unlikely(array_is_empty(free_list))){
51  ret = mm_alloc(sizeof(struct lp_msg));
52  ret->pl_size = payload_size;
53  return ret;
54  }
55  return array_pop(free_list);
56 }
57 
58 void msg_allocator_free(struct lp_msg *msg)
59 {
60  if(likely(msg->pl_size <= BASE_PAYLOAD_SIZE))
61  array_push(free_list, msg);
62  else
63  mm_free(msg);
64 }
65 
66 #ifdef ROOTSIM_MPI
67 void msg_allocator_free_at_gvt(struct lp_msg *msg)
68 {
69  array_push(free_gvt_list, msg);
70 }
71 
72 void msg_allocator_fossil_collect(simtime_t current_gvt)
73 {
74  array_count_t j = 0;
75  for(array_count_t i = 0; i < array_count(free_gvt_list); ++i){
76  struct lp_msg *msg = array_get_at(free_gvt_list, i);
77  // xxx this could need to check the actual sending time instead
78  // of the destination time in order to avoid a pseudo memory
79  // leak for LPs which send messages distant in logical time.
80  if (current_gvt > msg->dest_t) {
81  msg_allocator_free(msg);
82  } else {
83  array_get_at(free_gvt_list, j) = msg;
84  j++;
85  }
86  }
87  array_count(free_gvt_list) = j;
88 }
89 #endif
90 
91 extern struct lp_msg* msg_allocator_pack(lp_id_t receiver, simtime_t timestamp,
92  unsigned event_type, const void *payload, unsigned payload_size);
simtime_t
double simtime_t
The type used to represent logical time in the simulation.
Definition: core.h:62
lp_msg::extra_pl
unsigned char extra_pl[]
The continuation of the payload.
Definition: msg.h:56
mm_alloc
void * mm_alloc(size_t mem_size)
A version of the stdlib malloc() used internally.
Definition: mm.h:26
lp_msg
A model simulation message.
Definition: msg.h:34
msg_allocator.h
Memory management functions for messages.
array.h
Dynamic array datatype.
array_count_t
uint_fast32_t array_count_t
The type used to handle dynamic arrays count of elements and capacity.
Definition: array.h:21
mm_free
void mm_free(void *ptr)
A version of the stdlib free() used internally.
Definition: mm.h:61
likely
#define likely(exp)
Optimize the branch as likely taken.
Definition: core.h:57
array_count
#define array_count(self)
Gets the count of contained element in a dynamic array.
Definition: array.h:47
lp_id_t
uint64_t lp_id_t
Used to uniquely identify LPs in the simulation.
Definition: core.h:75
core.h
Core ROOT-Sim functionalities.
lp_msg::pl_size
uint_fast32_t pl_size
The message payload size.
Definition: msg.h:46
unlikely
#define unlikely(exp)
Optimize the branch as likely not taken.
Definition: core.h:59
dyn_array
#define dyn_array(type)
Declares a dynamic array.
Definition: array.h:27
gvt.h
Global Virtual Time.
lp_msg::dest_t
simtime_t dest_t
The intended destination logical time of this message.
Definition: msg.h:38