Scopira  20080306
thread_pthreads.h
1 
2 /*
3  * Copyright (c) 2002-2004 National Research Council
4  *
5  * All rights reserved.
6  *
7  * This material is confidential and proprietary information of
8  * National Research Council Canada ("Confidential Information").
9  * This Confidential Information may only be used and reproduced
10  * in accordance with the terms of the license agreement.
11  *
12  */
13 
14 #ifndef __INCLUDED_SCOPIRA_TOOL_THREAD_PTHREADS_H__
15 #define __INCLUDED_SCOPIRA_TOOL_THREAD_PTHREADS_H__
16 
17 #include <scopira/tool/platform.h>
18 #include <scopira/tool/export.h>
19 
20 #include <pthread.h>
21 #include <errno.h>
22 
23 #include <scopira/tool/object.h>
24 
25 namespace scopira
26 {
27  namespace tool
28  {
29  class runnable_i;
30  class job_i;
31 
34  typedef void* (*runfunc_t)(void*);
35  class thread;
36 
37  class condition;
38 
39  class rwlock;
40  class read_locker;
41  class write_locker;
42 
49  SCOPIRA_EXPORT int num_system_cpus(void);
50 
51  template <class T> class shared_area;
52  template <class T> class event_area;
53  template <class T> class rw_area;
54 
55  template <class T> class area_ptr;
56  template <class T> class const_area_ptr;
57  template <class T> class locker_ptr;
58  template <class T> class event_ptr;
59  template <class T> class read_locker_ptr;
60  template <class T> class write_locker_ptr;
61  }
62 }
63 
70 {
71  public:
76  SCOPIRA_EXPORT virtual void run(void) = 0;
77 
78  protected:
79  virtual ~runnable_i() { }
80 };
81 
88 {
89  public:
91  SCOPIRA_EXPORT virtual void start(void) = 0;
92 
94  SCOPIRA_EXPORT virtual void notify_stop(void) = 0;
95 
97  SCOPIRA_EXPORT virtual void wait_stop(void) = 0;
98 
100  SCOPIRA_EXPORT virtual bool is_running(void) const = 0;
101 };
102 
109  public virtual scopira::tool::runnable_i
110 {
111  public:
112  typedef pthread_key_t tlskey_t;
113 
114  protected:
115  runnable_i *dm_target;
116  runfunc_t dm_runfunc;
117  void *dm_runfunc_arg;
118  volatile bool dm_running;
119 
120  pthread_t dm_thread;
121 
122  public:
135  SCOPIRA_EXPORT thread(runnable_i* target);
146  SCOPIRA_EXPORT thread(runfunc_t func, void *arg);
147 
149  SCOPIRA_EXPORT virtual ~thread();
150 
152  SCOPIRA_EXPORT virtual void run(void);
153 
155  SCOPIRA_EXPORT virtual void start(void);
158  SCOPIRA_EXPORT virtual void notify_stop(void);
160  SCOPIRA_EXPORT virtual void wait_stop(void);
162  SCOPIRA_EXPORT virtual bool is_running(void) const { return dm_running; }
163 
170  SCOPIRA_EXPORT static void sleep(int msec);
171 
181  SCOPIRA_EXPORT static void open_tls(tlskey_t &outkey);
187  SCOPIRA_EXPORT static void close_tls(tlskey_t k);
188 
196  SCOPIRA_EXPORT static void set_tls(tlskey_t k, const void *val);
204  SCOPIRA_EXPORT static void * get_tls(tlskey_t k);
205 
206  protected:
207  SCOPIRA_EXPORT static void * voidrun(void *arg);
208 };
209 
221 {
222  protected:
223  pthread_cond_t dm_con;
224 
225  public:
229  SCOPIRA_EXPORT condition(void);
231  SCOPIRA_EXPORT ~condition();
232 
238  SCOPIRA_EXPORT void notify(void);
244  SCOPIRA_EXPORT void notify_all(void);
253  SCOPIRA_EXPORT void wait(mutex &mut);
265  SCOPIRA_EXPORT bool wait(mutex &mut, int msec);
266 };
267 
274 {
275  private:
276  pthread_rwlock_t dm_rw;
277 
278  public:
280  SCOPIRA_EXPORT rwlock(void);
282  SCOPIRA_EXPORT ~rwlock();
283 
285  SCOPIRA_EXPORT void write_lock(void);
287  SCOPIRA_EXPORT bool try_write_lock(void);
289  SCOPIRA_EXPORT void read_lock(void);
291  SCOPIRA_EXPORT bool try_read_lock(void);
293  SCOPIRA_EXPORT void unlock(void);
294 };
295 
302 {
303  private:
304  scopira::tool::rwlock &dm_rw;
305  public:
307  read_locker(rwlock &rw) : dm_rw(rw) { dm_rw.read_lock(); }
309  ~read_locker() { dm_rw.unlock(); }
310 };
311 
318 {
319  private:
320  scopira::tool::rwlock &dm_rw;
321 
322  public:
324  write_locker(rwlock &rw) : dm_rw(rw) { dm_rw.write_lock(); }
326  ~write_locker() { dm_rw.unlock(); }
327 };
328 
336 template <class T> class scopira::tool::shared_area
337 {
338  public:
339  volatile T pm_data;
341 };
342 
349 template <class T> class scopira::tool::event_area : public scopira::tool::shared_area<T>
350 {
351  public:
352  mutable scopira::tool::condition pm_condition;
353 };
354 
361 template <class T> class scopira::tool::rw_area
362 {
363  public:
364  volatile T pm_data;
366 };
367 
381 template <class T> class scopira::tool::area_ptr
382 {
383  protected:
384  T* dm_ptr;
385 
386  public:
391  area_ptr(const shared_area<T>& ref) : dm_ptr(const_cast<T*>(&ref.pm_data)) { }
396  area_ptr(const rw_area<T>& ref) : dm_ptr(const_cast<T*>(&ref.pm_data)) { }
397 
398  protected:
403  area_ptr(const volatile T& ref) : dm_ptr(const_cast<T*>(&ref)) { }
404 
405  public:
407  T* get(void) { return dm_ptr; }
409  T& operator*(void) { return *dm_ptr; }
411  T* operator->(void) { return dm_ptr; }
412 
419  void reset(void) { dm_ptr = const_cast<T*>(const_cast<volatile T*>(dm_ptr)); } // this is whacky :)
420 };
421 
434 template <class T> class scopira::tool::const_area_ptr
435 {
436  protected:
437  const T* dm_ptr;
438 
439  public:
444  const_area_ptr(const shared_area<T>& ref) : dm_ptr(const_cast<const T*>(&ref.pm_data)) { }
449  const_area_ptr(const rw_area<T>& ref) : dm_ptr(const_cast<const T*>(&ref.pm_data)) { }
450 
451  protected:
456  const_area_ptr(const volatile T& ref) : dm_ptr(const_cast<T*>(&ref)) { }
457 
458  public:
460  const T* get(void) { return dm_ptr; }
462  const T& operator*(void) { return *dm_ptr; }
464  const T* operator->(void) { return dm_ptr; }
465 
472  void reset(void) { dm_ptr = const_cast<const T*>(const_cast<volatile T*>(dm_ptr)); } // this is whacky :)
473 };
474 
482 template <class T> class scopira::tool::locker_ptr : public scopira::tool::area_ptr<T>
483 {
484  protected:
485  scopira::tool::mutex & dm_mut;
486 
487  public:
489  locker_ptr(const shared_area<T>& ref) : area_ptr<T>(ref.pm_data), dm_mut(ref.pm_mutex) { dm_mut.lock(); }
490 
492  ~locker_ptr() { dm_mut.unlock(); }
493  private:
494 };
495 
501 template <class T> class scopira::tool::event_ptr : public scopira::tool::locker_ptr<T>
502 {
503  protected:
504  scopira::tool::condition & dm_cond;
505 
506  public:
508  event_ptr(const event_area<T>& ref) : locker_ptr<T>(ref), dm_cond(ref.pm_condition) { }
509 
517  void notify(void) { dm_cond.notify(); }
525  void notify_all(void) { dm_cond.notify_all(); }
534  void wait(void) { dm_cond.wait(locker_ptr<T>::dm_mut); }
544  bool wait(int msec) { return dm_cond.wait(locker_ptr<T>::dm_mut, msec); }
545 };
546 
552 template <class T> class scopira::tool::read_locker_ptr : public scopira::tool::const_area_ptr<T>
553 {
554  protected:
555  scopira::tool::rwlock & dm_rw;
556 
557  public:
559  read_locker_ptr(const rw_area<T>& ref) : const_area_ptr<T>(ref.pm_data), dm_rw(ref.pm_rwlock) { dm_rw.read_lock(); }
560 
562  ~read_locker_ptr() { dm_rw.unlock(); }
563 };
564 
570 template <class T> class scopira::tool::write_locker_ptr : public scopira::tool::area_ptr<T>
571 {
572  protected:
573  scopira::tool::rwlock & dm_rw;
574 
575  public:
577  write_locker_ptr(const rw_area<T>& ref) : area_ptr<T>(ref.pm_data), dm_rw(ref.pm_rwlock) { dm_rw.write_lock(); }
578 
580  ~write_locker_ptr() { dm_rw.unlock(); }
581 };
582 
583 #endif
584 
585 
virtual bool is_running(void) const
is this thread currently running?
Definition: thread_pthreads.h:162
Definition: thread_pthreads.h:220
Definition: thread_pthreads.h:56
event_ptr(const event_area< T > &ref)
ctor
Definition: thread_pthreads.h:508
const_area_ptr(const volatile T &ref)
Definition: thread_pthreads.h:456
Definition: mutex_pthreads.h:40
area_ptr(const shared_area< T > &ref)
Definition: thread_pthreads.h:391
Definition: thread_pthreads.h:57
write_locker_ptr(const rw_area< T > &ref)
ctor
Definition: thread_pthreads.h:577
Definition: archiveflow.h:20
write_locker(rwlock &rw)
read locks the given rwlock
Definition: thread_pthreads.h:324
void unlock(void)
unlocks the rwlock (unclocks both WRITE and READ locks)
Definition: thread_pthreads.h:60
T * operator->(void)
pointer behaviour
Definition: thread_pthreads.h:411
~read_locker()
unlocks the given rwlock
Definition: thread_pthreads.h:309
~write_locker()
unlocks the given rwlock
Definition: thread_pthreads.h:326
const_area_ptr(const shared_area< T > &ref)
Definition: thread_pthreads.h:444
~read_locker_ptr()
dtor
Definition: thread_pthreads.h:562
Definition: object.h:71
Definition: thread_pthreads.h:317
virtual void run(void)=0
void notify(void)
Definition: thread_pthreads.h:517
int num_system_cpus(void)
read_locker(rwlock &rw)
read locks the given rwlock
Definition: thread_pthreads.h:307
scopira::tool::mutex pm_mutex
shared data
Definition: thread_pthreads.h:340
Definition: thread_pthreads.h:69
scopira::tool::rwlock pm_rwlock
shared data
Definition: thread_pthreads.h:365
void lock(void)
Definition: mutex_pthreads.h:55
void wait(mutex &mut)
area_ptr(const rw_area< T > &ref)
Definition: thread_pthreads.h:396
Definition: thread_pthreads.h:87
const_area_ptr(const rw_area< T > &ref)
Definition: thread_pthreads.h:449
void read_lock(void)
locks the rwlock in READ mode
Definition: thread_pthreads.h:108
Definition: thread_pthreads.h:58
const T & operator*(void)
pointer behaviour
Definition: thread_pthreads.h:462
~locker_ptr()
dtor
Definition: thread_pthreads.h:492
void unlock(void)
Definition: mutex_pthreads.h:63
void reset(void)
Definition: thread_pthreads.h:472
void write_lock(void)
locks the rwlock in WRITE mode
read_locker_ptr(const rw_area< T > &ref)
ctor
Definition: thread_pthreads.h:559
T & operator*(void)
pointer behaviour
Definition: thread_pthreads.h:409
Definition: thread_pthreads.h:51
Definition: thread_pthreads.h:53
void notify_all(void)
Definition: thread_pthreads.h:525
~write_locker_ptr()
dtor
Definition: thread_pthreads.h:580
void *(* runfunc_t)(void *)
Definition: thread_pthreads.h:34
Definition: thread_pthreads.h:273
locker_ptr(const shared_area< T > &ref)
ctor
Definition: thread_pthreads.h:489
area_ptr(const volatile T &ref)
Definition: thread_pthreads.h:403
Definition: thread_pthreads.h:52
bool wait(int msec)
Definition: thread_pthreads.h:544
Definition: thread_pthreads.h:55
void reset(void)
Definition: thread_pthreads.h:419
Definition: thread_pthreads.h:59
const T * operator->(void)
pointer behaviour
Definition: thread_pthreads.h:464
Definition: thread_pthreads.h:301
void wait(void)
Definition: thread_pthreads.h:534