The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
dymelor.h
Go to the documentation of this file.
1 
34 #pragma once
35 
36 #include <math.h>
37 #include <string.h>
38 
39 #include <core/core.h>
40 #include <datatypes/bitmap.h>
41 #include <mm/state.h>
42 #include <core/timer.h>
43 
44 /**************************************
45  * DyMeLoR definitions and structures *
46  **************************************/
47 
48 //ADDED BY MAT 0x00000200000000000
49 #define LP_PREALLOCATION_INITIAL_ADDRESS (void *)0x0000008000000000
50 
51 #define MIN_CHUNK_SIZE 128U // Size (in bytes) of the smallest chunk provideable by DyMeLoR
52 #define MAX_CHUNK_SIZE 4194304 // Size (in bytes) of the biggest one. Notice that if this number
53  // is too large, performance (and memory usage) might be affected.
54  // If it is too small, large amount of memory requests by the
55  // application level software (i.e, larger than this number)
56  // will fail, as DyMeLoR will not be able to handle them!
57 
58 #define NUM_AREAS (log2(MAX_CHUNK_SIZE) - log2(MIN_CHUNK_SIZE) + 1) // Number of initial malloc_areas available (will be increased at runtime if needed)
59 #define MAX_NUM_AREAS (NUM_AREAS * 32) // Maximum number of allocatable malloc_areas. If MAX_NUM_AREAS
60  // malloc_areas are filled at runtime, subsequent malloc() requests
61  // by the application level software will fail.
62 #define MAX_LIMIT_NUM_AREAS MAX_NUM_AREAS
63 #define MIN_NUM_CHUNKS 512 // Minimum number of chunks per malloc_area
64 #define MAX_NUM_CHUNKS 4096 // Maximum number of chunks per malloc_area
65 
66 #define MAX_LOG_THRESHOLD 1.7 // Threshold to check if a malloc_area is underused TODO: retest
67 #define MIN_LOG_THRESHOLD 1.7 // Threshold to check if a malloc_area is overused TODO: retest
68 
69 #ifndef INCREMENTAL_GRANULARITY
70 #define INCREMENTAL_GRANULARITY 50 // Number of incremental logs before a full log is forced
71 #endif
72 
73 // These macros are used to tune the statistical malloc_area diff
74 #define LITTLE_SIZE 32
75 #define CHECK_SIZE 0.25 // Must be <= 0.25!
76 
77 // This macro is used to retrieve a cache line in O(1)
78 #define GET_CACHE_LINE_NUMBER(P) ((unsigned long)((P >> 4) & (CACHE_SIZE - 1)))
79 
80 // Macros uset to check, set and unset special purpose bits
81 #define SET_LOG_MODE_BIT(m_area) (((malloc_area*)(m_area))->chunk_size |= (1UL << 0))
82 #define RESET_LOG_MODE_BIT(m_area) (((malloc_area*)(m_area))->chunk_size &= ~(1UL << 0))
83 #define CHECK_LOG_MODE_BIT(m_area) (((malloc_area*)(m_area))->chunk_size & (1UL << 0))
84 
85 #define SET_AREA_LOCK_BIT(m_area) (((malloc_area*)(m_area))->chunk_size |= (1UL << 1))
86 #define RESET_AREA_LOCK_BIT(m_area) (((malloc_area*)(m_area))->chunk_size &= ~(1UL << 1))
87 #define CHECK_AREA_LOCK_BIT(m_area) (((malloc_area*)(m_area))->chunk_size & (1UL << 1))
88 
89 #define UNTAGGED_CHUNK_SIZE(m_area) (((malloc_area*)(m_area))->chunk_size & ~((1UL << 0) | (1UL << 1)))
90 
91 #define POWEROF2(x) (1UL << (1 + (63 - __builtin_clzl((x) - 1))))
92 #define IS_POWEROF2(x) ((x) != 0 && ((x) & ((x) - 1)) == 0)
93 
94 #define PER_LP_PREALLOCATED_MEMORY (262144L * PAGE_SIZE) // This should be power of 2 multiplied by a page size. This is 1GB per LP.
95 
97 struct _malloc_area {
98 #ifndef NDEBUG
99  atomic_t presence;
100 #endif
101  size_t chunk_size;
102  int alloc_chunks;
103  int dirty_chunks;
104  int next_chunk;
105  int num_chunks;
106  int idx;
107  int state_changed;
108  simtime_t last_access;
109  struct _malloc_area *self_pointer; // This pointer is used in a free operation. Each chunk points here. If malloc_area is moved, only this is updated.
110  rootsim_bitmap *use_bitmap;
111  rootsim_bitmap *dirty_bitmap;
112  void *area;
113  int prev;
114  int next;
115 };
116 
117 typedef struct _malloc_area malloc_area;
118 
122  size_t total_log_size;
123  size_t total_inc_size;
124  int num_areas;
125  int max_num_areas;
126  simtime_t timestamp;
127  struct _malloc_area *areas;
128 };
129 
130 typedef struct _malloc_state malloc_state;
131 
132 #define is_incremental(ckpt) (((malloc_state *)ckpt)->is_incremental == true)
133 
134 #define get_top_pointer(ptr) ((unsigned long long *)((char *)ptr - sizeof(unsigned long long)))
135 #define get_area_top_pointer(ptr) ( (malloc_area **)(*get_top_pointer(ptr)) )
136 #define get_area(ptr) ( *(get_area_top_pointer(ptr)) )
137 
138 #define PER_LP_PREALLOCATED_MEMORY (262144L * PAGE_SIZE) // This should be power of 2 multiplied by a page size. This is 1GB per LP.
139 #define BUDDY_GRANULARITY PAGE_SIZE // This is the smallest chunk released by the buddy in bytes. PER_LP_PREALLOCATED_MEMORY/BUDDY_GRANULARITY must be integer and a power of 2
140 
141 
142 struct segment {
143  unsigned char *base;
144  unsigned char *brk;
145 };
146 
147 extern size_t __page_size;
148 #define PAGE_SIZE ({ \
149  if(unlikely(__page_size == 0))\
150  __page_size = getpagesize();\
151  __page_size;\
152  })
153 
154 struct slab_header {
155 #ifndef NDEBUG
156  atomic_t presence;
157 #endif
158  struct slab_header *prev, *next;
159  uint64_t slots;
160  uintptr_t refcount;
161  struct slab_header *page;
162  uint8_t data[] __attribute__((aligned(sizeof(void *))));
163 };
164 
165 struct slab_chain {
166  spinlock_t lock;
167  size_t itemsize, itemcount;
168  size_t slabsize, pages_per_alloc;
169  uint64_t initial_slotmask, empty_slotmask;
170  uintptr_t alignment_mask;
171  struct slab_header *partial, *empty, *full;
172 };
173 
174 
175 /***************
176  * EXPOSED API *
177  ***************/
178 
179 // DyMeLoR API
180 extern void set_force_full(unsigned int, int);
181 extern void dirty_mem(void *, int);
182 extern size_t get_state_size(int);
183 extern size_t get_log_size(malloc_state *);
184 extern size_t get_inc_log_size(void *);
185 extern int get_granularity(void);
186 extern size_t dirty_size(unsigned int, void *, double *);
187 extern malloc_state *malloc_state_init(void);
188 extern void *do_malloc(struct lp_struct *, size_t);
189 extern void do_free(struct lp_struct *, void *ptr);
190 extern void *allocate_lp_memory(struct lp_struct *, size_t);
191 extern void free_lp_memory(struct lp_struct *, void *);
192 
193 
194 // Userspace API
195 extern void *__wrap_malloc(size_t);
196 extern void __wrap_free(void *);
197 extern void *__wrap_realloc(void *, size_t);
198 extern void *__wrap_calloc(size_t, size_t);
199 
200 
201 /***************************
202  * BUDDY SYSTEM
203  ***************************/
204 
205 // buddy block size expressed in 2^n, e.g.: BUDDY_BLOCK_SIZE_EXP = 4, block_size = 16 TODO make this the pagesize
206 #define BUDDY_BLOCK_SIZE_EXP 12
207 
208 struct buddy {
209  spinlock_t lock;
210  size_t size;
211  size_t longest[] __attribute__((aligned(sizeof(size_t)))); // an array based binary tree
212 };
213 
214 extern struct buddy *buddy_new(size_t requested_size);
215 extern void buddy_destroy(struct buddy *self);
216 extern void *allocate_buddy_memory(struct buddy *self, void *base_mem, size_t requested_size);
217 extern void free_buddy_memory(struct buddy *self, void *base_mem, void *ptr);
218 
219 
220 // This is used to help ensure that the platform is not using malloc.
221 #pragma GCC poison malloc free realloc calloc
void dirty_mem(void *, int)
Definition: dymelor.c:445
malloc_state * malloc_state_init(void)
Definition: dymelor.c:78
struct buddy * buddy_new(size_t requested_size)
Definition: buddy.c:75
void * do_malloc(struct lp_struct *, size_t)
Definition: dymelor.c:167
void __wrap_free(void *)
Definition: dymelor.c:589
Core ROOT-Sim functionalities.
void * __wrap_calloc(size_t, size_t)
Definition: dymelor.c:664
void * __wrap_realloc(void *, size_t)
Definition: dymelor.c:615
Timers.
bool is_incremental
Tells if it is an incremental log or a full one (when used for logging)
Definition: dymelor.h:121
double simtime_t
This defines the type with whom timestamps are represented.
Definition: ROOT-Sim.h:56
Definition: dymelor.h:208
LP state management.
Bitmap data type.
size_t get_log_size(malloc_state *)
Definition: dymelor.c:526
Definition of the memory map.
Definition: dymelor.h:120
unsigned char rootsim_bitmap
This defines a generic bitmap.
Definition: bitmap.h:43
void * __wrap_malloc(size_t)
Definition: dymelor.c:553
This structure let DyMeLoR handle one malloc area (for serving given-size memory requests) ...
Definition: dymelor.h:97