00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_queuing_mutex_H
00022 #define __TBB_queuing_mutex_H
00023
00024 #include <cstring>
00025 #include "atomic.h"
00026
00027 namespace tbb {
00028
00030
00031 class queuing_mutex {
00032 public:
00034 queuing_mutex() {
00035 q_tail = NULL;
00036 };
00037
00039
00041 class scoped_lock : private internal:: no_copy {
00043 void initialize() {
00044 mutex = NULL;
00045 #if TBB_DO_ASSERT
00046 internal::poison_pointer(next);
00047 #endif
00048 }
00049 public:
00051
00052 scoped_lock() {initialize();}
00053
00055
00056 scoped_lock( queuing_mutex& m ) {
00057 initialize();
00058 acquire(m);
00059 }
00060
00062 ~scoped_lock() {
00063 if( mutex ) release();
00064 }
00065
00067 void acquire( queuing_mutex& m );
00068
00070 bool try_acquire( queuing_mutex& m );
00071
00073 void release();
00074
00075 private:
00077 queuing_mutex* mutex;
00078
00080 scoped_lock *next;
00081
00083
00086 internal::uintptr going;
00087 };
00088
00089
00090 static const bool is_rw_mutex = false;
00091 static const bool is_recursive_mutex = false;
00092 static const bool is_fair_mutex = true;
00093
00094 friend class scoped_lock;
00095 private:
00097 atomic<scoped_lock*> q_tail;
00098
00099 };
00100
00101 }
00102
00103 #endif