00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_reader_writer_lock_H
00022 #define __TBB_reader_writer_lock_H
00023
00024 #include "tbb_thread.h"
00025 #include "tbb_allocator.h"
00026 #include "atomic.h"
00027
00028 namespace tbb {
00029 namespace interface5 {
00031
00034 class reader_writer_lock : tbb::internal::no_copy {
00035 public:
00036 friend class scoped_lock;
00037 friend class scoped_lock_read;
00039
00074 enum status_t { waiting_nonblocking, waiting, active, invalid };
00075
00077 reader_writer_lock() {
00078 internal_construct();
00079 }
00080
00082 ~reader_writer_lock() {
00083 internal_destroy();
00084 }
00085
00087
00089 class scoped_lock : tbb::internal::no_copy {
00090 public:
00091 friend class reader_writer_lock;
00092
00094 scoped_lock(reader_writer_lock& lock) {
00095 internal_construct(lock);
00096 }
00097
00099 ~scoped_lock() {
00100 internal_destroy();
00101 }
00102
00103 void* operator new(size_t s) {
00104 return tbb::internal::allocate_via_handler_v3(s);
00105 }
00106 void operator delete(void* p) {
00107 tbb::internal::deallocate_via_handler_v3(p);
00108 }
00109
00110 private:
00112 reader_writer_lock *mutex;
00114 scoped_lock* next;
00116 atomic<status_t> status;
00117
00119 scoped_lock();
00120
00121 void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
00122 void __TBB_EXPORTED_METHOD internal_destroy();
00123 };
00124
00126 class scoped_lock_read : tbb::internal::no_copy {
00127 public:
00128 friend class reader_writer_lock;
00129
00131 scoped_lock_read(reader_writer_lock& lock) {
00132 internal_construct(lock);
00133 }
00134
00136 ~scoped_lock_read() {
00137 internal_destroy();
00138 }
00139
00140 void* operator new(size_t s) {
00141 return tbb::internal::allocate_via_handler_v3(s);
00142 }
00143 void operator delete(void* p) {
00144 tbb::internal::deallocate_via_handler_v3(p);
00145 }
00146
00147 private:
00149 reader_writer_lock *mutex;
00151 scoped_lock_read *next;
00153 atomic<status_t> status;
00154
00156 scoped_lock_read();
00157
00158 void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
00159 void __TBB_EXPORTED_METHOD internal_destroy();
00160 };
00161
00163
00168 void __TBB_EXPORTED_METHOD lock();
00169
00171
00175 bool __TBB_EXPORTED_METHOD try_lock();
00176
00178
00182 void __TBB_EXPORTED_METHOD lock_read();
00183
00185
00187 bool __TBB_EXPORTED_METHOD try_lock_read();
00188
00190 void __TBB_EXPORTED_METHOD unlock();
00191
00192 private:
00193 void __TBB_EXPORTED_METHOD internal_construct();
00194 void __TBB_EXPORTED_METHOD internal_destroy();
00195
00197
00198 bool start_write(scoped_lock *);
00200 void set_next_writer(scoped_lock *w);
00202 void end_write(scoped_lock *);
00204 bool is_current_writer();
00205
00207
00208 void start_read(scoped_lock_read *);
00210 void unblock_readers();
00212 void end_read();
00213
00215 atomic<scoped_lock_read*> reader_head;
00217 atomic<scoped_lock*> writer_head;
00219 atomic<scoped_lock*> writer_tail;
00221 tbb_thread::id my_current_writer;
00223 atomic<unsigned> rdr_count_and_flags;
00224 };
00225
00226 }
00227
00228 using interface5::reader_writer_lock;
00229
00230 }
00231
00232 #endif