Thursday, September 23, 2021

Digest for comp.lang.c++@googlegroups.com - 25 updates in 5 topics

"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 23 10:38AM -0700

On 9/20/2021 1:43 PM, Bonita Montero wrote:
> So this is the complete function but i put two empty lines around the
> code I mentioned.
 
> void dual_monitor::wait( bool b )
[...]
 
Please, try it out in a race detector? Create several programs that use
your code in high load scenarios, and see what happens in the detector.
Do we all have the time to examine your "tricky" code and test it out
for ourselves? Well, not really. I am fairly busy with some fractal work
right now. Sorry Bonita.
 
Relacy is a good one, ThreadSanitizer is nice. My friend created Relacy,
iirc, he is also working on ThreadSanitizer.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 23 08:29PM +0200

Am 23.09.2021 um 19:38 schrieb Chris M. Thomasson:
> Do we all have the time to examine your "tricky" code and test it out
> for ourselves? Well, not really. I am fairly busy with some fractal work
> right now. Sorry Bonita.
 
Not necessary. My montor works perfectly.
I've implemented something completely new: a poll_wait operation.
You simply supply a check-lambda that checks if there is valid state
and my code repeatedly tries to lock the lock and check if the con-
dition is true. The number of spins is re-calculated at each call
according to the recalculation-pattern of the glibc.
 
template<typename RetType, typename Predicate>
requires requires( Predicate pred )
{
{ pred() } -> std::same_as<std::pair<bool, RetType>>;
}
RetType monitor::wait_poll( Predicate const &pred )
{
using namespace std;
using retpair_t = pair<bool, RetType>;
uint32_t maxSpinT = (uint32_t)m_nextPollSpinCount * 2 + 10;
uint16_t maxSpin = maxSpinT <= m_maxPollSpinCount ?
(uint16_t)maxSpinT : m_maxPollSpinCount,
spinCount = 0;
bool notify = false;
uint64_t cmp = m_flagAndCounters.load( memory_order_relaxed );
for( ; !notify && spinCount < maxSpin; ++spinCount )
if( isOwned( cmp ) )
{
cpu_pause( PAUSE_ITERATIONS );
cmp = m_flagAndCounters.load( memory_order_relaxed );
continue;
}
else if( m_flagAndCounters.compare_exchange_weak( cmp, cmp |
OWNER_MASK, memory_order_acquire, memory_order_relaxed ) )
{
retpair_t ret = move( pred() );
uint64_t chg;
do
{
uint32_t visitors = getVisitors( cmp ),
waiters = getWaiters( cmp );
assert(visitors >= waiters);
chg = cmp & ~OWNER_MASK;
if( notify = visitors > waiters )
chg -= VISITOR_VALUE;
} while( !m_flagAndCounters.compare_exchange_weak( cmp, chg,
memory_order_relaxed, memory_order_relaxed ) );
if( notify )
#if defined(_MSC_VER)
while( !SetEvent( (HANDLE)m_xhEvtVisit ) );
#elif defined(__unix__)
for( m_sems( { sembuf( VISITOR_SEM, 1, 0 ) }, false ) == -1 );

No comments: