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:
125 
130  reader(const void *object);
131 
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:
188 
193  writer(const void *object);
194 
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 
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 
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 
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 
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 
570 
576  void set(const void *object);
577 
581  void release(void);
582 
583 public:
588  AutoProtect(const void *object);
589 
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 
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
Private heaps, pools, and associations.
Locking protocol classes for member function automatic operations.
Condition classes for thread sychronization and timing.
Runtime functions.
Realtime timers and timer queues.
Common namespace for all ucommon objects.
Definition: access.h:47
RWLock rwlock_t
Convenience type for using read/write locks.
Definition: thread.h:945
Mutex mutex_t
Convenience type for using exclusive mutex locks.
Definition: thread.h:940
TimedEvent timedevent_t
Convenience type for using timed events.
Definition: thread.h:935
RecursiveMutex rexlock_t
Convenience type for using recursive exclusive locks.
Definition: thread.h:950
An exclusive locking protocol interface base.
Definition: access.h:56
An exclusive locking access interface base.
Definition: access.h:123
The conditional is a common base for other thread synchronizing classes.
Definition: condition.h:228
The conditional rw seperates scheduling for optizming behavior or rw locks.
Definition: condition.h:338
Generic smart pointer class.
Definition: generics.h:55
Common base class for all objects that can be formed into a linked list.
Definition: linked.h:56
Reusable objects for forming private heaps.
Definition: linked.h:153
ReusableObject * getNext(void)
Get next effective reusable object when iterating.
Definition: linked.h:164
A generic and portable implementation of Read/Write locking.
Definition: thread.h:84
virtual void _share(void)
Access interface to share lock the object.
bool access(timeout_t timeout=Timer::inf)
Request shared (read) access through the lock.
RWLock()
Create an instance of a rwlock.
static bool release(const void *object)
Release an arbitrary object that has been protected by a rwlock.
void release(void)
Release the lock.
static void indexing(unsigned size)
Specify hash table size for guard protection.
bool modify(timeout_t timeout=Timer::inf)
Request modify (write) access through the lock.
Apply automatic scope based access locking to objects.
Definition: thread.h:113
~reader()
Release mutex when guard falls out of scope.
reader()
Create an unitialized instance of guard.
reader(const void *object)
Construct a guard for a specific object.
void release(void)
Prematurely release a guard.
void set(const void *object)
Set guard to mutex lock a new object.
static bool lock(const void *object, timeout_t timeout=Timer::inf)
Shared access to an arbitrary object.
void operator=(const void *pointer)
Set guard to read lock a new object.
Definition: thread.h:154
Apply automatic scope based exclusive locking to objects.
Definition: thread.h:176
~writer()
Release mutex when guard falls out of scope.
writer(const void *object)
Construct a guard for a specific object.
void operator=(const void *pointer)
Set guard to read lock a new object.
Definition: thread.h:217
void set(const void *object)
Set guard to mutex lock a new object.
static bool lock(const void *object, timeout_t timeout=Timer::inf)
Write protect access to an arbitrary object.
writer()
Create an unitialized instance of guard.
void release(void)
Prematurely release a guard.
Event notification to manage scheduled realtime threads.
Definition: thread.h:279
TimedEvent(time_t timeout)
Create event handler and timer set to trigger a timeout.
void reset(void)
Reset triggered conditional.
void wait(void)
A simple wait until triggered.
void lock(void)
Lock the object for wait or to manipulate derived data.
bool sync(void)
Wait while locked.
TimedEvent(void)
Create event handler and timer for timing of events.
void signal(void)
Signal pending event.
bool wait(timeout_t timeout)
Wait to be signalled or until timer expires.
~TimedEvent()
Destroy timer and release pending events.
TimedEvent(timeout_t timeout)
Create event handler and timer set to trigger a timeout.
void release(void)
Release the object lock after waiting.
Portable recursive exclusive lock.
Definition: thread.h:370
bool lock(timeout_t timeout)
Timed lock request.
void release(void)
Release or decrease locking.
RecursiveMutex()
Create rexlock.
void lock(void)
Acquire or increase locking.
Class for resource bound memory pools between threads.
Definition: thread.h:417
ReusableAllocator()
Initialize reusable allocator through a conditional.
ReusableObject * next(ReusableObject *object)
Get next reusable object in the pool.
Definition: thread.h:435
void release(ReusableObject *object)
Release resuable object.
Generic non-recursive exclusive lock class.
Definition: thread.h:460
static void release(pthread_mutex_t *lock)
Convenience function to release os native mutex lock directly.
Definition: thread.h:523
static void indexing(unsigned size)
Specify hash table size for guard protection.
Mutex()
Create a mutex lock.
static void acquire(pthread_mutex_t *lock)
Convenience function to acquire os native mutex lock directly.
Definition: thread.h:515
static bool release(const void *pointer)
Specify a pointer/object/resource to release.
void release(void)
Release acquired lock.
Definition: thread.h:507
void acquire(void)
Acquire mutex lock.
Definition: thread.h:486
static bool protect(const void *pointer)
Specify pointer/object/resource to guard protect.
void lock(void)
Acquire mutex lock.
Definition: thread.h:493
void unlock(void)
Release acquired lock.
Definition: thread.h:500
~Mutex()
Destroy mutex lock, release waiting threads.
Guard class to apply scope based mutex locking to objects.
Definition: thread.h:557
void release(void)
Prematurely release a guard.
void set(const void *object)
Set guard to mutex lock a new object.
~AutoProtect()
Release mutex when guard falls out of scope.
AutoProtect()
Create an unitialized instance of guard.
AutoProtect(const void *object)
Construct a guard for a specific object.
An abstract class for defining classes that operate as a thread.
Definition: thread.h:646
static size_t cache(void)
Get cache line size.
static bool equal(pthread_t thread1, pthread_t thread2)
Determine if two thread identifiers refer to the same thread.
static void policy(int polid)
Used to specify scheduling policy for threads above priority "0".
static void init(void)
Used to initialize threading library.
virtual ~Thread()
Destroy thread object, thread-specific data, and execution context.
virtual void exit(void)
Exit the thread context.
virtual void run(void)=0
Abstract interface for thread context run method.
Thread(size_t stack=0)
Create a thread object that will have a preset stack size.
void map(void)
Map thread for get method.
static void yield(void)
Yield execution context of the current thread.
virtual bool is_active(void) const
Check if running.
static Thread * get(void)
Get mapped thread object.
static void sleep(timeout_t timeout)
Sleep current thread for a specified time period.
static void concurrency(int level)
Set concurrency level of process.
void setPriority(void)
Set thread priority without disrupting scheduling if possible.
A child thread object that may be joined by parent.
Definition: thread.h:824
void join(void)
Join thread with parent.
JoinableThread(size_t size=0)
Create a joinable thread with a known context stack size.
bool is_active(void) const
Check if running.
void start(int priority=0)
Start execution of child context.
virtual ~JoinableThread()
Delete child thread.
virtual void run(void)=0
Abstract interface for thread context run method.
void background(void)
Start execution of child context as background thread.
Definition: thread.h:875
A detached thread object that is stand-alone.
Definition: thread.h:888
void exit(void)
Exit context of detached thread.
~DetachedThread()
Destroys object when thread context exits.
bool is_active(void) const
Check if running.
void start(int priority=0)
Start execution of detached context.
virtual void run(void)=0
Abstract interface for thread context run method.
DetachedThread(size_t size=0)
Create a detached thread with a known context stack size.
Timer class to use when scheduling realtime events.
Definition: timers.h:51