[*] Linux and UNIX QOL
This commit is contained in:
parent
9bd05a0752
commit
5cf7533eab
@ -13,8 +13,10 @@
|
|||||||
"deprecated-declarations",
|
"deprecated-declarations",
|
||||||
"c99-designator",
|
"c99-designator",
|
||||||
"reorder-init-list",
|
"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": [],
|
"defines": [],
|
||||||
"soft-depends": [
|
"soft-depends": [
|
||||||
"wxwidgets",
|
"wxwidgets",
|
||||||
|
@ -374,6 +374,8 @@ namespace Aurora
|
|||||||
AuUInt64 uAdaptiveSpinCUCnt16 : 4 { 4 };
|
AuUInt64 uAdaptiveSpinCUCnt16 : 4 { 4 };
|
||||||
AuUInt64 bPreferFutexRWLock : 1 { true };
|
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 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
|
struct DummyConfig
|
||||||
|
@ -122,7 +122,7 @@ namespace Aurora::Threading::Waitables
|
|||||||
AuUInt32 uWaitCount {};
|
AuUInt32 uWaitCount {};
|
||||||
AuUInt32 uWaiters {};
|
AuUInt32 uWaiters {};
|
||||||
|
|
||||||
while (uWaiters = AuAtomicLoad(&this->uAtomicSleeping))
|
while ((uWaiters = AuAtomicLoad(&this->uAtomicSleeping)))
|
||||||
{
|
{
|
||||||
AuAtomicAdd(&this->uAtomicState, uWaiters);
|
AuAtomicAdd(&this->uAtomicState, uWaiters);
|
||||||
WakeNOnAddress((const void *)&this->uAtomicState, uWaiters);
|
WakeNOnAddress((const void *)&this->uAtomicState, uWaiters);
|
||||||
|
@ -19,6 +19,12 @@
|
|||||||
#include "ConsoleTTY.Unix.hpp"
|
#include "ConsoleTTY.Unix.hpp"
|
||||||
#endif
|
#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"
|
#include "../ColorConvert.hpp"
|
||||||
|
|
||||||
namespace Aurora::Console::ConsoleTTY
|
namespace Aurora::Console::ConsoleTTY
|
||||||
|
@ -9,6 +9,12 @@
|
|||||||
#include "Debug.hpp"
|
#include "Debug.hpp"
|
||||||
#include "ErrorStack.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
|
namespace Aurora::Debug
|
||||||
{
|
{
|
||||||
struct ErrorStackAccessor
|
struct ErrorStackAccessor
|
||||||
|
@ -9,6 +9,12 @@
|
|||||||
#include <tomcrypt.h>
|
#include <tomcrypt.h>
|
||||||
#include "AuHashStream.hpp"
|
#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
|
namespace Aurora::Hashing
|
||||||
{
|
{
|
||||||
#define DIGEST_CHECK(n) SysAssert(n == CRYPT_OK)
|
#define DIGEST_CHECK(n) SysAssert(n == CRYPT_OK)
|
||||||
|
@ -17,6 +17,12 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.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
|
namespace Aurora::IO
|
||||||
{
|
{
|
||||||
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
|
AuUInt64 AFileHandle::DupHandle(AuUInt64 uOSHandle, bool bWriteAccess)
|
||||||
@ -44,122 +50,7 @@ namespace Aurora::IO
|
|||||||
|
|
||||||
struct UnixIOHandle final : AFileHandle
|
struct UnixIOHandle final : AFileHandle
|
||||||
{
|
{
|
||||||
bool InitFromPath(HandleCreate create) override
|
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 IsFile() override;
|
bool IsFile() override;
|
||||||
bool IsTTY() override;
|
bool IsTTY() override;
|
||||||
@ -170,6 +61,123 @@ namespace Aurora::IO
|
|||||||
AuOptionalEx<bool> optIsTTY {};
|
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 UnixIOHandle::IsFile()
|
||||||
{
|
{
|
||||||
bool bIsFile {};
|
bool bIsFile {};
|
||||||
|
@ -10,6 +10,12 @@
|
|||||||
#include "FileAdvisory.Unix.hpp"
|
#include "FileAdvisory.Unix.hpp"
|
||||||
#include <sys/file.h>
|
#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
|
namespace Aurora::IO::FS
|
||||||
{
|
{
|
||||||
bool ApplyDumbAdvisoryLock(int fd, EFileAdvisoryLockLevel level)
|
bool ApplyDumbAdvisoryLock(int fd, EFileAdvisoryLockLevel level)
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
#include <Source/Time/Time.hpp>
|
#include <Source/Time/Time.hpp>
|
||||||
#include <Source/IO/UNIX/IOSubmit.Linux.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
|
namespace Aurora::IO::Loop
|
||||||
{
|
{
|
||||||
// On Linux, Loop Queues are glorified eventfd to epoll adapters.
|
// On Linux, Loop Queues are glorified eventfd to epoll adapters.
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
#include "Networking.hpp"
|
#include "Networking.hpp"
|
||||||
#include "AuIPAddress.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
|
namespace Aurora::IO::Net
|
||||||
{
|
{
|
||||||
IPAddress::IPAddress()
|
IPAddress::IPAddress()
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
#include "Networking.hpp"
|
#include "Networking.hpp"
|
||||||
#include "AuNetEndpoint.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
|
namespace Aurora::IO::Net
|
||||||
{
|
{
|
||||||
AuUInt8 OptimizeEndpoint(NetEndpoint &ep)
|
AuUInt8 OptimizeEndpoint(NetEndpoint &ep)
|
||||||
|
@ -34,7 +34,7 @@ namespace Aurora::IO::TLS
|
|||||||
{
|
{
|
||||||
auto index = ret++;
|
auto index = ret++;
|
||||||
}
|
}
|
||||||
while (pCert = pCert->next);
|
while ((pCert = pCert->next));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ namespace Aurora::IO::TLS
|
|||||||
return AuMakeSharedThrow<View>(AuMemoryViewRead { pCert->raw.p, pCert->raw.len}, AuSharedFromThis());
|
return AuMakeSharedThrow<View>(AuMemoryViewRead { pCert->raw.p, pCert->raw.len}, AuSharedFromThis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (pCert = pCert->next);
|
while ((pCert = pCert->next));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ namespace Aurora::IO::TLS
|
|||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (pCert = pCert->next);
|
while ((pCert = pCert->next));
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
struct timespec tspec;
|
struct timespec tspec;
|
||||||
|
|
||||||
if (TryLockNoSpin())
|
if (this->TryLockNoSpin())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -57,12 +57,22 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
Time::monoabsns2ts(&tspec, uTimeout);
|
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);
|
AuAtomicAdd(&this->uSleeping_, 1u);
|
||||||
|
|
||||||
auto state = this->uState_;
|
auto state = this->uState_;
|
||||||
@ -143,9 +153,19 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
void LinuxConditionMutex::Lock()
|
void LinuxConditionMutex::Lock()
|
||||||
{
|
{
|
||||||
if (TryLockHeavy())
|
if (gRuntimeConfig.threadingConfig.bPreferLinuxPrimitivesFutexNoSpin)
|
||||||
{
|
{
|
||||||
return;
|
if (this->TryLockNoSpin())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this->TryLockHeavy())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuAtomicAdd(&this->uSleeping_, 1u);
|
AuAtomicAdd(&this->uSleeping_, 1u);
|
||||||
|
@ -14,6 +14,9 @@ namespace Aurora::Threading::Primitives
|
|||||||
#pragma pack(push)
|
#pragma pack(push)
|
||||||
#pragma pack(4)
|
#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
|
struct LinuxConditionMutex final
|
||||||
{
|
{
|
||||||
LinuxConditionMutex();
|
LinuxConditionMutex();
|
||||||
|
@ -163,7 +163,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
AuUInt32 uWaitCount {};
|
AuUInt32 uWaitCount {};
|
||||||
AuUInt32 uWaiters {};
|
AuUInt32 uWaiters {};
|
||||||
|
|
||||||
while (uWaiters = AuAtomicLoad(&this->uSleeping_))
|
while ((uWaiters = AuAtomicLoad(&this->uSleeping_)))
|
||||||
{
|
{
|
||||||
AuAtomicAdd(&this->uState_, uWaiters);
|
AuAtomicAdd(&this->uState_, uWaiters);
|
||||||
futex_wake(&this->uState_, uWaiters);
|
futex_wake(&this->uState_, uWaiters);
|
||||||
|
@ -41,11 +41,11 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxMutexSpinTryLock)
|
if (gRuntimeConfig.threadingConfig.bPreferLinuxMutexSpinTryLock)
|
||||||
{
|
{
|
||||||
return TryLockHeavy();
|
return this->TryLockHeavy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return TryLockNoSpin();
|
return this->TryLockNoSpin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,9 +72,19 @@ namespace Aurora::Threading::Primitives
|
|||||||
AuUInt64 uStart {};
|
AuUInt64 uStart {};
|
||||||
AuUInt64 uEnd {};
|
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);
|
AuAtomicAdd(&this->dwSleeping_, 1u);
|
||||||
|
@ -50,10 +50,17 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool MutexImpl::TryLock()
|
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)
|
bool MutexImpl::LockMS(AuUInt64 uTimeout)
|
||||||
|
@ -42,11 +42,11 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
if (gRuntimeConfig.threadingConfig.bPreferLinuxSemaphoreSpinTryLock)
|
if (gRuntimeConfig.threadingConfig.bPreferLinuxSemaphoreSpinTryLock)
|
||||||
{
|
{
|
||||||
return TryLockHeavy();
|
return this->TryLockHeavy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return TryLockNoSpin();
|
return this->TryLockNoSpin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +84,19 @@ namespace Aurora::Threading::Primitives
|
|||||||
Time::monoabsns2ts(&tspec, uEnd);
|
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);
|
AuAtomicAdd<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
@ -100,7 +110,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
{
|
{
|
||||||
if (Time::SteadyClockNS() >= uEnd)
|
if (Time::SteadyClockNS() >= uEnd)
|
||||||
{
|
{
|
||||||
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
AuAtomicSub<AuUInt32>(&this->dwSleeping_, 1u);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,13 +161,21 @@ namespace Aurora::Threading::Primitives
|
|||||||
bool SemaphoreImpl::LockAbsNS(AuUInt64 uTimeout)
|
bool SemaphoreImpl::LockAbsNS(AuUInt64 uTimeout)
|
||||||
{
|
{
|
||||||
AuUInt64 uEnd {};
|
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;
|
struct timespec tspec;
|
||||||
if (uTimeout != 0)
|
if (uTimeout != 0)
|
||||||
@ -235,6 +253,7 @@ namespace Aurora::Threading::Primitives
|
|||||||
void SemaphoreImpl::Unlock(AuUInt16 count)
|
void SemaphoreImpl::Unlock(AuUInt16 count)
|
||||||
{
|
{
|
||||||
AuAtomicAdd<AuUInt32>(&this->dwState_, count);
|
AuAtomicAdd<AuUInt32>(&this->dwState_, count);
|
||||||
|
|
||||||
if (AuAtomicLoad(&this->dwSleeping_))
|
if (AuAtomicLoad(&this->dwSleeping_))
|
||||||
{
|
{
|
||||||
futex_wake(&this->dwState_, count);
|
futex_wake(&this->dwState_, count);
|
||||||
|
@ -47,10 +47,17 @@ namespace Aurora::Threading::Primitives
|
|||||||
|
|
||||||
bool SemaphoreImpl::TryLock()
|
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)
|
bool SemaphoreImpl::LockMS(AuUInt64 uTimeout)
|
||||||
|
@ -36,6 +36,12 @@
|
|||||||
};
|
};
|
||||||
#endif
|
#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"
|
#include "AuSpawnThread.hpp"
|
||||||
|
|
||||||
namespace Aurora
|
namespace Aurora
|
||||||
|
Loading…
Reference in New Issue
Block a user