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
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
46typedef std::remove_pointer<os_unfair_lock_t>::type pthread_spinlock_t;
47
48inline void pthread_spin_init(pthread_spinlock_t* p, int /*mode*/) {
49 *p = OS_UNFAIR_LOCK_INIT;
50}
51inline int pthread_spin_trylock(pthread_spinlock_t* p) {
52 return !os_unfair_lock_trylock(p);
53}
54inline int pthread_spin_lock(pthread_spinlock_t* p) {
55 os_unfair_lock_lock(p);
56 return 0;
57}
58inline int pthread_spin_unlock(pthread_spinlock_t* p) {
59 os_unfair_lock_unlock(p);
60 return 0;
61}
62
63inline int pthread_spin_destroy(pthread_spinlock_t*) {
64 return 0;
65}
66
67#else
68
69#include <libkern/OSAtomic.h>
70typedef OSSpinLock pthread_spinlock_t;
71
72inline void pthread_spin_init(pthread_spinlock_t* p, int /*mode*/) {
73 *p=0;
74}
75inline int pthread_spin_trylock(pthread_spinlock_t* p) {
76 return !OSSpinLockTry(p);
77}
78inline int pthread_spin_lock(pthread_spinlock_t* p) {
79 OSSpinLockLock(p);
80 return 0;
81}
82inline int pthread_spin_unlock(pthread_spinlock_t* p) {
83 OSSpinLockUnlock(p);
84 return 0;
85}
86inline 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
95
96/// \file worldmutex.h
97/// \brief Implements Mutex, MutexFair, Spinlock, ConditionVariable
98/// \addtogroup mutexes
99///@{
100
101
102
103namespace madness {
104
105 namespace detail {
106 void print_mutex_error(int error_number);
107 }
108
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:
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
194
195 public:
196 /// Make and initialize a mutex ... initial state is unlocked
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>
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.
391
392 /// Always succeeds immediately
394 ScopedMutex<Spinlock> protect(this);
395 ++nreader;
396 writeflag=false;
397 }
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.
481 }
482
483 /// Always succeeds immediately
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)
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:
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_) {
525 while (!myturn) std::this_thread::yield();
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
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;
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;
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
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:
709 , sense(true)
710 {
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
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_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
pthread_mutex_t & get_pthread_mutex()
Definition worldmutex.h:646
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.
pthread_mutex_t * ptr() const
Return a pointer to the pthread mutex for use by a condition variable.
Definition worldmutex.h:225
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 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
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
Namespace for all elements and tools of MADNESS.
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
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
static const double m
Definition relops.cc:9
Wrappers around platform dependent timers and performance info.