AuroraRuntime/Source/Logging/AuLogClasses.cpp
2023-03-27 23:52:41 +01:00

159 lines
3.5 KiB
C++

/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuLogClasses.cpp
Date: 2023-3-22
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "AuLogClasses.hpp"
namespace Aurora::Logging
{
static const AuUInt8 kAvailableSlots = AuLog::kLogLevelMax - AuLog::kLogLevelUsr;
static AuUInt32 gAtomicInUseCount {};
static AuUInt32 gInUseMap[kAvailableSlots / 8] {};
static AuString gStringMap[kAvailableSlots];
static AuUInt32 gIterator {};
static AuThreadPrimitives::MutexSOO gMutex;
static const auto kBitsPerWord = 8 * sizeof(*gInUseMap);
AUKN_SYM bool LogClassInUse(AuUInt8 uIndex);
static bool TryAcquire(AuUInt8 uIdx)
{
if (AuAtomicSet(&gInUseMap[uIdx / kBitsPerWord], uIdx % kBitsPerWord))
{
return false;
}
AuAtomicAdd(&gAtomicInUseCount, 1u);
return true;
}
static void Release(AuUInt8 uIdx)
{
if (AuAtomicUnset(&gInUseMap[uIdx / kBitsPerWord], uIdx % kBitsPerWord))
{
AuAtomicSub(&gAtomicInUseCount, 1u);
AU_LOCK_GUARD(gMutex);
if (!LogClassInUse(uIdx + AuLog::kLogLevelUsr))
{
gStringMap[uIdx].clear();
}
}
}
static void SetString(AuUInt8 uIdx, const AuString &str)
{
AU_LOCK_GUARD(gMutex);
gStringMap[uIdx] = str;
}
static AuResult<AuUInt8> TryAcquire()
{
auto uFirstGuess = (AuAtomicAdd(&gIterator, 1u) - 1) % kAvailableSlots;
if (!TryAcquire(uFirstGuess))
{
for (AU_ITERATE_N(i, kAvailableSlots))
{
auto uIndex = (i + uFirstGuess) % kAvailableSlots;
if (TryAcquire(uIndex))
{
gIterator = uIndex;
return AuUInt8(uIndex);
}
}
return {};
}
else
{
return AuUInt8(uFirstGuess);
}
}
AUKN_SYM void LogClassAssociateName(AuUInt8 uIndex, const AuString &str)
{
uIndex -= AuLog::kLogLevelUsr;
if (uIndex >= kAvailableSlots)
{
return;
}
SetString(uIndex, str);
}
AUKN_SYM const AuString &LogClassGetNameUnsafe(AuUInt8 uIndex)
{
uIndex -= AuLog::kLogLevelUsr;
SysAssertDbg(uIndex < kAvailableSlots);
return gStringMap[uIndex];
}
AUKN_SYM AuString LogClassGetNameSafe(AuUInt8 uIndex)
{
AU_LOCK_GUARD(gMutex);
uIndex -= AuLog::kLogLevelUsr;
if (uIndex >= kAvailableSlots)
{
return {};
}
return gStringMap[uIndex];
}
AUKN_SYM void LogClassRelease(AuUInt8 uIndex)
{
uIndex -= AuLog::kLogLevelUsr;
if (uIndex >= kAvailableSlots)
{
return;
}
Release(uIndex);
}
AUKN_SYM AuResult<AuUInt8> LogClassGetNext()
{
auto uRes = TryAcquire();
if (uRes)
{
return AuUInt8(uRes.value() + AuLog::kLogLevelUsr);
}
return {};
}
AUKN_SYM bool LogClassInUse(AuUInt8 uIndex)
{
uIndex -= AuLog::kLogLevelUsr;
if (uIndex >= kAvailableSlots)
{
return false;
}
return AuTestBit(gInUseMap[uIndex / kBitsPerWord], uIndex % kBitsPerWord);
}
AUKN_SYM AuUInt8 LogClassTotalAvailable()
{
return kAvailableSlots;
}
AUKN_SYM AuUInt8 LogClassTotalInUse()
{
return gAtomicInUseCount;
}
}