Swapped from using system call wrappers to just system calls and designing the C/C++ RT.

This commit is contained in:
2024-02-08 03:38:56 -08:00
parent 586ed2dfd2
commit 2aecad825b
35 changed files with 1780 additions and 1417 deletions

View File

@@ -0,0 +1,51 @@
#pragma once
#include "ehs/Types.h"
namespace ehs
{
class BaseThread
{
private:
UInt_64 stackSize;
protected:
UInt_32 id;
public:
BaseThread();
BaseThread(UInt_64 stackSize);
BaseThread(BaseThread&& thread) noexcept;
BaseThread(const BaseThread& thread);
BaseThread& operator=(BaseThread&& thread) noexcept;
BaseThread& operator=(const BaseThread& thread);
virtual void Detach();
virtual void Join() = 0;
UInt_64 GetStackSize() const;
UInt_32 GetId() const;
static UInt_32 GetCurrentId();
virtual bool IsValid() const;
/// A software implementation for sleeping the calling thread.
/// @param [in] seconds The amount in seconds to sleep for.
/// @returns The amount in seconds that the sleep exceeded for.
/// @note A more precise sleep method but more taxing on the CPU.
static float SoftSleep(float seconds);
/// A hardware implementation for sleeping the calling thread.
/// @param [in] milliseconds The amount in milliseconds to sleep for.
/// @note A less precise sleep method but less taxing on the CPU.
static void HardSleep(UInt_32 milliseconds);
};
}

58
include/ehs/system/Lock.h Normal file
View File

@@ -0,0 +1,58 @@
#pragma once
#include "ehs/Types.h"
namespace ehs
{
class Lock
{
/// Does an atomic lock add operation.
/// @param [in] a The address of the value to add to.
/// @param [in] b The value to add from.
static void Add(UInt_64* a, UInt_64 b);
/// Does an atomic lock subtract operation.
/// @param [in] a The address of the value to subtract to.
/// @param [in] b The value to subtract from.
static void Sub(UInt_64* a, UInt_64 b);
/// Does an atomic lock compare exchange operation.
/// @param [in/out] a The address of the value to compare with the value of b.
/// @param [in/out] b The address of the value to compare with the value of a.
/// @param [in] setter The address of the value to set the value of b to when a and b are equal.
/// @returns True if equal.
/// @note If a and b are not equal the value at the address of a will be set to the value at the address of b.
static bool CmpXchg(UInt_64* a, UInt_64* b, UInt_64 setter);
/// Does an atomic lock and operation.
/// @param [in] a The address of the first value to compare.
/// @param [in] b The second value to compare.
static void And(UInt_64* a, UInt_64 b);
/// Does an atomic lock or operation.
/// @param [in] a The address of the first value to compare.
/// @param [in] b The second value to compare.
static void Or(UInt_64* a, UInt_64 b);
/// Does an atomic lock xor operation.
/// @param [in] a The address of the first value to compare.
/// @param [in] b The second value to compare.
static void XOr(UInt_64* a, UInt_64 b);
/// Does an atomic lock increase operation.
/// @param [in] a The address of the value to increase.
static void Inc(UInt_64* a);
/// Does an atomic lock decrease operation.
/// @param [in] a The address of the value to decrease.
static void Dec(UInt_64* a);
/// Does an atomic lock not operation.
/// @param [in] a The address of the value to not.
static void Not(UInt_64* a);
/// Does an atomic lock negate operation.
/// @param [in] a The address of the value to negate.
static void Neg(UInt_64* a);
};
}

View File

