UCommon
thread.h
Go to the documentation of this file.
1// Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2// Copyright (C) 2015-2020 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
66namespace ucommon {
67
83class __EXPORT RWLock : private ConditionalAccess, public __PROTOCOL ExclusiveProtocol, public __PROTOCOL SharedProtocol
84{
85private:
86 __DELETE_COPY(RWLock);
87
88protected:
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
100public:
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
278class __EXPORT TimedEvent : public Timer
279{
280private:
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
291protected:
296 void lock(void);
297
302 void release(void);
303
311 bool sync(void);
312
313public:
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
369class __EXPORT RecursiveMutex : private Conditional, public __PROTOCOL ExclusiveProtocol
370{
371private:
372 __DELETE_COPY(RecursiveMutex);
373
374protected:
375 unsigned waiting;
376 unsigned lockers;
377 pthread_t locker;
378
379 virtual void _lock(void) __OVERRIDE;
380 virtual void _unlock(void) __OVERRIDE;
381
382public:
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
416class __EXPORT ReusableAllocator : protected Conditional
417{
418private:
419 __DELETE_COPY(ReusableAllocator);
420
421protected:
422 ReusableObject *freelist;
423 unsigned waiting;
424
428 ReusableAllocator();
429
435 inline ReusableObject *next(ReusableObject *object) {
436 return object->getNext();
437 }
438
443 void release(ReusableObject *object);
444};
445
459class __EXPORT Mutex : public __PROTOCOL ExclusiveProtocol
460{
461private:
462 __DELETE_COPY(Mutex);
463
464protected:
465 mutable pthread_mutex_t mlock;
466
467 virtual void _lock(void) __OVERRIDE;
468 virtual void _unlock(void) __OVERRIDE;
469
470public:
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
556class __EXPORT AutoProtect
557{
558private:
559
560 __DELETE_COPY(AutoProtect);
561
562protected:
563 const void *object;
564
569 AutoProtect();
570
576 void set(const void *object);
577
581 void release(void);
582
583public:
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
604template<typename T>
605class autoprotect : public AutoProtect
606{
607public:
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() {
617 AutoProtect::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
645class __EXPORT Thread
646{
647private:
648 __DELETE_COPY(Thread);
649
650protected:
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
681public:
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
823class __EXPORT JoinableThread : public Thread
824{
825private:
826 __DELETE_COPY(JoinableThread);
827
828protected:
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
859public:
860
869 void start(int priority = 0);
870
875 inline void background(void) {
876 start(-1);
877 }
878};
879
887class __EXPORT DetachedThread : public Thread
888{
889private:
890 __DELETE_COPY(DetachedThread);
891
892protected:
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
922public:
929 void start(int priority = 0);
930};
931
935typedef TimedEvent timedevent_t;
936
940typedef Mutex mutex_t;
941
945typedef RWLock rwlock_t;
946
950typedef RecursiveMutex rexlock_t;
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.
Realtime timers and timer queues.
T * init(T *memory)
Template function to initialize memory by invoking default constructor.
Definition platform.h:566
Runtime functions.
Condition classes for thread sychronization and timing.
Locking protocol classes for member function automatic operations.
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
class __attribute__((visibility("default"))) JoinableThread class __attribute__((visibility("default"))) DetachedThread typedef TimedEvent timedevent_t
A child thread object that may be joined by parent.
Definition thread.h:887
RecursiveMutex rexlock_t
Convenience type for using recursive exclusive locks.
Definition thread.h:950