Zero  0.1.0
kits_thread.h
Go to the documentation of this file.
1 /* -*- mode:C++; c-basic-offset:4 -*-
2  Shore-kits -- Benchmark implementations for Shore-MT
3 
4  Copyright (c) 2007-2009
5  Data Intensive Applications and Systems Labaratory (DIAS)
6  Ecole Polytechnique Federale de Lausanne
7 
8  All Rights Reserved.
9 
10  Permission to use, copy, modify and distribute this software and
11  its documentation is hereby granted, provided that both the
12  copyright notice and this permission notice appear in all copies of
13  the software, derivative works or modified versions, and any
14  portions thereof, and that both notices appear in supporting
15  documentation.
16 
17  This code is distributed in the hope that it will be useful, but
18  WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
20  DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
21  RESULTING FROM THE USE OF THIS SOFTWARE.
22 */
23 
24 #ifndef __THREAD_H
25 #define __THREAD_H
26 
27 
28 // pthread.h should always be the first include!
29 #include <pthread.h>
30 #include <cstdio>
31 
32 // #include "k_defines.h"
33 
34 #include <cerrno>
35 #include <cassert>
36 #include <functional>
37 #include <cstdarg>
38 #include <cstdint>
39 #include <ctime>
40 
41 #include "kits_exception.h"
42 #include "util/randgen.h"
43 
44 #include "thread_wrapper.h"
45 
46 #ifndef __GCC
47 //using std::rand_r;
48 #endif
49 
50 pthread_mutex_t thread_mutex_create(const pthread_mutexattr_t* attr = nullptr);
51 
52 void thread_mutex_lock(pthread_mutex_t& mutex);
53 
54 void thread_mutex_unlock(pthread_mutex_t& mutex);
55 
56 void thread_mutex_destroy(pthread_mutex_t& mutex);
57 
58 pthread_cond_t thread_cond_create(const pthread_condattr_t* attr = nullptr);
59 
60 void thread_cond_destroy(pthread_cond_t& cond);
61 
62 void thread_cond_signal(pthread_cond_t& cond);
63 
64 void thread_cond_broadcast(pthread_cond_t& cond);
65 
66 void thread_cond_wait(pthread_cond_t& cond, pthread_mutex_t& mutex);
67 
68 bool thread_cond_wait(pthread_cond_t& cond, pthread_mutex_t& mutex,
69  struct timespec& timeout);
70 
71 bool thread_cond_wait(pthread_cond_t& cond, pthread_mutex_t& mutex,
72  int timeout_ms);
73 
74 template<class T>
75 T* thread_join(pthread_t tid) {
76  // the union keeps gcc happy about the "type-punned" pointer
77  // access going on here. Otherwise, -O3 could break the code.
78  union {
79  void* p;
80  T* v;
81  } u;
82 
83  if (pthread_join(tid, &u.p)) {
84  throw ThreadException(__FILE__, __LINE__, __PRETTY_FUNCTION__, "");
85  }
86 
87  return u.v;
88 }
89 
90 /***********************************************************************
91  *
92  * @struct thread_pool
93  *
94  * @brief Structure that represents a pool of (worker) threads
95  *
96  * @note A request of a new thread is either granted immediately or
97  * the requestor has to block until notified (by the conditional
98  * variable).
99  *
100  ***********************************************************************/
101 
102 
103 struct thread_pool {
104  pthread_mutex_t _lock;
105 
106  pthread_cond_t _cond;
107 
108  int _max_active; // how many can be active at a time?
109  int _active; // how many are actually active?
110 
111  thread_pool(int max_active)
112  : _lock(thread_mutex_create()),
113  _cond(thread_cond_create()),
114  _max_active(max_active),
115  _active(0) {}
116 
117  void start();
118 
119  void stop();
120 }; // EOF: thread_pool
121 
122 
123 #include "sm_vas.h"
124 
125 /***********************************************************************
126  *
127  * @class thread_t
128  *
129  * @brief shore-mt-client thread base class. Basically a thin wrapper around an
130  * internal method and a thread name.
131  *
132  ***********************************************************************/
133 
134 class thread_t : public thread_wrapper_t {
135 private:
136  std::string _thread_name;
137 
139 
140  void run();
142 
143  void setuppool(thread_pool* apool) {
144  _ppool = apool;
145  }
146 
147  void setupthr();
148 
149 protected:
151 
152 public:
153 
159  virtual void work() = 0;
160 
161  bool delete_me() {
162  return _delete_me;
163  }
164 
165  std::string thread_name() {
166  return _thread_name;
167  }
168 
173  return &_randgen;
174  }
175 
179  int rand() {
180  return _randgen.rand();
181  }
182 
189  int rand(int n) {
190  return _randgen.rand(n);
191  }
192 
193  virtual ~thread_t() {}
194 
195 protected:
196  thread_t(const std::string& name);
197 }; // EOF: thread_t
198 
199 
206 template<class Class, class Functor>
208  Class* _instance;
209 
210  Functor _func;
211 
212 public:
213  member_func_thread_t(Class* instance, Functor func, const std::string& thread_name)
214  : thread_t(thread_name),
215  _instance(instance),
216  _func(func) {}
217 
218  virtual void work() {
219  _func(_instance);
220  }
221 };
222 
229 template<class Return, class Class>
230 thread_t* member_func_thread(Class* instance,
231  Return (Class::*mem_func)(),
232  const std::string& thread_name) {
233  typedef std::mem_fun_t<Return, Class> Functor;
234  return new member_func_thread_t<Class, Functor>(instance,
235  Functor(mem_func),
236  thread_name);
237 }
238 
239 
240 
241 // exported functions
242 
243 void thread_init(void);
244 
246 
247 pthread_t thread_create(thread_t* t, thread_pool* p = nullptr);
248 
249 #if 0 // superceded by thread_local.h
250 template<typename T>
251 struct thread_local {
252  pthread_key_t _key;
253 
254  // NOTE:: the template is here because there because I am not
255  // aware of a way to pass 'extern "C" function pointers to a C++
256  // class member function. Fortunately the compiler can still
257  // instantiate a template taking 'extern "C"' stuff... However,
258  // this makes a default constructor argument of NULL ambiguous, so
259  // we have to have two constructors instead. Yuck.
260  template<class Destructor>
261  thread_local(Destructor d) {
262  pthread_key_create(&_key, d);
263  }
264  thread_local() {
265  pthread_key_create(&_key, nullptr);
266  }
267  ~thread_local() {
268  pthread_key_delete(_key);
269  }
270 
271  T* get() {
272  return reinterpret_cast<T*>(pthread_getspecific(_key));
273  }
274  void set(T* val) {
275  int result = pthread_setspecific(_key, val);
276  THROW_IF(ThreadException, result);
277  if(result)
278  throw ThreadException(__FILE__, __LINE__, __PRETTY_FUNCTION__, "");
279  }
280 
281 
282  thread_local &operator=(T* val) {
283  set(val);
284  return *this;
285  }
286  operator T*() {
287  return get();
288  }
289 };
290 #endif
291 
292 extern __thread thread_pool* THREAD_POOL;
293 
294 #endif // __THREAD_H
wraps up a class instance and a member function to look like a thread_t. Use the convenience function...
Definition: kits_thread.h:207
randgen_t _randgen
Definition: kits_thread.h:138
pthread_t thread_create(thread_t *t, thread_pool *p=nullptr)
Definition: kits_thread.cpp:168
bool _delete_me
Definition: kits_thread.h:150
void thread_cond_signal(pthread_cond_t &cond)
Definition: kits_thread.cpp:263
void thread_cond_destroy(pthread_cond_t &cond)
Definition: kits_thread.cpp:257
Definition: thread_wrapper.h:16
pthread_cond_t _cond
Definition: kits_thread.h:106
bool delete_me()
Definition: kits_thread.h:161
int rand()
Definition: randgen.h:40
Definition: kits_thread.h:134
pthread_mutex_t _lock
Definition: kits_thread.h:104
void thread_mutex_destroy(pthread_mutex_t &mutex)
Definition: kits_thread.cpp:243
virtual void work()
Definition: kits_thread.h:218
std::string thread_name()
Definition: kits_thread.h:165
T * thread_join(pthread_t tid)
Definition: kits_thread.h:75
void start()
Definition: kits_thread.cpp:359
std::string _thread_name
Definition: kits_thread.h:136
void stop()
Definition: kits_thread.cpp:375
void setuppool(thread_pool *apool)
Definition: kits_thread.h:143
void thread_cond_wait(pthread_cond_t &cond, pthread_mutex_t &mutex)
Definition: kits_thread.cpp:275
pthread_mutex_t thread_mutex_create(const pthread_mutexattr_t *attr=nullptr)
Definition: kits_thread.cpp:185
int rand()
Returns a pseudo-random integer between 0 and RAND_MAX.
Definition: kits_thread.h:179
Definition: kits_thread.h:103
#define __PRETTY_FUNCTION__
Definition: compat.h:34
#define THROW_IF(Exception, err)
Definition: kits_exception.h:63
void thread_init(void)
Initialize thread module.
Definition: kits_thread.cpp:142
Class * _instance
Definition: kits_thread.h:208
__thread thread_pool * THREAD_POOL
Definition: kits_thread.cpp:73
virtual ~thread_t()
Definition: kits_thread.h:193
int _active
Definition: kits_thread.h:109
void thread_cond_broadcast(pthread_cond_t &cond)
Definition: kits_thread.cpp:269
member_func_thread_t(Class *instance, Functor func, const std::string &thread_name)
Definition: kits_thread.h:213
void thread_mutex_lock(pthread_mutex_t &mutex)
Definition: kits_thread.cpp:216
pthread_cond_t thread_cond_create(const pthread_condattr_t *attr=nullptr)
Definition: kits_thread.cpp:249
thread_pool(int max_active)
Definition: kits_thread.h:111
thread_t * thread_get_self(void)
Definition: kits_thread.cpp:147
Definition: kits_exception.h:98
thread_t * member_func_thread(Class *instance, Return(Class::*mem_func)(), const std::string &thread_name)
Helper function for running class member functions in a pthread. The function must take no arguments ...
Definition: kits_thread.h:230
thread_pool * _ppool
Definition: kits_thread.h:141
randgen_t * randgen()
Returns pointer to thread_t&#39;s randgen_t object.
Definition: kits_thread.h:172
void thread_mutex_unlock(pthread_mutex_t &mutex)
Definition: kits_thread.cpp:237
#define T
Definition: w_okvl_inl.h:45
Functor _func
Definition: kits_thread.h:210
int _max_active
Definition: kits_thread.h:108
Definition: randgen.h:31
int rand(int n)
Definition: kits_thread.h:189