forked from Alepha/Alepha
Interlock for mailbox.
This commit is contained in:
@ -87,8 +87,7 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
const std::size_t boxLimit;
|
||||
|
||||
Alepha::mutex access;
|
||||
Alepha::condition_variable ready;
|
||||
bool suspended= false;
|
||||
Alepha::Interlock interlockPoint;
|
||||
|
||||
std::size_t weight= 0;
|
||||
std::vector< Item > preparing;
|
||||
@ -104,25 +103,26 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
void
|
||||
awaken( Lock &lock )
|
||||
{
|
||||
filled.clear();
|
||||
weight= 0;
|
||||
|
||||
using std::swap;
|
||||
swap( filled, preparing );
|
||||
pos= begin( filled );
|
||||
preparing.clear();
|
||||
suspended= false;
|
||||
weight= 0;
|
||||
ready.notify_one();
|
||||
}
|
||||
|
||||
template< typename Lock >
|
||||
void
|
||||
interlock( Lock &lock )
|
||||
interlock( Alepha::unique_lock< Alepha::mutex > &lock )
|
||||
{
|
||||
if( C::debugInterlock ) error() << "Interlock entered." << std::endl;
|
||||
if( suspended ) awaken( lock );
|
||||
else
|
||||
{
|
||||
suspended= true;
|
||||
while( suspended ) ready.wait( lock );
|
||||
}
|
||||
interlockPoint.checkpoint( lock, [&]{ awaken( lock ); } );
|
||||
}
|
||||
|
||||
void
|
||||
checkpoint( Alepha::unique_lock< Alepha::mutex > &lock )
|
||||
{
|
||||
if( C::debugInterlock ) error() << "Checkpoint entered." << std::endl;
|
||||
interlockPoint.checkpoint( lock, [&]{ awaken( lock ); } );
|
||||
}
|
||||
|
||||
[[noreturn]] void
|
||||
@ -222,8 +222,7 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m
|
||||
Alepha::unique_lock lock( access );
|
||||
assertion( not finished );
|
||||
finished= true;
|
||||
if( suspended ) interlock( lock );
|
||||
else suspended= true;
|
||||
checkpoint( lock );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user