Adjusted workflow.
All checks were successful
Build & Release / Windows-AMD64-Build (push) Successful in 1m8s
Build & Release / Linux-AMD64-Build (push) Successful in 1m30s
Build & Release / Linux-AARCH64-Build (push) Successful in 3m21s

This commit is contained in:
2024-02-05 22:25:30 -08:00
commit bcd71cf2b5
251 changed files with 45909 additions and 0 deletions

55
src/system/BaseMutex.cpp Normal file
View File

@@ -0,0 +1,55 @@
#include "ehs/system/BaseMutex.h"
namespace ehs
{
BaseMutex::~BaseMutex()
{
}
BaseMutex::BaseMutex()
: initialized(false), locked(false)
{
}
BaseMutex::BaseMutex(const BaseMutex& mutex)
: initialized(false), locked(false)
{
}
BaseMutex& BaseMutex::operator=(const BaseMutex& mutex)
{
if (this == &mutex)
return *this;
initialized = mutex.initialized;
locked = mutex.locked;
return *this;
}
void BaseMutex::Initialize()
{
}
void BaseMutex::UnInitialize()
{
}
bool BaseMutex::IsInitialized() const
{
return initialized;
}
void BaseMutex::Lock()
{
}
void BaseMutex::Unlock()
{
}
bool BaseMutex::IsLocked() const
{
return locked;
}
}

48
src/system/BaseOpen.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "ehs/system/BaseOpen.h"
namespace ehs
{
BaseOpen::BaseOpen()
{
}
BaseOpen::BaseOpen(Str_8 filePath)
: filePath((Str_8&&)filePath)
{
}
BaseOpen::BaseOpen(BaseOpen&& bo) noexcept
: filePath((Str_8&&)bo.filePath)
{
}
BaseOpen::BaseOpen(const BaseOpen& bo)
: filePath(bo.filePath)
{
}
BaseOpen& BaseOpen::operator=(BaseOpen&& bo) noexcept
{
if (this == &bo)
return *this;
filePath = (Str_8&&)bo.filePath;
return *this;
}
BaseOpen& BaseOpen::operator=(const BaseOpen& bo)
{
if (this == &bo)
return *this;
filePath = bo.filePath;
return *this;
}
Str_8 BaseOpen::GetFilePath() const
{
return filePath;
}
}

View File

@@ -0,0 +1,61 @@
#include "ehs/system/BaseSemaphore.h"
namespace ehs
{
BaseSemaphore::BaseSemaphore()
: initial(0)
{
}
BaseSemaphore::BaseSemaphore(Str_8 name, const UInt_32 initial)
: name(std::move(name)), initial(initial)
{
}
BaseSemaphore::BaseSemaphore(const UInt_32 initial)
: initial(initial)
{
}
BaseSemaphore::BaseSemaphore(BaseSemaphore&& sem) noexcept
: name(std::move(sem.name)), initial(sem.initial)
{
}
BaseSemaphore::BaseSemaphore(const BaseSemaphore& sem)
: name(sem.name), initial(sem.initial)
{
}
BaseSemaphore& BaseSemaphore::operator=(const BaseSemaphore& sem)
{
if (this == &sem)
return *this;
name = sem.name;
initial = sem.initial;
return *this;
}
BaseSemaphore& BaseSemaphore::operator=(BaseSemaphore&& sem) noexcept
{
if (this == &sem)
return *this;
name = std::move(sem.name);
initial = sem.initial;
return *this;
}
Str_8 BaseSemaphore::GetName() const
{
return name;
}
UInt_32 BaseSemaphore::GetInitial() const
{
return initial;
}
}

View File

@@ -0,0 +1,8 @@
#include "ehs/system/BaseSystem.h"
namespace ehs
{
void BaseSystem::OpenURI(const Str_8& uri)
{
}
}

561
src/system/CPU.cpp Normal file
View File

