The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
thread.c
Go to the documentation of this file.
1 
36 #include <stdbool.h>
37 #include <arch/thread.h>
38 #include <core/init.h>
39 #include <mm/mm.h>
40 
49 static tid_t os_tid;
50 
51 
60 __thread unsigned int tid;
61 
62 
72 __thread unsigned int local_tid;
73 
74 
83 static unsigned int thread_counter = 0;
84 
85 
103 static void *__helper_create_thread(void *arg)
104 {
105 
106  struct _helper_thread *real_arg = (struct _helper_thread *)arg;
107 
108  // Get a unique local thread id...
109  unsigned int old_counter;
110  unsigned int _local_tid;
111 
112  while (true) {
113  old_counter = thread_counter;
114  _local_tid = old_counter + 1;
115  if (iCAS(&thread_counter, old_counter, _local_tid)) {
116  break;
117  }
118  }
119  local_tid = _local_tid;
120 
121  // ...and make it globally unique
122  tid = to_global_tid(kid, _local_tid);
123 
124  // Set the affinity on a CPU core, for increased performance
127 
128  // Now get into the real thread's entry point
129  real_arg->start_routine(real_arg->arg);
130 
131  // Free arg and return (we don't really need any return value)
132  rsfree(arg);
133  return NULL;
134 }
135 
155 void create_threads(unsigned short int n, void *(*start_routine)(void *), void *arg)
156 {
157  int i;
158 
159  // We create our thread within our helper function, which accepts just
160  // one parameter. We thus have to create one single parameter containing
161  // the original pointer and the function to be used as real entry point.
162  // This malloc'd array is free'd by the helper function.
163  struct _helper_thread *new_arg = rsalloc(sizeof(struct _helper_thread));
164  new_arg->start_routine = start_routine;
165  new_arg->arg = arg;
166 
167  // n threads are created simply looping...
168  for (i = 0; i < n; i++) {
169  new_thread(__helper_create_thread, (void *)new_arg);
170  }
171 }
172 
180 void barrier_init(barrier_t * b, int t)
181 {
182  b->num_threads = t;
184 }
185 
201 {
202  // Wait for the leader to finish resetting the barrier
203  while (atomic_read(&b->barr) != -1) ;
204 
205  // Wait for all threads to synchronize
206  atomic_dec(&b->c1);
207  while (atomic_read(&b->c1)) ;
208 
209  // Leader election
210  if (unlikely(atomic_inc_and_test(&b->barr))) {
211 
212  // I'm sync'ed!
213  atomic_dec(&b->c2);
214 
215  // Wait all the other threads to leave the first part of the barrier
216  while (atomic_read(&b->c2)) ;
217 
218  // Reset the barrier to its initial values
220 
221  return true;
222  }
223  // I'm sync'ed!
224  atomic_dec(&b->c2);
225 
226  return false;
227 }
atomic_t c2
Second synchronization counter.
Definition: thread.h:105
#define new_thread(entry, arg)
Spawn a new thread.
Definition: thread.h:54
#define likely(exp)
Optimize the branch as likely taken.
Definition: core.h:72
Initialization routines.
pthread_t tid_t
How do we identify a thread?
Definition: thread.h:51
#define atomic_read(v)
Read operation on an atomic counter.
Definition: atomic.h:66
void atomic_dec(atomic_t *)
Definition: x86.c:103
void * arg
Arguments to be passed to start_routine.
Definition: thread.h:98
Generic thread management facilities.
void barrier_init(barrier_t *b, int t)
Definition: thread.c:180
This structure is used to call the thread creation helper function.
Definition: thread.h:96
simulation_configuration rootsim_config
This global variable holds the configuration for the current simulation.
Definition: core.c:70
void *(* start_routine)(void *)
A pointer to the entry point of the next-to-be thread.
Definition: thread.h:97
atomic_t c1
First synchronization counter.
Definition: thread.h:104
#define to_global_tid(kid, local_tid)
Convert a local tid in a global tid.
Definition: thread.h:152
Memory Manager main header.
__thread unsigned int tid
Definition: thread.c:60
bool thread_barrier(barrier_t *b)
Definition: thread.c:200
int num_threads
Number of threads which will synchronize on the barrier.
Definition: thread.h:103
void create_threads(unsigned short int n, void *(*start_routine)(void *), void *arg)
Definition: thread.c:155
bool iCAS(volatile uint32_t *ptr, uint32_t oldVal, uint32_t newVal)
Definition: x86.c:49
atomic_t barr
Definition: thread.h:106
#define thread_barrier_reset(b)
Reset operation on a thread barrier.
Definition: thread.h:167
static void * __helper_create_thread(void *arg)
Definition: thread.c:103
int atomic_inc_and_test(atomic_t *v)
Definition: x86.c:118
__thread unsigned int local_tid
Definition: thread.c:72
bool core_binding
Bind threads to specific core (reduce context switches and cache misses)
Definition: init.h:74
static unsigned int thread_counter
Definition: thread.c:83
static void set_affinity(int core)
Definition: thread.h:61
static tid_t os_tid
Definition: thread.c:49
#define unlikely(exp)
Optimize the branch as likely not taken.
Definition: core.h:74
unsigned int kid
Identifier of the local kernel.
Definition: core.c:55
Thread barrier definition.
Definition: thread.h:102