[+] Added first two examples and renamed sln

This commit is contained in:
Reece Wilson 2022-02-20 01:31:17 +00:00
parent 560912fe63
commit 52338d1e3f
4 changed files with 356 additions and 4 deletions

3
.gitmodules vendored
View File

@ -67,6 +67,3 @@
[submodule "Tests/googletest"]
path = Tests/googletest
url = https://github.com/google/googletest
[submodule "Vendor/Runtime"]
path = Vendor/Runtime
url = https://git.reece.sx/AuroraSupport/AuroraRuntime

View File

@ -1,6 +1,6 @@
require("aurora")
auStartSolution({name = "Runtime Project"})
auStartSolution({name = "Hello Aurora"})
local kNamespaceStlEx = "Vendor - 1 - STLEX"
local kNamespaceCompression = "Vendor - 2 - COMPRESSION"

View File

@ -0,0 +1,109 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Main.cpp
Date: 2022-2-18
Author: Reece
***/
#include <AuroraRuntime.hpp>
static void PrintSoftwareSpecs()
{
const auto &platformInfo = AuSwInfo::GetPlatformInfo();
AuLogInfo("OS: {} (kernel: {})", platformInfo.kUserlandBrand->c_str(), platformInfo.kKernelString->c_str());
AuLogInfo("Kernel Version: {}.{}.{}", platformInfo.uKernelMajor, platformInfo.uKernelMinor, platformInfo.uKernelPatch);
AuLogInfo("Userland Version: {}.{}.{}", platformInfo.uUserlandMajor, platformInfo.uUserlandMinor, platformInfo.uUserlandPatch);
AuLogInfo("OS Build String: {}", platformInfo.kBuildString->c_str());
AuLogInfo("IsEnterprise? {}", platformInfo.bIsEnterprise);
AuLogInfo("IsServer? {}", platformInfo.bIsServer);
AuLogInfo("");
}
static void PrintCPUSpecs()
{
const auto &cpuInfo = AuHwInfo::GetCPUInfo();
AuLogInfo("CpuInfo {} / {} / {} [sockets/cores/threads] ", cpuInfo.uSocket, cpuInfo.uCores, cpuInfo.uThreads);
AuLogInfo("Package: {} by {} (arch: {})", cpuInfo.cpuId.brand, cpuInfo.cpuId.vendor, AuBuild::EArchitectureToString(cpuInfo.cpuArch));
AuLogInfo("Complete CPUs: {} ", cpuInfo.serverTopology.size());
AuLogInfo("E-Cores: {} ", cpuInfo.maskECores.ToString());
for (const auto &cpu : cpuInfo.serverTopology)
{
AuLogInfo("Core: {}", cpu.ToString());
}
AuLogInfo("CPUID: \n{}", cpuInfo.cpuId.ToString());
AuLogInfo("");
}
static void PrintRamSpecs()
{
auto val = AuHwInfo::GetMemStatProcessBlamed().value_or(AuHwInfo::RamStat {});
AuLogInfo("RamInfo Private Allocation: {}/{}", val.used, val.available);
val = AuHwInfo::GetMemStatProcess().value_or(AuHwInfo::RamStat {});
AuLogInfo("RamInfo Address Space: {}/{}", val.used, val.available);
val = AuHwInfo::GetMemStatSystem().value_or(AuHwInfo::RamStat {});
AuLogInfo("RamInfo System Commit Charge: {}/{}", val.used, val.available);
AuLogInfo(" if high compared to phys, expand page file");
val = AuHwInfo::GetMemStatStartup().value_or(AuHwInfo::RamStat {});
AuLogInfo("RamInfo Startup Commit: {}/{}", val.used, val.available);
val = AuHwInfo::GetMemStatPhysical().value_or(AuHwInfo::RamStat {});
AuLogInfo("RamInfo Physical RAM: {}/{}", val.used, val.available);
AuLogInfo("");
}
static void DumpAddressSpace()
{
auto cur = AuProcess::GetSection(reinterpret_cast<AuUInt>(DumpAddressSpace));
if (!cur.has_value())
{
return;
}
auto section = cur.value_or(AuProcess::Section {});
auto temp = section.moduleMeta.lock();
AuLogInfo("Hello from:");
AuLogInfo(" Module: {} ({}) @ 0x{:x} (0x{:x})", temp->moduleMeta->moduleName, temp->moduleMeta->modulePath, temp->moduleMeta->moduleBase, temp->moduleMeta->origVa);
AuLogInfo(" Section: {} 0x{:x} (0x{:x}), file offset: 0x{:x}, size 0x{:x}. nx: {} write: {} read: {}", section.name, section.baseVa, section.origVa, section.fsOff, section.size, section.pt.NX, section.pt.writable, section.pt.readable);
AuLogInfo("");
AuSPtr<AuProcess::PublicModule> moduleMeta;
for (const auto &mod : AuProcess::DumpExecutableAll())
{
auto temp = mod.moduleMeta.lock();
if (temp != moduleMeta)
{
moduleMeta = temp;
AuLogInfo("Module: {} ({}) @ 0x{:x} (0x{:x})", temp->moduleMeta->moduleName, temp->moduleMeta->modulePath, temp->moduleMeta->moduleBase, temp->moduleMeta->origVa);
}
else if (!temp)
{
AuLogInfo("Module unknown");
}
AuLogInfo(" Section: {} 0x{:x} (0x{:x}), file offset: 0x{:x}, size 0x{:x}. nx: {} write: {} read: {}", mod.name, mod.baseVa, mod.origVa, mod.fsOff, mod.size, mod.pt.NX, mod.pt.writable, mod.pt.readable);
}
AuLogInfo("");
}
void RunTests()
{
Aurora::RuntimeStartInfo info;
info.console.fio.enableLogging = false;
info.console.forceToolKitWindow = false;
Aurora::RuntimeStart(info);
PrintSoftwareSpecs();
PrintRamSpecs();
PrintCPUSpecs();
DumpAddressSpace();
}

