fix mutex impl

This commit is contained in:
Daniel Larimer 2012-11-08 23:12:45 -05:00
parent 914b8b2d3e
commit 0e41cf98b5
2 changed files with 16 additions and 13 deletions

View file

@ -26,6 +26,7 @@ namespace fc {
: caller_context(0), : caller_context(0),
stack_alloc(&alloc), stack_alloc(&alloc),
next_blocked(0), next_blocked(0),
next_blocked_mutex(0),
next(0), next(0),
ctx_thread(t), ctx_thread(t),
canceled(false), canceled(false),
@ -43,6 +44,7 @@ namespace fc {
:caller_context(0), :caller_context(0),
stack_alloc(0), stack_alloc(0),
next_blocked(0), next_blocked(0),
next_blocked_mutex(0),
next(0), next(0),
ctx_thread(t), ctx_thread(t),
canceled(false), canceled(false),
@ -137,6 +139,7 @@ namespace fc {
time_point resume_time; time_point resume_time;
// time_point ready_time; // time that this context was put on ready queue // time_point ready_time; // time that this context was put on ready queue
fc::context* next_blocked; fc::context* next_blocked;
fc::context* next_blocked_mutex;
fc::context* next; fc::context* next;
fc::thread* ctx_thread; fc::thread* ctx_thread;
bool canceled; bool canceled;

View file

@ -16,7 +16,7 @@ namespace fc {
fc::thread::current().debug("~mutex"); fc::thread::current().debug("~mutex");
while( c ) { while( c ) {
elog( "still blocking on context %p (%s)", m_blist, (m_blist->cur_task ? m_blist->cur_task->get_desc() : "no current task") ); elog( "still blocking on context %p (%s)", m_blist, (m_blist->cur_task ? m_blist->cur_task->get_desc() : "no current task") );
c = c->next_blocked; c = c->next_blocked_mutex;
} }
} }
BOOST_ASSERT( !m_blist && "Attempt to free mutex while others are blocking on lock." ); BOOST_ASSERT( !m_blist && "Attempt to free mutex while others are blocking on lock." );
@ -30,9 +30,9 @@ namespace fc {
next = 0; next = 0;
fc::context* n = h; fc::context* n = h;
if( !n ) return n; if( !n ) return n;
while( n->next_blocked ) { while( n->next_blocked_mutex ) {
next = n; next = n;
n=n->next_blocked; n=n->next_blocked_mutex;
} }
return n; return n;
} }
@ -42,20 +42,20 @@ namespace fc {
while( c ) { while( c ) {
if( c == target ) { if( c == target ) {
if( p ) { if( p ) {
p->next_blocked = c->next_blocked; p->next_blocked_mutex = c->next_blocked_mutex;
return head; return head;
} }
return c->next_blocked; return c->next_blocked_mutex;
} }
p = c; p = c;
c = c->next_blocked; c = c->next_blocked_mutex;
} }
return head; return head;
} }
static void cleanup( fc::mutex& m, fc::spin_yield_lock& syl, fc::context*& bl, fc::context* cc ) { static void cleanup( fc::mutex& m, fc::spin_yield_lock& syl, fc::context*& bl, fc::context* cc ) {
{ {
fc::unique_lock<fc::spin_yield_lock> lock(syl); fc::unique_lock<fc::spin_yield_lock> lock(syl);
if( cc->next_blocked ) { if( cc->next_blocked_mutex ) {
bl = remove(bl, cc ); bl = remove(bl, cc );
return; return;
} }
@ -101,12 +101,12 @@ namespace fc {
if ( get_tail( m_blist, n ) == cc ) if ( get_tail( m_blist, n ) == cc )
return true; return true;
cc->next_blocked = m_blist; cc->next_blocked_mutex = m_blist;
m_blist = cc; m_blist = cc;
} // end lock scope } // end lock scope
try { try {
fc::thread::current().my->yield_until( abs_time, false ); fc::thread::current().my->yield_until( abs_time, false );
return( 0 == cc->next_blocked ); return( 0 == cc->next_blocked_mutex );
} catch (...) { } catch (...) {
cleanup( *this, m_blist_lock, m_blist, cc); cleanup( *this, m_blist_lock, m_blist, cc);
throw; throw;
@ -127,13 +127,13 @@ namespace fc {
if ( get_tail( m_blist, n ) == cc ) { if ( get_tail( m_blist, n ) == cc ) {
return; return;
} }
cc->next_blocked = m_blist; cc->next_blocked_mutex = m_blist;
m_blist = cc; m_blist = cc;
int cnt = 0; int cnt = 0;
auto i = m_blist; auto i = m_blist;
while( i ) { while( i ) {
i = i->next_blocked; i = i->next_blocked_mutex;
++cnt; ++cnt;
} }
wlog( "wait queue len %1%", cnt ); wlog( "wait queue len %1%", cnt );
@ -141,7 +141,7 @@ namespace fc {
try { try {
fc::thread::current().yield(false); fc::thread::current().yield(false);
BOOST_ASSERT( cc->next_blocked == 0 ); BOOST_ASSERT( cc->next_blocked_mutex == 0 );
} catch ( ... ) { } catch ( ... ) {
wlog( "lock with throw %p %s",this, fc::current_exception().diagnostic_information().c_str() ); wlog( "lock with throw %p %s",this, fc::current_exception().diagnostic_information().c_str() );
cleanup( *this, m_blist_lock, m_blist, cc); cleanup( *this, m_blist_lock, m_blist, cc);
@ -154,7 +154,7 @@ namespace fc {
{ fc::unique_lock<fc::spin_yield_lock> lock(m_blist_lock); { fc::unique_lock<fc::spin_yield_lock> lock(m_blist_lock);
get_tail(m_blist, next); get_tail(m_blist, next);
if( next ) { if( next ) {
next->next_blocked = 0; next->next_blocked_mutex = 0;
next->ctx_thread->my->unblock( next ); next->ctx_thread->my->unblock( next );
} else { } else {
m_blist = 0; m_blist = 0;