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 
85  ~ConditionMutex();
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
97 
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 
172  ~ConditionVar();
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
194 
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
275 
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 
300  Conditional();
301 
305  ~Conditional();
306 
307  friend class autolock;
308 
309 public:
310 #if !defined(_MSTHREADS_) && !defined(__PTH__)
311 
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
415 
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:
537  ConditionalLock();
538 
542  ~ConditionalLock();
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 
606  ~Barrier();
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
An optimized and convertable shared lock.
Definition: condition.h:508
The conditional is a common base for other thread synchronizing classes.
Definition: condition.h:227
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:445
void wait(void)
Wait (block) until signalled.
Definition: condition.h:278
Barrier barrier_t
Convenience type for using thread barriers.
Definition: condition.h:740
A portable implementation of "barrier" thread sychronization.
Definition: condition.h:588
void unlock(void)
Unlock the conditional's supporting mutex.
Definition: condition.h:425
static pthread_condattr_t * initializer(void)
Support function for getting conditional attributes for realtime scheduling.
Definition: condition.h:316
void waitBroadcast(void)
Wait (block) until broadcast.
Definition: condition.h:439
void waitSignal(void)
Wait (block) until signalled.
Definition: condition.h:432
void lock(void)
Lock the conditional's supporting mutex.
Definition: condition.h:100
Realtime timers and timer queues.
void unlock(void)
Unlock the conditional's supporting mutex.
Definition: condition.h:107
ConditionalAccess accesslock_t
Convenience type for scheduling access.
Definition: condition.h:730
void broadcast(void)
Signal the conditional to release all broadcast threads.
Definition: condition.h:454
Condition Mutex to pair with conditionals.
Definition: condition.h:61
Private heaps, pools, and associations.
void wait(void)
Wait (block) until signalled.
Definition: condition.h:197
static void set(struct timespec *hires, timeout_t timeout)
Convert a millisecond timeout into use for high resolution conditional timers.
Definition: condition.h:388
ConditionalLock condlock_t
Convenience type for using conditional locks.
Definition: condition.h:725
The conditional rw seperates scheduling for optizming behavior or rw locks.
Definition: condition.h:337
void broadcast(void)
Signal the conditional to release all waiting threads.
Definition: condition.h:292
The condition Var allows multiple conditions to share a mutex.
Definition: condition.h:148
void lock(void)
Lock the conditional's supporting mutex.
Definition: condition.h:418
Common namespace for all ucommon objects.
Definition: access.h:47
static void set(struct timespec *hires, timeout_t timeout)
Convert a millisecond timeout into use for high resolution conditional timers.
An exclusive locking access interface base.
Definition: access.h:122
void signal(void)
Signal the conditional to release one signalled thread.
Definition: condition.h:447
void signal(void)
Signal the conditional to release one waiting thread.
Definition: condition.h:204
void operator++(void)
Convenience operator to wait on a counting semaphore.
Definition: condition.h:710
Locking protocol classes for member function automatic operations.
void signal(void)
Signal the conditional to release one waiting thread.
Definition: condition.h:285
Semaphore semaphore_t
Convenience type for using counting semaphores.
Definition: condition.h:735
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.
void operator--(void)
Convenience operator to release a counting semaphore.
Definition: condition.h:717
void broadcast(void)
Signal the conditional to release all waiting threads.
Definition: condition.h:211
A portable counting semaphore class.
Definition: condition.h:655