/ / Qual è l'equivalente di Windows .NET (C ++) SpinWait su Linux e Mac OS X? - c ++, linux, macos, spinwait

Qual è l'equivalente di Windows .NET (C ++) SpinWait su Linux e Mac OS X? - c ++, linux, macos, spinwait

Finestre .NET (C ++) fornisce a SpinWait per il threading Hyper-friendly occupato in attesa con le istruzioni YIELD / PAUSE. Qual è la funzione equivalente su Linux e Mac OS X? Se una chiamata di sistema non è disponibile, come può essere implementato un equivalente nello spazio utente?

Vedere Thread di Windows :: SpinWait

Vedere Lunghi cicli di attesa di attesa con tecnologia Hyper-Threading per processori Intel abilitati per una discussione sui problemi di prestazioni con attese di rotazione.

risposte:

0 per risposta № 1

Vedere https://www.codeproject.com/articles/184046/spin-lock-in-c di sameer_87

#include "SpinLock.h"
#include <iostream>

using namespace LockFree;
using namespace std;

void tSpinWait::Lock(tSpinLock &LockObj)
{
m_iterations = 0;
while(true)
{
// A thread alreading owning the lock shouldn"t be allowed to wait to acquire the lock - reentrant safe
if(LockObj.dest == GetCurrentThreadId())
break;
/*
Spinning in a loop of interlockedxxx calls can reduce the available memory bandwidth and slow
down the rest of the system. Interlocked calls are expensive in their use of the system memory
bus. It is better to see if the "dest" value is what it is expected and then retry interlockedxx.
*/
if(InterlockedCompareExchange(&LockObj.dest, LockObj.exchange, LockObj.compare) == 0)
{
//assign CurrentThreadId to dest to make it re-entrant safe
LockObj.dest = GetCurrentThreadId();
// lock acquired
break;
}

// spin wait to acquire
while(LockObj.dest != LockObj.compare)
{
if(HasThreasholdReached())
{
if(m_iterations + YIELD_ITERATION >= MAX_SLEEP_ITERATION)
Sleep(0);

if(m_iterations >= YIELD_ITERATION && m_iterations < MAX_SLEEP_ITERATION)
{
m_iterations = 0;
SwitchToThread();
}
}
// Yield processor on multi-processor but if on single processor then give other thread the CPU
m_iterations++;
if(Helper::GetNumberOfProcessors() > 1) { YieldProcessor(/*no op*/); }
else { SwitchToThread(); }
}
}
}
//

void tSpinWait::Unlock(tSpinLock &LockObj)
{
if(LockObj.dest != GetCurrentThreadId())
throw std::runtime_error("Unexpected thread-id in release");
// lock released
InterlockedCompareExchange(&LockObj.dest, LockObj.compare, GetCurrentThreadId());
}