00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __TBB_reader_writer_lock_H
00030 #define __TBB_reader_writer_lock_H
00031
00032 #include "tbb_thread.h"
00033 #include "tbb_allocator.h"
00034 #include "atomic.h"
00035
00036 namespace tbb {
00037 namespace interface5 {
00039
00042 class reader_writer_lock : tbb::internal::no_copy {
00043 public:
00044 friend class scoped_lock;
00045 friend class scoped_lock_read;
00047
00082 enum status_t { waiting_nonblocking, waiting, active, invalid };
00083
00085 reader_writer_lock() {
00086 internal_construct();
00087 }
00088
00090 ~reader_writer_lock() {
00091 internal_destroy();
00092 }
00093
00095
00097 class scoped_lock : tbb::internal::no_copy {
00098 public:
00099 friend class reader_writer_lock;
00100
00102 scoped_lock(reader_writer_lock& lock) {
00103 internal_construct(lock);
00104 }
00105
00107 ~scoped_lock() {
00108 internal_destroy();
00109 }
00110
00111 void* operator new(size_t s) {
00112 return tbb::internal::allocate_via_handler_v3(s);
00113 }
00114 void operator delete(void* p) {
00115 tbb::internal::deallocate_via_handler_v3(p);
00116 }
00117
00118 private:
00120 reader_writer_lock *mutex;
00122 scoped_lock* next;
00124 atomic<status_t> status;
00125
00127 scoped_lock();
00128
00129 void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
00130 void __TBB_EXPORTED_METHOD internal_destroy();
00131 };
00132
00134 class scoped_lock_read : tbb::internal::no_copy {
00135 public:
00136 friend class reader_writer_lock;
00137
00139 scoped_lock_read(reader_writer_lock& lock) {
00140 internal_construct(lock);
00141 }
00142
00144 ~scoped_lock_read() {
00145 internal_destroy();
00146 }
00147
00148 void* operator new(size_t s) {
00149 return tbb::internal::allocate_via_handler_v3(s);
00150 }
00151 void operator delete(void* p) {
00152 tbb::internal::deallocate_via_handler_v3(p);
00153 }
00154
00155 private:
00157 reader_writer_lock *mutex;
00159 scoped_lock_read *next;
00161 atomic<status_t> status;
00162
00164 scoped_lock_read();
00165
00166 void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
00167 void __TBB_EXPORTED_METHOD internal_destroy();
00168 };
00169
00171
00176 void __TBB_EXPORTED_METHOD lock();
00177
00179
00183 bool __TBB_EXPORTED_METHOD try_lock();
00184
00186
00190 void __TBB_EXPORTED_METHOD lock_read();
00191
00193
00195 bool __TBB_EXPORTED_METHOD try_lock_read();
00196
00198 void __TBB_EXPORTED_METHOD unlock();
00199
00200 private:
00201 void __TBB_EXPORTED_METHOD internal_construct();
00202 void __TBB_EXPORTED_METHOD internal_destroy();
00203
00205
00206 bool start_write(scoped_lock *);
00208 void set_next_writer(scoped_lock *w);
00210 void end_write(scoped_lock *);
00212 bool is_current_writer();
00213
00215
00216 void start_read(scoped_lock_read *);
00218 void unblock_readers();
00220 void end_read();
00221
00223 atomic<scoped_lock_read*> reader_head;
00225 atomic<scoped_lock*> writer_head;
00227 atomic<scoped_lock*> writer_tail;
00229 tbb_thread::id my_current_writer;
00231 atomic<uintptr_t> rdr_count_and_flags;
00232 };
00233
00234 }
00235
00236 using interface5::reader_writer_lock;
00237
00238 }
00239
00240 #endif