52 #include "tbci/basics.h"
66 #if defined(SMP) && defined(HAVE_PTHREADS)
71 #ifndef HAVE_NO_NEW_HEADERS_BUG
78 #include <sys/types.h>
82 # define PAGESIZE EXEC_PAGESIZE
86 #define __need_sigset_t
89 typedef __sigset_t sigset_t;
92 #undef _POSIX_C_SOURCE
93 #define _POSIX_C_SOURCE 200112L
98 # define CACHELINE_SZ __WORDSIZE
100 # warning Setting cache line size manually to 32
101 # define CACHELINE_SZ 32
108 # define smp_barrier() asm ("": : :"memory")
111 # define smp_barrier()
115 #define MAIN_PID (main_thread_pid)
119 #if defined(NEED_SMP_DECLS) || defined(SMP)
123 #error NEED pthread.h if NEED_SMP_DECLS is set
127 typedef void* (*useful_job_t) (
void*);
129 #define THREAD_MAX_ARGS 6
130 #define THREAD_MAX_RES_LN 16
187 #if defined(SMP) && defined(HAVE_PTHREADS)
198 extern unsigned page_size;
211 int init_threads (
const int thr = 0,
const bool load =
false);
243 void bind_threads (
bool bind_main =
true,
bool enable_numa =
true,
bool add_sibl =
false);
251 const unsigned long offset,
const unsigned long sz, ...);
257 # define SLICE_ALIGN CACHELINE_SZ
259 #ifndef SLICE_DEF_ALIGN
260 # define SLICE_DEF_ALIGN 8
264 template <
typename T>
265 static inline unsigned long slice_offset(
int thr,
int no_thr,
unsigned long dim,
T* ptr)
268 const unsigned int align =
numa_avail? page_size: SLICE_ALIGN;
270 const unsigned int align = SLICE_ALIGN;
276 BCHK(thr < 0 || thr > no_thr,
NumErr, Illegal thread in slice_offset, thr, 0);
277 const unsigned step = dim/no_thr;
278 unsigned long offs = thr*dim/no_thr;
280 if (!ptr || 2*
sizeof(
T) > align) {
282 return offs + (SLICE_DEF_ALIGN - offs%SLICE_DEF_ALIGN);
284 offs +=
MIN((
unsigned int)(align/
sizeof(
T)), step-1);
285 unsigned long misalign = (
unsigned long)(ptr+offs)%align /
sizeof(
T);
288 return offs - misalign;
292 inline void update_n_thr(
const unsigned int n_thr)
299 typedef void cbackfn(
void *ptr,
const int thr);
305 int do_numa_move_pages(
int node,
int fault_in,
306 unsigned long firstaddr,
unsigned long lastaddr);
307 void numa_move_pages_job(
struct thr_ctrl *tc);
312 #if defined(SMP) && (!defined(_REENTRANT) && !defined(_THREAD_SAFE))
313 # warning "Define _REENTRANT and/or _THREAD_SAFE for multithreaded (SMP) compilation!"
317 # define MAIN_PID (getpid())
319 # define num_threads (0)
321 # define ismainthread (1)
322 # define threads_avail(x) (0)
328 { omp_set_num_threads(1); }
334 { omp_set_num_threads(omp_get_num_procs()); }
void thread_dereg_callback(cbackfn ctor, cbackfn dtor, void *parm)
static void free_threads()
volatile char t_res_dummy[16]
unsigned long t_job_output_no
int t_pipe_from_thread[2]
void thread_start(const int thr_no, thr_job_t job, const unsigned long sz,...)
exception base class for the TBCI NumLib
#define BCHK(cond, exc, txt, ind, rtval)
void(* thr_job_t)(struct thr_ctrl *)
Before the double inclusion guard on purpose!
struct thr_struct * threads
static int init_threads(const int=0, const bool=false)
void thread_reg_callback(cbackfn ctor, cbackfn dtor, void *parm)
volatile char t_res_dummy[16]
static void bind_threads(bool=true, bool=true, bool=false)
THREAD__ struct thr_struct * this_thread
static void reenable_threads()
void thread_wait(const int thr_no, struct job_output *out)
double thread_wait_result(const int thr_no)
static void disable_threads()
void thread_start_off(const int thr_no, thr_job_t job, const unsigned long off, const unsigned long sz,...)