Update of /cvsroot/boost/boost/boost/thread/win32
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv7181
Modified Files:
Tag: thread_rewrite
read_write_mutex.hpp
Log Message:
New look read-write mutex
Index: read_write_mutex.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/thread/win32/Attic/read_write_mutex.hpp,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -d -r1.1.2.4 -r1.1.2.5
--- read_write_mutex.hpp 8 Jun 2006 09:57:00 -0000 1.1.2.4
+++ read_write_mutex.hpp 5 Oct 2006 09:38:13 -0000 1.1.2.5
@@ -1,22 +1,152 @@
#ifndef BOOST_THREAD_WIN32_READ_WRITE_MUTEX_HPP
#define BOOST_THREAD_WIN32_READ_WRITE_MUTEX_HPP
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/condition.hpp>
+#include <boost/assert.hpp>
+#include <boost/detail/interlocked.hpp>
+#include <boost/thread/win32/thread_primitives.hpp>
+#include <boost/thread/win32/interlocked_read.hpp>
namespace boost
{
class read_write_mutex
{
private:
- boost::mutex guard;
- boost::condition cond;
- long reader_count;
-
+ long state;
+ void* shared_event;
+ void* writer_sem;
+ void* upgrader_sem;
+
+ BOOST_STATIC_CONSTANT(long,shared_count_shift=0);
+ BOOST_STATIC_CONSTANT(long,shared_count_mask=0x3ff);
+ BOOST_STATIC_CONSTANT(long,exclusive_count_shift=10);
+ BOOST_STATIC_CONSTANT(long,exclusive_count_mask=0xffc00);
+ BOOST_STATIC_CONSTANT(long,shared_mask=0x20000000);
+ BOOST_STATIC_CONSTANT(long,upgrading_mask=0x40000000);
+ BOOST_STATIC_CONSTANT(long,exclusive_mask=0x80000000);
+
+ template<long lock_mask,long count_mask,long count_increment,long
loop_mask,bool test_first>
+ long update_state(long old_state)
+ {
+ if(test_first && (old_state&loop_mask))
+ {
+ return old_state;
+ }
+ do
+ {
+ long const new_count=((old_state&count_mask)+count_increment);
+ BOOST_ASSERT(new_count<=count_mask);
+ long const
new_state=(old_state&~count_mask)|new_count|lock_mask;
+ long const
current_state=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&state,new_state,old_state);
+ if(current_state==old_state)
+ {
+ break;
+ }
+ old_state=current_state;
+ }
+ while(!(old_state&loop_mask));
+ return old_state;
+ }
+
public:
read_write_mutex():
- reader_count(0)
+ state(0),
+ shared_event(::boost::detail::CreateEventA(NULL,true,false,NULL)),
+ writer_sem(::boost::detail::CreateSemaphoreA(NULL,0,1,NULL)),
+ upgrader_sem(::boost::detail::CreateSemaphoreA(NULL,0,1,NULL))
{}
+
+ ~read_write_mutex()
+ {
+ ::boost::detail::CloseHandle(shared_event);
+ ::boost::detail::CloseHandle(writer_sem);
+ ::boost::detail::CloseHandle(upgrader_sem);
+ }
+
+ void lock_shareable()
+ {
+ // try and add ourselves to the current readers
+ long
old_state=update_state<shared_mask,shared_count_mask,1,exclusive_mask,false>(0);
+
+ if(!(old_state&shared_mask))
+ {
+ // someone else has exclusive access
+ // mark that we're interested
+
old_state=update_state<0,shared_count_mask,1,0,false>(old_state);
+ // now we're marked as waiting, if the exclusive lock is now
free, try and claim
+ // loop until we can claim shared lock
+ while(true)
+ {
+
old_state=update_state<shared_mask,0,0,exclusive_mask|shared_mask,true>(old_state);
+ if(old_state&shared_mask)
+ {
+ break;
+ }
+
+ bool const
success=::boost::detail::WaitForSingleObject(shared_event,BOOST_INFINITE)==0;
+ BOOST_ASSERT(success);
+ }
+ }
+ }
+
+ void unlock_shareable()
+ {
+ long
old_state=update_state<0,shared_count_mask,-1,0,false>(old_state); // decrement
shared count
+ if((old_state&shared_count_mask)==1) // if it was just us sharing
+ {
+
old_state=update_state<0,shared_mask,-shared_mask,0,false>(old_state);
+ if(old_state&exclusive_count_mask)
+ {
+ bool const
res=::boost::detail::ReleaseSemaphore(writer_sem)!=0;
+ BOOST_ASSERT(res);
+ }
+ }
+ }
+
+ void lock()
+ {
+ // try and acquire an exclusive lock
+ long
old_state=update_state<exclusive_mask,exclusive_count_mask,1<<exclusive_count_shift,exclusive_mask|shared_mask>(old_state);
+ if(old_state&(exclusive_mask|shared_mask))
+ {
+ // someone else has the lock
+ // mark that we're interested
+
old_state=update_state<0,exclusive_count_mask,1,0,false>(old_state);
+ // now we're marked as waiting, if the lock is now free, try
and claim
+ // loop until we can claim exclusive lock
+ while(true)
+ {
+
old_state=update_state<exclusive_mask,0,0,exclusive_mask|shared_mask,true>(old_state);
+ if(!(old_state&(shared_mask|exclusive_mask)))
+ {
+ break;
+ }
+
+ bool const
success=::boost::detail::WaitForSingleObject(writer_sem,BOOST_INFINITE)==0;
+ BOOST_ASSERT(success);
+ }
+ }
+ bool const success=::boost::detail::ResetEvent(shared_event);
+ BOOST_ASSERT(success);
+ }
+
+ void unlock()
+ {
+ long
old_state=update_state<0,exclusive_mask|exclusive_count_mask,-(exclusive_mask |
(1<<exclusive_count_shift)),0,false>(old_state);
+ if(old_state&shared_count_mask)
+ {
+ bool const success=::boost::detail::SetEvent(shared_event)!=0;
+ BOOST_ASSERT(success);
+ }
+
+ if(old_state&exclusive_count_mask)
+ {
+ bool const
success=::boost::detail::ReleaseSemaphore(writer_sem)!=0;
+ BOOST_ASSERT(success);
+ }
+ }
+
+
+
class scoped_read_lock
{
@@ -25,14 +155,11 @@
scoped_read_lock(read_write_mutex& m_):
m(m_)
{
- boost::mutex::scoped_lock lock(m.guard);
- ++m.reader_count;
+ m.lock_shareable();
}
~scoped_read_lock()
{
- boost::mutex::scoped_lock lock(m.guard);
- --m.reader_count;
- m.cond.notify_one();
+ m.unlock_shareable();
}
};
@@ -46,15 +173,11 @@
m(m_),
lock(m.guard)
{
- while(m.reader_count)
- {
- m.cond.wait(lock);
- }
+ m.lock();
}
void unlock()
{
- m.cond.notify_one();
- lock.unlock();
+ m.unlock();
}
~scoped_write_lock()
{
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs