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 #include "tbb_profiling.h"
00027
00028 namespace tbb {
00029
00031
00032 class queuing_mutex {
00033 public:
00035 queuing_mutex() {
00036 q_tail = NULL;
00037 #if TBB_USE_THREADING_TOOLS
00038 internal_construct();
00039 #endif
00040 }
00041
00043
00045 class scoped_lock: internal::no_copy {
00047 void initialize() {
00048 mutex = NULL;
00049 #if TBB_USE_ASSERT
00050 internal::poison_pointer(next);
00051 #endif
00052 }
00053 public:
00055
00056 scoped_lock() {initialize();}
00057
00059
00060 scoped_lock( queuing_mutex& m ) {
00061 initialize();
00062 acquire(m);
00063 }
00064
00066 ~scoped_lock() {
00067 if( mutex ) release();
00068 }
00069
00071 void __TBB_EXPORTED_METHOD acquire( queuing_mutex& m );
00072
00074 bool __TBB_EXPORTED_METHOD try_acquire( queuing_mutex& m );
00075
00077 void __TBB_EXPORTED_METHOD release();
00078
00079 private:
00081 queuing_mutex* mutex;
00082
00084 scoped_lock *next;
00085
00087
00090 internal::uintptr going;
00091 };
00092
00093 void __TBB_EXPORTED_METHOD internal_construct();
00094
00095
00096 static const bool is_rw_mutex = false;
00097 static const bool is_recursive_mutex = false;
00098 static const bool is_fair_mutex = true;
00099
00100 friend class scoped_lock;
00101 private:
00103 atomic<scoped_lock*> q_tail;
00104
00105 };
00106
00107 __TBB_DEFINE_PROFILING_SET_NAME(queuing_mutex)
00108
00109 }
00110
00111 #endif