The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
preempt.c
Go to the documentation of this file.
1 
32 #ifdef HAVE_PREEMPTION
33 
34 #include <timestretch.h>
35 
36 #include <arch/atomic.h>
37 #include <core/core.h>
38 #include <scheduler/process.h>
39 #include <scheduler/scheduler.h>
40 #include <mm/dymelor.h>
41 
42 extern void preempt_callback(void);
43 
44 static simtime_t *volatile min_in_transit_lvt;
45 
46 atomic_t preempt_count;
47 atomic_t overtick_platform;
48 atomic_t would_preempt;
49 
50 __thread volatile bool platform_mode = true;
51 
52 void preempt_init(void)
53 {
54  register unsigned int i;
55  int ret;
56 
58  return;
59 
60  min_in_transit_lvt = rsalloc(sizeof(simtime_t) * n_cores);
61  for (i = 0; i < n_cores; i++) {
62  min_in_transit_lvt[i] = INFTY;
63  }
64 
65  // Try to get control over libtimestretch device file
66  ret = ts_open();
67  if (ret == TS_OPEN_ERROR) {
68  rootsim_error(false, "libtimestretch unavailable: is the module mounted? Will run without preemption...\n");
70  }
71 
72  atomic_set(&preempt_count, 0);
73 
74 // enable_preemption();
75 }
76 
77 void preempt_fini(void)
78 {
79 
81  return;
82 
83  rsfree(min_in_transit_lvt);
84 
85  printf("Total preemptions: %d\n", atomic_read(&preempt_count));
86 
87 // disable_preemption();
88 
89  //ts_close();
90 }
91 
92 void reset_min_in_transit(unsigned int thread)
93 {
95 
97  return;
98 
99  local_min = min_in_transit_lvt[thread];
100 
101  // If the CAS (unlikely) fails, then some other thread has updated
102  // the min in transit. We do not retry the operation, as this
103  // case must be handled.
104  CAS((uint64_t *) & min_in_transit_lvt[thread], UNION_CAST(local_min, uint64_t), UNION_CAST(INFTY, uint64_t));
105 }
106 
107 void update_min_in_transit(unsigned int thread, simtime_t lvt)
108 {
110 
112  return;
113 
114  do {
115  local_min = min_in_transit_lvt[thread];
116 
117  if (lvt >= local_min) {
118  break;
119  }
120  // simtime_t is 64-bits wide, so we use 64-bits CAS
121  } while (!CAS((uint64_t *) & min_in_transit_lvt[thread], UNION_CAST(local_min, uint64_t), UNION_CAST(lvt, uint64_t)));
122 }
123 
124 __thread bool rolling_back = false;
125 
133 __attribute__((used))
134 void preempt(void)
135 {
136 // return;
137 
139  return;
140 
141  // if min_in_transit_lvt < current_lvt
142  // and in platform mode
143 
144 /* if(current != NULL) {
145  if( (count++) % 100 == 0)
146  printf("Overtick interrupt from application mode\n");
147  }
148 */
149 
150 // atomic_inc(&preempt_count);
151 
152  if (platform_mode || rolling_back) {
153 // atomic_inc(&overtick_platform);
154 
155  } else if (min_in_transit_lvt[local_tid] < current_lvt) {
156 // atomic_inc(&would_preempt);
157  current->state = LP_STATE_SUSPENDED; // Questo triggera la logica di ripartenza dell'LP di ECS, ma forse va cambiato nome...
158  switch_to_platform_mode();
160  }
161 
162 /* if(!platform_mode && min_in_transit_lvt[local_tid] < current_lvt) {
163 
164  atomic_inc(&preempt_count);
165 
166  current->state = LP_STATE_READY_FOR_SYNCH; // Questo triggera la logica di ripartenza dell'LP di ECS, ma forse va cambiato nome...
167 
168  // Assembly module has placed a lot of stuff on the stack: put everything back
169  // TODO: this is quite nasty, find a cleaner way to do this...
170  __asm__ __volatile__("pop %r15;"
171  "pop %r14;"
172  "pop %r13;"
173  "pop %r12;"
174  "pop %r11;"
175  "pop %r10;"
176  "pop %r9;"
177  "pop %r8;");
178 
179  __asm__ __volatile__("pop %rsi;"
180  "pop %rdi;"
181  "pop %rdx;"
182  "pop %rcx;"
183  "pop %rbx;"
184  "pop %rax;"
185  "popfq;"
186  "pop %rbp;");
187 
188  }
189 */
190 
191 }
192 
193 void enable_preemption(void)
194 {
195  if (register_ts_thread() != TS_REGISTER_OK) {
196  rootsim_error(true, "Error activating high-frequency interrupts. Aborting...\n");
197  }
198 
199  if (register_callback(preempt_callback) != TS_REGISTER_CALLBACK_OK) {
200  rootsim_error(true, "Error registering callback from kernel module. Aborting...\n");
201  }
202 
203  if (ts_start(0) != TS_START_OK) {
204  rootsim_error(true, "General error\n");
205  }
206 
207 }
208 
209 void disable_preemption(void)
210 {
211  if (deregister_ts_thread() != TS_DEREGISTER_OK) {
212  rootsim_error(true, "Error de-activating high-frequency interrupts. Aborting...\n",);
213  }
214 }
215 
216 #endif /* HAVE_PREEMPTION */
#define lvt(lp)
Definition: process.h:168
#define context_switch(context_old, context_new)
Swicth machine context for userspace context switch. This is used to schedule a LP or return control ...
Definition: ult.h:75
#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
#define UNION_CAST(x, destType)
Macro to "legitimately" pun a type.
Definition: core.h:121
static simtime_t * local_min
The local (per-thread) minimum. It&#39;s not TLS, rather an array, to allow reduction by master thread...
Definition: gvt.c:125
Dynamic Memory Logger and Restorer (DyMeLoR)
The ROOT-Sim scheduler main module header.
__thread struct lp_struct * current
This is a per-thread variable pointing to the block state of the LP currently scheduled.
Definition: scheduler.c:72
#define atomic_set(v, i)
Set operation on an atomic counter.
Definition: atomic.h:69
#define INFTY
Infinite timestamp: this is the highest timestamp in a simulation run.
Definition: ROOT-Sim.h:58
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
__thread kernel_context_t kernel_context
This is the execution context of the simulation kernel.
Definition: ult.c:51
LP control blocks.
Atomic operations.
void preempt(void)
Definition: preempt.c:134
short unsigned int state
Current execution state of the LP.
Definition: process.h:88
LP_context_t context
LP execution state.
Definition: process.h:67
__thread unsigned int local_tid
Definition: thread.c:72
bool disable_preemption
If compiled for preemptive Time Warp, it can be disabled at runtime.
Definition: init.h:77