MADNESS  0.10.1
worldmutex.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program 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 General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id$
32 */
33 #ifndef MADNESS_WORLD_WORLDMUTEX_H__INCLUDED
34 #define MADNESS_WORLD_WORLDMUTEX_H__INCLUDED
35 
36 #include <madness/madness_config.h>
37 #include <pthread.h>
38 #include <thread>
39 #include <cstdio>
40 #ifdef ON_A_MAC
41 #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
42 
43 #include <os/lock.h>
44 #include <type_traits>
45 
46 typedef std::remove_pointer<os_unfair_lock_t>::type pthread_spinlock_t;
47 
48 inline void pthread_spin_init(pthread_spinlock_t* p, int /*mode*/) {
49  *p = OS_UNFAIR_LOCK_INIT;
50 }
51 inline int pthread_spin_trylock(pthread_spinlock_t* p) {
52  return !os_unfair_lock_trylock(p);
53 }
54 inline int pthread_spin_lock(pthread_spinlock_t* p) {
55  os_unfair_lock_lock(p);
56  return 0;
57 }
58 inline int pthread_spin_unlock(pthread_spinlock_t* p) {
59  os_unfair_lock_unlock(p);
60  return 0;
61 }
62 
63 inline int pthread_spin_destroy(pthread_spinlock_t*) {
64  return 0;
65 }
66 
67 #else
68 
69 #include <libkern/OSAtomic.h>
70 typedef OSSpinLock pthread_spinlock_t;
71 
72 inline void pthread_spin_init(pthread_spinlock_t* p, int /*mode*/) {
73  *p=0;
74 }
75 inline int pthread_spin_trylock(pthread_spinlock_t* p) {
76  return !OSSpinLockTry(p);
77 }
78 inline int pthread_spin_lock(pthread_spinlock_t* p) {
79  OSSpinLockLock(p);
80  return 0;
81 }
82 inline int pthread_spin_unlock(pthread_spinlock_t* p) {
83  OSSpinLockUnlock(p);
84  return 0;
85 }
86 inline void pthread_spin_destroy(pthread_spinlock_t* /*p*/) {}
87 #endif // __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
88 #endif // ON_A_MAC
89 
90 
92 #include <madness/world/timers.h>
95 
96 /// \file worldmutex.h
97 /// \brief Implements Mutex, MutexFair, Spinlock, ConditionVariable
98 /// \addtogroup mutexes
99 ///@{
100 
101 
102 
103 namespace madness {
104 
105  namespace detail {
106  void print_mutex_error(int error_number);
107  }
108 
109  class MutexWaiter {
110  private:
111  unsigned int count;
112 
113  /// Yield for specified number of microseconds unless dedicated CPU
114  /// Blue Gene always has a dedicated hw thread
115  void yield(int us) {
116 #if !defined(HAVE_IBMBGP) && !defined(HAVE_IBMBGQ)
117  myusleep(us);
118 #endif
119  }
120 
121  public:
122  MutexWaiter() : count(0) { }
123 
124  void reset() { count = 0; }
125 
126  void wait();
127  }; // class MutexWaiter
128 
129 
130  /// Mutex using pthread mutex operations
131  class Mutex {
132  private:
133  mutable pthread_mutex_t mutex;
134 
135  /// Copy constructor is forbidden
136  Mutex(const Mutex&);
137 
138  /// Assignment is forbidden
139  void operator=(const Mutex&);
140 
141  public:
142  /// Make and initialize a mutex ... initial state is unlocked
143  Mutex(int junk=0) // Junk so that can force initializer in mraX.cc
144  {
145  const int result = pthread_mutex_init(&mutex, 0);
146  if (result) MADNESS_EXCEPTION("failed to initialize mutex", result);
147  }
148 
149  /// Try to acquire the mutex ... return true on success, false on failure
150  bool try_lock() const {
151  return pthread_mutex_trylock(&mutex)==0;
152  }
153 
154  /// Acquire the mutex waiting if necessary
155  void lock() const {
156  const int result = pthread_mutex_lock(&mutex);
157  if (result) {
158  fprintf(stderr, "!! MADNESS ERROR: Mutex::lock() failed acquiring mutex\n");
160  MADNESS_EXCEPTION("Mutex::lock() failed acquiring mutex", result);
161  }
162  }
163 
164  /// Free a mutex owned by this thread
165  void unlock() const {
166  const int result = pthread_mutex_unlock(&mutex);
167  if (result) {
168  fprintf(stderr, "!! MADNESS ERROR: Mutex::unlock() failed releasing mutex\n");
170  MADNESS_EXCEPTION("Mutex::unlock() failed releasing mutex", result);
171  }
172  }
173 
174  /// Return a pointer to the pthread mutex for use by a condition variable
175  pthread_mutex_t* ptr() const {
176  return &mutex;
177  }
178 
179  virtual ~Mutex() {
180  pthread_mutex_destroy(&mutex);
181  }
182  }; // class Mutex
183 
184  /// Recursive mutex using pthread mutex operations
186  private:
187  mutable pthread_mutex_t mutex;
188 
189  /// Copy constructor is forbidden
191 
192  /// Assignment is forbidden
193  void operator=(const RecursiveMutex&);
194 
195  public:
196  /// Make and initialize a mutex ... initial state is unlocked
197  RecursiveMutex();
198 
199  /// Try to acquire the mutex ... return true on success, false on failure
200  bool try_lock() const {
201  return pthread_mutex_trylock(&mutex)==0;
202  }
203 
204  /// Acquire the mutex waiting if necessary
205  void lock() const {
206  int result = pthread_mutex_lock(&mutex);
207  if (result) {
208  fprintf(stderr, "!! MADNESS ERROR: RecursiveMutex::lock() failed acquiring mutex\n");
210  MADNESS_EXCEPTION("RecursiveMutex::lock() failed acquiring mutex", result);
211  }
212  }
213 
214  /// Free a mutex owned by this thread
215  void unlock() const {
216  int result = pthread_mutex_unlock(&mutex);
217  if (result) {
218  fprintf(stderr, "!! MADNESS ERROR: RecursiveMutex::unlock() failed releasing mutex\n");
220  MADNESS_EXCEPTION("RecursiveMutex::unlock() failed releasing mutex", result);
221  }
222  }
223 
224  /// Return a pointer to the pthread mutex for use by a condition variable
225  pthread_mutex_t* ptr() const {
226  return &mutex;
227  }
228 
230  pthread_mutex_destroy(&mutex);
231  }
232  }; // class Mutex
233 
234 
235  /// Mutex that is applied/released at start/end of a scope
236 
237  /// The mutex must provide lock and unlock methods
238  template <class mutexT = Mutex>
239  class ScopedMutex {
240  const mutexT* mutex;
241  public:
242  ScopedMutex(const mutexT* m) : mutex(m) { mutex->lock(); }
243 
244  ScopedMutex(const mutexT& m) : mutex(&m) { mutex->lock(); }
245 
246  virtual ~ScopedMutex() { mutex->unlock(); }
247  }; // class ScopedMutex
248 
249 #ifdef NEVER_SPIN
250  typedef Mutex Spinlock;
251 #else
252  /// Spinlock using pthread spinlock operations
253  class Spinlock {
254  private:
255  //mutable pthread_spinlock_t spinlock __attribute__ ((aligned (64)));
256  mutable pthread_spinlock_t spinlock;
257 
258  /// Copy constructor is forbidden
260 
261  /// Assignment is forbidden
262  void operator=(const Spinlock&);
263 
264  public:
265  /// Make and initialize a spinlock ... initial state is unlocked
266  Spinlock(int junk=0) // Junk so that can force initializer in mraX.cc
267  {
268  pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE);
269  }
270 
271  /// Try to acquire the spinlock ... return true on success, false on failure
272  bool try_lock() const {
273  return pthread_spin_trylock(&spinlock)==0;
274  }
275 
276  /// Acquire the spinlock waiting if necessary
277  void lock() const {
278  int result = pthread_spin_lock(&spinlock);
279  if (result) {
280  fprintf(stderr, "!! MADNESS ERROR: Spinlock::lock() failed acquiring spinlock\n");
282  MADNESS_EXCEPTION("Spinlock::lock() failed acquiring spinlock", result);
283  }
284  }
285 
286  /// Free a spinlock owned by this thread
287  void unlock() const {
288  int result = pthread_spin_unlock(&spinlock);
289  if (result) {
290  fprintf(stderr, "!! MADNESS ERROR: Spinlock::unlock() failed releasing spinlock\n");
292  MADNESS_EXCEPTION("Spinlock::unlock() failed releasing spinlock", result);
293  }
294  }
295 
296  virtual ~Spinlock() {
297  pthread_spin_destroy(&spinlock);
298  }
299  }; // class Spinlock
300 #endif
301 
302 
303 #define OLDXXX
304 #ifdef OLDXXX
305  // This version uses a spin lock
306  class MutexReaderWriter : private Spinlock, private NO_DEFAULTS {
307  mutable int nreader; // used to be volatile but is protected by mutex and associated barriers
308  mutable bool writeflag; // ditto
309  public:
310  static const int NOLOCK=0;
311  static const int READLOCK=1;
312  static const int WRITELOCK=2;
313 
315 
316  bool try_read_lock() const {
317  ScopedMutex<Spinlock> protect(this);
318  bool gotit = !writeflag;
319  if (gotit) ++nreader;
320  return gotit;
321  }
322 
323  bool try_write_lock() const {
324  ScopedMutex<Spinlock> protect(this);
325  bool gotit = (!writeflag) && (nreader==0);
326  if (gotit) writeflag = true;
327  return gotit;
328  }
329 
330  bool try_lock(int lockmode) const {
331  if (lockmode == READLOCK) {
332  return try_read_lock();
333  }
334  else if (lockmode == WRITELOCK) {
335  return try_write_lock();
336  }
337  else if (lockmode == NOLOCK) {
338  return true;
339  }
340  else {
341  MADNESS_EXCEPTION("MutexReaderWriter: try_lock: invalid lock mode", lockmode);
342  }
343  }
344 
346  ScopedMutex<Spinlock> protect(this);
347  bool gotit = (!writeflag) && (nreader==1);
348  if (gotit) {
349  nreader = 0;
350  writeflag = true;
351  }
352  return gotit;
353  }
354 
355  void read_lock() const {
356  while (!try_read_lock()) cpu_relax();
357  }
358 
359  void write_lock() const {
360  while (!try_write_lock()) cpu_relax();
361  }
362 
363  void lock(int lockmode) const {
364  while (!try_lock(lockmode)) cpu_relax();
365  }
366 
367  void read_unlock() const {
368  ScopedMutex<Spinlock> protect(this);
369  nreader--;
370  }
371 
372  void write_unlock() const {
373  // Only a single thread should be setting writeflag but
374  // probably still need the mutex just to get memory fence?
375  ScopedMutex<Spinlock> protect(this);
376  writeflag = false;
377  }
378 
379  void unlock(int lockmode) const {
380  if (lockmode == READLOCK) read_unlock();
381  else if (lockmode == WRITELOCK) write_unlock();
382  else if (lockmode != NOLOCK) MADNESS_EXCEPTION("MutexReaderWriter: try_lock: invalid lock mode", lockmode);
383  }
384 
385  /// Converts read to write lock without releasing the read lock
386 
387  /// Note that deadlock is guaranteed if two+ threads wait to convert at the same time.
390  }
391 
392  /// Always succeeds immediately
394  ScopedMutex<Spinlock> protect(this);
395  ++nreader;
396  writeflag=false;
397  }
398  virtual ~MutexReaderWriter() {}
399  };
400 
401 #else
402 
403  // This version uses AtomicInt and CAS
404  class MutexReaderWriter : private NO_DEFAULTS {
405  mutable AtomicInt nreader;
406  mutable AtomicInt writeflag;
407  enum {UNLOCKED, LOCKED};
408 
409  public:
410  enum lockT {NOLOCK, READLOCK, WRITELOCK};
411 
413 
414  bool try_read_lock() const {
415  nreader++;
416  if (writeflag == UNLOCKED) return true;
417  nreader--;
418  return false;
419  }
420 
421  bool try_write_lock() const {
422  return (writeflag.compare_and_swap((int) UNLOCKED, (int) LOCKED) == 0);
423  }
424 
425  bool try_lock(int lockmode) const {
426  if (lockmode == READLOCK) {
427  return try_read_lock();
428  }
429  else if (lockmode == WRITELOCK) {
430  return try_write_lock();
431  }
432  else if (lockmode == NOLOCK) {
433  return true;
434  }
435  else {
436  MADNESS_EXCEPTION("MutexReaderWriter: try_lock: invalid lock mode", lockmode);
437  }
438  }
439 
441  if (!try_write_lock()) return false;
442  if (nreader > 1) {
443  write_unlock();
444  return false;
445  }
446  nreader = 0;
447  return true;
448  }
449 
450  void read_lock() const {
451  while (!try_read_lock()) cpu_relax();
452  }
453 
454  void write_lock() const {
455  while (!try_write_lock()) cpu_relax();
456  }
457 
458  void lock(int lockmode) const {
459  while (!try_lock(lockmode)) cpu_relax();
460  }
461 
462  void read_unlock() const {
463  nreader--;
464  }
465 
466  void write_unlock() const {
467  writeflag = UNLOCKED;
468  }
469 
470  void unlock(int lockmode) const {
471  if (lockmode == READLOCK) read_unlock();
472  else if (lockmode == WRITELOCK) write_unlock();
473  else if (lockmode != NOLOCK) MADNESS_EXCEPTION("MutexReaderWriter: try_lock: invalid lock mode", lockmode);
474  }
475 
476  /// Converts read to write lock without releasing the read lock
477 
478  /// Note that deadlock is guaranteed if two+ threads wait to convert at the same time.
479  void convert_read_lock_to_write_lock() const {
481  }
482 
483  /// Always succeeds immediately
484  void convert_write_lock_to_read_lock() const {
485  nreader++;
486  writeflag = UNLOCKED;
487  }
488  };
489 #endif
490 
491  /// wait policies supported by ConditionVariable/DQueue/ThreadPool
492  enum class WaitPolicy {
493  Busy = 1, Yield, Sleep
494  };
495 
496  /// Scalable and fair condition variable (spins on local value)
497  class ConditionVariable : public Spinlock {
498  public:
499  static const int MAX_NTHREAD = 128;
500  mutable int back; // used to be volatile, but is protected by mutex and associated barriers
501  mutable int front; // ditto
502  mutable volatile bool* fifo[MAX_NTHREAD]; // volatile needed here; Circular buffer of flags
503 
504  void set_wait_policy(WaitPolicy p, int us = 0) {
505  wait_policy_ = p;
506  wait_usleep_ = std::chrono::microseconds(us);
507  }
508 
509  public:
510  ConditionVariable() : back(0), front(0), fifo() { }
511 
512  /// You should acquire the mutex before waiting
513  void wait() const {
514  // We put a pointer to a thread-local variable at the
515  // end of the queue and wait for that value to be set,
516  // thus generate no memory traffic while waiting.
517  volatile bool myturn = false;
518  int b = this->back;
519  fifo[b] = &myturn;
520  this->back = (b+1 < MAX_NTHREAD ? b+1 : 0);
521 
522  unlock(); // Release lock before blocking
523  switch (this->wait_policy_) {
524  case WaitPolicy::Yield:
525  while (!myturn) std::this_thread::yield();
526  case WaitPolicy::Sleep:
527  while (!myturn) std::this_thread::sleep_for(this->wait_usleep_);
528  default:
529  while (!myturn) cpu_relax();
530  }
531  lock();
532  }
533 
534  /// You should acquire the mutex before signalling
535  void signal() const {
536  int f = this->front;
537  if (f == this->back) return;
538  *fifo[f] = true;
539  int next = (f+1 < MAX_NTHREAD ? f+1 : 0);
540  this->front = next;
541  }
542 
543  /// You should acquire the mutex before broadcasting
544  void broadcast() const {
545  while (front != back)
546  signal();
547  }
548 
549  virtual ~ConditionVariable() {}
550 
551  private:
553  std::chrono::microseconds wait_usleep_ = std::chrono::microseconds(0);
554 
555  };
556 
557 
558  /// A scalable and fair mutex (not recursive)
559 
560  /// Needs rewriting to use the CV above and do we really
561  /// need this if using pthread_mutex .. why not pthread_cv?
562  class MutexFair : private Spinlock {
563  private:
564  static const int MAX_NTHREAD = 128;
565  mutable volatile bool* q[MAX_NTHREAD]; // volatile needed
566  mutable int n; // volatile not needed due to use of spinlock and associated barriers
567  mutable int front;
568  mutable int back;
569 
570  public:
571  MutexFair() : n(0), front(0), back(0) {};
572 
573  void lock() const {
574  volatile bool myturn = false;
575  Spinlock::lock();
576  ++n;
577  if (n == 1) {
578  myturn = true;
579  }
580  else {
581  int b = back + 1;
582  if (b >= MAX_NTHREAD) b = 0;
583  q[b] = &myturn;
584  back = b;
585  }
587 
588  while (!myturn) cpu_relax();
589  }
590 
591  void unlock() const {
592  volatile bool* p = 0;
593  Spinlock::lock();
594  n--;
595  if (n > 0) {
596  int f = front + 1;
597  if (f >= MAX_NTHREAD) f = 0;
598  p = q[f];
599  front = f;
600  }
602  if (p) *p = true;
603  }
604 
605  bool try_lock() const {
606  bool got_lock;
607 
608  Spinlock::lock();
609  int nn = n;
610  got_lock = (nn == 0);
611  if (got_lock) n = nn + 1;
613 
614  return got_lock;
615  }
616  };
617 
618 
619  /// Attempt to acquire two locks without blocking holding either one
620 
621  /// The code will first attempt to acquire mutex m1 and if successful
622  /// will then attempt to acquire mutex m2.
623  inline bool try_two_locks(const Mutex& m1, const Mutex& m2) {
624  if (!m1.try_lock()) return false;
625  if (m2.try_lock()) return true;
626  m1.unlock();
627  return false;
628  }
629 
630 
631  /// Simple wrapper for Pthread condition variable with its own mutex
632 
633  /// Use this when you need to block without consuming cycles.
634  /// Scheduling granularity is at the level of kernel ticks.
636  private:
637  mutable pthread_cond_t cv;
638  mutable pthread_mutex_t mutex;
639 
640  public:
642  pthread_cond_init(&cv, nullptr);
643  pthread_mutex_init(&mutex, 0);
644  }
645 
646  pthread_mutex_t& get_pthread_mutex() {
647  return mutex;
648  }
649 
650  void lock() const {
651  int result = pthread_mutex_lock(&mutex);
652  if (result) {
653  fprintf(stderr, "!! MADNESS ERROR: PthreadConditionVariable::lock() failed acquiring mutex\n");
655  MADNESS_EXCEPTION("PthreadConditionVariable::lock() failed acquiring mutex", result);
656  }
657  }
658 
659  void unlock() const {
660  int result = pthread_mutex_unlock(&mutex);
661  if (result) {
662  fprintf(stderr, "!! MADNESS ERROR: PthreadConditionVariable::unlock() failed releasing mutex\n");
664  MADNESS_EXCEPTION("PthreadConditionVariable::unlock() failed releasing mutex", result);
665  }
666  }
667 
668  /// You should have acquired the mutex before entering here
669  void wait() const {
670  pthread_cond_wait(&cv,&mutex);
671  }
672 
673  void signal() const {
674  int result = pthread_cond_signal(&cv);
675  if (result) MADNESS_EXCEPTION("ConditionalVariable: signalling failed", result);
676  }
677 
678  void broadcast() const {
679  int result = pthread_cond_broadcast(&cv);
680  if (result) MADNESS_EXCEPTION("ConditionalVariable: signalling failed", result);
681  }
682 
684  pthread_mutex_destroy(&mutex);
685  pthread_cond_destroy(&cv);
686  }
687  }; // class PthreadConditionVariable
688 
689 #ifdef USE_SPINLOCKS
690  typedef ConditionVariable CONDITION_VARIABLE_TYPE ;
691  typedef Spinlock SPINLOCK_TYPE;
692  typedef MutexFair SCALABLE_MUTEX_TYPE;
693 #else
697 #endif
698 
699  // I THINK THIS IS NO LONGER USED???????????????????????????????????
700  class Barrier {
701  const int nthread;
702  volatile bool sense;
704  volatile bool* pflags[128];
705 
706  public:
708  : nthread(nthread)
709  , sense(true)
710  {
711  nworking = nthread;
712  }
713 
714  /// Each thread calls this once before first use
715 
716  /// id should be the thread id (0,..,nthread-1) and pflag a pointer to
717  /// thread-local bool (probably in the thread's stack)
718  void register_thread(int id, volatile bool* pflag) {
719  if (id > 63) MADNESS_EXCEPTION("Barrier : hard dimension failed", id);
720  pflags[id] = pflag;
721  *pflag=!sense;
722  }
723 
724  /// Each thread calls this with its id (0,..,nthread-1) to enter the barrier
725 
726  /// The thread last to enter the barrier returns true. Others return false.
727  ///
728  /// All calls to the barrier must use the same value of nthread.
729  bool enter(const int id) {
730  if (nthread <= 1) {
731  return true;
732  }
733  else {
734  if (id > 63) MADNESS_EXCEPTION("Barrier : hard dimension failed", id);
735  bool lsense = sense; // Local copy of sense
736  bool result = nworking.dec_and_test();
737  if (result) {
738  // Reset counter and sense for next entry
739  nworking = nthread;
740  sense = !sense;
741  __asm__ __volatile__("" : : : "memory");
742 
743  // Notify everyone including me
744  for (int i = 0; i < nthread; ++i)
745  *(pflags[i]) = lsense;
746  } else {
747  volatile bool* myflag = pflags[id]; // Local flag;
748  while (*myflag != lsense) {
749  cpu_relax();
750  }
751  }
752  return result;
753  }
754  }
755  }; // class Barrier
756 
757  namespace detail {
758  extern Mutex printmutex;
759  }
760 }
761 
762 ///@}
763 
764 
765 #endif // MADNESS_WORLD_WORLDMUTEX_H__INCLUDED
Implements AtomicInt.
Disables default copy constructor and assignment operators.
Definition: nodefaults.h:49
An integer with atomic set, get, read+increment, read+decrement, and decrement+test operations.
Definition: atomicint.h:126
bool dec_and_test()
Decrements the counter and returns true if the new value is zero,.
Definition: atomicint.h:297
Definition: worldmutex.h:700
const int nthread
Definition: worldmutex.h:701
volatile bool * pflags[128]
Definition: worldmutex.h:704
volatile bool sense
Definition: worldmutex.h:702
AtomicInt nworking
Definition: worldmutex.h:703
bool enter(const int id)
Each thread calls this with its id (0,..,nthread-1) to enter the barrier.
Definition: worldmutex.h:729
Barrier(int nthread)
Definition: worldmutex.h:707
void register_thread(int id, volatile bool *pflag)
Each thread calls this once before first use.
Definition: worldmutex.h:718
Scalable and fair condition variable (spins on local value)
Definition: worldmutex.h:497
void wait() const
You should acquire the mutex before waiting.
Definition: worldmutex.h:513
int front
Definition: worldmutex.h:501
void signal() const
You should acquire the mutex before signalling.
Definition: worldmutex.h:535
void broadcast() const
You should acquire the mutex before broadcasting.
Definition: worldmutex.h:544
int back
Definition: worldmutex.h:500
static const int MAX_NTHREAD
Definition: worldmutex.h:499
virtual ~ConditionVariable()
Definition: worldmutex.h:549
volatile bool * fifo[MAX_NTHREAD]
Definition: worldmutex.h:502
ConditionVariable()
Definition: worldmutex.h:510
std::chrono::microseconds wait_usleep_
Definition: worldmutex.h:553
void set_wait_policy(WaitPolicy p, int us=0)
Definition: worldmutex.h:504
WaitPolicy wait_policy_
Definition: worldmutex.h:552
A scalable and fair mutex (not recursive)
Definition: worldmutex.h:562
bool try_lock() const
Definition: worldmutex.h:605
void lock() const
Definition: worldmutex.h:573
int front
Definition: worldmutex.h:567
MutexFair()
Definition: worldmutex.h:571
static const int MAX_NTHREAD
Definition: worldmutex.h:564
void unlock() const
Definition: worldmutex.h:591
int n
Definition: worldmutex.h:566
int back
Definition: worldmutex.h:568
volatile bool * q[MAX_NTHREAD]
Definition: worldmutex.h:565
Definition: worldmutex.h:306
void convert_read_lock_to_write_lock() const
Converts read to write lock without releasing the read lock.
Definition: worldmutex.h:388
void write_unlock() const
Definition: worldmutex.h:372
static const int WRITELOCK
Definition: worldmutex.h:312
void convert_write_lock_to_read_lock() const
Always succeeds immediately.
Definition: worldmutex.h:393
virtual ~MutexReaderWriter()
Definition: worldmutex.h:398
bool try_read_lock() const
Definition: worldmutex.h:316
MutexReaderWriter()
Definition: worldmutex.h:314
static const int READLOCK
Definition: worldmutex.h:311
void lock(int lockmode) const
Definition: worldmutex.h:363
int nreader
Definition: worldmutex.h:307
bool try_lock(int lockmode) const
Definition: worldmutex.h:330
void unlock(int lockmode) const
Definition: worldmutex.h:379
static const int NOLOCK
Definition: worldmutex.h:310
void write_lock() const
Definition: worldmutex.h:359
void read_lock() const
Definition: worldmutex.h:355
bool try_write_lock() const
Definition: worldmutex.h:323
bool writeflag
Definition: worldmutex.h:308
bool try_convert_read_lock_to_write_lock() const
Definition: worldmutex.h:345
void read_unlock() const
Definition: worldmutex.h:367
Definition: worldmutex.h:109
void wait()
Definition: worldmutex.cc:103
MutexWaiter()
Definition: worldmutex.h:122
unsigned int count
Definition: worldmutex.h:111
void yield(int us)
Definition: worldmutex.h:115
void reset()
Definition: worldmutex.h:124
Mutex using pthread mutex operations.
Definition: worldmutex.h:131
pthread_mutex_t mutex
Definition: worldmutex.h:133
pthread_mutex_t * ptr() const
Return a pointer to the pthread mutex for use by a condition variable.
Definition: worldmutex.h:175
void operator=(const Mutex &)
Assignment is forbidden.
Mutex(const Mutex &)
Copy constructor is forbidden.
Mutex(int junk=0)
Make and initialize a mutex ... initial state is unlocked.
Definition: worldmutex.h:143
void unlock() const
Free a mutex owned by this thread.
Definition: worldmutex.h:165
virtual ~Mutex()
Definition: worldmutex.h:179
bool try_lock() const
Try to acquire the mutex ... return true on success, false on failure.
Definition: worldmutex.h:150
void lock() const
Acquire the mutex waiting if necessary.
Definition: worldmutex.h:155
Simple wrapper for Pthread condition variable with its own mutex.
Definition: worldmutex.h:635
pthread_mutex_t mutex
Definition: worldmutex.h:638
void lock() const
Definition: worldmutex.h:650
pthread_mutex_t & get_pthread_mutex()
Definition: worldmutex.h:646
pthread_cond_t cv
Definition: worldmutex.h:637
virtual ~PthreadConditionVariable()
Definition: worldmutex.h:683
void unlock() const
Definition: worldmutex.h:659
void broadcast() const
Definition: worldmutex.h:678
void signal() const
Definition: worldmutex.h:673
void wait() const
You should have acquired the mutex before entering here.
Definition: worldmutex.h:669
PthreadConditionVariable()
Definition: worldmutex.h:641
Recursive mutex using pthread mutex operations.
Definition: worldmutex.h:185
void operator=(const RecursiveMutex &)
Assignment is forbidden.
void lock() const
Acquire the mutex waiting if necessary.
Definition: worldmutex.h:205
RecursiveMutex(const RecursiveMutex &)
Copy constructor is forbidden.
void unlock() const
Free a mutex owned by this thread.
Definition: worldmutex.h:215
bool try_lock() const
Try to acquire the mutex ... return true on success, false on failure.
Definition: worldmutex.h:200
pthread_mutex_t * ptr() const
Return a pointer to the pthread mutex for use by a condition variable.
Definition: worldmutex.h:225
pthread_mutex_t mutex
Definition: worldmutex.h:187
~RecursiveMutex()
Definition: worldmutex.h:229
RecursiveMutex()
Make and initialize a mutex ... initial state is unlocked.
Definition: worldmutex.cc:127
Mutex that is applied/released at start/end of a scope.
Definition: worldmutex.h:239
const mutexT * mutex
Definition: worldmutex.h:240
ScopedMutex(const mutexT &m)
Definition: worldmutex.h:244
ScopedMutex(const mutexT *m)
Definition: worldmutex.h:242
virtual ~ScopedMutex()
Definition: worldmutex.h:246
Spinlock using pthread spinlock operations.
Definition: worldmutex.h:253
void lock() const
Acquire the spinlock waiting if necessary.
Definition: worldmutex.h:277
bool try_lock() const
Try to acquire the spinlock ... return true on success, false on failure.
Definition: worldmutex.h:272
void operator=(const Spinlock &)
Assignment is forbidden.
Spinlock(int junk=0)
Make and initialize a spinlock ... initial state is unlocked.
Definition: worldmutex.h:266
void unlock() const
Free a spinlock owned by this thread.
Definition: worldmutex.h:287
Spinlock(const Spinlock &)
Copy constructor is forbidden.
virtual ~Spinlock()
Definition: worldmutex.h:296
pthread_spinlock_t spinlock
Definition: worldmutex.h:256
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
const double m
Definition: gfit.cc:199
Macros and tools pertaining to the configuration of MADNESS.
Defines madness::MadnessException for exception handling.
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
void print_mutex_error(int error_number)
Definition: worldmutex.cc:44
Mutex printmutex
Definition: worldmutex.cc:146
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
PthreadConditionVariable CONDITION_VARIABLE_TYPE
Definition: worldmutex.h:694
WaitPolicy
wait policies supported by ConditionVariable/DQueue/ThreadPool
Definition: worldmutex.h:492
bool try_two_locks(const Mutex &m1, const Mutex &m2)
Attempt to acquire two locks without blocking holding either one.
Definition: worldmutex.h:623
Mutex SPINLOCK_TYPE
Definition: worldmutex.h:695
static void myusleep(unsigned int us)
Sleep or spin for specified number of microseconds.
Definition: timers.h:164
NDIM & f
Definition: mra.h:2416
std::string type(const PairType &n)
Definition: PNOParameters.h:18
void cpu_relax()
Do nothing and especially do not touch memory.
Definition: timers.h:148
Mutex SCALABLE_MUTEX_TYPE
Definition: worldmutex.h:696
Implements NO_DEFAULTS.
static const double b
Definition: nonlinschro.cc:119
Wrappers around platform dependent timers and performance info.