@@ -0,0 +1,561 @@
#include "ehs/system/CPU.h"
#include "ehs/Log.h"
#include "ehs/io/File.h"
#include "ehs/json/Json.h"
#include "ehs/system/Thread.h"
namespace ehs
{
#ifdef EHS_OS_LINUX
UInt_64 CPU::TSC_Freq = 0;
#endif
Architecture CPU::GetArchitecture()
{
#if defined(EHS_ARCH_X64)
return Architecture::X64;
#elif defined(EHS_ARCH_ARM64)
return Architecture::ARM64;
#else
return Architecture::UNKNOWN;
#endif
}
UInt_8 CPU::PointerSize()
{
return sizeof(void*);
}
Endianness CPU::GetEndianness()
{
#if defined(EHS_LITTLE_ENDIAN)
return Endianness::LE;
#elif defined(EHS_BIG_ENDIAN)
return Endianness::BE;
#else
UInt_16 tmp = 1;
if (((Byte*)&tmp)[0] == 1)
return Endianness::LE;
return Endianness::BE;
#endif
}
UInt_64 CPU::GetTSC_Freq()
{
#if defined(EHS_OS_WINDOWS)
LARGE_INTEGER frequency = {};
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
#elif defined(EHS_OS_LINUX)
if (!TSC_Freq)
TSC_Freq = RetrieveTSC_Freq();
return TSC_Freq;
#endif
return 0;
}
UInt_64 CPU::GetTSC()
{
#if defined(EHS_OS_WINDOWS)
LARGE_INTEGER count = {};
QueryPerformanceCounter(&count);
return count.QuadPart;
#elif defined(EHS_OS_LINUX)
TSC tsc;
RDTSCP(&tsc);
#if defined(EHS_ARCH_X64)
UInt_64 result = 0;
#if defined(EHS_LITTLE_ENDIAN)
((UInt_32*)&result)[0] = tsc.lowCount;
((UInt_32*)&result)[1] = tsc.highCount;
#elif defined(EHS_BIG_ENDIAN)
((UInt_32*)&result)[0] = tsc.highCount;
((UInt_32*)&result)[1] = tsc.lowCount;
#endif
return result;
#elif defined(EHS_ARCH_X86)
return tsc.lowPart;
#endif
#endif
return 0;
}
UInt_8 CPU::GetSteppingId()
{
return (UInt_8)GetInfoBits() & 0x00001111;
}
UInt_8 CPU::GetModelId()
{
return (UInt_8)GetInfoBits() & 0x11110000;
}
UInt_8 CPU::GetFamilyId()
{
return (UInt_8)(GetInfoBits() >> 8) & 0x00001111;
}
UInt_8 CPU::GetProcessorTypeId()
{
return (UInt_8)(GetInfoBits() >> 12) & 0x00000011;
}
UInt_8 CPU::GetExtModelId()
{
return (UInt_8)(GetInfoBits() >> 16) & 0x00001111;
}
UInt_8 CPU::GetExtFamilyId()
{
return (UInt_8)(GetInfoBits() >> 20);
}
bool CPU::HasFPU()
{
return GetFeatureBits_1() & 0b00000000000000000000000000000001;
}
bool CPU::HasVME()
{
return GetFeatureBits_1() & 0b00000000000000000000000000000010;
}
bool CPU::HasDE()
{
return GetFeatureBits_1() & 0b00000000000000000000000000000100;
}
bool CPU::HasPSE()
{
return GetFeatureBits_1() & 0b00000000000000000000000000001000;
}
bool CPU::HasTSC()
{
return GetFeatureBits_1() & 0b00000000000000000000000000010000;
}
bool CPU::HasMSR()
{
return GetFeatureBits_1() & 0b00000000000000000000000000100000;
}
bool CPU::HasPAE()
{
return GetFeatureBits_1() & 0b00000000000000000000000001000000;
}
bool CPU::HasMCE()
{
return GetFeatureBits_1() & 0b00000000000000000000000010000000;
}
bool CPU::HasCX8()
{
return GetFeatureBits_1() & 0b00000000000000000000000100000000;
}
bool CPU::HasAPIC()
{
return GetFeatureBits_1() & 0b00000000000000000000001000000000;
}
bool CPU::HasSEP()
{
return GetFeatureBits_1() & 0b00000000000000000000100000000000;
}
bool CPU::HasMTRR()
{
return GetFeatureBits_1() & 0b00000000000000000001000000000000;
}
bool CPU::HasPGE()
{
return GetFeatureBits_1() & 0b00000000000000000010000000000000;
}
bool CPU::HasMCA()
{
return GetFeatureBits_1() & 0b00000000000000000100000000000000;
}
bool CPU::HasCMOV()
{
return GetFeatureBits_1() & 0b00000000000000001000000000000000;
}
bool CPU::HasPAT()
{
return GetFeatureBits_1() & 0b00000000000000010000000000000000;
}
bool CPU::HasPSE_36()
{
return GetFeatureBits_1() & 0b00000000000000100000000000000000;
}
bool CPU::HasPSN()
{
return GetFeatureBits_1() & 0b00000000000001000000000000000000;
}
bool CPU::HasCLFSH()
{
return GetFeatureBits_1() & 0b00000000000010000000000000000000;
}
bool CPU::HasDS()
{
return GetFeatureBits_1() & 0b00000000001000000000000000000000;
}
bool CPU::HasACPI()
{
return GetFeatureBits_1() & 0b00000000010000000000000000000000;
}
bool CPU::HasMMX()
{
return GetFeatureBits_1() & 0b00000000100000000000000000000000;
}
bool CPU::HasFXSR()
{
return GetFeatureBits_1() & 0b00000001000000000000000000000000;
}
bool CPU::HasSSE()
{
return GetFeatureBits_1() & 0b00000010000000000000000000000000;
}
bool CPU::HasSSE2()
{
return GetFeatureBits_1() & 0b00000100000000000000000000000000;
}
bool CPU::HasSS()
{
return GetFeatureBits_1() & 0b00001000000000000000000000000000;
}
bool CPU::HasHTT()
{
return GetFeatureBits_1() & 0b00010000000000000000000000000000;
}
bool CPU::HasTM()
{
return GetFeatureBits_1() & 0b00100000000000000000000000000000;
}
bool CPU::HasIA64()
{
return GetFeatureBits_1() & 0b01000000000000000000000000000000;
}
bool CPU::HasPBE()
{
return GetFeatureBits_1() & 0b10000000000000000000000000000000;
}
bool CPU::HasSSE3()
{
return GetFeatureBits_2() & 0b00000000000000000000000000000001;
}
bool CPU::HasPCLMULQDQ()
{
return GetFeatureBits_2() & 0b00000000000000000000000000000010;
}
bool CPU::HasDTES64()
{
return GetFeatureBits_2() & 0b00000000000000000000000000000100;
}
bool CPU::HasMONITOR()
{
return GetFeatureBits_2() & 0b00000000000000000000000000001000;
}
bool CPU::HasDS_CPL()
{
return GetFeatureBits_2() & 0b00000000000000000000000000010000;
}
bool CPU::HasVMX()
{
return GetFeatureBits_2() & 0b00000000000000000000000000100000;
}
bool CPU::HasSMX()
{
return GetFeatureBits_2() & 0b00000000000000000000000001000000;
}
bool CPU::HasEST()
{
return GetFeatureBits_2() & 0b00000000000000000000000010000000;
}
bool CPU::HasTM2()
{
return GetFeatureBits_2() & 0b00000000000000000000000100000000;
}
bool CPU::HasSSSE3()
{
return GetFeatureBits_2() & 0b00000000000000000000001000000000;
}
bool CPU::HasCNXT_ID()
{
return GetFeatureBits_2() & 0b00000000000000000000010000000000;
}
bool CPU::HasSDBG()
{
return GetFeatureBits_2() & 0b00000000000000000000100000000000;
}
bool CPU::HasFMA()
{
return GetFeatureBits_2() & 0b00000000000000000001000000000000;
}
bool CPU::HasCX16()
{
return GetFeatureBits_2() & 0b00000000000000000010000000000000;
}
bool CPU::HasXTPR()
{
return GetFeatureBits_2() & 0b00000000000000000100000000000000;
}
bool CPU::HasPDCM()
{
return GetFeatureBits_2() & 0b00000000000000001000000000000000;
}
bool CPU::HasPCID()
{
return GetFeatureBits_2() & 0b00000000000000100000000000000000;
}
bool CPU::HasDCA()
{
return GetFeatureBits_2() & 0b00000000000001000000000000000000;
}
bool CPU::HasSSE4_1()
{
return GetFeatureBits_2() & 0b00000000000010000000000000000000;
}
bool CPU::HasSSE4_2()
{
return GetFeatureBits_2() & 0b00000000000100000000000000000000;
}
bool CPU::HasX2APIC()
{
return GetFeatureBits_2() & 0b00000000001000000000000000000000;
}
bool CPU::HasMOVBE()
{
return GetFeatureBits_2() & 0b00000000010000000000000000000000;
}
bool CPU::HasPOPCNT()
{
return GetFeatureBits_2() & 0b00000000100000000000000000000000;
}
bool CPU::HasTSC_DEADLINE()
{
return GetFeatureBits_2() & 0b00000001000000000000000000000000;
}
bool CPU::HasAES()
{
return GetFeatureBits_2() & 0b00000010000000000000000000000000;
}
bool CPU::HasXSAVE()
{
return GetFeatureBits_2() & 0b00000100000000000000000000000000;
}
bool CPU::HasOSXSAVE()
{
return GetFeatureBits_2() & 0b00001000000000000000000000000000;
}
bool CPU::HasAVX()
{
return GetFeatureBits_2() & 0b00010000000000000000000000000000;
}
bool CPU::HasF16C()
{
return GetFeatureBits_2() & 0b00100000000000000000000000000000;
}
bool CPU::HasRDRND()
{
return GetFeatureBits_2() & 0b01000000000000000000000000000000;
}
bool CPU::HasHYPERVISOR()
{
return GetFeatureBits_2() & 0b10000000000000000000000000000000;
}
bool CPU::HasAVX2()
{
return GetExtFeatureBits_1() & 0b00000000000000000000000000100000;
}
bool CPU::HasRDSEED()
{
return GetExtFeatureBits_1() & 0b00000000000001000000000000000000;
}
bool CPU::HasADX()
{
return GetExtFeatureBits_1() & 0b00000000000010000000000000000000;
}
/*
Str_8 CPU::ToStr()
{
return "Manufacturer: " + GetManufacturer() + "\r\n" +
"Brand: " + GetBrand() + "\r\n" +
"Stepping Id: " + Str_8::FromNum(GetSteppingId()) + "\r\n" +
"GpuModel Id: " + Str_8::FromNum(GetModelId()) + "\r\n" +
"Family Id: " + Str_8::FromNum(GetFamilyId()) + "\r\n" +
"Processor Type Id: " + Str_8::FromNum(GetProcessorTypeId()) + "\r\n" +
"Extended GpuModel Id: " + Str_8::FromNum(GetExtModelId()) + "\r\n" +
"Extended Family Id: " + Str_8::FromNum(GetExtFamilyId()) + "\r\n" +
"Has FPU: " + Str_8::FromNum((UInt_8)HasFPU()) + "\r\n" +
"Has SSE: " + Str_8::FromNum((UInt_8)HasSSE()) + "\r\n" +
"Has SSE 2: " + Str_8::FromNum((UInt_8)HasSSE2()) + "\r\n" +
"Has SSE 3: " + Str_8::FromNum((UInt_8)HasSSE3()) + "\r\n" +
"Has SSSE 3: " + Str_8::FromNum((UInt_8)HasSSSE3()) + "\r\n" +
"Has SSE 4.1: " + Str_8::FromNum((UInt_8)HasSSE4_1()) + "\r\n" +
"Has SSE 4.2: " + Str_8::FromNum((UInt_8)HasSSE4_2()) + "\r\n" +
"Has AVX: " + Str_8::FromNum((UInt_8)HasAVX()) + "\r\n" +
"Has RDRND: " + Str_8::FromNum((UInt_8)HasRDRND()) + "\r\n" +
"Has AVX 2: " + Str_8::FromNum((UInt_8)HasAVX2()) + "\r\n" +
"Has ADX: " + Str_8::FromNum((UInt_8)HasADX()) + "\r\n" +
"Has RDSEED: " + Str_8::FromNum((UInt_8)HasRDSEED());
}
*/
UInt_64 CPU::RetrieveTSC_Freq()
{
File tscDatabase("TSC_Frequencies.json", Mode::READ_WRITE, Disposition::CREATE_PERSISTENT);
if (tscDatabase.Size())
{
Json json(tscDatabase.ReadStr_8(tscDatabase.Size()), 5);
JsonObj* root = (JsonObj*)json.GetValue();
Char_8 manu[13];
manu[12] = 0;
GetManufacturer(manu);
JsonVar* jManu = root->GetVar(manu);
if (jManu)
{
JsonObj* joManu = (JsonObj*)jManu->GetValue();
Char_8 brand[48];
GetBrand(brand);
JsonVar* jBrand = joManu->GetVar(brand);
if (jBrand)
{
tscDatabase.Release();
return (UInt_64)*(JsonNum*)jBrand->GetValue();
}
else
{
UInt_64 tscFreq = CalculateTSC_Freq();
joManu->AddVar({brand, tscFreq});
tscDatabase.SeekBeginning();
tscDatabase.WriteStr_8(json.ToStr(false));
tscDatabase.Release();
return tscFreq;
}
}
else
{
UInt_64 tscFreq = CalculateTSC_Freq();
Char_8 brand[48];
GetBrand(brand);
JsonObj cpus(1, 0);
cpus[0] = JsonVar(brand, tscFreq);
JsonVar tmp({brand, cpus});
root->AddVar(tmp);
tscDatabase.SeekBeginning();
tscDatabase.WriteStr_8(json.ToStr(false));
tscDatabase.Release();
return tscFreq;
}
}
UInt_64 tscFreq = CalculateTSC_Freq();
Char_8 manu[13];
manu[12] = 0;
GetManufacturer(manu);
Char_8 brand[49];
brand[48] = 0;
GetBrand(brand);
JsonObj jManu(1, 0);
jManu[0] = JsonVar(brand, tscFreq);
JsonObj root(1, 0);
root[0] = JsonVar(manu, jManu);
Json json(root);
tscDatabase.WriteStr_8(json.ToStr(false));
tscDatabase.Release();
return tscFreq;
}
UInt_64 CPU::CalculateTSC_Freq()
{
UInt_64 result = GetTSC();
Thread::SleepFor(10000);
return (GetTSC() - result) / 10;
}
}

