PTLib  Version 2.18.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
syncthrd.h
Go to the documentation of this file.
1 /*
2  * syncthrd.h
3  *
4  * Various thread synchronisation classes.
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  */
29 
30 #ifndef PTLIB_SYNCTHRD_H
31 #define PTLIB_SYNCTHRD_H
32 
33 #ifdef P_USE_PRAGMA
34 #pragma interface
35 #endif
36 
37 #include <ptlib/mutex.h>
38 #include <ptlib/semaphor.h>
39 #include <ptlib/syncpoint.h>
40 #include <map>
41 #include <queue>
42 
43 
65 class PSyncPointAck : public PSyncPoint
66 {
67  PCLASSINFO(PSyncPointAck, PSyncPoint);
68 
69  public:
81  virtual void Signal();
82  void Signal(const PTimeInterval & waitTime);
83 
89  void Acknowledge();
90 
91  protected:
93 };
94 
95 
101 class PCondMutex : public PMutex
102 {
103  PCLASSINFO(PCondMutex, PMutex);
104 
105  public:
110  virtual void WaitCondition();
111 
116  virtual void Signal();
117 
121  virtual PBoolean Condition() = 0;
122 
127  virtual void OnWait();
128 
129  protected:
131 };
132 
133 
136 class PIntCondMutex : public PCondMutex
137 {
138  PCLASSINFO(PIntCondMutex, PCondMutex);
139 
140  public:
143  enum Operation {
146  LT,
148  LE,
150  EQ,
152  GE,
155  };
156 
161  int value = 0,
162  int target = 0,
164  );
166 
172  void PrintOn(ostream & strm) const;
174 
182  virtual PBoolean Condition();
183 
187  operator int() const { return value; }
188 
196  PIntCondMutex & operator=(int newval);
197 
206 
214  PIntCondMutex & operator+=(int inc);
215 
224 
232  PIntCondMutex & operator-=(int dec);
234 
235 
236  protected:
237  int value, target;
239 };
240 
241 
257 {
258  PCLASSINFO(PReadWriteMutex, PObject);
259  public:
262  explicit PReadWriteMutex();
263  explicit PReadWriteMutex(
264  const PDebugLocation & location,
265  unsigned timeout = 0
266  );
269 
276  __inline void StartRead() { InternalStartRead(NULL); }
277  __inline void StartRead(const PDebugLocation & location) { InternalStartRead(&location); }
278 
281  __inline void EndRead() { InternalEndRead(NULL); }
282  __inline void EndRead(const PDebugLocation & location) { InternalEndRead(&location); }
283 
299  __inline void StartWrite() { InternalStartWrite(NULL); }
300  __inline void StartWrite(const PDebugLocation & location) { InternalStartWrite(&location); }
301 
313  void EndWrite() { InternalEndWrite(NULL); }
314  void EndWrite(const PDebugLocation & location) { InternalEndWrite(&location); }
316 
317  virtual void PrintOn(ostream &strm) const;
318 
319  protected:
320  void InternalStartRead(const PDebugLocation * location);
321  void InternalEndRead(const PDebugLocation * location);
322  void InternalStartWrite(const PDebugLocation * location);
323  void InternalEndWrite(const PDebugLocation * location);
324 
325 #if P_READ_WRITE_ALGO2
326  PSemaphore m_inSemaphore;
327  unsigned m_inCount;
328  PSemaphore m_outSemaphore;
329  unsigned m_outCount;
330  PSemaphore m_writeSemaphore;
331  bool m_wait;
332 #else
335  unsigned m_readerCount;
337 
340  unsigned m_writerCount;
341 #endif
342  struct Nest
343  {
349 
350  Nest();
351  Nest(const Nest & other);
352  Nest & operator=(const Nest & other);
353  };
354  typedef std::map<PThreadIdentifier, Nest> NestMap;
357 
358  Nest * GetNest();
359  Nest & StartNest();
360  void EndNest();
361  void InternalStartReadWithNest(Nest & nest, const PDebugLocation & location);
362  void InternalEndReadWithNest(Nest & nest, const PDebugLocation & location);
363  void InternalStartWriteWithNest(Nest & nest, const PDebugLocation & location);
364  void InternalEndWriteWithNest(Nest & nest, const PDebugLocation & location);
365  void InternalWait(Nest & nest, PSync & sync, const PDebugLocation & location) const;
366 
367  private:
368  PReadWriteMutex(const PReadWriteMutex & other) : PObject(other), m_readerCount(), m_writerCount() { }
369  void operator=(const PReadWriteMutex &) { }
370 
371  friend class PSafeObject;
372  friend class PReadWaitAndSignal;
373  friend class PWriteWaitAndSignal;
376 };
377 
379 #define PDECLARE_READ_WRITE_MUTEX_ARG_1(var) struct PReadWriteMutex_##var : PReadWriteMutex { PReadWriteMutex_##var() : PReadWriteMutex(P_DEBUG_LOCATION) { } } var
380 #define PDECLARE_READ_WRITE_MUTEX_ARG_2(var,nam) struct PReadWriteMutex_##var : PReadWriteMutex { PReadWriteMutex_##var() : PReadWriteMutex(#nam, ) { } } var
381 #define PDECLARE_READ_WRITE_MUTEX_ARG_3(var,nam,to) struct PReadWriteMutex_##var : PReadWriteMutex { PReadWriteMutex_##var() : PReadWriteMutex(#nam,to ) { } } var
382 #define PDECLARE_READ_WRITE_MUTEX_ARG_4(var,nam,to,tw) struct PReadWriteMutex_##var : PReadWriteMutex { PReadWriteMutex_##var() : PReadWriteMutex(#nam,to,tw ) { } } var
383 #define PDECLARE_READ_WRITE_MUTEX_ARG_5(var,nam,to,tw,th) struct PReadWriteMutex_##var : PReadWriteMutex { PReadWriteMutex_##var() : PReadWriteMutex(#nam,to,tw,th ) { } } var
384 
385 #define PDECLARE_READ_WRITE_MUTEX_PART1(narg, args) PDECLARE_READ_WRITE_MUTEX_PART2(narg, args)
386 #define PDECLARE_READ_WRITE_MUTEX_PART2(narg, args) PDECLARE_READ_WRITE_MUTEX_ARG_##narg args
387 
388 #define PDECLARE_READ_WRITE_MUTEX(...) PDECLARE_READ_WRITE_MUTEX_PART1(PARG_COUNT(__VA_ARGS__), (__VA_ARGS__))
389 
391 {
392  protected:
393  typedef void (PReadWriteMutex:: * StartFn)(const PDebugLocation * location);
394  typedef void (PReadWriteMutex:: * EndFn)(const PDebugLocation * location);
395 
396  PReadWriteWaitAndSignalBase(const PReadWriteMutex & mutex, const PDebugLocation * location, StartFn start, EndFn end)
397  : m_mutex(const_cast<PReadWriteMutex &>(mutex))
398  , m_location(location)
399  , m_end(end)
400  {
401  if (start)
402  (m_mutex.*start)(&m_location);
403  }
404 
405  public:
407  {
408  (m_mutex.*m_end)(&m_location);
409  }
410 
411  protected:
415 };
416 
417 
418 
437 {
438  public:
444  const PReadWriteMutex & mutex,
445  bool start = true
446  ) : PReadWriteWaitAndSignalBase(mutex, NULL, start ? &PReadWriteMutex::InternalStartRead : NULL, &PReadWriteMutex::InternalEndRead) { }
447 };
448 
449 
468 {
469  public:
475  const PReadWriteMutex & mutex,
476  PBoolean start = true
477  ) : PReadWriteWaitAndSignalBase(mutex, NULL, start ? &PReadWriteMutex::InternalStartWrite : NULL, &PReadWriteMutex::InternalEndWrite) { }
478 };
479 
480 
481 #if PTRACING
482  class PInstrumentedReadWriteMutex : public PReadWriteMutex
483  {
484  public:
485  PInstrumentedReadWriteMutex(
486  const char * baseName,
487  const char * file,
488  unsigned line,
489  const char * waitReadOnlyName,
490  const char * heldReadOnlyName,
491  const char * waitReadWriteName,
492  const char * heldReadWriteName,
493  unsigned waitTime,
494  unsigned heldTime,
495  unsigned throttleTime = 10000,
496  unsigned throttledLogLevel = 2,
497  unsigned unthrottledLogLevel = 6,
498  unsigned thresholdPercent = 5,
499  unsigned maxHistory = 0
500  ) : PReadWriteMutex (PDebugLocation(file, line, baseName ), MinDeadlockTime(waitTime))
501  , m_timeWaitReadOnlyContext (PDebugLocation(file, line, waitReadOnlyName ), waitTime, throttleTime, throttledLogLevel, unthrottledLogLevel, thresholdPercent, maxHistory)
502  , m_timeHeldReadOnlyContext (PDebugLocation(file, line, heldReadOnlyName ), heldTime, throttleTime, throttledLogLevel, unthrottledLogLevel, thresholdPercent, maxHistory)
503  , m_timeWaitReadWriteContext(PDebugLocation(file, line, waitReadWriteName), waitTime, throttleTime, throttledLogLevel, unthrottledLogLevel, thresholdPercent, maxHistory)
504  , m_timeHeldReadWriteContext(PDebugLocation(file, line, heldReadWriteName), heldTime, throttleTime, throttledLogLevel, unthrottledLogLevel, thresholdPercent, maxHistory)
505  { }
506 
507  void SetWaitReadOnlyThrottleTime(unsigned throttleTime) { m_timeWaitReadOnlyContext.SetThrottleTime(throttleTime); }
508  void SetWaitReadOnlyThrottledLogLevel(unsigned throttledLogLevel) { m_timeWaitReadOnlyContext.SetThrottledLogLevel(throttledLogLevel); }
509  void SetWaitReadOnlyUnthrottledLogLevel(unsigned unthrottledLogLevel) { m_timeWaitReadOnlyContext.SetUnthrottledLogLevel(unthrottledLogLevel); }
510  void SetWaitReadOnlyThresholdPercent(unsigned thresholdPercent) { m_timeWaitReadOnlyContext.SetThresholdPercent(thresholdPercent); }
511  void SetWaitReadOnlyMaxHistory(unsigned maxHistory) { m_timeWaitReadOnlyContext.SetMaxHistory(maxHistory); }
512 
513  void SetHeldReadOnlyThrottleTime(unsigned throttleTime) { m_timeHeldReadOnlyContext.SetThrottleTime(throttleTime); }
514  void SetHeldReadOnlyThrottledLogLevel(unsigned throttledLogLevel) { m_timeHeldReadOnlyContext.SetThrottledLogLevel(throttledLogLevel); }
515  void SetHeldReadOnlyUnthrottledLogLevel(unsigned unthrottledLogLevel) { m_timeHeldReadOnlyContext.SetUnthrottledLogLevel(unthrottledLogLevel); }
516  void SetHeldReadOnlyThresholdPercent(unsigned thresholdPercent) { m_timeHeldReadOnlyContext.SetThresholdPercent(thresholdPercent); }
517  void SetHeldReadOnlyMaxHistory(unsigned maxHistory) { m_timeHeldReadOnlyContext.SetMaxHistory(maxHistory); }
518 
519  void SetWaitReadWriteThrottleTime(unsigned throttleTime) { m_timeWaitReadWriteContext.SetThrottleTime(throttleTime); }
520  void SetWaitReadWriteThrottledLogLevel(unsigned throttledLogLevel) { m_timeWaitReadWriteContext.SetThrottledLogLevel(throttledLogLevel); }
521  void SetWaitReadWriteUnthrottledLogLevel(unsigned unthrottledLogLevel) { m_timeWaitReadWriteContext.SetUnthrottledLogLevel(unthrottledLogLevel); }
522  void SetWaitReadWriteThresholdPercent(unsigned thresholdPercent) { m_timeWaitReadWriteContext.SetThresholdPercent(thresholdPercent); }
523  void SetWaitReadWriteMaxHistory(unsigned maxHistory) { m_timeWaitReadWriteContext.SetMaxHistory(maxHistory); }
524 
525  void SetHeldReadWriteThrottleTime(unsigned throttleTime) { m_timeHeldReadWriteContext.SetThrottleTime(throttleTime); }
526  void SetHeldReadWriteThrottledLogLevel(unsigned throttledLogLevel) { m_timeHeldReadWriteContext.SetThrottledLogLevel(throttledLogLevel); }
527  void SetHeldReadWriteUnthrottledLogLevel(unsigned unthrottledLogLevel) { m_timeHeldReadWriteContext.SetUnthrottledLogLevel(unthrottledLogLevel); }
528  void SetHeldReadWriteThresholdPercent(unsigned thresholdPercent) { m_timeHeldReadWriteContext.SetThresholdPercent(thresholdPercent); }
529  void SetHeldReadWriteMaxHistory(unsigned maxHistory) { m_timeHeldReadWriteContext.SetMaxHistory(maxHistory); }
530 
531  protected:
532  virtual void AcquiredLock(uint64_t startWaitCycle, bool readOnly, const PDebugLocation & location);
533  virtual void ReleasedLock(const PObject & mutex, uint64_t startHeldSamplePoint, bool readOnly, const PDebugLocation & location);
534 
535  PProfiling::TimeScope m_timeWaitReadOnlyContext;
536  PProfiling::TimeScope m_timeHeldReadOnlyContext;
537  PProfiling::TimeScope m_timeWaitReadWriteContext;
538  PProfiling::TimeScope m_timeHeldReadWriteContext;
539  };
540 
541  class PInstrumentedReadWaitAndSignal : public PReadWriteWaitAndSignalBase
542  {
543  public:
544  PInstrumentedReadWaitAndSignal(
545  const PReadWriteMutex & mutex,
546  const PDebugLocation & location,
547  bool start = true
548  ) : PReadWriteWaitAndSignalBase(mutex, &location, start ? &PReadWriteMutex::InternalStartRead : NULL, &PReadWriteMutex::InternalEndRead) { }
549  };
550 
551  class PInstrumentedWriteWaitAndSignal : public PReadWriteWaitAndSignalBase
552  {
553  public:
554  PInstrumentedWriteWaitAndSignal(
555  const PReadWriteMutex & mutex,
556  const PDebugLocation & location,
557  PBoolean start = true
558  ) : PReadWriteWaitAndSignalBase(mutex, &location, start ? &PReadWriteMutex::InternalStartWrite : NULL, &PReadWriteMutex::InternalEndWrite) { }
559  };
560 
561  #define PDECLARE_INSTRUMENTED_READ_WRITE_MUTEX(var, name, ...) \
562  struct PInstrumentedReadWriteMutex_##name : PInstrumentedReadWriteMutex { \
563  PInstrumentedReadWriteMutex_##name(const char * mutexName = #name) \
564  : PInstrumentedReadWriteMutex(mutexName, __FILE__, __LINE__, \
565  "Wait R/O " #name, "Held R/O " #name, \
566  "Wait R/W " #name, "Held R/W " #name, \
567  __VA_ARGS__) { } \
568  } var
569 #else
570  #define PDECLARE_INSTRUMENTED_READ_WRITE_MUTEX(var, name, waitTime, heldTime, ...) \
571  PDECLARE_READ_WRITE_MUTEX(var, name, MinDeadlockTime(waitTime))
572 #endif
573 
574 
579 template <class T> class PSyncQueue : public PObject
580 {
581  PCLASSINFO(PSyncQueue, PObject);
582  public:
583  typedef std::queue<T> BaseQueue;
584 
585  enum State
586  {
591  };
592 
595  : m_state(e_Open)
596  , m_available(0, INT_MAX)
597  {
598  }
599 
602  {
603  Close(true);
604  }
605 
607  bool Enqueue(const T & obj)
608  {
609  PWaitAndSignal lock(m_mutex);
610  if (m_state == e_Closed || m_state == e_Draining)
611  return false;
612  m_queue.push(obj);
614  return true;
615  }
616 
620  bool Dequeue(T & value, const PTimeInterval & timeout = PMaxTimeInterval)
621  {
622  bool dequeued = false;
623 
624  m_mutex.Wait();
625 
626  switch (m_state) {
627  case e_Blocked :
628  PAssertAlways("Multiple threads in PSyncQueue::Dequeue()");
629  break;
630 
631  case e_Open :
632  m_state = e_Blocked;
633 
634  {
635  m_mutex.Signal();
636  bool available = m_available.Wait(timeout);
637  m_mutex.Wait();
638 
639  if (available && !m_queue.empty()) {
640  value = m_queue.front();
641  m_queue.pop();
642  dequeued = true;
643  }
644  }
645 
646  if (m_state == e_Blocked) {
647  m_state = e_Open;
648  break;
649  }
650  if (m_state == e_Draining && m_queue.empty())
651  m_state = e_Closed; // Just popped the last item
652  if (m_state == e_Closed)
653  m_closed.Signal();
654  break;
655 
656  case e_Draining:
657  if (!m_queue.empty()) {
658  // Continue draining
659  value = m_queue.front();
660  m_queue.pop();
661  dequeued = true;
662  break;
663  }
664  m_state = e_Closed;
665  // Do closed case
666 
667  case e_Closed :
668  m_closed.Signal();
669  }
670 
671  m_mutex.Signal();
672 
673  return dequeued;
674  }
675 
679  void Drain(bool wait)
680  {
681  bool blocked;
682  {
683  PWaitAndSignal mutex(m_mutex);
684  if (m_state == e_Closed || m_state == e_Draining)
685  return;
686 
687  blocked = m_state == e_Blocked;
688  m_state = m_queue.empty() ? e_Closed : e_Draining;
690  }
691 
692  if (blocked && wait)
693  m_closed.Wait();
694  }
695 
699  void Close(bool wait)
700  {
701  m_mutex.Wait();
702 
703  bool blocked = m_state == e_Blocked;
704  m_state = e_Closed;
705 
706  while (!m_queue.empty())
707  m_queue.pop();
708 
710  m_mutex.Signal();
711 
712  if (blocked && wait)
713  m_closed.Wait();
714  }
715 
716  // Indicate queue is in use.
717  bool IsOpen() const
718  {
719  PWaitAndSignal mutex(m_mutex);
720  return m_state != e_Closed;
721  }
722 
724  void Restart()
725  {
726  m_mutex.Wait();
727  if (m_state == e_Closed) {
728  while (!m_queue.empty())
729  m_queue.pop();
730  while (m_available.Wait(0))
731  ;
732  m_state = e_Open;
733  }
734  m_mutex.Signal();
735  }
736 
737 
739  size_t size() const
740  {
741  PWaitAndSignal lock(m_mutex);
742  return m_queue.size();
743  }
744 
745 
747  bool empty() const
748  {
749  PWaitAndSignal lock(m_mutex);
750  return m_queue.empty();
751  }
752 
753 
754  __inline const PMutex & GetMutex() const { return m_mutex; }
755  __inline PMutex & GetMutex() { return m_mutex; }
756 
757  protected:
761  PDECLARE_MUTEX(m_mutex);
763 
764  private:
765  __inline PSyncQueue(const PSyncQueue & other) : PObject(other) { }
766  __inline void operator=(const PSyncQueue &) { }
767 };
768 
769 
770 #endif // PTLIB_SYNCTHRD_H
771 
772 
773 // End Of File ///////////////////////////////////////////////////////////////
std::queue< T > BaseQueue
Definition: syncthrd.h:583
Information about a source file location.
Definition: object.h:333
__inline const PMutex & GetMutex() const
Definition: syncthrd.h:754
#define PMaxTimeInterval
Definition: timeint.h:31
This class waits for the semaphore on construction and automatically signals the semaphore on destruc...
Definition: psync.h:115
Definition: syncthrd.h:342
This class defines a thread synchronisation object.
Definition: semaphor.h:74
PReadWriteMutex & m_mutex
Definition: syncthrd.h:412
Greater than.
Definition: syncthrd.h:154
void(PReadWriteMutex::* StartFn)(const PDebugLocation *location)
Definition: syncthrd.h:393
~PSyncQueue()
Destroy synchronous queue.
Definition: syncthrd.h:601
EndFn m_end
Definition: syncthrd.h:414
PIntCondMutex & operator=(int newval)
Assign new condition value.
Nest & operator=(const Nest &other)
This class defines an arbitrary time interval to millisecond accuracy.
Definition: timeint.h:51
This is a PCondMutex for which the conditional is the value of an integer.
Definition: syncthrd.h:136
PIntCondMutex & operator--()
Decrement condition value.
size_t size() const
Get the current size of the queue.
Definition: syncthrd.h:739
std::map< PThreadIdentifier, Nest > NestMap
Definition: syncthrd.h:354
void Restart()
Restart the queue after it has been closed.
Definition: syncthrd.h:724
virtual void Signal()
If there are waiting (blocked) threads then unblock the first one that was blocked.
bool Dequeue(T &value, const PTimeInterval &timeout=PMaxTimeInterval)
Dequeue an object from the synchronous queue.
Definition: syncthrd.h:620
void InternalWait(Nest &nest, PSync &sync, const PDebugLocation &location) const
#define PAssertAlways(msg)
This macro is used to assert immediately.
Definition: object.h:437
Nest * GetNest()
This class implements critical section mutexes using the most efficient mechanism available on the ho...
Definition: mutex.h:270
void Close(bool wait)
Close the queue and break block in Dequeue() function.
Definition: syncthrd.h:699
void PrintOn(ostream &strm) const
Print the object on the stream.
PReadWriteWaitAndSignalBase(const PReadWriteMutex &mutex, const PDebugLocation *location, StartFn start, EndFn end)
Definition: syncthrd.h:396
virtual void ReleasedLock(const PObject &mutex, uint64_t startHeldSamplePoint, bool readOnly, const PDebugLocation &location)
atomic< unsigned > m_readerCount
Definition: syncthrd.h:344
BaseQueue m_queue
Definition: syncthrd.h:758
Definition: psync.h:45
Definition: syncthrd.h:587
__inline void StartWrite()
This function attempts to acquire the mutex for writing.
Definition: syncthrd.h:299
A synchronous queue of objects.
Definition: syncthrd.h:579
Definition: syncthrd.h:590
PSyncPoint syncPoint
Definition: syncthrd.h:130
virtual void Signal()
If there are waiting (blocked) threads then unblock the first one that was blocked.
void InternalEndWriteWithNest(Nest &nest, const PDebugLocation &location)
int value
Definition: syncthrd.h:237
PIntCondMutex & operator+=(int inc)
Add to condition value.
PIntCondMutex & operator++()
Increment condition value.
virtual void WaitCondition()
This function attempts to acquire the mutex, but will block not only until the mutex is free...
NestMap m_nestedThreads
Definition: syncthrd.h:355
virtual void PrintOn(ostream &strm) const
Output the contents of the object to the stream.
__inline void StartWrite(const PDebugLocation &location)
Definition: syncthrd.h:300
This class defines a thread synchronisation object.
Definition: syncthrd.h:101
PCriticalSection m_nestingMutex
Definition: syncthrd.h:356
Operation
defines possible operators on current value and target value
Definition: syncthrd.h:144
virtual void Wait()
If the semaphore count is &gt; 0, decrement the semaphore and return.
PWriteWaitAndSignal(const PReadWriteMutex &mutex, PBoolean start=true)
Create the PWriteWaitAndSignal wait instance.
Definition: syncthrd.h:474
PSemaphore m_readerSemaphore
Definition: syncthrd.h:333
virtual void OnWait()
This function is called immediately before blocking on the condition in the WaitCondition() function...
unsigned m_readerCount
Definition: syncthrd.h:335
__inline void StartRead()
This function attempts to acquire the mutex for reading.
Definition: syncthrd.h:276
bool empty() const
Determine if queue is empty.
Definition: syncthrd.h:747
PSyncPoint m_closed
Definition: syncthrd.h:762
State m_state
Definition: syncthrd.h:759
atomic< PUniqueThreadIdentifier > m_uniqueId
Definition: syncthrd.h:348
unsigned m_writerCount
Definition: syncthrd.h:340
virtual void Wait()
Block until the synchronisation object is available.
PSyncPoint ack
Definition: syncthrd.h:92
This class starts a read operation for the PReadWriteMutex on construction and automatically ends the...
Definition: syncthrd.h:436
Nest & StartNest()
void InternalEndWrite(const PDebugLocation *location)
Operation operation
Definition: syncthrd.h:238
This class defines a thread-safe object in a collection.
Definition: safecoll.h:123
bool PBoolean
Definition: object.h:174
void(PReadWriteMutex::* EndFn)(const PDebugLocation *location)
Definition: syncthrd.h:394
friend class PInstrumentedWriteWaitAndSignal
Definition: syncthrd.h:375
int target
Definition: syncthrd.h:237
Less than or equal to.
Definition: syncthrd.h:148
void InternalStartWriteWithNest(Nest &nest, const PDebugLocation &location)
Equal to.
Definition: syncthrd.h:150
Definition: syncthrd.h:390
~PReadWriteWaitAndSignalBase()
Definition: syncthrd.h:406
This class, along with the PPROFILE_TIMESCOPE() macro, allows the measurement of the time used by a s...
Definition: object.h:1430
Greater than or equal to.
Definition: syncthrd.h:152
This class starts a write operation for the PReadWriteMutex on construction and automatically ends th...
Definition: syncthrd.h:467
Definition: syncthrd.h:589
void EndWrite(const PDebugLocation &location)
Definition: syncthrd.h:314
virtual PBoolean Condition()=0
This is the condition that must be met for the WaitCondition() function to acquire the mutex...
This class defines a thread mutual exclusion object.
Definition: mutex.h:101
void Drain(bool wait)
Begin graceful draining of the queue.
Definition: syncthrd.h:679
Definition: mutex.h:41
void InternalStartRead(const PDebugLocation *location)
friend class PInstrumentedReadWaitAndSignal
Definition: syncthrd.h:374
PIntCondMutex(int value=0, int target=0, Operation operation=LE)
Create a cond mutex using an integer.
PReadWaitAndSignal(const PReadWriteMutex &mutex, bool start=true)
Create the PReadWaitAndSignal wait instance.
Definition: syncthrd.h:443
void InternalEndRead(const PDebugLocation *location)
__inline void StartRead(const PDebugLocation &location)
Definition: syncthrd.h:277
virtual void AcquiredLock(uint64_t startWaitCycle, bool readOnly, const PDebugLocation &location)
bool Enqueue(const T &obj)
Enqueue an object to the synchronous queue.
Definition: syncthrd.h:607
atomic< bool > m_waiting
Definition: syncthrd.h:346
void EndWrite()
This function attempts to release the mutex for writing.
Definition: syncthrd.h:313
atomic< unsigned > m_writerCount
Definition: syncthrd.h:345
PIntCondMutex & operator-=(int dec)
Subtract from condition value.
PSemaphore m_writerSemaphore
Definition: syncthrd.h:338
virtual void Signal()
Signal that the synchronisation object is available.
PSemaphore m_available
Definition: syncthrd.h:760
PSyncQueue()
Construct synchronous queue.
Definition: syncthrd.h:594
virtual void Signal()
If there are waiting (blocked) threads then unblock the first one that was blocked.
bool IsOpen() const
Definition: syncthrd.h:717
This class defines a thread synchronisation object.
Definition: syncthrd.h:256
Less than.
Definition: syncthrd.h:146
Definition: object.h:1537
void Acknowledge()
This indicates that the thread that was blocked in a Wait() on this synchronisation object has comple...
__inline void EndRead()
This function attempts to release the mutex for reading.
Definition: syncthrd.h:281
void InternalEndReadWithNest(Nest &nest, const PDebugLocation &location)
void InternalStartReadWithNest(Nest &nest, const PDebugLocation &location)
__inline PMutex & GetMutex()
Definition: syncthrd.h:755
This class defines a thread synchronisation object.
Definition: syncthrd.h:65
atomic< uint64_t > m_startHeldCycle
Definition: syncthrd.h:347
void InternalStartWrite(const PDebugLocation *location)
PTimedMutex m_writerMutex
Definition: syncthrd.h:339
PTimedMutex m_readerMutex
Definition: syncthrd.h:334
Definition: syncthrd.h:588
PTimedMutex m_starvationPreventer
Definition: syncthrd.h:336
Ultimate parent class for all objects in the class library.
Definition: object.h:2204
PDebugLocation m_location
Definition: syncthrd.h:413
This class defines a thread synchronisation object.
Definition: syncpoint.h:63
PDECLARE_MUTEX(m_mutex)
virtual PBoolean Condition()
This is the condition that must be met for the WaitCondition() function to acquire the mutex...
__inline void EndRead(const PDebugLocation &location)
Definition: syncthrd.h:282