AuroraRuntime/Source/Threading/Primitives/AuEvent.cpp

160 lines
3.4 KiB
C++
Raw Normal View History

2021-06-27 21:25:29 +00:00
/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Event.cpp
Date: 2021-6-12
Author: Reece
***/
2021-09-30 14:57:41 +00:00
#include <Source/RuntimeInternal.hpp>
2022-11-17 07:46:07 +00:00
#include "AuEvent.hpp"
#include "SMTYield.hpp"
2021-06-27 21:25:29 +00:00
namespace Aurora::Threading::Primitives
{
2022-12-29 00:02:56 +00:00
EventImpl::EventImpl(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers) :
bTriggered_(bTriggered),
bAtomicRelease_(bAtomicRelease),
2023-08-21 16:34:24 +00:00
bPermitMultipleTriggers_(bPermitMultipleTriggers)
2022-12-29 00:02:56 +00:00
{}
2021-06-27 21:25:29 +00:00
EventImpl::~EventImpl() {}
bool EventImpl::Init()
{
return true;
}
bool EventImpl::LockMS(AuUInt64 uTimeout /*=0*/)
{
return LockNS(AuMSToNS<AuUInt64>(uTimeout));
}
bool EventImpl::LockNS(AuUInt64 uTimeout /*=0*/)
2021-06-27 21:25:29 +00:00
{
AuInt64 uStartTime {};
AuInt64 uEndTime {};
if (uTimeout)
{
uStartTime = Time::SteadyClockNS();
uEndTime = uStartTime + uTimeout;
}
AU_LOCK_GUARD(this->mutex_);
2021-06-27 21:25:29 +00:00
while (!AtomicIsEventSetLogic())
2021-06-27 21:25:29 +00:00
{
AuUInt32 uTimeoutNS {};
2021-06-27 21:25:29 +00:00
if (uTimeout)
2021-06-27 21:25:29 +00:00
{
uStartTime = Time::SteadyClockNS();
if (uStartTime >= uEndTime)
2021-06-27 21:25:29 +00:00
{
return false;
}
uTimeoutNS = uEndTime - uStartTime;
2021-06-27 21:25:29 +00:00
}
2023-08-21 16:34:24 +00:00
if (!this->condition_.WaitForSignalNsEx(&this->mutex_, uTimeoutNS))
2021-06-27 21:25:29 +00:00
{
continue;
2021-06-27 21:25:29 +00:00
}
}
return true;
}
bool EventImpl::TryLock()
{
AU_LOCK_GUARD(this->mutex_);
2021-06-27 21:25:29 +00:00
return AtomicIsEventSetLogic();
2021-06-27 21:25:29 +00:00
}
bool EventImpl::AtomicIsEventSetLogic()
2021-06-27 21:25:29 +00:00
{
if (!this->bTriggered_)
{
return false;
}
2021-06-27 21:25:29 +00:00
if (this->bAtomicRelease_)
{
this->bTriggered_ = false;
}
2021-06-27 21:25:29 +00:00
return true;
}
void EventImpl::Reset()
{
AU_LOCK_GUARD(this->mutex_);
this->bTriggered_ = false;
2021-06-27 21:25:29 +00:00
}
void EventImpl::Set()
{
{
AU_LOCK_GUARD(this->mutex_);
SysAssertExp((this->bPermitMultipleTriggers_) || (!this->bTriggered_), "Can not trigger an awake event object");
this->bTriggered_ = true;
}
if (this->bAtomicRelease_)
{
this->condition_.Signal();
}
else
{
this->condition_.Broadcast();
}
2021-06-27 21:25:29 +00:00
}
bool EventImpl::HasOSHandle(AuMach &mach)
{
mach = 0;
return false;
}
bool EventImpl::HasLockImplementation()
{
return true;
}
void EventImpl::Lock()
{
auto ok = LockNS(0);
2021-06-27 21:25:29 +00:00
SysAssert(ok);
}
void EventImpl::Unlock()
{
// Unlock is always a NOP; inverse of a lock/wait is nothing
2021-06-27 21:25:29 +00:00
}
2022-12-29 00:02:56 +00:00
AUKN_SYM IEvent *EventNew(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers)
2021-06-27 21:25:29 +00:00
{
2022-12-29 00:02:56 +00:00
auto event = _new EventImpl(bTriggered, bAtomicRelease, bPermitMultipleTriggers);
2021-06-27 21:25:29 +00:00
if (!event)
{
return nullptr;
}
if (!event->Init())
{
EventRelease(event);
return nullptr;
}
return event;
}
2022-11-17 07:46:07 +00:00
AUKN_SYM void EventRelease(IEvent *pEvent)
2021-06-27 21:25:29 +00:00
{
2022-11-17 07:46:07 +00:00
AuSafeDelete<EventImpl *>(pEvent);
2021-06-27 21:25:29 +00:00
}
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, Event, EventImpl, (bool, bTriggered), (bool, bAtomicRelease), (bool, bPermitMultipleTriggers))
2021-06-27 21:25:29 +00:00
}