[+] Added first two examples and renamed sln
This commit is contained in:
parent
560912fe63
commit
52338d1e3f
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -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
|
||||
|
@ -1,6 +1,6 @@
|
||||
require("aurora")
|
||||
|
||||
auStartSolution({name = "Runtime Project"})
|
||||
auStartSolution({name = "Hello Aurora"})
|
||||
|
||||
local kNamespaceStlEx = "Vendor - 1 - STLEX"
|
||||
local kNamespaceCompression = "Vendor - 2 - COMPRESSION"
|
||||
|
109
Tests/Public/1. Hello System/Main.cpp
Normal file
109
Tests/Public/1. Hello System/Main.cpp
Normal 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();
|
||||
}
|
246
Tests/Public/2. Hello Threading/Main.cpp
Normal file
246
Tests/Public/2. Hello Threading/Main.cpp
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user