46
src/system/CPU_ARM64.cpp Normal file
View File

@@ -0,0 +1,46 @@
#include "ehs/system/CPU.h"
namespace ehs
{
void CPU::RDTSCP(TSC* tsc)
{
}
void CPU::GetManufacturer(Char_8* input)
{
}
UInt_32 CPU::GetInfoBits()
{
return 0;
}
UInt_32 CPU::GetFeatureBits_1()
{
return 0;
}
UInt_32 CPU::GetFeatureBits_2()
{
return 0;
}
UInt_32 CPU::GetExtFeatureBits_1()
{
return 0;
}
UInt_32 CPU::GetExtFeatureBits_2()
{
return 0;
}
UInt_32 CPU::GetExtFeatureBits_3()
{
return 0;
}
void CPU::GetBrand(Char_8* input)
{
}
}

View File

@@ -0,0 +1,132 @@
global _ZN3ehs3CPU6RDTSCPEPNS_3TSCE
global _ZN3ehs3CPU15GetManufacturerEPc
global _ZN3ehs3CPU11GetInfoBitsEv
global _ZN3ehs3CPU16GetFeatureBits_1Ev
global _ZN3ehs3CPU16GetFeatureBits_2Ev
global _ZN3ehs3CPU19GetExtFeatureBits_1Ev
global _ZN3ehs3CPU19GetExtFeatureBits_2Ev
global _ZN3ehs3CPU19GetExtFeatureBits_3Ev
global _ZN3ehs3CPU8GetBrandEPc
section .text
_ZN3ehs3CPU6RDTSCPEPNS_3TSCE:
RDTSCP
MOV DWORD [RDI], ECX
MOV DWORD [RDI + 4], EDX
MOV DWORD [RDI + 8], EAX
RET
_ZN3ehs3CPU15GetManufacturerEPc:
PUSH RBX
XOR EAX, EAX
CPUID
MOV DWORD [RDI], EBX
MOV DWORD [RDI + 4], EDX
MOV DWORD [RDI + 8], ECX
POP RBX
RET
_ZN3ehs3CPU11GetInfoBitsEv:
PUSH RBX
MOV EAX, 1
CPUID
POP RBX
RET
_ZN3ehs3CPU16GetFeatureBits_1Ev:
PUSH RBX
MOV EAX, 1
CPUID
MOV EAX, EDX
POP RBX
RET
_ZN3ehs3CPU16GetFeatureBits_2Ev:
PUSH RBX
MOV EAX, 1
CPUID
MOV EAX, ECX
POP RBX
RET
_ZN3ehs3CPU19GetExtFeatureBits_1Ev:
PUSH RBX
MOV EAX, 7
XOR ECX, ECX
CPUID
MOV EAX, EBX
POP RBX
RET
_ZN3ehs3CPU19GetExtFeatureBits_2Ev:
PUSH RBX
MOV EAX, 7
XOR ECX, ECX
CPUID
MOV EAX, ECX
POP RBX
RET
_ZN3ehs3CPU19GetExtFeatureBits_3Ev:
PUSH RBX
MOV EAX, 7
XOR ECX, ECX
CPUID
MOV EAX, EDX
POP RBX
RET
_ZN3ehs3CPU8GetBrandEPc:
PUSH RBX
MOV EAX, 80000002h
CPUID
MOV DWORD [RDI], EAX
MOV DWORD [RDI + 4], EBX
MOV DWORD [RDI + 8], ECX
MOV DWORD [RDI + 12], EDX
MOV EAX, 80000003h
CPUID
MOV DWORD [RDI + 16], EAX
MOV DWORD [RDI + 20], EBX
MOV DWORD [RDI + 24], ECX
MOV DWORD [RDI + 28], EDX
MOV EAX, 80000004h
CPUID
MOV DWORD [RDI + 32], EAX
MOV DWORD [RDI + 36], EBX
MOV DWORD [RDI + 40], ECX
MOV DWORD [RDI + 44], EDX
POP RBX
RET

View File

@@ -0,0 +1,127 @@
global ?GetManufacturer@CPU@ehs@@SAXPEAD@Z
global ?GetInfoBits@CPU@ehs@@SAIXZ
global ?GetFeatureBits_1@CPU@ehs@@SAIXZ
global ?GetFeatureBits_2@CPU@ehs@@SAIXZ
global ?GetExtFeatureBits_1@CPU@ehs@@SAIXZ
global ?GetExtFeatureBits_2@CPU@ehs@@SAKXZ
global ?GetExtFeatureBits_3@CPU@ehs@@SAKXZ
global ?GetBrand@CPU@ehs@@SAXPEAD@Z
section .text
?GetManufacturer@CPU@ehs@@SAXPEAD@Z:
PUSH RBX
XOR EAX, EAX
MOV R8, RCX
CPUID
MOV DWORD [R8], EBX
MOV DWORD [R8 + 4], EDX
MOV DWORD [R8 + 8], ECX
POP RBX
RET
?GetInfoBits@CPU@ehs@@SAIXZ:
PUSH RBX
MOV EAX, 1
CPUID
POP RBX
RET
?GetFeatureBits_1@CPU@ehs@@SAIXZ:
PUSH RBX
MOV EAX, 1
CPUID
MOV EAX, EDX
POP RBX
RET
?GetFeatureBits_2@CPU@ehs@@SAIXZ:
PUSH RBX
MOV EAX, 1
CPUID
MOV EAX, ECX
POP RBX
RET
?GetExtFeatureBits_1@CPU@ehs@@SAIXZ:
PUSH RBX
MOV EAX, 7
XOR ECX, ECX
CPUID
MOV EAX, EBX
POP RBX
RET
?GetExtFeatureBits_2@CPU@ehs@@SAKXZ:
PUSH RBX
MOV EAX, 7
XOR ECX, ECX
CPUID
MOV EAX, ECX
POP RBX
RET
?GetExtFeatureBits_3@CPU@ehs@@SAKXZ:
PUSH RBX
MOV EAX, 7
XOR ECX, ECX
CPUID
MOV EAX, EDX
POP RBX
RET
?GetBrand@CPU@ehs@@SAXPEAD@Z:
PUSH RBX
MOV R8, RCX
MOV EAX, 80000002h
CPUID
MOV DWORD [R8], EAX
MOV DWORD [R8 + 4], EBX
MOV DWORD [R8 + 8], ECX
MOV DWORD [R8 + 12], EDX
MOV EAX, 80000003h
CPUID
MOV DWORD [R8 + 16], EAX
MOV DWORD [R8 + 20], EBX
MOV DWORD [R8 + 24], ECX
MOV DWORD [R8 + 28], EDX
MOV EAX, 80000004h
CPUID
MOV DWORD [R8 + 32], EAX
MOV DWORD [R8 + 36], EBX
MOV DWORD [R8 + 40], ECX
MOV DWORD [R8 + 44], EDX
POP RBX
RET

