UCommon
condition.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
34#ifndef _UCOMMON_CONDITION_H_
35#define _UCOMMON_CONDITION_H_
36
37#ifndef _UCOMMON_CPR_H_
38#include <ucommon/cpr.h>
39#endif
40
41#ifndef _UCOMMON_ACCESS_H_
42#include <ucommon/access.h>
43#endif
44
45#ifndef _UCOMMON_TIMERS_H_
46#include <ucommon/timers.h>
47#endif
48
49#ifndef _UCOMMON_MEMORY_H_
50#include <ucommon/memory.h>
51#endif
52
53namespace ucommon {
54
61class __EXPORT ConditionMutex
62{
63private:
64 friend class ConditionVar;
65 friend class autolock;
66
67 __DELETE_COPY(ConditionMutex);
68
69protected:
70#if defined(_MSTHREADS_)
71 mutable CRITICAL_SECTION mutex;
72#else
73 mutable pthread_mutex_t mutex;
74#endif
75
76public:
81
86
87#ifdef _MSTHREADS_
88 inline void lock(void) {
89 EnterCriticalSection(&mutex);
90 }
91
92 inline void unlock(void) {
93 LeaveCriticalSection(&mutex);
94 }
95
96#else
100 inline void lock(void) {
101 pthread_mutex_lock(&mutex);
102 }
103
107 inline void unlock(void) {
108 pthread_mutex_unlock(&mutex);
109 }
110#endif
111
112 class __EXPORT autolock
113 {
114 private:
115#ifdef _MSTHREADS_
116 CRITICAL_SECTION *mutex;
117#else
118 pthread_mutex_t *mutex;
119#endif
120 __DELETE_COPY(autolock);
121
122 public:
123 inline autolock(const ConditionMutex* object) {
124 mutex = &object->mutex;
125#ifdef _MSTHREADS_
126 EnterCriticalSection(mutex);
127#else
128 pthread_mutex_lock(mutex);
129#endif
130 }
131
132 inline ~autolock() {
133#ifdef _MSTHREADS_
134 LeaveCriticalSection(mutex);
135#else
136 pthread_mutex_unlock(mutex);
137#endif
138 }
139 };
140};
141
148class __EXPORT ConditionVar
149{
150private:
151 __DELETE_DEFAULTS(ConditionVar);
152
153protected:
154 friend class ConditionList;
155
156#if defined(_MSTHREADS_)
157 mutable CONDITION_VARIABLE cond;
158#else
159 mutable pthread_cond_t cond;
160#endif
161 ConditionMutex *shared;
162
163public:
168
173
179 bool wait(timeout_t timeout);
180
186 bool wait(struct timespec *timeout);
187
188#ifdef _MSTHREADS_
189 void wait(void);
190 void signal(void);
191 void broadcast(void);
192
193#else
197 inline void wait(void) {
198 pthread_cond_wait(&cond, &shared->mutex);
199 }
200
204 inline void signal(void) {
205 pthread_cond_signal(&cond);
206 }
207
211 inline void broadcast(void) {
212 pthread_cond_broadcast(&cond);
213 }
214#endif
215};
216
227class __EXPORT Conditional : protected ConditionMutex
228{
229private:
230 __DELETE_COPY(Conditional);
231
232protected:
233 friend class ConditionalAccess;
234 friend class ConditionVar;
235
236#if defined(_MSTHREADS_)
237 mutable CONDITION_VARIABLE cond;
238#else
239#ifndef __PTH__
240 class __LOCAL attribute
241 {
242 public:
243 pthread_condattr_t attr;
244 attribute();
245 };
246
247 __LOCAL static attribute attr;
248#endif
249
250 mutable pthread_cond_t cond;
251#endif
252
253 friend class TimedEvent;
254
260 bool wait(timeout_t timeout);
261
267 bool wait(struct timespec *timeout);
268
269#ifdef _MSTHREADS_
270 void wait(void);
271 void signal(void);
272 void broadcast(void);
273
274#else
278 inline void wait(void) {
279 pthread_cond_wait(&cond, &mutex);
280 }
281
285 inline void signal(void) {
286 pthread_cond_signal(&cond);
287 }
288
292 inline void broadcast(void) {
293 pthread_cond_broadcast(&cond);
294 }
295#endif
296
301
306
307 friend class autolock;
308
309public:
310#if !defined(_MSTHREADS_) && !defined(__PTH__)
316 static inline pthread_condattr_t *initializer(void) {
317 return &attr.attr;
318 }
319#endif
320
327 static void set(struct timespec *hires, timeout_t timeout);
328};
329
337class __EXPORT ConditionalAccess : private Conditional
338{
339private:
340 __DELETE_COPY(ConditionalAccess);
341
342protected:
343#if defined _MSTHREADS_
344 CONDITION_VARIABLE bcast;
345#else
346 mutable pthread_cond_t bcast;
347#endif
348
349 static unsigned max_sharing;
350
351 unsigned pending, waiting, sharing;
352
358 bool waitSignal(timeout_t timeout);
359
365 bool waitBroadcast(timeout_t timeout);
366
367
373 bool waitSignal(struct timespec *timeout);
374
380 bool waitBroadcast(struct timespec *timeout);
381
388 inline static void set(struct timespec *hires, timeout_t timeout) {
389 Conditional::set(hires, timeout);
390 }
391
392
393#ifdef _MSTHREADS_
394 inline void lock(void) {
395 EnterCriticalSection(&mutex);
396 }
397
398 inline void unlock(void) {
399 LeaveCriticalSection(&mutex);
400 }
401
402 void waitSignal(void);
403
404 void waitBroadcast(void);
405
406 inline void signal(void) {
407 Conditional::signal();
408 }
409
410 inline void broadcast(void) {
411 Conditional::broadcast();
412 }
413
414#else
418 inline void lock(void) {
419 pthread_mutex_lock(&mutex);
420 }
421
425 inline void unlock(void) {
426 pthread_mutex_unlock(&mutex);
427 }
428
432 inline void waitSignal(void) {
433 pthread_cond_wait(&cond, &mutex);
434 }
435
439 inline void waitBroadcast(void) {
440 pthread_cond_wait(&bcast, &mutex);
441 }
442
443
447 inline void signal(void) {
448 pthread_cond_signal(&cond);
449 }
450
454 inline void broadcast(void) {
455 pthread_cond_broadcast(&bcast);
456 }
457#endif
458public:
463
468
472 void access(void);
473
477 void modify(void);
478
482 void release(void);
483
487 void commit(void);
488
495 void limit_sharing(unsigned max);
496};
497
508class __EXPORT ConditionalLock : protected ConditionalAccess, public __PROTOCOL SharedProtocol
509{
510private:
511 __DELETE_COPY(ConditionalLock);
512
513protected:
514 class Context : public LinkedObject
515 {
516 private:
517 __DELETE_COPY(Context);
518
519 public:
520 inline Context(LinkedObject **root) : LinkedObject(root) {}
521
522 pthread_t thread;
523 unsigned count;
524 };
525
526 LinkedObject *contexts;
527
528 virtual void _share(void) __OVERRIDE;
529 virtual void _unshare(void) __OVERRIDE;
530
531 Context *getContext(void);
532
533public:
538
543
547 void modify(void);
548
552 void commit(void);
553
557 void access(void);
558
562 void release(void);
563
568 virtual void exclusive(void);
569
573 virtual void share(void);
574};
575
588class __EXPORT Barrier : private Conditional
589{
590private:
591 unsigned count;
592 unsigned waits;
593
594 __DELETE_DEFAULTS(Barrier);
595
596public:
601 Barrier(unsigned count);
602
607
613 void set(unsigned count);
614
618 void inc(void);
619
623 void dec(void);
624
629 unsigned operator++(void);
630
631 unsigned operator--(void);
632
636 void wait(void);
637
644 bool wait(timeout_t timeout);
645};
646
655class __EXPORT Semaphore : public __PROTOCOL SharedProtocol, protected Conditional
656{
657protected:
658 unsigned count, waits, used;
659
660 virtual void _share(void) __OVERRIDE;
661 virtual void _unshare(void) __OVERRIDE;
662
663 __DELETE_COPY(Semaphore);
664
665public:
666 typedef autoshared<Semaphore> autosync;
667
672 Semaphore(unsigned count = 0);
673
679 Semaphore(unsigned count, unsigned avail);
680
685 void wait(void);
686
694 bool wait(timeout_t timeout);
695
700 void set(unsigned count);
701
705 void release(void);
706
710 inline void operator++(void) {
711 wait();
712 }
713
717 inline void operator--(void) {
718 release();
719 }
720};
721
726
731
736
741
742} // namespace ucommon
743
744#endif
Private heaps, pools, and associations.
Runtime functions.
Locking protocol classes for member function automatic operations.
Realtime timers and timer queues.
Common namespace for all ucommon objects.
Definition access.h:47
ConditionalAccess accesslock_t
Convenience type for scheduling access.
Definition condition.h:730
Semaphore semaphore_t
Convenience type for using counting semaphores.
Definition condition.h:735
ConditionalLock condlock_t
Convenience type for using conditional locks.
Definition condition.h:725
Barrier barrier_t
Convenience type for using thread barriers.
Definition condition.h:740
An exclusive locking access interface base.
Definition access.h:123
Condition Mutex to pair with conditionals.
Definition condition.h:62
void unlock(void)
Unlock the conditional's supporting mutex.
Definition condition.h:107
void lock(void)
Lock the conditional's supporting mutex.
Definition condition.h:100
ConditionMutex()
Initialize and construct conditional.
~ConditionMutex()
Destroy conditional, release any blocked threads.
The condition Var allows multiple conditions to share a mutex.
Definition condition.h:149
bool wait(struct timespec *timeout)
Conditional wait for signal on timespec timeout.
ConditionVar(ConditionMutex *mutex)
Initialize and construct conditional.
void broadcast(void)
Signal the conditional to release all waiting threads.
Definition condition.h:211
void wait(void)
Wait (block) until signalled.
Definition condition.h:197
bool wait(timeout_t timeout)
Conditional wait for signal on millisecond timeout.
void signal(void)
Signal the conditional to release one waiting thread.
Definition condition.h:204
~ConditionVar()
Destroy conditional, release any blocked threads.
The conditional is a common base for other thread synchronizing classes.
Definition condition.h:228
static pthread_condattr_t * initializer(void)
Support function for getting conditional attributes for realtime scheduling.
Definition condition.h:316
void wait(void)
Wait (block) until signalled.
Definition condition.h:278
Conditional()
Initialize and construct conditional.
bool wait(struct timespec *timeout)
Conditional wait for signal on timespec timeout.
bool wait(timeout_t timeout)
Conditional wait for signal on millisecond timeout.
void broadcast(void)
Signal the conditional to release all waiting threads.
Definition condition.h:292
~Conditional()
Destroy conditional, release any blocked threads.
static void set(struct timespec *hires, timeout_t timeout)
Convert a millisecond timeout into use for high resolution conditional timers.
void signal(void)
Signal the conditional to release one waiting thread.
Definition condition.h:285
The conditional rw seperates scheduling for optizming behavior or rw locks.
Definition condition.h:338
void access(void)
Access mode shared thread scheduling.
static void set(struct timespec *hires, timeout_t timeout)
Convert a millisecond timeout into use for high resolution conditional timers.
Definition condition.h:388
void broadcast(void)
Signal the conditional to release all broadcast threads.
Definition condition.h:454
void release(void)
Release access mode read scheduling.
bool waitSignal(struct timespec *timeout)
Conditional wait for signal on timespec timeout.
void unlock(void)
Unlock the conditional's supporting mutex.
Definition condition.h:425
bool waitSignal(timeout_t timeout)
Conditional wait for signal on millisecond timeout.
void modify(void)
Exclusive mode write thread scheduling.
void commit(void)
Complete exclusive mode write scheduling.
void waitBroadcast(void)
Wait (block) until broadcast.
Definition condition.h:439
void limit_sharing(unsigned max)
Specify a maximum sharing (access) limit.
~ConditionalAccess()
Destroy conditional, release any blocked threads.
ConditionalAccess()
Initialize and construct conditional.
void lock(void)
Lock the conditional's supporting mutex.
Definition condition.h:418
bool waitBroadcast(struct timespec *timeout)
Conditional wait for broadcast on timespec timeout.
void waitSignal(void)
Wait (block) until signalled.
Definition condition.h:432
void signal(void)
Signal the conditional to release one signalled thread.
Definition condition.h:447
bool waitBroadcast(timeout_t timeout)
Conditional wait for broadcast on millisecond timeout.
An optimized and convertable shared lock.
Definition condition.h:509
~ConditionalLock()
Destroy conditional lock.
void modify(void)
Acquire write (exclusive modify) lock.
virtual void exclusive(void)
Convert read lock into exclusive (write/modify) access.
void access(void)
Acquire access (shared read) lock.
void commit(void)
Commit changes / release a modify lock.
virtual void _share(void)
Access interface to share lock the object.
ConditionalLock()
Construct conditional lock for default concurrency.
virtual void share(void)
Return an exclusive access lock back to share mode.
void release(void)
Release a shared lock.
A portable implementation of "barrier" thread sychronization.
Definition condition.h:589
void inc(void)
Dynamically increment the number of threads required.
~Barrier()
Destroy barrier and release pending threads.
unsigned operator++(void)
Alternative prefix form of the same increment operation.
void wait(void)
Wait at the barrier until the count of threads waiting is reached.
bool wait(timeout_t timeout)
Wait at the barrier until either the count of threads waiting is reached or a timeout has occurred.
Barrier(unsigned count)
Construct a barrier with an initial size.
void set(unsigned count)
Dynamically alter the number of threads required.
void dec(void)
Reduce the number of threads required.
A portable counting semaphore class.
Definition condition.h:656
bool wait(timeout_t timeout)
Wait until the semphore usage count is less than the thread limit.
void operator--(void)
Convenience operator to release a counting semaphore.
Definition condition.h:717
void operator++(void)
Convenience operator to wait on a counting semaphore.
Definition condition.h:710
virtual void _share(void)
Access interface to share lock the object.
Semaphore(unsigned count, unsigned avail)
Alternate onstructor with ability to preset available slots.
void release(void)
Release the semaphore after waiting for it.
Semaphore(unsigned count=0)
Construct a semaphore with an initial count of threads to permit.
void wait(void)
Wait until the semphore usage count is less than the thread limit.
void set(unsigned count)
Alter semaphore limit at runtime.
Common base class for all objects that can be formed into a linked list.
Definition linked.h:56
Event notification to manage scheduled realtime threads.
Definition thread.h:279