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 
53 namespace ucommon {
54 
61 class __EXPORT ConditionMutex
62 {
63 private:
64  friend class ConditionVar;
65  friend class autolock;
66 
67  __DELETE_COPY(ConditionMutex);
68 
69 protected:
70 #if defined(_MSTHREADS_)
71  mutable CRITICAL_SECTION mutex;
72 #else
73  mutable pthread_mutex_t mutex;
74 #endif
75 
76 public:
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 
148 class __EXPORT ConditionVar
149 {
150 private:
151  __DELETE_DEFAULTS(ConditionVar);
152 
153 protected:
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 
163 public:
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 
227 class __EXPORT Conditional : protected ConditionMutex
228 {
229 private:
230  __DELETE_COPY(Conditional);
231 
232 protected:
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 
309 public:
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 
337 class __EXPORT ConditionalAccess : private Conditional
338 {
339 private:
340  __DELETE_COPY(ConditionalAccess);
341 
342 protected:
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) {
408  }
409 
410  inline void broadcast(void) {
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
458 public:
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 
508 class __EXPORT ConditionalLock : protected ConditionalAccess, public __PROTOCOL SharedProtocol
509 {
510 private:
511  __DELETE_COPY(ConditionalLock);
512 
513 protected:
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 
533 public:
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 
588 class __EXPORT Barrier : private Conditional
589 {
590 private:
591  unsigned count;
592  unsigned waits;
593 
594  __DELETE_DEFAULTS(Barrier);
595 
596 public:
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 
655 class __EXPORT Semaphore : public __PROTOCOL SharedProtocol, protected Conditional
656 {
657 protected:
658  unsigned count, waits, used;
659 
660  virtual void _share(void) __OVERRIDE;
661  virtual void _unshare(void) __OVERRIDE;
662 
663  __DELETE_COPY(Semaphore);
664 
665 public:
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.
Locking protocol classes for member function automatic operations.
Runtime functions.
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
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:445
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
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
static pthread_condattr_t * initializer(void)
Support function for getting conditional attributes for realtime scheduling.
Definition: condition.h:316
~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