32
src/system/FileSystem.cpp Normal file
View File

@@ -0,0 +1,32 @@
#include "ehs/system/FileSystem.h"
#include "ehs/Log.h"
#include <unistd.h>
#include <cstring>
#include <cerrno>
namespace ehs
{
void FileSystem::SetWorkingDir(const Str_8& dir)
{
int code = chdir(dir);
if (code == -1)
EHS_LOG_INT("Error", 0, strerror(errno));
}
Str_8 FileSystem::GetWorkingDir()
{
char result[EHS_MAX_PATH];
if (!getcwd(result, EHS_MAX_PATH))
EHS_LOG_INT("Error", 0, strerror(errno));
return result;
}
void FileSystem::SetOwner(const Str_8& dir, const UInt_32 userId, const UInt_32 groupId)
{
if (chown(dir, userId, groupId) == -1)
EHS_LOG_INT("Error", 0, strerror(errno));
}
}

76
src/system/Mutex_PT.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include "ehs/system/Mutex_PT.h"
namespace ehs
{
Mutex::~Mutex()
{
if (!initialized)
return;
pthread_mutex_destroy(&hdl);
}
Mutex::Mutex()
: hdl{}
{
}
Mutex::Mutex(const Mutex& mutex)
: BaseMutex(mutex), hdl{}
{
}
Mutex& Mutex::operator=(const Mutex& mutex)
{
if (this == &mutex)
return *this;
BaseMutex::operator=(mutex);
hdl = {};
return *this;
}
void Mutex::Initialize()
{
if (initialized)
return;
pthread_mutex_t hdl = {};
int code = pthread_mutex_init(&hdl, nullptr);
initialized = true;
}
void Mutex::UnInitialize()
{
if (!initialized)
return;
pthread_mutex_destroy(&hdl);
initialized = false;
}
void Mutex::Lock()
{
if (locked)
return;
pthread_mutex_lock(&hdl);
locked = true;
}
void Mutex::Unlock()
{
if (!locked)
return;
pthread_mutex_unlock(&hdl);
locked = false;
}
}

88
src/system/Mutex_W32.cpp Normal file
View File