@@ -10,7 +10,7 @@ namespace ehs
class Mutex : public BaseMutex
{
private:
pthread_mutex_t hdl;
volatile UInt_64 state;
public:
~Mutex() override;

View File

@@ -1,148 +1,9 @@
#pragma once
#include "ehs/EHS.h"
#include "ehs/Serializer.h"
#include "ehs/Array.h"
#include "ehs/Log.h"
#include "ehs/Str.h"
#include "ehs/system/OS.h"
#ifdef EHS_OS_WINDOWS
#include <processthreadsapi.h>
#endif
namespace ehs
{
#if defined(EHS_OS_WINDOWS)
#define EHS_INVALID_THREAD nullptr
typedef void* THandle;
#elif defined(EHS_OS_LINUX)
#define EHS_INVALID_THREAD 0
typedef UInt_64 THandle;
#endif
class Thread
{
private:
static UInt_32 mainId;
#ifdef EHS_OS_WINDOWS
static Handle mainTaskHdl;
static UInt_32 mainTaskIndex;
#endif
UInt_64 stackSize;
THandle hdl;
UInt_32 id;
#ifdef EHS_OS_WINDOWS
Handle taskHdl;
UInt_32 taskIndex;
#endif
public:
/// Frees any native handles.
~Thread();
/// Default members initialization.
Thread(const UInt_64 stackSize = 0);
/// Copies some members from the given thread object.
/// @param [in] thread The thread object to copy from.
Thread(const Thread& thread);
/// Copies some members from the given thread object.
/// @param [in] thread The thread object to copy from.
/// @returns The thread that has been assigned to.
Thread& operator=(const Thread& thread);
/// Creates a thread handle and starts it with the given method.
/// @param cb The function to run on the thread.
/// @param args Raw data to send over to the thread.
void Start(UInt_32 (*cb)(void*), void* args);
/// Blocks the calling thread until the referenced thread is finished.
/// @param timeout The time to wait for before moving on.
/// @note Pass "EHS_INFINITE" to wait until the thread is finished.
bool Join(const unsigned int timeout = EHS_INFINITE);
/// Detaches the referenced thread, removing ownership.
void Detach();
/// Retrieves the given stack size available to the referenced thread.
/// @returns The stack size.
UInt_64 GetStackSize() const;
/// Retrieves the native thread handle.
/// @returns The native handle.
THandle GetHandle() const;
/// Retrieves the thread's id.
/// @returns The id.
UInt_32 GetId() const;
/// Checks whether or not the calling thread is the referenced thread.
/// @returns The result.
bool IsCurrent() const;
bool IsValid() const;
#ifdef EHS_OS_WINDOWS
/// Adjusts the thread's performance based on the type of task provided, that's going to be executed.
/// @param[in] task A task name from the provided list in the registry.
/// @note A list of tasks are in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\Tasks.
void SetTaskType_32(const Str_32& task);
/// Adjusts the thread's performance based on the type of task provided, that's going to be executed.
/// @param[in] task A task name from the provided list in the registry.
/// @note A list of tasks are in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\Tasks.
void SetTaskType_16(const Str_16& task);
/// Adjusts the thread's performance based on the type of task provided, that's going to be executed.
/// @param[in] task A task name from the provided list in the registry.
/// @note A list of tasks are in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\Tasks.
void SetTaskType_8(const Str_8& task);
void RevertTaskType();
#endif
/// Gets the main thread id.
static UInt_32 GetMainId();
/// Retrieves the calling thread's id.
/// @returns The id.
static UInt_64 GetCurrentId();
#ifdef EHS_OS_WINDOWS
/// Adjusts the main thread's performance based on the type of task provided, that's going to be executed.
/// @param[in] task A task name from the provided list in the registry.
/// @note A list of tasks are in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\Tasks.
static void SetMainTaskType_32(const Str_32& task);
/// Adjusts the main thread's performance based on the type of task provided, that's going to be executed.
/// @param[in] task A task name from the provided list in the registry.
/// @note A list of tasks are in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\Tasks.
static void SetMainTaskType_16(const Str_16& task);
/// Adjusts the main thread's performance based on the type of task provided, that's going to be executed.
/// @param[in] task A task name from the provided list in the registry.
/// @note A list of tasks are in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\Tasks.
static void SetMainTaskType_8(const Str_8& task);
static void RevertMainTaskType();
#endif
/// Causes the calling thread to wait until the given time using a while loop and the CPU clock.
/// @param seconds The time in seconds to wait for.
/// @returns The total elapsed time slept for due to this not being a 100% accurate.
/// @warning Use "SleepFor" instead unless accuracy is required because this does not do other tasks while sleeping.
static float HardSleepFor(const float seconds);
/// Causes the calling thread to wait until the given time using native sleep calls.
/// @param miliseconds The time in miliseconds to wait for.
/// @warning This is not at all accurate.
static void SleepFor(const UInt_32 miliseconds);
private:
static void* Redirect(void* args);
};
}
#if defined(EHS_OS_WINDOWS)
#include "Thread_W32.h"
#elif defined(EHS_OS_LINUX)
#include "Thread_LNX.h"
#endif

View File

@@ -0,0 +1,42 @@
#pragma once
#include "BaseThread.h"
#include <sys/wait.h>
namespace ehs
{
class Thread : public BaseThread
{
private:
void* stack;
pid_t hdl;
volatile bool* detached;
public:
~Thread();
Thread();
Thread(UInt_64 stackSize, void* args, UInt_32 (*func)(void*));
Thread(Thread&& thread) noexcept;
Thread(const Thread& thread);
Thread& operator=(Thread&& thread) noexcept;
Thread& operator=(const Thread& thread);
void Detach() override;
void Join() override;
static UInt_32 GetCurrentId();
static void HardSleep(UInt_32 milliseconds);
private:
static UInt_32 Redirect(void* args);
};
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include "BaseThread.h"
namespace ehs
{
class Thread : public BaseThread
{
private:
void* hdl;
public:
~Thread();
Thread();
Thread(UInt_64 stackSize, void* args, UInt_32 (*func)(void*));
Thread(Thread&& thread) noexcept;
Thread(const Thread& thread);
Thread& operator=(Thread&& thread) noexcept;
Thread& operator=(const Thread& thread);
void Detach() override;
void Join() override;
static UInt_32 GetCurrentId();
bool IsValid() const override;
static void HardSleep(UInt_32 milliseconds);
};
}