2023-03-23 00:01:49 +00:00
|
|
|
/***
|
|
|
|
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 {};
|
2023-12-26 21:01:29 +00:00
|
|
|
static AuMutex gMutex;
|
2023-03-23 00:01:49 +00:00
|
|
|
|
2023-03-27 05:21:42 +00:00
|
|
|
static const auto kBitsPerWord = 8 * sizeof(*gInUseMap);
|
|
|
|
|
2023-03-23 00:01:49 +00:00
|
|
|
AUKN_SYM bool LogClassInUse(AuUInt8 uIndex);
|
|
|
|
|
|
|
|
static bool TryAcquire(AuUInt8 uIdx)
|
|
|
|
{
|
2023-03-27 05:21:42 +00:00
|
|
|
if (AuAtomicSet(&gInUseMap[uIdx / kBitsPerWord], uIdx % kBitsPerWord))
|
2023-03-23 00:01:49 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
AuAtomicAdd(&gAtomicInUseCount, 1u);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Release(AuUInt8 uIdx)
|
|
|
|
{
|
2023-03-27 05:21:42 +00:00
|
|
|
if (AuAtomicUnset(&gInUseMap[uIdx / kBitsPerWord], uIdx % kBitsPerWord))
|
2023-03-23 00:01:49 +00:00
|
|
|
{
|
|
|
|
AuAtomicSub(&gAtomicInUseCount, 1u);
|
|
|
|
|
|
|
|
AU_LOCK_GUARD(gMutex);
|
|
|
|
|
|
|
|
if (!LogClassInUse(uIdx + AuLog::kLogLevelUsr))
|
|
|
|
{
|
|
|
|
gStringMap[uIdx].clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-26 21:01:29 +00:00
|
|
|
static bool SetString(AuUInt8 uIdx, const AuString &str)
|
2023-03-23 00:01:49 +00:00
|
|
|
{
|
|
|
|
AU_LOCK_GUARD(gMutex);
|
2023-12-26 21:01:29 +00:00
|
|
|
return bool(AuTryConstruct(gStringMap[uIdx], str));
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2023-03-27 05:21:42 +00:00
|
|
|
return AuUInt8(uIndex);
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return AuUInt8(uFirstGuess);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-26 21:01:29 +00:00
|
|
|
AUKN_SYM bool LogClassAssociateName(AuUInt8 uIndex, const AuString &str)
|
2023-03-23 00:01:49 +00:00
|
|
|
{
|
2023-03-27 05:21:42 +00:00
|
|
|
uIndex -= AuLog::kLogLevelUsr;
|
|
|
|
|
|
|
|
if (uIndex >= kAvailableSlots)
|
|
|
|
{
|
2023-12-26 21:01:29 +00:00
|
|
|
return false;
|
2023-03-27 05:21:42 +00:00
|
|
|
}
|
|
|
|
|
2023-12-26 21:01:29 +00:00
|
|
|
return SetString(uIndex, str);
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM const AuString &LogClassGetNameUnsafe(AuUInt8 uIndex)
|
|
|
|
{
|
2023-03-27 05:21:42 +00:00
|
|
|
uIndex -= AuLog::kLogLevelUsr;
|
|
|
|
|
2023-03-27 22:52:41 +00:00
|
|
|
SysAssertDbg(uIndex < kAvailableSlots);
|
2023-03-27 05:21:42 +00:00
|
|
|
|
|
|
|
return gStringMap[uIndex];
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM AuString LogClassGetNameSafe(AuUInt8 uIndex)
|
|
|
|
{
|
|
|
|
AU_LOCK_GUARD(gMutex);
|
2023-03-27 05:21:42 +00:00
|
|
|
|
|
|
|
uIndex -= AuLog::kLogLevelUsr;
|
|
|
|
|
|
|
|
if (uIndex >= kAvailableSlots)
|
|
|
|
{
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
return gStringMap[uIndex];
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM void LogClassRelease(AuUInt8 uIndex)
|
|
|
|
{
|
2023-03-27 05:21:42 +00:00
|
|
|
uIndex -= AuLog::kLogLevelUsr;
|
|
|
|
|
|
|
|
if (uIndex >= kAvailableSlots)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Release(uIndex);
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2023-03-27 05:21:42 +00:00
|
|
|
|
|
|
|
if (uIndex >= kAvailableSlots)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return AuTestBit(gInUseMap[uIndex / kBitsPerWord], uIndex % kBitsPerWord);
|
2023-03-23 00:01:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM AuUInt8 LogClassTotalAvailable()
|
|
|
|
{
|
|
|
|
return kAvailableSlots;
|
|
|
|
}
|
|
|
|
|
|
|
|
AUKN_SYM AuUInt8 LogClassTotalInUse()
|
|
|
|
{
|
|
|
|
return gAtomicInUseCount;
|
|
|
|
}
|
|
|
|
}
|