#include "barrier.h"
#include "condition.h"
#include "regression.h"
#include "thread.h"
#if defined (__WIN32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
namespace embree
{
struct BarrierSysImplementation
{
__forceinline BarrierSysImplementation (size_t N)
: i(0), enterCount(0), exitCount(0), barrierSize(0)
{
events[0] = CreateEvent(nullptr, TRUE, FALSE, nullptr);
events[1] = CreateEvent(nullptr, TRUE, FALSE, nullptr);
init(N);
}
__forceinline ~BarrierSysImplementation ()
{
CloseHandle(events[0]);
CloseHandle(events[1]);
}
__forceinline void init(size_t N)
{
barrierSize = N;
enterCount.store(N);
exitCount.store(N);
}
__forceinline void wait()
{
size_t i0 = i;
size_t cnt0 = enterCount--;
if (cnt0 > 1)
{
if (WaitForSingleObject(events[i0], INFINITE) != WAIT_OBJECT_0)
THROW_RUNTIME_ERROR("WaitForSingleObjects failed");
}
else
{
i = 1-i;
enterCount.store(barrierSize);
if (SetEvent(events[i0]) == 0)
THROW_RUNTIME_ERROR("SetEvent failed");
}
size_t cnt1 = exitCount--;
if (cnt1 == 1)
{
exitCount.store(barrierSize);
if (ResetEvent(events[i0]) == 0)
THROW_RUNTIME_ERROR("ResetEvent failed");
}
}
public:
HANDLE events[2];
atomic<size_t> i;
atomic<size_t> enterCount;
atomic<size_t> exitCount;
size_t barrierSize;
};
}
#else
namespace embree
{
struct BarrierSysImplementation
{ … };
}
#endif
namespace embree
{
BarrierSys::BarrierSys (size_t N) { … }
BarrierSys::~BarrierSys () { … }
void BarrierSys::init(size_t count) { … }
void BarrierSys::wait() { … }
LinearBarrierActive::LinearBarrierActive (size_t N)
: … { … }
LinearBarrierActive::~LinearBarrierActive()
{ … }
void LinearBarrierActive::init(size_t N)
{ … }
void LinearBarrierActive::wait (const size_t threadIndex)
{ … }
struct barrier_sys_regression_test : public RegressionTest
{ … };
barrier_sys_regression_test barrier_sys_regression_test;
}