View File

@ -0,0 +1,246 @@
/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Main.cpp
Date: 2022-2-18
Author: Reece
***/
#include <AuroraRuntime.hpp>
#include <gtest/gtest.h>
/**
* @brief Single threaded mutex lock test (rentrant mutexes are called critical sections in this subsystem)
*/
TEST(Mutex, LockTest)
{
auto mutex = AuThreadPrimitives::MutexUnique();
mutex->Lock();
ASSERT_FALSE(mutex->TryLock());
mutex->Unlock();
ASSERT_TRUE(mutex->TryLock());
ASSERT_FALSE(mutex->Lock(10));
mutex->Unlock();
ASSERT_TRUE(mutex->TryLock());
mutex->Unlock();
}
/**
* @brief Spinlock lock test
*/
TEST(Spinlock, LockTest)
{
AuThreadPrimitives::SpinLock mutex;
mutex.Lock();
ASSERT_FALSE(mutex.TryLock());
mutex.Unlock();
ASSERT_TRUE(mutex.TryLock());
ASSERT_FALSE(mutex.Lock(10));
mutex.Unlock();
ASSERT_TRUE(mutex.TryLock());
mutex.Unlock();
}
/**
* @brief Single threaded semaphore lock test
*/
TEST(Semaphore, LockTest)
{
auto semaphore = AuThreadPrimitives::SemaphoreUnique(0);
ASSERT_FALSE(semaphore->TryLock());
semaphore->Unlock(1);
ASSERT_TRUE(semaphore->TryLock());
ASSERT_FALSE(semaphore->Lock(10));
semaphore->Unlock(2);
ASSERT_TRUE(semaphore->TryLock());
ASSERT_TRUE(semaphore->TryLock());
}
/**
* @brief More of a compile check for the RAII stack/object lock guards
* Also validates TRY_[...]_NAMED returns false on failure
*/
TEST(LockGuard, Test)
{
auto mutex = AuThreadPrimitives::MutexUnique();
AU_LOCK_GUARD(mutex);
AuThreadPrimitives::SpinLock spinlock;
AU_LOCK_GUARD(spinlock);
AuThreadPrimitives::SpinLock spinlock2;
AU_LOCK_GUARD(&spinlock2);
AU_TRY_LOCK_GUARD_NAMED(spinlock, testlock);
ASSERT_TRUE(!testlock.Locked());
}
/**
* @brief Test write-entrant read-routines
*/
TEST(RWLocks, GodMode)
{
auto rwlock = AuThreadPrimitives::RWLockUnique();
// Test exclusive ownership
ASSERT_TRUE(rwlock->AsReadable()->TryLock());
ASSERT_FALSE(rwlock->AsWritable()->TryLock());
rwlock->AsReadable()->Unlock();
// Enter exclusive mode
ASSERT_TRUE(rwlock->AsWritable()->TryLock());
// Enter read routines
ASSERT_TRUE(rwlock->AsReadable()->TryLock());
ASSERT_TRUE(rwlock->AsReadable()->TryLock());
ASSERT_TRUE(rwlock->AsReadable()->TryLock());
rwlock->AsReadable()->Unlock(); // NOP
rwlock->AsReadable()->Unlock(); // NOP
rwlock->AsReadable()->Unlock(); // NOP
rwlock->AsWritable()->Unlock();
// Confirm release
ASSERT_TRUE(rwlock->AsReadable()->TryLock());
rwlock->AsReadable()->Unlock();
}
/**
* @brief Allocates a new thread, dispatches the ep, destroys the thread, and waits a reasonable amount of time
* to rejoin until the the context is terminated by the watchdog. In this instance, the thread exists in time.
*/
TEST(Thread, Spawn)
{
auto helloThread = []
{
AuLogDbg("Hello from worker thread");
};
auto thread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
AuMakeShared<AuThreads::IThreadVectorsFunctional>(
AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(helloThread)),
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
"SpawnTest"
));
// Fail on resource allocation failure
SysAssert(thread);
ASSERT_TRUE(thread->Run());
}
/**
* @brief Tests watchdog shutdown on thread object release
*/
TEST(Thread, GracefulExit)
{
auto helloThread = []
{
AuLogDbg("Start: worker thread");
while (AuIsThreadRunning())
{
// Do work...
// Wait for signal/CV
}
AuLogDbg("Thread exiting...");
};
auto thread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
AuMakeShared<AuThreads::IThreadVectorsFunctional>(
AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(helloThread)),
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
"SpawnTest"
));
// Fail on resource allocation failure
SysAssert(thread);
// Start the thread and assert
ASSERT_TRUE(thread->Run());
}
/**
* @brief Tests watchdog thread termination on manual exit request
*/
TEST(Thread, GracefulExitNoFree)
{
auto helloThread = []
{
AuLogDbg("Start: worker thread");
while (AuIsThreadRunning())
{
// Do work...
// Wait for signal/CV
AuThreading::Sleep(5 /*ms*/);
}
AuLogDbg("Thread exiting...");
};
auto thread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
AuMakeShared<AuThreads::IThreadVectorsFunctional>(
AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(helloThread)),
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
"SpawnTest"
));
// Fail on resource allocation failure
SysAssert(thread);
// Start [and assert]
ASSERT_TRUE(thread->Run());
// Set flag and sync/join under a watchdog
thread->Exit();
// Has exited?
ASSERT_TRUE(thread->AsWaitable()->TryLock());
}
/**
* @brief Tests watchdog thread termination on manual exit request
*/
TEST(Thread, ForcefulExitNoFree)
{
auto helloThread = []
{
while (true)
{
AuThreading::Sleep(50000 /*ms*/);
}
};
auto thread = AuThreads::ThreadUnique(AuThreads::ThreadInfo(
AuMakeShared<AuThreads::IThreadVectorsFunctional>(
AuThreads::IThreadVectorsFunctional::OnEntry_t(std::bind(helloThread)),
AuThreads::IThreadVectorsFunctional::OnExit_t {}),
"SpawnTest"
));
// Fail on resource allocation failure
SysAssert(thread);
// Start [and assert]
ASSERT_TRUE(thread->Run());
// Set flag and sync/join under a watchdog
thread->Exit();
// Has exited?
ASSERT_TRUE(thread->AsWaitable()->TryLock());
}
// TODO: sample and test code for:
// * Events
// * Condition Variables
// * Rentrant Mutexes
// * Sleep
// * TLS
// * Test approx timeout
// * Semaphore based RunInX utility for MT tests
void RunTests()
{
Aurora::RuntimeStartInfo info;
info.console.fio.enableLogging = false;
info.console.forceToolKitWindow = false;
Aurora::RuntimeStart(info);
}