@@ -0,0 +1,88 @@
#include "ehs/system/Mutex_W32.h"
#include "ehs/Str.h"
#include "ehs/Log.h"
namespace ehs
{
Mutex::~Mutex()
{
if (!initialized)
return;
if (!CloseHandle(hdl))
EHS_LOG_INT("Error", 0, "Failed to uninitialize mutex with error #" + Str_8::FromNum(GetLastError()) + ".");
}
Mutex::Mutex()
: hdl(nullptr)
{
}
Mutex::Mutex(const Mutex& mutex)
: BaseMutex(mutex), hdl(nullptr)
{
}
Mutex& Mutex::operator=(const Mutex& mutex)
{
if (this == &mutex)
return *this;
BaseMutex::operator=(mutex);
hdl = nullptr;
return *this;
}
void Mutex::Initialize()
{
if (initialized)
return;
hdl = CreateMutexW(nullptr, FALSE, nullptr);
if (!hdl)
{
EHS_LOG_INT("Error", 0, "Failed to create mutex with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
initialized = true;
}
void Mutex::UnInitialize()
{
if (!initialized)
return;
if (!CloseHandle(hdl))
EHS_LOG_INT("Error", 0, "Failed to uninitialize mutex with error #" + Str_8::FromNum(GetLastError()) + ".");
initialized = false;
}
void Mutex::Lock()
{
if (locked)
return;
if (WaitForSingleObject(hdl, EHS_INFINITE) == WAIT_FAILED)
{
EHS_LOG_INT("Error", 0, "Failed to lock mutex with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
locked = true;
}
void Mutex::Unlock()
{
if (!locked)
return;
if (!ReleaseMutex(hdl))
EHS_LOG_INT("Error", 0, "Failed to unlock mutex with error #" + Str_8::FromNum(GetLastError()) + ".");
locked = false;
}
}

117
src/system/Open_UNX.cpp Normal file
View File

@@ -0,0 +1,117 @@
#include "ehs/system/Open_UNX.h"
#include "ehs/Log.h"
#include <dlfcn.h>
namespace ehs
{
Open::~Open()
{
if (!Open::IsInitialize())
return;
if (dlclose(hdl))
EHS_LOG_INT("Error", 0, "Failed to close.");
}
Open::Open()
: hdl(nullptr)
{
}
Open::Open(Str_8 filePath)
: BaseOpen((Str_8&&)filePath), hdl(nullptr)
{
Open::Initialize();
}
Open::Open(Open&& o) noexcept
: BaseOpen((BaseOpen&&)o), hdl(o.hdl)
{
o.hdl = nullptr;
}
Open::Open(const Open& o)
: BaseOpen(o), hdl(nullptr)
{
Open::Initialize();
}
Open& Open::operator=(Open&& o) noexcept
{
if (this == &o)
return *this;
Open::Release();
BaseOpen::operator=((BaseOpen&&)o);
hdl = o.hdl;
o.hdl = nullptr;
return *this;
}
Open& Open::operator=(const Open& o)
{
if (this == &o)
return *this;
Open::Release();
BaseOpen::operator=(o);
hdl = nullptr;
Open::Initialize();
return *this;
}
void Open::Initialize()
{
if (IsInitialize())
return;
hdl = dlopen(filePath, RTLD_LAZY);
if (!hdl)
{
EHS_LOG_INT("Error", 0, dlerror());
return;
}
}
void Open::Release()
{
if (!IsInitialize())
return;
if (dlclose(hdl))
EHS_LOG_INT("Error", 0, "Failed to close.");
hdl = nullptr;
}
void* Open::Retrieve(Str_8 symbol)
{
if (!IsInitialize())
return nullptr;
void* func = dlsym(hdl, symbol);
if (!func)
{
dlerror();
EHS_LOG_INT("Error", 0, "Undefined symbol, \"" + symbol + "\".");
Release();
return nullptr;
}
return func;
}
bool Open::IsInitialize() const
{
return hdl;
}
}

5
src/system/Open_W32.cpp Normal file
View File

@@ -0,0 +1,5 @@
#include "ehs/system/Open_W32.h"
namespace ehs
{
}

163
src/system/Semaphore_P.cpp Normal file
View File

@@ -0,0 +1,163 @@
#include "ehs/system/Semaphore_P.h"
#include "ehs/Log.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <cerrno>
namespace ehs
{
Semaphore::~Semaphore()
{
if (!Semaphore::IsValid())
return;
if (sem_destroy(&hdl) == -1)
EHS_LOG_INT("Error", 0, "Failed to release semaphore with error #" + Str_8::FromNum(errno) + ".");
valid = false;
}
Semaphore::Semaphore()
: hdl{}, valid(false)
{
}
Semaphore::Semaphore(const Str_8& name, const UInt_32 initial)
: BaseSemaphore(name, initial), hdl{}, valid(false)
{
Semaphore::Initialize();
}
Semaphore::Semaphore(const UInt_32 initial)
: BaseSemaphore(initial), hdl{}, valid(false)
{
Semaphore::Initialize();
}
Semaphore::Semaphore(Semaphore&& sem) noexcept
: BaseSemaphore((Semaphore&&)sem), hdl(sem.hdl), valid(sem.valid)
{
sem.hdl = {};
sem.valid = false;
}
Semaphore::Semaphore(const Semaphore& sem)
: BaseSemaphore(sem), hdl{}, valid(false)
{
Semaphore::Initialize();
}
Semaphore& Semaphore::operator=(Semaphore&& sem) noexcept
{
if (this == &sem)
return *this;
Release();
BaseSemaphore::operator=((Semaphore&&)sem);
hdl = sem.hdl;
valid = sem.valid;
sem.hdl = {};
sem.valid = false;
return *this;
}
Semaphore& Semaphore::operator=(const Semaphore& sem)
{
if (this == &sem)
return *this;
Release();
BaseSemaphore::operator=(sem);
hdl = {};
valid = false;
Initialize();
return *this;
}
void Semaphore::Initialize()
{
if (IsValid())
return;
if (GetName().Size())
{
sem_t* result = sem_open("/" + GetName(), O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, GetInitial());
if (!result)
EHS_LOG_INT("Error", 0, "Failed to create semaphore with error #" + Str_8::FromNum(errno) + ".");
hdl = *result;
}
else
{
if (sem_init(&hdl, 0, GetInitial()) == -1)
EHS_LOG_INT("Error", 0, "Failed to create semaphore with error #" + Str_8::FromNum(errno) + ".");
}
valid = true;
}
void Semaphore::Release()
{
if (!IsValid())
return;
if (sem_destroy(&hdl) == -1)
EHS_LOG_INT("Error", 0, "Failed to release semaphore with error #" + Str_8::FromNum(errno) + ".");
hdl = {};
valid = false;
}
void Semaphore::Signal(const UInt_32 inc)
{
if (!IsValid())
return;
if (sem_post(&hdl) == -1)
EHS_LOG_INT("Error", 0, "Failed to signal semaphore with error #" + Str_8::FromNum(errno) + ".");
}
bool Semaphore::Wait(const UInt_32 timeout)
{
if (!IsValid())
return false;
int result;
if (timeout == EHS_INFINITE)
{
result = sem_wait(&hdl);
}
else
{
timespec time = {timeout / 1000, timeout % 1000 * 1000000};
result = sem_timedwait(&hdl, &time);
}
if (result == -1)
{
int code = errno;
if (code != ETIMEDOUT)
EHS_LOG_INT("Error", 0, "Failed to wait for semaphore with error #" + Str_8::FromNum(errno) + ".");
return false;
}
return true;
}
bool Semaphore::IsValid() const
{
return valid;
}
}

View File

@@ -0,0 +1,136 @@
#include "ehs/system/Semaphore_W32.h"
#include "ehs/UTF.h"
#include "ehs/Log.h"
namespace ehs
{
Semaphore::~Semaphore()
{
if (!hdl)
return;
if (!CloseHandle(hdl))
{
DWORD code = GetLastError();
EHS_LOG_INT("Error", 0, Str_8("Failed to free semaphore with error #") + code + ".");
}
}
Semaphore::Semaphore()
: hdl(nullptr)
{
Semaphore::Initialize();
}
Semaphore::Semaphore(Str_8 name, const UInt_32 initial)
: BaseSemaphore(std::move(name), initial), hdl(nullptr)
{
Semaphore::Initialize();
}
Semaphore::Semaphore(const UInt_32 initial)
: BaseSemaphore(initial), hdl(nullptr)
{
Semaphore::Initialize();
}
Semaphore::Semaphore(Semaphore&& sem) noexcept
: BaseSemaphore(std::move(sem)), hdl(sem.hdl)
{
sem.hdl = nullptr;
}
Semaphore::Semaphore(const Semaphore& sem)
: BaseSemaphore(sem), hdl(nullptr)
{
}
Semaphore& Semaphore::operator=(Semaphore&& sem) noexcept
{
if (this == &sem)
return *this;
Release();
BaseSemaphore::operator=(std::move(sem));
hdl = sem.hdl;
sem.hdl = nullptr;
return *this;
}
Semaphore& Semaphore::operator=(const Semaphore& sem)
{
if (this == &sem)
return *this;
Release();
BaseSemaphore::operator=(sem);
hdl = nullptr;
return *this;
}
void Semaphore::Initialize()
{
if (IsValid())
return;
hdl = CreateSemaphoreW(nullptr, (LONG)GetInitial(), EHS_SINT_32_MAX, UTF::To_16(GetName()));
if (!hdl)
EHS_LOG_INT("Error", 0, Str_8("Failed to create semaphore with error #") + GetLastError() + ".");
}
void Semaphore::Release()
{
if (!IsValid())
return;
if (!CloseHandle(hdl))
{
DWORD code = GetLastError();
EHS_LOG_INT("Error", 0, Str_8("Failed to free semaphore with error #") + code + ".");
}
hdl = nullptr;
}
void Semaphore::Signal(const UInt_32 inc)
{
if (!IsValid())
return;
if (!ReleaseSemaphore(hdl, (LONG)inc, nullptr))
EHS_LOG_INT("Error", 0, Str_8("Failed to release semaphore with error #") + GetLastError() + ".");
}
bool Semaphore::Wait(const UInt_32 timeout)
{
if (!IsValid())
return false;
DWORD result = WaitForSingleObject(hdl, timeout);
if (result == WAIT_ABANDONED)
{
EHS_LOG_INT("Error", 0, "Wait abandoned.");
return false;
}
else if (result == WAIT_FAILED)
{
EHS_LOG_INT("Error", 1, Str_8("Wait failed with error #") + GetLastError() + ".");
return false;
}
else if (result == WAIT_TIMEOUT)
return false;
return true;
}
bool Semaphore::IsValid() const
{
return hdl;
}
}

22
src/system/System_LNX.cpp Normal file
View File

@@ -0,0 +1,22 @@
#include "ehs/system/System_LNX.h"
#include "ehs/system/Thread.h"
#include "ehs/Log.h"
namespace ehs
{
UInt_32 XDG_Thread(void* args)
{
Str_8* uri = (Str_8*)args;
system("xdg-open \"" + *uri + "\"");
return 0;
}
void System::OpenURI(const Str_8& uri)
{
Thread xdg;
xdg.Start(XDG_Thread, (void*)&uri);
xdg.Detach();
}
}

11
src/system/System_W32.cpp Normal file
View File

@@ -0,0 +1,11 @@
#include "ehs/system/System_W32.h"
#include <shellapi.h>
namespace ehs
{
void System::OpenURI(const Str_8& uri)
{
ShellExecuteA(nullptr, "open", uri, nullptr, nullptr, SW_SHOW);
}
}

284
src/system/Thread.cpp Normal file
View File

@@ -0,0 +1,284 @@
#include "ehs/system/Thread.h"
#include "ehs/system/CPU.h"
#if defined(EHS_OS_WINDOWS)
#include <avrt.h>
#elif defined(EHS_OS_LINUX)
#include <pthread.h>
#include <unistd.h>
#endif
namespace ehs
{
UInt_32 Thread::mainId = GetCurrentId();
#ifdef EHS_OS_WINDOWS
Handle Thread::mainTaskHdl = nullptr;
UInt_32 Thread::mainTaskIndex = 0;
#endif
Thread::~Thread()
{
Join();
}
Thread::Thread(const UInt_64 stackSize)
: stackSize(stackSize), hdl(EHS_INVALID_THREAD), id(0)
#ifdef EHS_OS_WINDOWS
,taskHdl(nullptr), taskIndex(0)
#endif
{
}
Thread::Thread(const Thread& thread)
: stackSize(thread.stackSize), hdl(EHS_INVALID_THREAD), id(0)
#ifdef EHS_OS_WINDOWS
, taskHdl(nullptr), taskIndex(0)
#endif
{
}
Thread& Thread::operator=(const Thread& thread)
{
if (this == &thread)
return *this;
stackSize = thread.stackSize;
hdl = EHS_INVALID_THREAD;
id = 0;
#ifdef EHS_OS_WINDOWS
taskHdl = nullptr;
taskIndex = 0;
#endif
return* this;
}
void Thread::Start(UInt_32 (*cb)(void*), void* args)
{
#if defined(EHS_OS_WINDOWS)
hdl = CreateThread(nullptr, stackSize, (LPTHREAD_START_ROUTINE)cb, args, 0, (DWORD*)&id);
if (!hdl)
EHS_LOG_INT("Error", 0, "Failed to start thread with error #" + Str_8::FromNum(GetLastError()) + ".");
#elif defined(EHS_OS_LINUX)
UInt_64* rArgs = new UInt_64[sizeof(UInt_64) * 2];
rArgs[0] = (UInt_64)cb;
rArgs[1] = (UInt_64)args;
pthread_create((pthread_t*)&hdl, nullptr, Redirect, (void*)rArgs);
#endif
}
bool Thread::Join(const unsigned int timeout)
{
if (hdl == EHS_INVALID_THREAD)
return false;
#if defined(EHS_WINDOWS)
unsigned int r = WaitForSingleObject(hdl, timeout);
if (r == WAIT_ABANDONED)
{
EHS_LOG_INT("Error", 0, "Abandoned wait because a mutex was not released.");
return false;
}
else if (r == WAIT_TIMEOUT)
{
return false;
}
else if (r == WAIT_FAILED)
{
EHS_LOG_INT("Error", 1, "Failed to wait for thread with error #" + Str_8::FromNum(GetLastError()) + ".");
return false;
}
mainTaskIndex = 0;
#elif defined(EHS_OS_LINUX)
int code = pthread_join((pthread_t)hdl, nullptr);
if (code != 0)
EHS_LOG_INT("Error", 1, "Failed to wait for thread with error #" + Str_8::FromNum(code) + ".");
hdl = EHS_INVALID_THREAD;
#endif
return true;
}
void Thread::Detach()
{
if (!hdl)
return;
#if defined(EHS_OS_WINDOWS)
if (!CloseHandle(hdl))
{
EHS_LOG_INT("Error", 0, "Failed to detach thread with error #" + Str_8::FromNum(GetLastError()) + ".");
return;
}
#elif defined(EHS_OS_LINUX)
pthread_detach(hdl);
hdl = EHS_INVALID_THREAD;
#endif
}
UInt_64 Thread::GetStackSize() const
{
return stackSize;
}
THandle Thread::GetHandle() const
{
return hdl;
}
UInt_32 Thread::GetId() const
{
return id;
}
bool Thread::IsCurrent() const
{
return id == GetCurrentId();
}
bool Thread::IsValid() const
{
return hdl;
}
#ifdef EHS_OS_WINDOWS
void Thread::SetTaskType_32(const Str_32& task)
{
if (!IsCurrent())
return;
taskHdl = AvSetMmThreadCharacteristicsW(UTF::To_16(task), (LPDWORD)&taskIndex);
if (!taskHdl)
EHS_LOG_INT("Error", 0, "Failed to set the thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
}
void Thread::SetTaskType_16(const Str_16& task)
{
if (!IsCurrent())
return;
taskHdl = AvSetMmThreadCharacteristicsW(task, (LPDWORD)&taskIndex);
if (!taskHdl)
EHS_LOG_INT("Error", 0, "Failed to set the thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
}
void Thread::SetTaskType_8(const Str_8& task)
{
if (!IsCurrent())
return;
taskHdl = AvSetMmThreadCharacteristicsW(UTF::To_16(task), (LPDWORD)&taskIndex);
if (!taskHdl)
EHS_LOG_INT("Error", 0, "Failed to set the thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
}
void Thread::RevertTaskType()
{
if (!IsCurrent())
return;
if (!AvRevertMmThreadCharacteristics(taskHdl))
EHS_LOG_INT("Error", 0, "Failed to revert the thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
taskIndex = 0;
}
#endif
UInt_32 Thread::GetMainId()
{
return mainId;
}
UInt_64 Thread::GetCurrentId()
{
#if defined(EHS_OS_WINDOWS)
return GetCurrentThreadId();
#elif defined(EHS_OS_LINUX)
return pthread_self();
#endif
}
#ifdef EHS_OS_WINDOWS
void Thread::SetMainTaskType_32(const Str_32& task)
{
if (GetCurrentId() != mainId)
return;
mainTaskHdl = AvSetMmThreadCharacteristicsW(UTF::To_16(task), (LPDWORD)&mainTaskIndex);
if (!mainTaskHdl)
EHS_LOG_INT("Error", 0, "Failed to set the main thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
}
void Thread::SetMainTaskType_16(const Str_16& task)
{
if (GetCurrentId() != mainId)
return;
mainTaskHdl = AvSetMmThreadCharacteristicsW(task, (LPDWORD)&mainTaskIndex);
if (!mainTaskHdl)
EHS_LOG_INT("Error", 0, "Failed to set the main thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
}
void Thread::SetMainTaskType_8(const Str_8& task)
{
if (GetCurrentId() != mainId)
return;
mainTaskHdl = AvSetMmThreadCharacteristicsW(UTF::To_16(task), (LPDWORD)&mainTaskIndex);
if (!mainTaskHdl)
EHS_LOG_INT("Error", 0, "Failed to set the main thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
}
void Thread::RevertMainTaskType()
{
if (GetCurrentId() != mainId)
return;
if (!AvRevertMmThreadCharacteristics(mainTaskHdl))
EHS_LOG_INT("Error", 0, "Failed to revert the main thread's characteristics with error #" + Str_8::FromNum(GetLastError()) + ".");
mainTaskIndex = 0;
}
#endif
float Thread::HardSleepFor(const float seconds)
{
UInt_64 freq = CPU::GetTSC_Freq();
UInt_64 start = CPU::GetTSC();
float elapsed = 0.0f;
while ((elapsed = (float)(CPU::GetTSC() - start) / (float)freq) <= seconds);
return elapsed;
}
void Thread::SleepFor(const UInt_32 miliseconds)
{
#if defined(EHS_OS_WINDOWS)
Sleep(miliseconds);
#elif defined(EHS_OS_LINUX)
timespec req = {miliseconds / 1000, miliseconds % 1000 * 1000000};
nanosleep(&req, nullptr);
#endif
}
void* Thread::Redirect(void *args)
{
UInt_64* rArgs = (UInt_64*)args;
UInt_32 (*cb)(void*) = (UInt_32 (*)(void*))rArgs[0];
void* params = (void*)rArgs[1];
UInt_32* code = new UInt_32();
*code = cb(params);
delete[] rArgs;
return code;
}
}

40
src/system/User.cpp Normal file
View File

@@ -0,0 +1,40 @@
#include "ehs/system/User.h"
#include "ehs/Log.h"
#include <unistd.h>
#include <cstring>
#include <cerrno>
namespace ehs
{
void User::GetId(UInt_32* const real, UInt_32* const effective, UInt_32* const saved)
{
if (getresuid(real, effective, saved) == -1)
EHS_LOG_INT("Error", 0, strerror(errno));
}
Str_8 User::GetName()
{
SInt_64 max = sysconf(_SC_LOGIN_NAME_MAX);
if (max == -1)
{
EHS_LOG_INT("Error", 0, strerror(errno));
return {};
}
Char_8* name = new Char_8[max];
if (getlogin_r(name, max) == -1)
{
delete[] name;
EHS_LOG_INT("Error", 1, strerror(errno));
return {};
}
Str_8 result(name);
delete[] name;
return result;
}
}