The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
segment.c
Go to the documentation of this file.
1 
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #include <fcntl.h>
33 #include <sys/types.h>
34 
35 #include <mm/mm.h>
36 #include <mm/ecs.h>
38 #include <scheduler/process.h>
39 
40 size_t __page_size = 0;
41 
42 //TODO: document this magic! This is related to the pml4 index intialized in the ECS kernel module
43 static unsigned char *init_address = (unsigned char *)(10LL << 39);
44 
45 void *get_base_pointer(GID_t gid)
46 {
47 // printf("get base pointer for lid % d (gid %d) returns: %p\n",GidToLid(gid),gid,init_address + PER_LP_PREALLOCATED_MEMORY * gid);
48  return init_address + PER_LP_PREALLOCATED_MEMORY * gid.to_int;
49 }
50 
51 void *get_segment_memory(struct segment *seg, size_t size)
52 {
53  unsigned char *new_brk, *ret = NULL;
54 
55  // Align the new brk to a multiple of 64 bytes, to increase L1 cache efficiency
56  new_brk =
57  (unsigned char *)(((unsigned long long)seg->brk + size + (64 - 1)) &
58  -64);
59 
60  // Do we have enough space?
61  if (likely(new_brk >= seg->base + PER_LP_PREALLOCATED_MEMORY)) {
62  ret = seg->brk;
63  seg->brk = new_brk;
64  }
65 
66  return ret;
67 }
68 
69 void free_segment_memory(void *ptr)
70 {
71  // there ain't much we can do here...
72  (void)ptr;
73 }
74 
75 struct segment *get_segment(GID_t gid)
76 {
77  void *the_address;
78  struct segment *seg;
79 
80  seg = rsalloc(sizeof(struct segment));
81  if (seg == NULL)
82  return NULL;
83 
84  // Addresses are determined in the same way across all kernel instances
85  the_address = init_address + PER_LP_PREALLOCATED_MEMORY * gid.to_int;
86 
87  seg->base =
88  mmap(the_address, PER_LP_PREALLOCATED_MEMORY,
89  PROT_READ | PROT_WRITE,
90  MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0);
91  if (unlikely(seg->base == MAP_FAILED)) {
92  perror("mmap");
93  rootsim_error(true, "Unable to mmap LPs memory\n");
94  return NULL;
95  }
96  seg->brk = seg->base;
97 
98  // Access the memory in write mode to force the kernel to create the page table entries
99  *seg->base = 'x';
100 
101  return seg;
102 }
103 
104 void segment_init(void)
105 {
106  struct rlimit limit;
107  size_t max_address_space = PER_LP_PREALLOCATED_MEMORY * n_prc_tot * 2;
108 
109  // Configure the system to allow mmapping 1GB of VM at a time
110  limit.rlim_cur = max_address_space;
111  limit.rlim_max = max_address_space;
112 
113  if (setrlimit(RLIMIT_AS, &limit) != 0) {
114  perror("Unable to set the maximum address space");
115  rootsim_error(true,
116  "Unable to pre-allocate per-LP memory. Aborting...\n");
117  }
118 }
119 
120 /*
121  * TODO: this should reconstruct the addresses similarly to what is done in get_segment. Anyhow, this is called at simulation shutdown and doesn't cause much harm if it's not called.
122  */
123 /*
124  * void segment_allocator_fini(unsigned int sobjs){
125  unsigned int i;
126  int return_value;
127  for(i=0;i<sobjs;i++){
128  return_value = munmap(mem_region[i].base_pointer,PER_LP_PREALLOCATED_MEMORY);
129  if(unlikely(return_value)) {
130  printf("ERROR on release value:%d\n",return_value);
131  break;
132  }
133  mem_region[i].base_pointer = NULL;
134  }
135  close(ioctl_fd);
136 
137 }
138 */
139 
140 void initialize_memory_map(struct lp_struct *lp)
141 {
142  lp->mm = rsalloc(sizeof(struct memory_map));
143 
144  lp->mm->segment = NULL; //get_segment(lp->gid);
145  lp->mm->buddy = NULL; //buddy_new(lp, PER_LP_PREALLOCATED_MEMORY / BUDDY_GRANULARITY);
146  lp->mm->slab = slab_init(SLAB_MSG_SIZE);
147  lp->mm->m_state = malloc_state_init();
148 }
149 
150 void finalize_memory_map(struct lp_struct *lp)
151 {
152  malloc_state_wipe(&lp->mm->m_state);
153  //buddy_destroy(lp->mm->buddy);
154  // No free segment function here!
155  rsfree(lp->mm);
156 }
Per-thread page table.
#define likely(exp)
Optimize the branch as likely taken.
Definition: core.h:72
#define SLAB_MSG_SIZE
Slab allocator max message size.
Definition: communication.h:43
Definition: mm.h:77
unsigned int to_int
The GID numerical value.
Definition: core.h:133
struct memory_map * mm
Memory map of the LP.
Definition: process.h:76
Definition: mm.h:39
Memory Manager main header.
LP control blocks.
Definition of a GID.
Definition: core.h:132
malloc_state * malloc_state_init(void)
Definition: dymelor.c:77
Event & Cross State Synchornization.
unsigned int n_prc_tot
Total number of logical processes running in the simulation.
Definition: core.c:64
#define unlikely(exp)
Optimize the branch as likely not taken.
Definition: core.h:74