1
0
forked from Alepha/Alepha

Non-blocking states and documentation for Interlock.

This commit is contained in:
2023-12-12 23:56:17 -05:00
parent 94596d0d7d
commit c04fc7be3c
3 changed files with 61 additions and 5 deletions

View File

@ -9,10 +9,18 @@ static_assert( __cplusplus > 2020'99 );
#include <Alepha/Utility/StaticValue.h>
#include <Alepha/Utility/evaluation_helpers.h>
#include "error.h"
namespace Alepha::Hydrogen::detail::Thread_m
{
namespace
{
namespace C
{
const bool debug= false;
const bool debugWaiters= false or C::debug;
}
struct ThreadState
{
std::mutex access;
@ -105,6 +113,7 @@ namespace Alepha::Hydrogen::detail::Thread_m
struct Interlock::Impl
{
State state= Open;
bool threadBlocked= false;
ConditionVariable var;
};
@ -143,6 +152,7 @@ namespace Alepha::Hydrogen::detail::Thread_m
if( impl().state == Waiting )
{
// Nolock form will just leave the bit set.
assert( not impl().threadBlocked );
}
else if( impl().state == Synchronizing )
{
@ -157,21 +167,35 @@ namespace Alepha::Hydrogen::detail::Thread_m
{
if( impl().state == Waiting )
{
impl().threadBlocked= true;
while( impl().state == Waiting )
{
impl().var.wait( lock );
}
assert( not impl().threadBlocked );
impl().state= Open;
impl().var.notify_one();
}
else if( impl().state == Synchronizing )
{
impl().state= Opening;
impl().var.notify_one();
while( impl().state == Opening )
const bool unblock= impl().threadBlocked;
impl().threadBlocked= false;
if( unblock )
{
impl().var.wait( lock );
impl().var.notify_one();
while( impl().state == Opening )
{
impl().var.wait( lock );
}
}
else
{
if( C::debugWaiters )
{
error() << "Not waiting on other side, as nobody's there." << std::endl;
}
}
}
else{ abort(); }