The ROme OpTimistic Simulator  2.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
thread.h File Reference

Generic thread management facilities. More...

#include <stdbool.h>
#include <arch/atomic.h>
#include <sched.h>
#include <unistd.h>
#include <pthread.h>
+ Include dependency graph for thread.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  _helper_thread
 This structure is used to call the thread creation helper function. More...
 
struct  barrier_t
 Thread barrier definition. More...
 

Macros

#define get_cores()   (sysconf( _SC_NPROCESSORS_ONLN ))
 Macro to get the core count on the hosting machine.
 
#define new_thread(entry, arg)   pthread_create(&os_tid, NULL, entry, arg)
 Spawn a new thread.
 
#define HALF_UINT_BITS   (sizeof(unsigned int) * 8 / 2)
 
#define MAX_KERNELS   ((1 << HALF_UINT_BITS) - 1)
 
#define MAX_THREADS_PER_KERNEL   ((1 << HALF_UINT_BITS) - 1)
 
#define to_global_tid(kid, local_tid)   ( (kid << HALF_UINT_BITS) | local_tid )
 Convert a local tid in a global tid. More...
 
#define master_thread()   (local_tid == 0)
 This macro expands to true if the current KLT is the master thread for the local kernel.
 
#define thread_barrier_reset(b)
 Reset operation on a thread barrier. More...
 

Typedefs

typedef pthread_t tid_t
 How do we identify a thread?
 

Functions

static void set_affinity (int core)
 
void barrier_init (barrier_t *b, int t)
 
bool thread_barrier (barrier_t *b)
 
void create_threads (unsigned short int n, void *(*start_routine)(void *), void *arg)
 

Variables

__thread unsigned int tid
 
__thread unsigned int local_tid
 

Detailed Description

Generic thread management facilities.

This module provides generic facilities for thread management. In particular, helper functions to startup worker threads are exposed, and a function to synchronize multiple threads on a software barrier.

The software barrier also offers a leader election facility, so that once all threads are synchronized on the barrier, the function returns true to only one of them.

This file is part of ROOT-Sim (ROme OpTimistic Simulator).

ROOT-Sim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; only version 3 of the License applies.

ROOT-Sim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with ROOT-Sim; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Author
Alessandro Pellegrini
Date
Jan 25, 2012

Definition in file thread.h.

Macro Definition Documentation

#define HALF_UINT_BITS   (sizeof(unsigned int) * 8 / 2)

The global tid is obtained by concatenating of the kid and the local_tid and is stored into an unsigned int. Since we are using half of the unsigned int for each part we have that the total number of kernels and the number of threads per kernel must be less then (2^HALF_UINT_BITS - 1)

Definition at line 117 of file thread.h.

#define MAX_KERNELS   ((1 << HALF_UINT_BITS) - 1)

This macro tells what is the maximum number of simulation kernel instances which are supported. This has to do with the maximum representable number give the fact that half of the available bits in a tid are used to keep track of the kid on which that kernel resides.

Definition at line 129 of file thread.h.

#define MAX_THREADS_PER_KERNEL   ((1 << HALF_UINT_BITS) - 1)

This macro tells how many threads we can have on a single simulation kernel. The logis is the same as that of MAX_KERNELS, i.e. sharing the available bit in an unsigned long to keep both representations.

Definition at line 137 of file thread.h.

#define thread_barrier_reset (   b)
Value:
do { \
(atomic_set((&b->c1), (b)->num_threads)); \
(atomic_set((&b->c2), (b)->num_threads)); \
(atomic_set((&b->barr), -1)); \
} while (0)
#define atomic_set(v, i)
Set operation on an atomic counter.
Definition: atomic.h:69

Reset operation on a thread barrier.

This macro can be used to initialize (or reset) a thread barrier.

Warning
Using this macro on a thread barrier on which some thread_barrier is already synchronizing leads to undefined behaviour.
Parameters
bThe thread barrier to reset (the name, not a pointer to)

Definition at line 167 of file thread.h.

#define to_global_tid (   kid,
  local_tid 
)    ( (kid << HALF_UINT_BITS) | local_tid )

Convert a local tid in a global tid.

This macro takes a local tid and inserts in the upper part of the bits the id of the kernel on which that thread is running. This makes the global tid.

Parameters
kidThe kid on which a thread is running
local_tidThe locally-assigned tid of the thread
Returns
The global kid

Definition at line 152 of file thread.h.

Function Documentation

void barrier_init ( barrier_t b,
int  t 
)

This function initializes a thread barrier. If more than the hereby specified number of threads try to synchronize on the barrier, the behaviour is undefined.

Parameters
bthe thread barrier to initialize
tthe number of threads which will synchronize on the barrier

Definition at line 180 of file thread.c.

+ Here is the caller graph for this function:

void create_threads ( unsigned short int  n,
void *(*)(void *)  start_routine,
void *  arg 
)

This function creates n threads, all having the same entry point and the same arguments. It creates a new thread starting from the __helper_create_thread function which silently sets the new thread's tid. Note that the arguments passed to __helper_create_thread are malloc'd here, and free'd there. This means that if start_routine does not return, there is a memory leak. Additionally, note that we don't make a copy of the arguments pointed by arg, so all the created threads will share them in memory. Changing passed arguments from one of the newly created threads will result in all the threads seeing the change.

Parameters
nThe number of threads which should be created
start_routineThe new threads' entry point
argA pointer to an array of arguments to be passed to the new threads' entry point

Definition at line 155 of file thread.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void set_affinity ( int  core)
inlinestatic

This inline function sets the affinity of the thread which calls it.

Parameters
coreThe core id on which the thread wants to be stuck on.

Definition at line 61 of file thread.h.

+ Here is the caller graph for this function:

bool thread_barrier ( barrier_t b)

This function synchronizes all the threads. After a thread leaves this function, it is guaranteed that no other thread has (at least) not entered the function, therefore allowing to create a separation between the execution in portions of the code. If more threads than specified in the initialization of the barrier try to synchronize on it, the behaviour is undefined. The function additionally returns 'true' only to one of the calling threads, allowing the execution of portions of code in isolated mode after the barrier itself. This is like a leader election for free.

Parameters
bA pointer to the thread barrier to synchronize on
Returns
false to all threads, except for one which is elected as the leader

Definition at line 200 of file thread.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

__thread unsigned int local_tid

The "local" id of the thread. This is a per-instance value which uniquely identifies a thread on a compute node.

Definition at line 72 of file thread.c.

__thread unsigned int tid

The id of the thread.

Definition at line 60 of file thread.c.