UCommon
thread.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
43 #ifndef _UCOMMON_THREAD_H_
44 #define _UCOMMON_THREAD_H_
45 
46 #ifndef _UCOMMON_CPR_H_
47 #include <ucommon/cpr.h>
48 #endif
49 
50 #ifndef _UCOMMON_ACCESS_H_
51 #include <ucommon/access.h>
52 #endif
53 
54 #ifndef _UCOMMON_TIMERS_H_
55 #include <ucommon/timers.h>
56 #endif
57 
58 #ifndef _UCOMMON_MEMORY_H_
59 #include <ucommon/memory.h>
60 #endif
61 
62 #ifndef _UCOMMON_CONDITION_H_
63 #include <ucommon/condition.h>
64 #endif
65 
66 namespace ucommon {
67 
83 class __EXPORT RWLock : private ConditionalAccess, public __PROTOCOL ExclusiveProtocol, public __PROTOCOL SharedProtocol
84 {
85 private:
86  __DELETE_COPY(RWLock);
87 
88 protected:
89  unsigned writers;
90  pthread_t writeid;
91 
92  virtual void _share(void) __OVERRIDE;
93 
94  virtual void _lock(void) __OVERRIDE;
95 
96  virtual void _unlock(void) __OVERRIDE;
97 
98  virtual void _unshare(void) __OVERRIDE;
99 
100 public:
101  typedef autoshared<RWLock> autoreader;
102 
103  typedef autoexclusive<RWLock> autowriter;
104 
112  class __EXPORT reader
113  {
114  private:
115  const void *object;
116 
117  __DELETE_COPY(reader);
118 
119  public:
124  reader();
125 
130  reader(const void *object);
131 
135  ~reader();
136 
142  void set(const void *object);
143 
147  void release(void);
148 
154  inline void operator=(const void *pointer) {
155  set(pointer);
156  }
157 
165  static bool lock(const void *object, timeout_t timeout = Timer::inf);
166  };
167 
175  class __EXPORT writer
176  {
177  private:
178  const void *object;
179 
180  __DELETE_COPY(writer);
181 
182  public:
187  writer();
188 
193  writer(const void *object);
194 
198  ~writer();
199 
205  void set(const void *object);
206 
210  void release(void);
211 
217  inline void operator=(const void *pointer) {
218  set(pointer);
219  }
220 
228  static bool lock(const void *object, timeout_t timeout = Timer::inf);
229  };
230 
234  RWLock();
235 
241  bool modify(timeout_t timeout = Timer::inf);
242 
248  bool access(timeout_t timeout = Timer::inf);
249 
256  static void indexing(unsigned size);
257 
262  static bool release(const void *object);
263 
267  void release(void);
268 };
269 
278 class __EXPORT TimedEvent : public Timer
279 {
280 private:
281 #ifdef _MSTHREADS_
282  HANDLE event;
283 #else
284  mutable pthread_cond_t cond;
285  bool signalled;
286 #endif
287  mutable pthread_mutex_t mutex;
288 
289  __DELETE_COPY(TimedEvent);
290 
291 protected:
296  void lock(void);
297 
302  void release(void);
303 
311  bool sync(void);
312 
313 public:
317  TimedEvent(void);
318 
323  TimedEvent(timeout_t timeout);
324 
329  TimedEvent(time_t timeout);
330 
334  ~TimedEvent();
335 
341  void signal(void);
342 
349  bool wait(timeout_t timeout);
350 
354  void wait(void);
355 
359  void reset(void);
360 };
361 
369 class __EXPORT RecursiveMutex : private Conditional, public __PROTOCOL ExclusiveProtocol
370 {
371 private:
372  __DELETE_COPY(RecursiveMutex);
373 
374 protected:
375  unsigned waiting;
376  unsigned lockers;
377  pthread_t locker;
378 
379  virtual void _lock(void) __OVERRIDE;
380  virtual void _unlock(void) __OVERRIDE;
381 
382 public:
383  typedef autoexclusive<RecursiveMutex> autolock;
384 
388  RecursiveMutex();
389 
393  void lock(void);
394 
398  bool lock(timeout_t timeout);
399 
403  void release(void);
404 };
405 
416 class __EXPORT ReusableAllocator : protected Conditional
417 {
418 private:
419  __DELETE_COPY(ReusableAllocator);
420 
421 protected:
422  ReusableObject *freelist;
423  unsigned waiting;
424 
429 
435  inline ReusableObject *next(ReusableObject *object) {
436  return object->getNext();
437  }
438 
443  void release(ReusableObject *object);
444 };
445 
459 class __EXPORT Mutex : public __PROTOCOL ExclusiveProtocol
460 {
461 private:
462  __DELETE_COPY(Mutex);
463 
464 protected:
465  mutable pthread_mutex_t mlock;
466 
467  virtual void _lock(void) __OVERRIDE;
468  virtual void _unlock(void) __OVERRIDE;
469 
470 public:
471  typedef autoexclusive<Mutex> autolock;
472 
476  Mutex();
477 
481  ~Mutex();
482 
486  inline void acquire(void) {
487  pthread_mutex_lock(&mlock);
488  }
489 
493  inline void lock(void) {
494  pthread_mutex_lock(&mlock);
495  }
496 
500  inline void unlock(void) {
501  pthread_mutex_unlock(&mlock);
502  }
503 
507  inline void release(void) {
508  pthread_mutex_unlock(&mlock);
509  }
510 
515  inline static void acquire(pthread_mutex_t *lock) {
516  pthread_mutex_lock(lock);
517  }
518 
523  inline static void release(pthread_mutex_t *lock) {
524  pthread_mutex_unlock(lock);
525  }
526 
533  static void indexing(unsigned size);
534 
540  static bool protect(const void *pointer);
541 
546  static bool release(const void *pointer);
547 };
548 
556 class __EXPORT AutoProtect
557 {
558 private:
559 
560  __DELETE_COPY(AutoProtect);
561 
562 protected:
563  const void *object;
564 
569  AutoProtect();
570 
576  void set(const void *object);
577 
581  void release(void);
582 
583 public:
588  AutoProtect(const void *object);
589 
593  ~AutoProtect();
594 
595  inline operator bool() const {
596  return object != NULL;
597  }
598 
599  inline bool operator!() const {
600  return object == NULL;
601  }
602 };
603 
604 template<typename T>
605 class autoprotect : public AutoProtect
606 {
607 public:
608  inline autoprotect() : AutoProtect() {};
609 
610  inline autoprotect(const T *object) : AutoProtect(object) {};
611 
612  inline void set(const T *object) {
613  AutoProtect::set(object);
614  }
615 
616  inline void release() {
618  }
619 
620  inline autoprotect& operator=(const T* object) {
621  AutoProtect::set(object);
622  return *this;
623  }
624 
625  inline T* operator->() const {
626  return static_cast<T*>(object);
627  }
628 
629  inline T& operator*() const {
630  __THROW_DEREF(object);
631  return *(static_cast<T*>(object));
632  }
633 };
634 
645 class __EXPORT Thread
646 {
647 private:
648  __DELETE_COPY(Thread);
649 
650 protected:
651 // may be used in future if we need cancelable threads...
652 #ifdef _MSTHREADS_
653  HANDLE cancellor;
654 #else
655  void *cancellor;
656 #endif
657 
658  enum {R_UNUSED} reserved; // cancel mode?
659  pthread_t tid;
660  stacksize_t stack;
661  int priority;
662 
668  Thread(size_t stack = 0);
669 
674  void map(void);
675 
679  virtual bool is_active(void) const;
680 
681 public:
682  class __EXPORT Local : public LinkedObject
683  {
684  private:
685  friend class Thread;
686 
687  pthread_key_t key;
688  static LinkedObject *list;
689 
690  __DELETE_COPY(Local);
691 
692  protected:
693  Local();
694 
695  virtual void release(void *instance) = 0;
696 
697  virtual void *allocate();
698 
699  public:
700  ~Local();
701 
702  void *operator*();
703 
704  void set(void *instance);
705 
706  void *get(void);
707 
708  inline void clear() {
709  set(nullptr);
710  }
711  };
712 
719  void setPriority(void);
720 
725  static void yield(void);
726 
731  static void sleep(timeout_t timeout);
732 
739  static Thread *get(void);
740 
744  virtual void run(void) = 0;
745 
749  virtual ~Thread();
750 
759  virtual void exit(void);
760 
764  static void init(void);
765 
769  static size_t cache(void);
770 
776  static void policy(int polid);
777 
782  static void concurrency(int level);
783 
790  static bool equal(pthread_t thread1, pthread_t thread2);
791 
796  static pthread_t self(void);
797 
798  inline operator bool() const {
799  return is_active();
800  }
801 
802  inline bool operator!() const {
803  return !is_active();
804  }
805 
806  inline bool isRunning(void) const {
807  return is_active();
808  }
809 
810  static void release(void);
811 };
812 
823 class __EXPORT JoinableThread : public Thread
824 {
825 private:
826  __DELETE_COPY(JoinableThread);
827 
828 protected:
829 #ifdef _MSTHREADS_
830  HANDLE running;
831 #else
832  volatile bool running;
833 #endif
834  volatile bool joining;
835 
840  JoinableThread(size_t size = 0);
841 
846  virtual ~JoinableThread();
847 
853  void join(void);
854 
855  bool is_active(void) const __OVERRIDE;
856 
857  virtual void run(void) __OVERRIDE = 0;
858 
859 public:
860 
869  void start(int priority = 0);
870 
875  inline void background(void) {
876  start(-1);
877  }
878 };
879 
887 class __EXPORT DetachedThread : public Thread
888 {
889 private:
890  __DELETE_COPY(DetachedThread);
891 
892 protected:
893  bool active;
894 
899  DetachedThread(size_t size = 0);
900 
906  ~DetachedThread();
907 
916  void exit(void) __OVERRIDE;
917 
918  bool is_active(void) const __OVERRIDE;
919 
920  virtual void run(void) __OVERRIDE = 0;
921 
922 public:
929  void start(int priority = 0);
930 };
931 
936 
940 typedef Mutex mutex_t;
941 
945 typedef RWLock rwlock_t;
946 
951 
952 #define __AUTOLOCK(x) autolock __autolock__(x)
953 #define __AUTOPROTECT(x) AutoProtect __autolock__(x)
954 #define __SYNC(x) for(bool _sync_flag_ = Mutex::protect(x); _sync_flag_; _sync_flag_ = !Mutex::release(x))
955 
956 } // namespace ucommon
957 
958 #endif
RWLock rwlock_t
Convenience type for using read/write locks.
Definition: thread.h:945
The conditional is a common base for other thread synchronizing classes.
Definition: condition.h:227
Class for resource bound memory pools between threads.
Definition: thread.h:416
Apply automatic scope based exclusive locking to objects.
Definition: thread.h:175
void operator=(const void *pointer)
Set guard to read lock a new object.
Definition: thread.h:217
void unlock(void)
Release acquired lock.
Definition: thread.h:500
Timer class to use when scheduling realtime events.
Definition: timers.h:50
An exclusive locking protocol interface base.
Definition: access.h:55
Guard class to apply scope based mutex locking to objects.
Definition: thread.h:556
void lock(void)
Acquire mutex lock.
Definition: thread.h:493
T * init(T *memory)
Template function to initialize memory by invoking default constructor.
Definition: platform.h:551
A detached thread object that is stand-alone.
Definition: thread.h:887
RecursiveMutex rexlock_t
Convenience type for using recursive exclusive locks.
Definition: thread.h:950
Realtime timers and timer queues.
A generic and portable implementation of Read/Write locking.
Definition: thread.h:83
static void acquire(pthread_mutex_t *lock)
Convenience function to acquire os native mutex lock directly.
Definition: thread.h:515
void background(void)
Start execution of child context as background thread.
Definition: thread.h:875
void release(void)
Release acquired lock.
Definition: thread.h:507
void acquire(void)
Acquire mutex lock.
Definition: thread.h:486
Mutex mutex_t
Convenience type for using exclusive mutex locks.
Definition: thread.h:940
Private heaps, pools, and associations.
Reusable objects for forming private heaps.
Definition: linked.h:152
The conditional rw seperates scheduling for optizming behavior or rw locks.
Definition: condition.h:337
Portable recursive exclusive lock.
Definition: thread.h:369
ReusableObject * getNext(void)
Get next effective reusable object when iterating.
Definition: linked.h:164
Apply automatic scope based access locking to objects.
Definition: thread.h:112
void release(void)
Prematurely release a guard.
Common namespace for all ucommon objects.
Definition: access.h:47
An exclusive locking access interface base.
Definition: access.h:122
static void release(pthread_mutex_t *lock)
Convenience function to release os native mutex lock directly.
Definition: thread.h:523
An abstract class for defining classes that operate as a thread.
Definition: thread.h:645
Condition classes for thread sychronization and timing.
Generic non-recursive exclusive lock class.
Definition: thread.h:459
Locking protocol classes for member function automatic operations.
void operator=(const void *pointer)
Set guard to read lock a new object.
Definition: thread.h:154
A child thread object that may be joined by parent.
Definition: thread.h:823
TimedEvent timedevent_t
Convenience type for using timed events.
Definition: thread.h:935
Common base class for all objects that can be formed into a linked list.
Definition: linked.h:55
Event notification to manage scheduled realtime threads.
Definition: thread.h:278
Runtime functions.
Generic smart pointer class.
Definition: generics.h:54
ReusableObject * next(ReusableObject *object)
Get next reusable object in the pool.
Definition: thread.h:435
void set(const void *object)
Set guard to mutex lock a new object.