[*] Linux and UNIX QOL
This commit is contained in:
parent
9bd05a0752
commit
5cf7533eab
@ -13,8 +13,10 @@
|
||||
"deprecated-declarations",
|
||||
"c99-designator",
|
||||
"reorder-init-list",
|
||||
"ignored-attributes"
|
||||
"ignored-attributes",
|
||||
"missing-declarations"
|
||||
],
|
||||
"notesClang": "missing-declarations was added to slience a macro hack. dw about it. it being '(struct {};)'. all the other options are my desire for c++ to be less stupid of a language, we all know whats unofficially supported and commonly suppressed in large projects.",
|
||||
"defines": [],
|
||||
"soft-depends": [
|
||||
"wxwidgets",
|
||||
|
@ -374,6 +374,8 @@ namespace Aurora
|
||||
AuUInt64 uAdaptiveSpinCUCnt16 : 4 { 4 };
|
||||
AuUInt64 bPreferFutexRWLock : 1 { true };
|
||||
AuUInt64 bWinXpThrough7BlazeOptimizerPower : 7 { 12 }; // dont worry about it. we dont care about old portables. lets try to make older win32 targets tweak the scheduling in our favor a bit.
|
||||
AuUInt64 bPreferLinuxPrimitivesFutexNoSpin : 1 { false };
|
||||
AuUInt64 bPreferUnixPrimitivesNoSpin : 1 { false };
|
||||
};
|
||||
|
||||
struct DummyConfig
|
||||
|
@ -122,7 +122,7 @@ namespace Aurora::Threading::Waitables
|
||||
AuUInt32 uWaitCount {};
|
||||
AuUInt32 uWaiters {};
|
||||
|
||||
while (uWaiters = AuAtomicLoad(&this->uAtomicSleeping))
|
||||
while ((uWaiters = AuAtomicLoad(&this->uAtomicSleeping)))
|
||||
{
|
||||
AuAtomicAdd(&this->uAtomicState, uWaiters);
|
||||
WakeNOnAddress((const void *)&this->uAtomicState, uWaiters);
|
||||
|
@ -19,6 +19,12 @@
|
||||
#include "ConsoleTTY.Unix.hpp"
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
#include "../ColorConvert.hpp"
|
||||
|
||||
namespace Aurora::Console::ConsoleTTY
|
||||
|
@ -9,6 +9,12 @@
|
||||
#include "Debug.hpp"
|
||||
#include "ErrorStack.hpp"
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'AuSPtr<Aurora::Debug::ThreadMessage>' (aka 'ExSharedPtr<Aurora::Debug::ThreadMessage, std::shared_ptr<ThreadMessage>>') and 'AuSPtr<Aurora::Debug::ThreadMessage>' (aka 'ExSharedPtr<Aurora::Debug::ThreadMessage, std::shared_ptr<ThreadMessage>>')) to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
|
||||
#pragma clang diagnostic ignored "-Wambiguous-reversed-operator"
|
||||
// Yea, I couldn't give less of a nanoshit what some C++20 spec says. Even llvm/clang doesn't care to language police it into a fatal unimplemented compiler condition. So, idc.
|
||||
#endif
|
||||
|
||||
namespace Aurora::Debug
|
||||
{
|
||||
struct ErrorStackAccessor
|
||||
|
@ -9,6 +9,12 @@
|
||||
#include <tomcrypt.h>
|
||||
#include "AuHashStream.hpp"
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
namespace Aurora::Hashing
|
||||
{
|
||||
#define DIGEST_CHECK(n) SysAssert(n == CRYPT_OK)
|
||||
|
@ -17,6 +17,12 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO
|
||||
{
|
||||
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
|
||||
@ -44,122 +50,7 @@ namespace Aurora::IO
|
||||
|
||||
struct UnixIOHandle final : AFileHandle
|
||||
{
|
||||
bool InitFromPath(HandleCreate create) override
|
||||
{
|
||||
int iFileDescriptor { -1 };
|
||||
|
||||
if (create.path.empty())
|
||||
{
|
||||
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::EFileOpenModeIsValid(create.eMode))
|
||||
{
|
||||
SysPushErrorParam("Invalid open mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
|
||||
{
|
||||
SysPushErrorParam("Invalid lock mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pathex = FS::NormalizePathRet(create.path);
|
||||
if (pathex.empty())
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (create.bAsyncHandle ||
|
||||
create.bDirectIOMode)
|
||||
{
|
||||
this->bDirectIO = true;
|
||||
}
|
||||
|
||||
switch (create.eMode)
|
||||
{
|
||||
case FS::EFileOpenMode::eRead:
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eReadWrite:
|
||||
case FS::EFileOpenMode::eWrite:
|
||||
{
|
||||
if (create.bAlwaysCreateDirTree)
|
||||
{
|
||||
FS::CreateDirectories(pathex, true);
|
||||
}
|
||||
|
||||
if (create.bFailIfNonEmptyFile)
|
||||
{
|
||||
if (AuFS::FileExists(pathex.c_str()))
|
||||
{
|
||||
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
iFileDescriptor = ::open(pathex.c_str(),
|
||||
(create.eMode == FS::EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC | (this->bDirectIO ? O_DIRECT : 0),
|
||||
0664);
|
||||
|
||||
if (iFileDescriptor < 0)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::ApplyDumbAdvisoryLock(iFileDescriptor, create.eAdvisoryLevel))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
|
||||
::close(iFileDescriptor);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (create.bFailIfNonEmptyFile)
|
||||
{
|
||||
if (FS::PosixGetLength(iFileDescriptor))
|
||||
{
|
||||
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||
::close(iFileDescriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (create.eMode)
|
||||
{
|
||||
case FS::EFileOpenMode::eRead:
|
||||
{
|
||||
this->uOSReadHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eReadWrite:
|
||||
{
|
||||
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
|
||||
this->uOSReadHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eWrite:
|
||||
{
|
||||
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this->bIsAsync = create.bAsyncHandle;
|
||||
|
||||
this->path = create.path;
|
||||
|
||||
return this->IsValid();
|
||||
}
|
||||
bool InitFromPath(HandleCreate create) override;
|
||||
|
||||
bool IsFile() override;
|
||||
bool IsTTY() override;
|
||||
@ -170,6 +61,123 @@ namespace Aurora::IO
|
||||
AuOptionalEx<bool> optIsTTY {};
|
||||
};
|
||||
|
||||
bool UnixIOHandle::InitFromPath(HandleCreate create)
|
||||
{
|
||||
int iFileDescriptor { -1 };
|
||||
|
||||
if (create.path.empty())
|
||||
{
|
||||
SysPushErrorArg("Cannot open an IO handle to the provided empty path");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::EFileOpenModeIsValid(create.eMode))
|
||||
{
|
||||
SysPushErrorParam("Invalid open mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::EFileAdvisoryLockLevelIsValid(create.eAdvisoryLevel))
|
||||
{
|
||||
SysPushErrorParam("Invalid lock mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto pathex = FS::NormalizePathRet(create.path);
|
||||
if (pathex.empty())
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (create.bAsyncHandle ||
|
||||
create.bDirectIOMode)
|
||||
{
|
||||
this->bDirectIO = true;
|
||||
}
|
||||
|
||||
switch (create.eMode)
|
||||
{
|
||||
case FS::EFileOpenMode::eRead:
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eReadWrite:
|
||||
case FS::EFileOpenMode::eWrite:
|
||||
{
|
||||
if (create.bAlwaysCreateDirTree)
|
||||
{
|
||||
FS::CreateDirectories(pathex, true);
|
||||
}
|
||||
|
||||
if (create.bFailIfNonEmptyFile)
|
||||
{
|
||||
if (AuFS::FileExists(pathex.c_str()))
|
||||
{
|
||||
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
iFileDescriptor = ::open(pathex.c_str(),
|
||||
(create.eMode == FS::EFileOpenMode::eRead ? O_RDONLY : (O_RDWR | O_CREAT)) | O_CLOEXEC | (this->bDirectIO ? O_DIRECT : 0),
|
||||
0664);
|
||||
|
||||
if (iFileDescriptor < 0)
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {} ({}) {}", path, pathex, errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FS::ApplyDumbAdvisoryLock(iFileDescriptor, create.eAdvisoryLevel))
|
||||
{
|
||||
SysPushErrorIO("Couldn't open file: {}. File node (not section) is locked.", path);
|
||||
::close(iFileDescriptor);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (create.bFailIfNonEmptyFile)
|
||||
{
|
||||
if (FS::PosixGetLength(iFileDescriptor))
|
||||
{
|
||||
SysPushErrorResourceExists("File {} already exists", create.path);
|
||||
::close(iFileDescriptor);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (create.eMode)
|
||||
{
|
||||
case FS::EFileOpenMode::eRead:
|
||||
{
|
||||
this->uOSReadHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eReadWrite:
|
||||
{
|
||||
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
|
||||
this->uOSReadHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
case FS::EFileOpenMode::eWrite:
|
||||
{
|
||||
this->uOSWriteHandle = AuUInt64(iFileDescriptor);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
this->bIsAsync = create.bAsyncHandle;
|
||||
|
||||
this->path = create.path;
|
||||
|
||||
return this->IsValid();
|
||||
}
|
||||
|
||||
bool UnixIOHandle::IsFile()
|
||||
{
|
||||
bool bIsFile {};
|
||||
|
@ -10,6 +10,12 @@
|
||||
#include "FileAdvisory.Unix.hpp"
|
||||
#include <sys/file.h>
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO::FS
|
||||
{
|
||||
bool ApplyDumbAdvisoryLock(int fd, EFileAdvisoryLockLevel level)
|
||||
|
@ -13,6 +13,12 @@
|
||||
#include <Source/Time/Time.hpp>
|
||||
#include <Source/IO/UNIX/IOSubmit.Linux.hpp>
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: ISO C++20 considers use of overloaded operator '!=' (with operand types 'AuSPtr<Aurora::IO::Loop::ILoopSource>' (aka 'ExSharedPtr<Aurora::IO::Loop::ILoopSource, std::shared_ptr<ILoopSource>>') and 'typename tuple_element<0UL, tuple<ExSharedPtr<ILoopSource, shared_ptr<ILoopSource>>, ExSharedPtr<ILoopSourceSubscriber, shared_ptr<ILoopSourceSubscriber>>, ExSharedPtr<ILoopSourceSubscriberEx, shared_ptr<ILoopSourceSubscriberEx>>>>::type' (aka '__type_pack_element<0UL, Aurora::Memory::ExSharedPtr<Aurora::IO::Loop::ILoopSource, std::shared_ptr<Aurora::IO::Loop::ILoopSource>>, Aurora::Memory::ExSharedPtr<Aurora::IO::Loop::ILoopSourceSubscriber, std::shared_ptr<Aurora::IO::Loop::ILoopSourceSubscriber>>, Aurora::Memory::ExSharedPtr<Aurora::IO::Loop::ILoopSourceSubscriberEx, std::shared_ptr<Aurora::IO::Loop::ILoopSourceSubscriberEx>>>')) to be ambiguous despite there being a unique best viable function with non-reversed arguments [-Wambiguous-reversed-operator]
|
||||
#pragma clang diagnostic ignored "-Wambiguous-reversed-operator"
|
||||
// Yea, I couldn't give less of a nanoshit what some C++20 spec says. Even llvm/clang doesn't care to language police it into a fatal unimplemented compiler condition. So, idc.
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO::Loop
|
||||
{
|
||||
// On Linux, Loop Queues are glorified eventfd to epoll adapters.
|
||||
|
@ -8,6 +8,12 @@
|
||||
#include "Networking.hpp"
|
||||
#include "AuIPAddress.hpp"
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO::Net
|
||||
{
|
||||
IPAddress::IPAddress()
|
||||
|
@ -8,6 +8,12 @@
|
||||
#include "Networking.hpp"
|
||||
#include "AuNetEndpoint.hpp"
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
namespace Aurora::IO::Net
|
||||
{
|
||||
AuUInt8 OptimizeEndpoint(NetEndpoint &ep)
|
||||
|
@ -34,7 +34,7 @@ namespace Aurora::IO::TLS
|
||||
{
|
||||
auto index = ret++;
|
||||
}
|
||||
while (pCert = pCert->next);
|
||||
while ((pCert = pCert->next));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -67,7 +67,7 @@ namespace Aurora::IO::TLS
|
||||
return AuMakeSharedThrow<View>(AuMemoryViewRead { pCert->raw.p, pCert->raw.len}, AuSharedFromThis());
|
||||
}
|
||||
}
|
||||
while (pCert = pCert->next);
|
||||
while ((pCert = pCert->next));
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -92,7 +92,7 @@ namespace Aurora::IO::TLS
|
||||
return cert;
|
||||
}
|
||||
}
|
||||
while (pCert = pCert->next);
|
||||
while ((pCert = pCert->next));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
struct timespec tspec;
|
||||
|
||||
if (TryLockNoSpin())
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -57,12 +57,22 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
Time::monoabsns2ts(&tspec, uTimeout);
|
||||
}
|
||||
|
||||
if (TryLockHeavy())
|
||||
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
|
||||
{
|
||||
return true;
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AuAtomicAdd(&this->uSleeping_, 1u);
|
||||
|
||||
auto state = this->uState_;
|
||||
@ -143,9 +153,19 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
void LinuxConditionMutex::Lock()
|
||||
{
|
||||
if (TryLockHeavy())
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
|
||||
{
|
||||
return;
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AuAtomicAdd(&this->uSleeping_, 1u);
|
||||
|
@ -14,6 +14,9 @@ namespace Aurora::Threading::Primitives
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
// We're being recycled as a tiny mutex for AuCriticalSection
|
||||
// The thread cookie of sizeof(void *) under linux/x86_64 is too large
|
||||
// We can be in parity with other platforms by switching to whichever mutex type is most convenient
|
||||
struct LinuxConditionMutex final
|
||||
{
|
||||
LinuxConditionMutex();
|
||||
|
@ -163,7 +163,7 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt32 uWaitCount {};
|
||||
AuUInt32 uWaiters {};
|
||||
|
||||
while (uWaiters = AuAtomicLoad(&this->uSleeping_))
|
||||
while ((uWaiters = AuAtomicLoad(&this->uSleeping_)))
|
||||
{
|
||||
AuAtomicAdd(&this->uState_, uWaiters);
|
||||
futex_wake(&this->uState_, uWaiters);
|
||||
|
@ -41,11 +41,11 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxMutexSpinTryLock)
|
||||
{
|
||||
return TryLockHeavy();
|
||||
return this->TryLockHeavy();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
return this->TryLockNoSpin();
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,9 +72,19 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt64 uStart {};
|
||||
AuUInt64 uEnd {};
|
||||
|
||||
if (this->TryLockHeavy())
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
|
||||
{
|
||||
return true;
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AuAtomicAdd(&this->dwSleeping_, 1u);
|
||||
|
@ -50,10 +50,17 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool MutexImpl::TryLock()
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
if (gRuntimeConfig.threadingConfig.bPreferUnixPrimitivesNoSpin)
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
});
|
||||
return this->TryLockNoSpin();
|
||||
}
|
||||
else
|
||||
{
|
||||
return return DoTryIf([=]()
|
||||
{
|
||||
return this->TryLockNoSpin();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool MutexImpl::LockMS(AuUInt64 uTimeout)
|
||||
|
@ -42,11 +42,11 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxSemaphoreSpinTryLock)
|
||||
{
|
||||
return TryLockHeavy();
|
||||
return this->TryLockHeavy();
|
||||
}
|
||||
else
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
return this->TryLockNoSpin();
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,9 +84,19 @@ namespace Aurora::Threading::Primitives
|
||||
Time::monoabsns2ts(&tspec, uEnd);
|
||||
}
|
||||
|
||||
if (this->TryLockHeavy())
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
|
||||
{
|
||||
return true;
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
||||
@ -100,7 +110,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
if (Time::SteadyClockNS() >= uEnd)
|
||||
{
|
||||
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -151,13 +161,21 @@ namespace Aurora::Threading::Primitives
|
||||
bool SemaphoreImpl::LockAbsNS(AuUInt64 uTimeout)
|
||||
{
|
||||
AuUInt64 uEnd {};
|
||||
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
|
||||
{
|
||||
if (this->TryLockNoSpin())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->TryLockHeavy())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
struct timespec tspec;
|
||||
if (uTimeout != 0)
|
||||
@ -235,6 +253,7 @@ namespace Aurora::Threading::Primitives
|
||||
void SemaphoreImpl::Unlock(AuUInt16 count)
|
||||
{
|
||||
AuAtomicAdd<AuUInt32>(&this->dwState_, count);
|
||||
|
||||
if (AuAtomicLoad(&this->dwSleeping_))
|
||||
{
|
||||
futex_wake(&this->dwState_, count);
|
||||
|
@ -47,10 +47,17 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool SemaphoreImpl::TryLock()
|
||||
{
|
||||
return DoTryIf([=]()
|
||||
if (gRuntimeConfig.threadingConfig.bPreferUnixPrimitivesNoSpin)
|
||||
{
|
||||
return TryLockNoSpin();
|
||||
});
|
||||
return this->TryLockNoSpin();
|
||||
}
|
||||
else
|
||||
{
|
||||
return return DoTryIf([=]()
|
||||
{
|
||||
return this->TryLockNoSpin();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
bool SemaphoreImpl::LockMS(AuUInt64 uTimeout)
|
||||
|
@ -36,6 +36,12 @@
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
// warning: enumeration values 'kEnumCount' and 'kEnumInvalid' not handled in switch [-Wswitch
|
||||
#pragma clang diagnostic ignored "-Wswitch"
|
||||
// Yea, I don't give a shit.
|
||||
#endif
|
||||
|
||||
#include "AuSpawnThread.hpp"
|
||||
|
||||
namespace Aurora
|
||||
|
Loading…
Reference in New Issue
Block a user