00001 /* **************************************************************************** 00002 * Owner: Evgeniy Makeev 00003 * Created by: Evgeniy Makeev 00004 * **************************************************************************** 00005 */ 00006 #ifndef __RW_LOCK_H_Included__ 00007 #define __RW_LOCK_H_Included__ 00008 00009 #include "atomic_util.h" 00010 #include "system_abstraction.h" 00011 00012 /*---------------------------------*/ 00013 /* Written by Evgeniy Makeev, 1998 */ 00014 /*---------------------------------*/ 00015 // 00016 // Multiple readers - one writer interface class. 00017 // Implements multiple readers one writer mechanism. 00018 // Optimizes readers speed, provides fast readers 00019 // synchronization when no writers are waiting. 00020 // Useful when data is needed to be written/changed 00021 // only occasionally but it is read often by multiple 00022 // threads. 00023 // 00024 00025 class NonblockingRWLock 00026 { 00027 public: 00028 static const char *name() { return "Nonblocking_Reader_Lock"; } 00029 NonblockingRWLock() : readers(0), writers(0) {} 00030 virtual ~NonblockingRWLock() {} 00031 // 00032 // Must be called at the beginning of any read/data access. 00033 // 00034 void enter_read() 00035 { 00036 atomic_inc(&readers); 00037 if(writers > 0) 00038 { 00039 atomic_dec(&readers); 00040 l.lock(); 00041 atomic_inc(&readers); 00042 l.unlock(); 00043 } 00044 } 00045 00046 // 00047 // Must be called at the end of any read/data access. 00048 // 00049 void leave_read() 00050 { 00051 atomic_dec(&readers); 00052 } 00053 00054 // 00055 // Must be called at the beginning of a write operation 00056 // 00057 void enter_write() 00058 { 00059 l.lock(); 00060 atomic_inc(&writers); 00061 while(readers) thread_yield(); 00062 } 00063 00064 // 00065 // Must be called at the end of a write operation 00066 // 00067 void leave_write() 00068 { 00069 atomic_dec(&writers); 00070 l.unlock(); 00071 } 00072 00073 private: 00074 volatile int readers; 00075 volatile int writers; 00076 SystemLock l; 00077 }; 00078 00079 #endif // __RW_LOCK_H_Included__ 00080 00081 00082