Swapped from using system call wrappers to just system calls and designing the C/C++ RT.
This commit is contained in:
parent
586ed2dfd2
commit
2aecad825b
@ -85,7 +85,8 @@ set(EHS_SOURCES
|
|||||||
src/database/DVar.cpp include/ehs/database/DVar.h
|
src/database/DVar.cpp include/ehs/database/DVar.h
|
||||||
|
|
||||||
src/system/CPU.cpp include/ehs/system/CPU.h
|
src/system/CPU.cpp include/ehs/system/CPU.h
|
||||||
src/system/Thread.cpp include/ehs/system/Thread.h
|
include/ehs/system/BaseThread.h src/system/BaseThread.cpp
|
||||||
|
include/ehs/system/Thread.h
|
||||||
src/system/BaseMutex.cpp include/ehs/system/BaseMutex.h
|
src/system/BaseMutex.cpp include/ehs/system/BaseMutex.h
|
||||||
src/system/BaseSemaphore.cpp include/ehs/system/BaseSemaphore.h
|
src/system/BaseSemaphore.cpp include/ehs/system/BaseSemaphore.h
|
||||||
src/system/BaseSystem.cpp include/ehs/system/BaseSystem.h
|
src/system/BaseSystem.cpp include/ehs/system/BaseSystem.h
|
||||||
@ -107,7 +108,7 @@ set(EHS_SOURCES
|
|||||||
src/json/JsonVar.cpp include/ehs/json/JsonVar.h
|
src/json/JsonVar.cpp include/ehs/json/JsonVar.h
|
||||||
|
|
||||||
src/io/Resource.cpp include/ehs/io/Resource.h
|
src/io/Resource.cpp include/ehs/io/Resource.h
|
||||||
src/io/Console.cpp include/ehs/io/Console.h
|
src/io/BaseConsole.cpp include/ehs/io/BaseConsole.h
|
||||||
src/io/RIFF_Chunk.cpp include/ehs/io/RIFF_Chunk.h
|
src/io/RIFF_Chunk.cpp include/ehs/io/RIFF_Chunk.h
|
||||||
src/io/RIFF.cpp include/ehs/io/RIFF.h
|
src/io/RIFF.cpp include/ehs/io/RIFF.h
|
||||||
src/io/BaseWindow.cpp include/ehs/io/BaseWindow.h
|
src/io/BaseWindow.cpp include/ehs/io/BaseWindow.h
|
||||||
@ -160,6 +161,8 @@ set(EHS_SOURCES
|
|||||||
src/io/hid/HID.cpp include/ehs/io/hid/HID.h
|
src/io/hid/HID.cpp include/ehs/io/hid/HID.h
|
||||||
src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h
|
src/io/hid/InputHandler.cpp include/ehs/io/hid/InputHandler.h
|
||||||
src/io/hid/Input.cpp include/ehs/io/hid/Input.h
|
src/io/hid/Input.cpp include/ehs/io/hid/Input.h
|
||||||
|
include/ehs/io/Console.h
|
||||||
|
include/ehs/system/Lock.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if (IS_OS_WINDOWS)
|
if (IS_OS_WINDOWS)
|
||||||
@ -168,9 +171,11 @@ if (IS_OS_WINDOWS)
|
|||||||
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
|
src/io/socket/TCP_W32.cpp include/ehs/io/socket/TCP_W32.h
|
||||||
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
|
src/system/Semaphore_W32.cpp include/ehs/system/Semaphore_W32.h
|
||||||
src/system/System_W32.cpp include/ehs/system/System_W32.h
|
src/system/System_W32.cpp include/ehs/system/System_W32.h
|
||||||
|
src/system/Thread_W32.cpp include/ehs/system/Thread_W32.h
|
||||||
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
|
src/system/Mutex_W32.cpp include/ehs/system/Mutex_W32.h
|
||||||
src/system/Open_W32.cpp include/ehs/system/Open_W32.h
|
src/system/Open_W32.cpp include/ehs/system/Open_W32.h
|
||||||
src/io/audio/audioDevice_W32.cpp include/ehs/io/audio/audioDevice_W32.h
|
src/io/audio/audioDevice_W32.cpp include/ehs/io/audio/audioDevice_W32.h
|
||||||
|
src/io/Console_W32.cpp include/ehs/io/Console_W32.h
|
||||||
src/io/File_W32.cpp include/ehs/io/File_W32.h
|
src/io/File_W32.cpp include/ehs/io/File_W32.h
|
||||||
src/io/FileMonitor_W32.cpp include/ehs/io/FileMonitor_W32.h
|
src/io/FileMonitor_W32.cpp include/ehs/io/FileMonitor_W32.h
|
||||||
src/io/Window_W32.cpp include/ehs/io/Window_W32.h
|
src/io/Window_W32.cpp include/ehs/io/Window_W32.h
|
||||||
@ -179,17 +184,21 @@ if (IS_OS_WINDOWS)
|
|||||||
)
|
)
|
||||||
elseif (IS_OS_LINUX)
|
elseif (IS_OS_LINUX)
|
||||||
list(APPEND EHS_SOURCES
|
list(APPEND EHS_SOURCES
|
||||||
|
src/CRT_LNX.cpp
|
||||||
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
|
src/io/socket/UDP_BSD.cpp include/ehs/io/socket/UDP_BSD.h
|
||||||
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
|
src/io/socket/TCP_BSD.cpp include/ehs/io/socket/TCP_BSD.h
|
||||||
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
|
src/system/Semaphore_P.cpp include/ehs/system/Semaphore_P.h
|
||||||
src/system/System_LNX.cpp include/ehs/system/System_LNX.h
|
src/system/System_LNX.cpp include/ehs/system/System_LNX.h
|
||||||
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h
|
src/system/Open_UNX.cpp include/ehs/system/Open_UNX.h
|
||||||
|
src/io/Console_LNX.cpp include/ehs/io/Console_LNX.h
|
||||||
src/io/File_UNX.cpp include/ehs/io/File_UNX.h
|
src/io/File_UNX.cpp include/ehs/io/File_UNX.h
|
||||||
src/io/FileMonitor_UNX.cpp include/ehs/io/FileMonitor_UNX.h
|
src/io/FileMonitor_UNX.cpp include/ehs/io/FileMonitor_UNX.h
|
||||||
|
src/system/Thread_LNX.cpp include/ehs/system/Thread_LNX.h
|
||||||
src/system/Mutex_PT.cpp include/ehs/system/Mutex_PT.h
|
src/system/Mutex_PT.cpp include/ehs/system/Mutex_PT.h
|
||||||
src/io/audio/AudioDevice_ALSA.cpp include/ehs/io/audio/AudioDevice_ALSA.h
|
src/io/audio/AudioDevice_ALSA.cpp include/ehs/io/audio/AudioDevice_ALSA.h
|
||||||
src/system/FileSystem.cpp include/ehs/system/FileSystem.h
|
src/system/FileSystem.cpp include/ehs/system/FileSystem.h
|
||||||
src/system/User.cpp include/ehs/system/User.h
|
src/system/User.cpp include/ehs/system/User.h
|
||||||
|
src/system/Lock_GCC_AMD64.asm
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
|
set(LINUX_WINDOW_SYSTEM "Wayland" CACHE STRING "Linux Window System")
|
||||||
@ -221,6 +230,7 @@ add_executable(StrToHash src/StrToHash.cpp)
|
|||||||
target_include_directories(EHS PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
target_include_directories(EHS PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
if (IS_OS_LINUX)
|
if (IS_OS_LINUX)
|
||||||
|
target_link_options(EHS PUBLIC -nostdlib -nostartfiles -e _start)
|
||||||
set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/.local")
|
set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/.local")
|
||||||
elseif (IS_OS_WINDOWS)
|
elseif (IS_OS_WINDOWS)
|
||||||
set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/EHS")
|
set(CMAKE_INSTALL_PREFIX "${USER_HOME_DIRECTORY}/EHS")
|
||||||
|
@ -33,7 +33,7 @@ namespace ehs
|
|||||||
|
|
||||||
/// Sets the maximum amount of garbage to delete per poll.
|
/// Sets the maximum amount of garbage to delete per poll.
|
||||||
/// @param[in] newMax The new maximum.
|
/// @param[in] newMax The new maximum.
|
||||||
static void SetMax(const UInt_64 newMax);
|
static void SetMax(UInt_64 newMax);
|
||||||
|
|
||||||
/// Gets the maximum amount of garbage to delete per poll.
|
/// Gets the maximum amount of garbage to delete per poll.
|
||||||
/// @returns The maximum.
|
/// @returns The maximum.
|
||||||
@ -41,7 +41,7 @@ namespace ehs
|
|||||||
|
|
||||||
/// Sets a new amount for memory pre-allocation to save on memory operations.
|
/// Sets a new amount for memory pre-allocation to save on memory operations.
|
||||||
/// @param[in] newStride The stride to pre-allocate.
|
/// @param[in] newStride The stride to pre-allocate.
|
||||||
static void SetStride(const UInt_64 newStride);
|
static void SetStride(UInt_64 newStride);
|
||||||
|
|
||||||
/// The amount of data pre-allocated to save on memory operations.
|
/// The amount of data pre-allocated to save on memory operations.
|
||||||
/// @returns The stride.
|
/// @returns The stride.
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "EHS.h"
|
#include "EHS.h"
|
||||||
#include "BaseObj.h"
|
#include "BaseObj.h"
|
||||||
|
#include "ehs/Serializer.h"
|
||||||
#include "ehs/system/Thread.h"
|
#include "ehs/system/Thread.h"
|
||||||
#include "ehs/system/Semaphore.h"
|
#include "ehs/system/Semaphore.h"
|
||||||
|
|
||||||
|
91
include/ehs/io/BaseConsole.h
Normal file
91
include/ehs/io/BaseConsole.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ehs/Str.h"
|
||||||
|
#include "ehs/UTF.h"
|
||||||
|
#include "ehs/Array.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
class BaseConsole
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Attach();
|
||||||
|
|
||||||
|
/// Frees the current console being used.
|
||||||
|
static void Free();
|
||||||
|
|
||||||
|
/// Writes to console using UTF32.
|
||||||
|
/// @param [in] str The text to write to the console.
|
||||||
|
/// @param [in] newLine To make a new line after the given text.
|
||||||
|
/// @warning Has to convert from UTF32 to UTF16 for the Windows API.
|
||||||
|
static void Write_32(const Str_32& str, bool newLine = true);
|
||||||
|
|
||||||
|
/// Writes to console using UTF16.
|
||||||
|
/// @param [in] str The text to write to the console.
|
||||||
|
/// @param [in] newLine To make a new line after the given text.
|
||||||
|
static void Write_16(const Str_16& str, bool newLine = true);
|
||||||
|
|
||||||
|
/// Writes to console using UTF8.
|
||||||
|
/// @param [in] str The text to write to the console.
|
||||||
|
/// @param [in] newLine To make a new line after the given text.
|
||||||
|
/// @warning Has to convert from UTF8 to UTF16 for the Windows API.
|
||||||
|
static void Write_8(const Str_8& str, bool newLine = true);
|
||||||
|
|
||||||
|
/// Reads from the console using UTF32.
|
||||||
|
/// @returns The text the user wrote to the console.
|
||||||
|
/// @warning Has to convert from UTF16 to UTF32 for the Windows API.
|
||||||
|
static Str_32 Read_32(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
/// Reads from the console using UTF16.
|
||||||
|
/// @returns The text the user wrote to the console.
|
||||||
|
static Str_16 Read_16(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
/// Reads from the console using UTF8.
|
||||||
|
/// @returns The text the user wrote to the console.
|
||||||
|
/// @warning Has to convert from UTF8 to UTF16 for the Windows API.
|
||||||
|
static Str_8 Read_8(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
/// Clears the console.
|
||||||
|
static void Clear();
|
||||||
|
|
||||||
|
/// Changes the console's title.
|
||||||
|
/// @param [in] title The text to change the title to.
|
||||||
|
/// @warning Has to convert from UTF32 to UTF16 for the Windows API.
|
||||||
|
static void SetTitle_32(const Str_32& title);
|
||||||
|
|
||||||
|
/// Changes the console's title.
|
||||||
|
/// @param [in] title The text to change the title to.
|
||||||
|
static void SetTitle_16(const Str_16& title);
|
||||||
|
|
||||||
|
/// Changes the console's title.
|
||||||
|
/// @param [in] title The text to change the title to.
|
||||||
|
/// @warning Has to convert from UTF8 to UTF16 for the Windows API.
|
||||||
|
static void SetTitle_8(const Str_8& title);
|
||||||
|
|
||||||
|
/// Retrieves the console's title in UTF32.
|
||||||
|
/// @returns The console's title.
|
||||||
|
/// @warning Has to convert from UTF16 to UTF32 for the Windows API.
|
||||||
|
static Str_32 GetTitle_32();
|
||||||
|
|
||||||
|
/// Retrieves the console's title in UTF16.
|
||||||
|
/// @returns The console's title.
|
||||||
|
static Str_16 GetTitle_16();
|
||||||
|
|
||||||
|
/// Retrieves the console's title in UTF8.
|
||||||
|
/// @returns The console's title.
|
||||||
|
/// @warning Has to convert from UTF16 to UTF8 for the Windows API.
|
||||||
|
static Str_8 GetTitle_8();
|
||||||
|
|
||||||
|
/// Retrieves the string used when executing the end application through a command line interface in UTF32.
|
||||||
|
/// @returns The result.
|
||||||
|
static Vector<Str_32> GetArgs_32(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
/// Retrieves the string used when executing the end application through a command line interface in UTF16.
|
||||||
|
/// @returns The result.
|
||||||
|
static Vector<Str_16> GetArgs_16(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
/// Retrieves the string used when executing the end application through a command line interface in UTF8.
|
||||||
|
/// @returns The result.
|
||||||
|
static Vector<Str_8> GetArgs_8(UInt_64 bufferSize = 1024);
|
||||||
|
};
|
||||||
|
}
|
@ -1,115 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ehs/Str.h"
|
#include "ehs/system/OS.h"
|
||||||
#include "ehs/UTF.h"
|
|
||||||
#include "ehs/Array.h"
|
|
||||||
|
|
||||||
namespace ehs
|
#if defined(EHS_OS_WINDOWS)
|
||||||
{
|
#include "Console_W32.h"
|
||||||
#if defined(EHS_OS_WINDOWS)
|
#elif defined(EHS_OS_LINUX)
|
||||||
typedef void* ConsoleHdl;
|
#include "Console_LNX.h"
|
||||||
#elif defined(EHS_OS_LINUX)
|
#endif
|
||||||
typedef int ConsoleHdl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Console
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static ConsoleHdl hdlOut;
|
|
||||||
static ConsoleHdl hdlIn;
|
|
||||||
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
static bool isConsole;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void Attach();
|
|
||||||
|
|
||||||
/// Creates a console using standard input and output.
|
|
||||||
/// @param [in] inputRequired Whether or not input is required from the console.
|
|
||||||
static bool Create();
|
|
||||||
|
|
||||||
/// Frees the current console being used.
|
|
||||||
static void Free();
|
|
||||||
|
|
||||||
static bool CanRead();
|
|
||||||
|
|
||||||
static bool CanWrite();
|
|
||||||
|
|
||||||
/// Writes to console using UTF32.
|
|
||||||
/// @param [in] str The text to write to the console.
|
|
||||||
/// @param [in] newLine To make a new line after the given text.
|
|
||||||
/// @warning Has to convert from UTF32 to UTF16 for the Windows API.
|
|
||||||
static void Write_32(const Str_32& str, const bool newLine = true);
|
|
||||||
|
|
||||||
/// Writes to console using UTF16.
|
|
||||||
/// @param [in] str The text to write to the console.
|
|
||||||
/// @param [in] newLine To make a new line after the given text.
|
|
||||||
static void Write_16(const Str_16& str, const bool newLine = true);
|
|
||||||
|
|
||||||
/// Writes to console using UTF8.
|
|
||||||
/// @param [in] str The text to write to the console.
|
|
||||||
/// @param [in] newLine To make a new line after the given text.
|
|
||||||
/// @warning Has to convert from UTF8 to UTF16 for the Windows API.
|
|
||||||
static void Write_8(const Str_8& str, const bool newLine = true);
|
|
||||||
|
|
||||||
/// Reads from the console using UTF32.
|
|
||||||
/// @returns The text the user wrote to the console.
|
|
||||||
/// @warning Has to convert from UTF16 to UTF32 for the Windows API.
|
|
||||||
static Str_32 Read_32(const UInt_64 bufferSize = 1024);
|
|
||||||
|
|
||||||
/// Reads from the console using UTF16.
|
|
||||||
/// @returns The text the user wrote to the console.
|
|
||||||
static Str_16 Read_16(const UInt_64 bufferSize = 1024);
|
|
||||||
|
|
||||||
/// Reads from the console using UTF8.
|
|
||||||
/// @returns The text the user wrote to the console.
|
|
||||||
/// @warning Has to convert from UTF8 to UTF16 for the Windows API.
|
|
||||||
static Str_8 Read_8(const UInt_64 bufferSize = 1024);
|
|
||||||
|
|
||||||
/// Clears the console.
|
|
||||||
static void Clear();
|
|
||||||
|
|
||||||
/// Changes the console's title.
|
|
||||||
/// @param [in] title The text to change the title to.
|
|
||||||
/// @warning Has to convert from UTF32 to UTF16 for the Windows API.
|
|
||||||
static void SetTitle_32(const Str_32& title);
|
|
||||||
|
|
||||||
/// Changes the console's title.
|
|
||||||
/// @param [in] title The text to change the title to.
|
|
||||||
static void SetTitle_16(const Str_16& title);
|
|
||||||
|
|
||||||
/// Changes the console's title.
|
|
||||||
/// @param [in] title The text to change the title to.
|
|
||||||
/// @warning Has to convert from UTF8 to UTF16 for the Windows API.
|
|
||||||
static void SetTitle_8(const Str_8& title);
|
|
||||||
|
|
||||||
/// Retrieves the console's title in UTF32.
|
|
||||||
/// @returns The console's title.
|
|
||||||
/// @warning Has to convert from UTF16 to UTF32 for the Windows API.
|
|
||||||
static Str_32 GetTitle_32();
|
|
||||||
|
|
||||||
/// Retrieves the console's title in UTF16.
|
|
||||||
/// @returns The console's title.
|
|
||||||
static Str_16 GetTitle_16();
|
|
||||||
|
|
||||||
/// Retrieves the console's title in UTF8.
|
|
||||||
/// @returns The console's title.
|
|
||||||
/// @warning Has to convert from UTF16 to UTF8 for the Windows API.
|
|
||||||
static Str_8 GetTitle_8();
|
|
||||||
|
|
||||||
/// Retrieves the string used when executing the end application through a command line interface in UTF32.
|
|
||||||
/// @returns The result.
|
|
||||||
static Vector<Str_32> GetArgs_32(const UInt_64 bufferSize = 1024);
|
|
||||||
|
|
||||||
/// Retrieves the string used when executing the end application through a command line interface in UTF16.
|
|
||||||
/// @returns The result.
|
|
||||||
static Vector<Str_16> GetArgs_16(const UInt_64 bufferSize = 1024);
|
|
||||||
|
|
||||||
/// Retrieves the string used when executing the end application through a command line interface in UTF8.
|
|
||||||
/// @returns The result.
|
|
||||||
static Vector<Str_8> GetArgs_8(const UInt_64 bufferSize = 1024);
|
|
||||||
|
|
||||||
//static void* GetHandle();
|
|
||||||
};
|
|
||||||
}
|
|
50
include/ehs/io/Console_LNX.h
Normal file
50
include/ehs/io/Console_LNX.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BaseConsole.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
class Console : public BaseConsole
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static int hdlOut;
|
||||||
|
static int hdlIn;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Attach();
|
||||||
|
|
||||||
|
static void Free();
|
||||||
|
|
||||||
|
static void Write_32(const Str_32& str, bool newLine = true);
|
||||||
|
|
||||||
|
static void Write_16(const Str_16& str, bool newLine = true);
|
||||||
|
|
||||||
|
static void Write_8(const Str_8& str, bool newLine = true);
|
||||||
|
|
||||||
|
static Str_32 Read_32(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Str_16 Read_16(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Str_8 Read_8(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static void Clear();
|
||||||
|
|
||||||
|
static void SetTitle_32(const Str_32& title);
|
||||||
|
|
||||||
|
static void SetTitle_16(const Str_16& title);
|
||||||
|
|
||||||
|
static void SetTitle_8(const Str_8& title);
|
||||||
|
|
||||||
|
static Str_32 GetTitle_32();
|
||||||
|
|
||||||
|
static Str_16 GetTitle_16();
|
||||||
|
|
||||||
|
static Str_8 GetTitle_8();
|
||||||
|
|
||||||
|
static Vector<Str_32> GetArgs_32(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Vector<Str_16> GetArgs_16(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Vector<Str_8> GetArgs_8(UInt_64 bufferSize = 1024);
|
||||||
|
};
|
||||||
|
}
|
51
include/ehs/io/Console_W32.h
Normal file
51
include/ehs/io/Console_W32.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BaseConsole.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
class Console : public BaseConsole
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static void* hdlOut;
|
||||||
|
static void* hdlIn;
|
||||||
|
static bool isConsole;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void Attach();
|
||||||
|
|
||||||
|
static void Free();
|
||||||
|
|
||||||
|
static void Write_32(const Str_32& str, bool newLine = true);
|
||||||
|
|
||||||
|
static void Write_16(const Str_16& str, bool newLine = true);
|
||||||
|
|
||||||
|
static void Write_8(const Str_8& str, bool newLine = true);
|
||||||
|
|
||||||
|
static Str_32 Read_32(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Str_16 Read_16(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Str_8 Read_8(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static void Clear();
|
||||||
|
|
||||||
|
static void SetTitle_32(const Str_32& title);
|
||||||
|
|
||||||
|
static void SetTitle_16(const Str_16& title);
|
||||||
|
|
||||||
|
static void SetTitle_8(const Str_8& title);
|
||||||
|
|
||||||
|
static Str_32 GetTitle_32();
|
||||||
|
|
||||||
|
static Str_16 GetTitle_16();
|
||||||
|
|
||||||
|
static Str_8 GetTitle_8();
|
||||||
|
|
||||||
|
static Vector<Str_32> GetArgs_32(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Vector<Str_16> GetArgs_16(UInt_64 bufferSize = 1024);
|
||||||
|
|
||||||
|
static Vector<Str_8> GetArgs_8(UInt_64 bufferSize = 1024);
|
||||||
|
};
|
||||||
|
}
|
51
include/ehs/system/BaseThread.h
Normal file
51
include/ehs/system/BaseThread.h
Normal 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
58
include/ehs/system/Lock.h
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
@ -10,7 +10,7 @@ namespace ehs
|
|||||||
class Mutex : public BaseMutex
|
class Mutex : public BaseMutex
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
pthread_mutex_t hdl;
|
volatile UInt_64 state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Mutex() override;
|
~Mutex() override;
|
||||||
|
@ -1,148 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ehs/EHS.h"
|
#include "ehs/system/OS.h"
|
||||||
#include "ehs/Serializer.h"
|
|
||||||
#include "ehs/Array.h"
|
|
||||||
#include "ehs/Log.h"
|
|
||||||
#include "ehs/Str.h"
|
|
||||||
|
|
||||||
#ifdef EHS_OS_WINDOWS
|
#if defined(EHS_OS_WINDOWS)
|
||||||
#include <processthreadsapi.h>
|
#include "Thread_W32.h"
|
||||||
#endif
|
#elif defined(EHS_OS_LINUX)
|
||||||
|
#include "Thread_LNX.h"
|
||||||
namespace ehs
|
#endif
|
||||||
{
|
|
||||||
#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);
|
|
||||||
};
|
|
||||||
}
|
|
42
include/ehs/system/Thread_LNX.h
Normal file
42
include/ehs/system/Thread_LNX.h
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
37
include/ehs/system/Thread_W32.h
Normal file
37
include/ehs/system/Thread_W32.h
Normal 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);
|
||||||
|
};
|
||||||
|
}
|
96
src/CRT_LNX.cpp
Normal file
96
src/CRT_LNX.cpp
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#include "ehs/Log.h"
|
||||||
|
#include "ehs/HRNG.h"
|
||||||
|
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
long syscall(long number, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, number);
|
||||||
|
|
||||||
|
// Retrieve the system call arguments.
|
||||||
|
unsigned long arg1 = va_arg(args, unsigned long);
|
||||||
|
unsigned long arg2 = va_arg(args, unsigned long);
|
||||||
|
unsigned long arg3 = va_arg(args, unsigned long);
|
||||||
|
unsigned long arg4 = va_arg(args, unsigned long);
|
||||||
|
unsigned long arg5 = va_arg(args, unsigned long);
|
||||||
|
unsigned long arg6 = va_arg(args, unsigned long);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Variable to store the system call return value
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
// Inline assembly to perform the system call
|
||||||
|
__asm__ volatile (
|
||||||
|
"mov %1, %%rax\n\t" // System call number -> RAX
|
||||||
|
"mov %2, %%rdi\n\t" // First argument -> RDI
|
||||||
|
"mov %3, %%rsi\n\t" // Second argument -> RSI
|
||||||
|
"mov %4, %%rdx\n\t" // Third argument -> RDX
|
||||||
|
"mov %5, %%r10\n\t" // Fourth argument -> R10
|
||||||
|
"mov %6, %%r8\n\t" // Fifth argument -> R8
|
||||||
|
"mov %7, %%r9\n\t" // Sixth argument -> R9
|
||||||
|
"syscall\n\t" // Invoke system call
|
||||||
|
"mov %%rax, %0\n\t" // Store return value
|
||||||
|
: "=r"(ret) // output
|
||||||
|
: "r"(number), "r"(arg1), "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5), "r"(arg6) // inputs
|
||||||
|
: "%rax", "%rdi", "%rsi", "%rdx", "%r10", "%r8", "%r9", "memory", "cc" // clobbers
|
||||||
|
);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int* __errno_location()
|
||||||
|
{
|
||||||
|
static __thread int tls_errno = 0; // __thread or thread_local (C++11 and later)
|
||||||
|
return &tls_errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef EHS_DEBUG
|
||||||
|
unsigned long __stack_chk_guard = 0x0000DEAD;
|
||||||
|
#else
|
||||||
|
unsigned long __stack_chk_guard = ehs::HRNG::GenerateSeed_u64();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void __stack_chk_fail(void)
|
||||||
|
{
|
||||||
|
EHS_LOG("Error", 0, "Found corrupted stack.");
|
||||||
|
|
||||||
|
syscall(SYS_exit, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __cxa_atexit(void (*func)(void *), void *arg, void * /*dso_handle*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t strlen(const char *s)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
while (s[count])
|
||||||
|
count++;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* operator new[](unsigned long size) noexcept(false)
|
||||||
|
{
|
||||||
|
syscall(SYS_brk,)
|
||||||
|
void* ptr = (void*)syscall(SYS_mmap, nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (ptr == MAP_FAILED)
|
||||||
|
{
|
||||||
|
EHS_LOG("Error", 0, "Failed to allocate memory on the heap.");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void* ptr) noexcept
|
||||||
|
{
|
||||||
|
syscall(SYS_munmap, ptr, GetStackSize())
|
||||||
|
}
|
@ -10,10 +10,6 @@
|
|||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
#if defined(EHS_OS_LINUX)
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
constexpr Char_32 name_32[] = U"Event Horizon Suite";
|
constexpr Char_32 name_32[] = U"Event Horizon Suite";
|
||||||
@ -636,7 +632,7 @@ void LogRaised(const ehs::Log& log)
|
|||||||
|
|
||||||
result += "} (" + ehs::Str_8::FromNum(log.GetCode()) + "): " + log.GetMsg();
|
result += "} (" + ehs::Str_8::FromNum(log.GetCode()) + "): " + log.GetMsg();
|
||||||
|
|
||||||
ehs::Console::Write_8(result);
|
ehs::BaseConsole::Write_8(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@ -685,5 +681,7 @@ int main()
|
|||||||
|
|
||||||
ehs::GarbageCollector::Stop();
|
ehs::GarbageCollector::Stop();
|
||||||
|
|
||||||
|
ehs::Console::Free();
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ namespace ehs
|
|||||||
while (GarbageCollector::IsRunning())
|
while (GarbageCollector::IsRunning())
|
||||||
{
|
{
|
||||||
GarbageCollector::Poll();
|
GarbageCollector::Poll();
|
||||||
Thread::SleepFor(50);
|
Thread::HardSleep(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
GarbageCollector::Dump();
|
GarbageCollector::Dump();
|
||||||
@ -37,7 +37,7 @@ namespace ehs
|
|||||||
|
|
||||||
mutex.Initialize();
|
mutex.Initialize();
|
||||||
|
|
||||||
thread.Start(GarbageCollectionThread, nullptr);
|
thread = Thread(1, nullptr, GarbageCollectionThread);
|
||||||
|
|
||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <ehs/EHS.h>
|
#include <ehs/EHS.h>
|
||||||
#include <ehs/Str.h>
|
#include <ehs/Str.h>
|
||||||
#include <ehs/io/Console.h>
|
#include <ehs/io/BaseConsole.h>
|
||||||
|
|
||||||
ehs::Int_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVer)
|
ehs::Int_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVer)
|
||||||
{
|
{
|
||||||
@ -8,23 +8,23 @@ ehs::Int_32 Main(ehs::Str_8* appName, ehs::Str_8* appVerId, ehs::Version* appVer
|
|||||||
*appVerId = "Release";
|
*appVerId = "Release";
|
||||||
*appVer = {1, 0, 0};
|
*appVer = {1, 0, 0};
|
||||||
|
|
||||||
ehs::Vector<ehs::Str_8> args = ehs::Console::GetArgs_8();
|
ehs::Vector<ehs::Str_8> args = ehs::BaseConsole::GetArgs_8();
|
||||||
|
|
||||||
if (args.Size() > 1)
|
if (args.Size() > 1)
|
||||||
{
|
{
|
||||||
for (ehs::UInt_64 i = 1; i < args.Size(); ++i)
|
for (ehs::UInt_64 i = 1; i < args.Size(); ++i)
|
||||||
ehs::Console::Write_8("Result " + ehs::Str_8::FromNum(i) + ": " + ehs::Str_8::FromNum(args[i].Hash_64()));
|
ehs::BaseConsole::Write_8("Result " + ehs::Str_8::FromNum(i) + ": " + ehs::Str_8::FromNum(args[i].Hash_64()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ehs::Console::Write_8("String: ", false);
|
ehs::BaseConsole::Write_8("String: ", false);
|
||||||
ehs::Str_8 in = ehs::Console::Read_8();
|
ehs::Str_8 in = ehs::BaseConsole::Read_8();
|
||||||
ehs::Console::Write_8("Result: " + ehs::Str_8::FromNum(in.Hash_64()));
|
ehs::BaseConsole::Write_8("Result: " + ehs::Str_8::FromNum(in.Hash_64()));
|
||||||
|
|
||||||
ehs::Console::Read_8();
|
ehs::BaseConsole::Read_8();
|
||||||
}
|
}
|
||||||
|
|
||||||
ehs::Console::Free();
|
ehs::BaseConsole::Free();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ namespace ehs
|
|||||||
threadArgs->Write(callback);
|
threadArgs->Write(callback);
|
||||||
threadArgs->SetOffset(0);
|
threadArgs->SetOffset(0);
|
||||||
|
|
||||||
thread.Start(TaskThread, threadArgs);
|
thread = Thread(1024, threadArgs, TaskThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Task::Release()
|
void Task::Release()
|
||||||
|
85
src/io/BaseConsole.cpp
Normal file
85
src/io/BaseConsole.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#include "ehs/io/BaseConsole.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
void BaseConsole::Attach()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::Free()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::Write_32(const Str_32& str, const bool newLine)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::Write_16(const Str_16& str, const bool newLine)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::Write_8(const Str_8& str, const bool newLine)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_32 BaseConsole::Read_32(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_16 BaseConsole::Read_16(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 BaseConsole::Read_8(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::Clear()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::SetTitle_32(const Str_32& title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::SetTitle_16(const Str_16& title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseConsole::SetTitle_8(const Str_8& title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_32 BaseConsole::GetTitle_32()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_16 BaseConsole::GetTitle_16()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 BaseConsole::GetTitle_8()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_32> BaseConsole::GetArgs_32(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_16> BaseConsole::GetArgs_16(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_8> BaseConsole::GetArgs_8(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
@ -1,799 +0,0 @@
|
|||||||
#include "ehs/io/Console.h"
|
|
||||||
#include "ehs/Log.h"
|
|
||||||
#include "ehs/io/File.h"
|
|
||||||
|
|
||||||
#if defined(EHS_OS_LINUX)
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <cerrno>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ehs
|
|
||||||
{
|
|
||||||
ConsoleHdl Console::hdlOut = 0;
|
|
||||||
ConsoleHdl Console::hdlIn = 0;
|
|
||||||
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
bool Console::isConsole = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Console::Attach()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (!AttachConsole(ATTACH_PARENT_PROCESS))
|
|
||||||
{
|
|
||||||
DWORD code = GetLastError();
|
|
||||||
if (code == ERROR_INVALID_HANDLE)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdlIn = GetStdHandle(STD_INPUT_HANDLE);
|
|
||||||
hdlOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
|
|
||||||
DWORD mode = 0;
|
|
||||||
|
|
||||||
if (!GetConsoleMode(hdlOut, &mode))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_INVALID_HANDLE)
|
|
||||||
isConsole = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//DWORD code = WaitForSingleObject(hdlIn, 15000);
|
|
||||||
//if (code == WAIT_FAILED || code == WAIT_TIMEOUT || code == WAIT_ABANDONED)
|
|
||||||
// EHS_LOG_INT("Error", 0, "Failed to wait for console input.");
|
|
||||||
|
|
||||||
isConsole = true;
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
hdlOut = open("/dev/stdout", O_WRONLY | O_SYNC);
|
|
||||||
hdlIn = open("/dev/stdin", O_RDONLY);
|
|
||||||
#else
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Console::Create()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (!AllocConsole())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
hdlIn = GetStdHandle(STD_INPUT_HANDLE);
|
|
||||||
hdlOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
|
|
||||||
if (WaitForSingleObject(hdlIn, EHS_INFINITE) == WAIT_FAILED)
|
|
||||||
EHS_LOG_INT("Error", 2, "Failed to wait for console input.");
|
|
||||||
|
|
||||||
//if (!SetConsoleActiveScreenBuffer(hdlOut))
|
|
||||||
// EHS_LOG_INT("Error", 3, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
isConsole = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::Free()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (!FreeConsole())
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
int code = close(hdlOut);
|
|
||||||
if (code == -1)
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to free the console output with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
|
|
||||||
code = close(hdlIn);
|
|
||||||
if (code == -1)
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to free the console input with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hdlOut = 0;
|
|
||||||
hdlIn = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Console::CanRead()
|
|
||||||
{
|
|
||||||
return hdlIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Console::CanWrite()
|
|
||||||
{
|
|
||||||
return hdlOut;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::Write_32(const Str_32& str, const bool newLine)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (isConsole)
|
|
||||||
{
|
|
||||||
Str_16 r = UTF::To_16(str);
|
|
||||||
if (newLine)
|
|
||||||
r += L"\r\n";
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < r.Size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Str_8 r = UTF::To_8(str);
|
|
||||||
if (newLine)
|
|
||||||
r += "\r\n";
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < r.Size(true));
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_32 result = str;
|
|
||||||
if (newLine)
|
|
||||||
result += U"\n";
|
|
||||||
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, result, result.Size(true));
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < result.Size(true));
|
|
||||||
#else
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::Write_16(const Str_16& str, const bool newLine)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (isConsole)
|
|
||||||
{
|
|
||||||
Str_16 r = str;
|
|
||||||
if (newLine)
|
|
||||||
r += L"\r\n";
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < r.Size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Str_8 r = UTF::To_8(str);
|
|
||||||
if (newLine)
|
|
||||||
r += "\r\n";
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < r.Size(true));
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_16 result = str;
|
|
||||||
if (newLine)
|
|
||||||
result += L"\n";
|
|
||||||
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, result, result.Size(true));
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < result.Size(true));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::Write_8(const Str_8& str, const bool newLine)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (isConsole)
|
|
||||||
{
|
|
||||||
Str_16 r = UTF::To_16(str);
|
|
||||||
if (newLine)
|
|
||||||
r += L"\r\n";
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < r.Size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Str_8 r = str;
|
|
||||||
if (newLine)
|
|
||||||
r += "\r\n";
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!WriteFile(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < r.Size());
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_8 result = str;
|
|
||||||
if (newLine)
|
|
||||||
result += "\n";
|
|
||||||
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, result, result.Size());
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < result.Size());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Str_32 Console::Read_32(const UInt_64 bufferSize)
|
|
||||||
{
|
|
||||||
if (!hdlIn)
|
|
||||||
return U"";
|
|
||||||
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (isConsole)
|
|
||||||
{
|
|
||||||
Str_16 result;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result.Resize(result.Size() + bufferSize);
|
|
||||||
|
|
||||||
DWORD read = 0;
|
|
||||||
|
|
||||||
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return U"";
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
while (result[offset - 1] != L'\n');
|
|
||||||
|
|
||||||
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
|
||||||
result.Resize(offset - 2);
|
|
||||||
else
|
|
||||||
result.Resize(offset - 1);
|
|
||||||
|
|
||||||
return UTF::To_32(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Str_8 result;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result.Resize(result.Size() + bufferSize);
|
|
||||||
|
|
||||||
DWORD read = 0;
|
|
||||||
|
|
||||||
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return U"";
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
while (result[offset - 1] != '\n');
|
|
||||||
|
|
||||||
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
|
||||||
result.Resize(offset - 2);
|
|
||||||
else
|
|
||||||
result.Resize(offset - 1);
|
|
||||||
|
|
||||||
return UTF::To_32(result);
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_32 result;
|
|
||||||
Str_32 input(bufferSize);
|
|
||||||
ssize_t read = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
read = ::read(hdlIn, input, bufferSize);
|
|
||||||
if (read == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result.Push(input, read);
|
|
||||||
}
|
|
||||||
while (input[read - 1] != U'\n');
|
|
||||||
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Str_16 Console::Read_16(const UInt_64 bufferSize)
|
|
||||||
{
|
|
||||||
if (!hdlIn)
|
|
||||||
return L"";
|
|
||||||
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (isConsole)
|
|
||||||
{
|
|
||||||
Str_16 result;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result.Resize(result.Size() + bufferSize);
|
|
||||||
|
|
||||||
DWORD read = 0;
|
|
||||||
|
|
||||||
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return L"";
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
while (result[offset - 1] != L'\n');
|
|
||||||
|
|
||||||
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
|
||||||
result.Resize(offset - 2);
|
|
||||||
else
|
|
||||||
result.Resize(offset - 1);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Str_8 result;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result.Resize(result.Size() + bufferSize);
|
|
||||||
|
|
||||||
DWORD read = 0;
|
|
||||||
|
|
||||||
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return L"";
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
while (result[offset - 1] != '\n');
|
|
||||||
|
|
||||||
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
|
||||||
result.Resize(offset - 2);
|
|
||||||
else
|
|
||||||
result.Resize(offset - 1);
|
|
||||||
|
|
||||||
return UTF::To_16(result);
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_16 result;
|
|
||||||
Str_16 input(bufferSize);
|
|
||||||
ssize_t read = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
read = ::read(hdlIn, input, bufferSize);
|
|
||||||
if (read == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result.Push(input, read);
|
|
||||||
}
|
|
||||||
while (input[read - 1] != L'\n');
|
|
||||||
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Str_8 Console::Read_8(const UInt_64 bufferSize)
|
|
||||||
{
|
|
||||||
if (!hdlIn)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (isConsole)
|
|
||||||
{
|
|
||||||
Str_16 result;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result.Resize(result.Size() + bufferSize);
|
|
||||||
|
|
||||||
DWORD read = 0;
|
|
||||||
|
|
||||||
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
while (result[offset - 1] != L'\n');
|
|
||||||
|
|
||||||
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
|
||||||
result.Resize(offset - 2);
|
|
||||||
else
|
|
||||||
result.Resize(offset - 1);
|
|
||||||
|
|
||||||
return UTF::To_8(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Str_8 result;
|
|
||||||
|
|
||||||
DWORD offset = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
result.Resize(result.Size() + bufferSize);
|
|
||||||
|
|
||||||
DWORD read = 0;
|
|
||||||
|
|
||||||
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += read;
|
|
||||||
}
|
|
||||||
while (result[offset - 1] != '\n');
|
|
||||||
|
|
||||||
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
|
||||||
result.Resize(offset - 2);
|
|
||||||
else
|
|
||||||
result.Resize(offset - 1);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_8 result;
|
|
||||||
Str_8 input(bufferSize);
|
|
||||||
ssize_t read = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
read = ::read(hdlIn, input, bufferSize);
|
|
||||||
if (read == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result.Push(input, read);
|
|
||||||
}
|
|
||||||
while (input[read - 1] != '\n');
|
|
||||||
|
|
||||||
return result.Sub(0, result.Size() - 1);
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::Clear()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
|
||||||
if (!GetConsoleScreenBufferInfo(hdlOut, &info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
DWORD size = info.dwSize.X * info.dwSize.Y;
|
|
||||||
|
|
||||||
DWORD written = 0;
|
|
||||||
if (!FillConsoleOutputCharacterW(hdlOut, L' ', size, {0, 0}, &written))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!GetConsoleScreenBufferInfo(hdlOut, &info))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!FillConsoleOutputAttribute(hdlOut, info.wAttributes, size, {0, 0}, &written))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SetConsoleCursorPosition(hdlOut, {0, 0});
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
const Char_8 code[] = "\033[2J\033[1;1H";
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, code, sizeof(code));
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to clear console with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < sizeof(code));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::SetTitle_32(const Str_32& title)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (!SetConsoleTitleW(UTF::To_16(title)))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_32 code = U"\033]0;" + title + U"\007";
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, code, code.Size(true));
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < code.Size(true));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::SetTitle_16(const Str_16& title)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (!SetConsoleTitleW(title))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_16 code = L"\033]0;" + title + L"\007";
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, code, code.Size(true));
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < code.Size(true));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Console::SetTitle_8(const Str_8& title)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
if (!SetConsoleTitleW(UTF::To_16(title)))
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
Str_8 code = "\033]0;" + title + "\007";
|
|
||||||
UInt_64 offset = 0;
|
|
||||||
do {
|
|
||||||
ssize_t written = write(hdlOut, code, code.Size());
|
|
||||||
if (written == -1)
|
|
||||||
{
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
offset += written;
|
|
||||||
}
|
|
||||||
while (offset < code.Size());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Str_32 Console::GetTitle_32()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
Str_16 title(EHS_MAX_PATH);
|
|
||||||
|
|
||||||
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
|
||||||
|
|
||||||
title.Resize(size);
|
|
||||||
|
|
||||||
return UTF::To_32(title);
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Str_16 Console::GetTitle_16()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
Str_16 title(EHS_MAX_PATH);
|
|
||||||
|
|
||||||
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
|
||||||
|
|
||||||
title.Resize(size);
|
|
||||||
|
|
||||||
return title;
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Str_8 Console::GetTitle_8()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
Str_16 title(EHS_MAX_PATH);
|
|
||||||
|
|
||||||
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
|
||||||
|
|
||||||
title.Resize(size);
|
|
||||||
|
|
||||||
return UTF::To_8(title);
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Str_32> Console::GetArgs_32(const UInt_64 bufferSize)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
return UTF::To_32(GetCommandLineW()).Split(U" ");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
|
||||||
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
|
||||||
cmdFile.Release();
|
|
||||||
|
|
||||||
Vector<Str_32> args;
|
|
||||||
|
|
||||||
UInt_64 o = 0;
|
|
||||||
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
|
||||||
{
|
|
||||||
if (data[i] != '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
args.Push(UTF::To_32((Char_8*)&data[o], i - o));
|
|
||||||
o = i + sizeof(Char_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o < data.Size())
|
|
||||||
args.Push(UTF::To_32((Char_8*)&data[o], data.Size() - o - 1));
|
|
||||||
|
|
||||||
return args;
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
return Str_16(GetCommandLineW()).Split(L" ");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
|
||||||
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
|
||||||
cmdFile.Release();
|
|
||||||
|
|
||||||
Vector<Str_16> args;
|
|
||||||
|
|
||||||
UInt_64 o = 0;
|
|
||||||
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
|
||||||
{
|
|
||||||
if (data[i] != '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
args.Push(UTF::To_16((Char_8*)&data[o], i - o));
|
|
||||||
o = i + sizeof(Char_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o < data.Size())
|
|
||||||
args.Push(UTF::To_16((Char_8*)&data[o], data.Size() - o - 1));
|
|
||||||
|
|
||||||
return args;
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize)
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
return UTF::To_8(GetCommandLineW()).Split(" ");
|
|
||||||
#elif defined(EHS_OS_LINUX)
|
|
||||||
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
|
||||||
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
|
||||||
cmdFile.Release();
|
|
||||||
|
|
||||||
Vector<Str_8> args;
|
|
||||||
|
|
||||||
UInt_64 o = 0;
|
|
||||||
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
|
||||||
{
|
|
||||||
if (data[i] != '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
args.Push(Str_8((Char_8*)&data[o], i - o));
|
|
||||||
o = i + sizeof(Char_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o < data.Size())
|
|
||||||
args.Push(Str_8((Char_8*)&data[o], data.Size() - o - 1));
|
|
||||||
|
|
||||||
return args;
|
|
||||||
#else
|
|
||||||
return {};
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void* Console::GetHandle()
|
|
||||||
{
|
|
||||||
#if defined(EHS_OS_WINDOWS)
|
|
||||||
void* hdl = FindWindowW(nullptr, GetTitle_16());
|
|
||||||
if (hdl == nullptr)
|
|
||||||
EHS_LOG_INT("Error", 0, "Failed to retrieve native handle with error #" + Str_8::FromNum(GetLastError()) + ".");
|
|
||||||
|
|
||||||
return hdl;
|
|
||||||
#else
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
308
src/io/Console_LNX.cpp
Normal file
308
src/io/Console_LNX.cpp
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
#include "ehs/io/Console_LNX.h"
|
||||||
|
#include "ehs/io/File.h"
|
||||||
|
#include "ehs/Log.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
int Console::hdlOut = 0;
|
||||||
|
int Console::hdlIn = 0;
|
||||||
|
|
||||||
|
void Console::Attach()
|
||||||
|
{
|
||||||
|
hdlOut = (int)syscall(SYS_open, "/dev/stdout", O_WRONLY | O_SYNC);
|
||||||
|
hdlIn = (int)syscall(SYS_open, "/dev/stdin", O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Free()
|
||||||
|
{
|
||||||
|
int code = (int)syscall(SYS_close, hdlOut);
|
||||||
|
if (code == -1)
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to free the console output with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
|
hdlOut = 0;
|
||||||
|
|
||||||
|
code = (int)syscall(SYS_close, hdlIn);
|
||||||
|
if (code == -1)
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to free the console input with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
|
hdlIn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Write_32(const Str_32& str, const bool newLine)
|
||||||
|
{
|
||||||
|
Str_32 result = str;
|
||||||
|
if (newLine)
|
||||||
|
result += U"\n";
|
||||||
|
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, &result[0], result.Size(true));
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < result.Size(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Write_16(const Str_16& str, const bool newLine)
|
||||||
|
{
|
||||||
|
Str_16 result = str;
|
||||||
|
if (newLine)
|
||||||
|
result += L"\n";
|
||||||
|
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, &result[0], result.Size(true));
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < result.Size(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Write_8(const Str_8& str, const bool newLine)
|
||||||
|
{
|
||||||
|
Str_8 result = str;
|
||||||
|
if (newLine)
|
||||||
|
result += "\n";
|
||||||
|
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, &result[0], result.Size());
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to write to console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < result.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_32 Console::Read_32(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
Str_32 result;
|
||||||
|
Str_32 input(bufferSize);
|
||||||
|
ssize_t read = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read = syscall(SYS_read, hdlIn, &input[0], bufferSize);
|
||||||
|
if (read == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.Push(input, read);
|
||||||
|
}
|
||||||
|
while (input[read - 1] != U'\n');
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_16 Console::Read_16(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
Str_16 result;
|
||||||
|
Str_16 input(bufferSize);
|
||||||
|
ssize_t read = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read = syscall(SYS_read, hdlIn, &input[0], bufferSize);
|
||||||
|
if (read == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.Push(input, read);
|
||||||
|
}
|
||||||
|
while (input[read - 1] != L'\n');
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 Console::Read_8(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
Str_8 result;
|
||||||
|
Str_8 input(bufferSize);
|
||||||
|
ssize_t read = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
read = syscall(SYS_read, hdlIn, &input[0], bufferSize);
|
||||||
|
if (read == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to read from console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.Push(input, read);
|
||||||
|
}
|
||||||
|
while (input[read - 1] != '\n');
|
||||||
|
|
||||||
|
return result.Sub(0, result.Size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Clear()
|
||||||
|
{
|
||||||
|
const Char_8 code[] = "\033[2J\033[1;1H";
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, code, sizeof(code));
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to clear console with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < sizeof(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::SetTitle_32(const Str_32& title)
|
||||||
|
{
|
||||||
|
Str_32 code = U"\033]0;" + title + U"\007";
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, &code[0], code.Size(true));
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < code.Size(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::SetTitle_16(const Str_16& title)
|
||||||
|
{
|
||||||
|
Str_16 code = L"\033]0;" + title + L"\007";
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, &code[0], code.Size(true));
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < code.Size(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::SetTitle_8(const Str_8& title)
|
||||||
|
{
|
||||||
|
Str_8 code = "\033]0;" + title + "\007";
|
||||||
|
UInt_64 offset = 0;
|
||||||
|
do {
|
||||||
|
ssize_t written = syscall(SYS_write, hdlOut, &code[0], code.Size());
|
||||||
|
if (written == -1)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < code.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_32 Console::GetTitle_32()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_16 Console::GetTitle_16()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 Console::GetTitle_8()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_32> Console::GetArgs_32(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
||||||
|
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
||||||
|
cmdFile.Release();
|
||||||
|
|
||||||
|
Vector<Str_32> args;
|
||||||
|
|
||||||
|
UInt_64 o = 0;
|
||||||
|
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
||||||
|
{
|
||||||
|
if (data[i] != '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
args.Push(UTF::To_32((Char_8*)&data[o], i - o));
|
||||||
|
o = i + sizeof(Char_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o < data.Size())
|
||||||
|
args.Push(UTF::To_32((Char_8*)&data[o], data.Size() - o - 1));
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
||||||
|
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
||||||
|
cmdFile.Release();
|
||||||
|
|
||||||
|
Vector<Str_16> args;
|
||||||
|
|
||||||
|
UInt_64 o = 0;
|
||||||
|
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
||||||
|
{
|
||||||
|
if (data[i] != '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
args.Push(UTF::To_16((Char_8*)&data[o], i - o));
|
||||||
|
o = i + sizeof(Char_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o < data.Size())
|
||||||
|
args.Push(UTF::To_16((Char_8*)&data[o], data.Size() - o - 1));
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
File cmdFile("/proc/self/cmdline", Mode::READ, Disposition::OPEN);
|
||||||
|
Array<Byte> data = cmdFile.ReadArray(bufferSize);
|
||||||
|
cmdFile.Release();
|
||||||
|
|
||||||
|
Vector<Str_8> args;
|
||||||
|
|
||||||
|
UInt_64 o = 0;
|
||||||
|
for (UInt_64 i = 0; i < data.Size() - 1; i += sizeof(Char_8))
|
||||||
|
{
|
||||||
|
if (data[i] != '\0')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
args.Push(Str_8((Char_8*)&data[o], i - o));
|
||||||
|
o = i + sizeof(Char_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o < data.Size())
|
||||||
|
args.Push(Str_8((Char_8*)&data[o], data.Size() - o - 1));
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
442
src/io/Console_W32.cpp
Normal file
442
src/io/Console_W32.cpp
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
#include "ehs/io/Console_W32.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
void* Console::hdlOut = nullptr;
|
||||||
|
void* Console::hdlIn = nullptr;
|
||||||
|
bool Console::isConsole = true;
|
||||||
|
|
||||||
|
void Console::Attach()
|
||||||
|
{
|
||||||
|
if (!AttachConsole(ATTACH_PARENT_PROCESS))
|
||||||
|
{
|
||||||
|
DWORD code = GetLastError();
|
||||||
|
if (code == ERROR_INVALID_HANDLE)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdlIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
hdlOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
DWORD mode = 0;
|
||||||
|
|
||||||
|
if (!GetConsoleMode(hdlOut, &mode))
|
||||||
|
{
|
||||||
|
if (GetLastError() == ERROR_INVALID_HANDLE)
|
||||||
|
isConsole = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//DWORD code = WaitForSingleObject(hdlIn, 15000);
|
||||||
|
//if (code == WAIT_FAILED || code == WAIT_TIMEOUT || code == WAIT_ABANDONED)
|
||||||
|
// EHS_LOG_INT("Error", 0, "Failed to wait for console input.");
|
||||||
|
|
||||||
|
isConsole = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Free()
|
||||||
|
{
|
||||||
|
hdlOut = nullptr;
|
||||||
|
hdlIn = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Write_32(const Str_32& str, const bool newLine)
|
||||||
|
{
|
||||||
|
if (isConsole)
|
||||||
|
{
|
||||||
|
Str_16 r = UTF::To_16(str);
|
||||||
|
if (newLine)
|
||||||
|
r += L"\r\n";
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < r.Size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Str_8 r = UTF::To_8(str);
|
||||||
|
if (newLine)
|
||||||
|
r += "\r\n";
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < r.Size(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Write_16(const Str_16& str, const bool newLine)
|
||||||
|
{
|
||||||
|
if (isConsole)
|
||||||
|
{
|
||||||
|
Str_16 r = str;
|
||||||
|
if (newLine)
|
||||||
|
r += L"\r\n";
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < r.Size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Str_8 r = UTF::To_8(str);
|
||||||
|
if (newLine)
|
||||||
|
r += "\r\n";
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!WriteFile(hdlOut, &((Char_8*)r)[offset], (DWORD)r.Size(true) - offset, &written, nullptr))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < r.Size(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Write_8(const Str_8& str, const bool newLine)
|
||||||
|
{
|
||||||
|
if (isConsole)
|
||||||
|
{
|
||||||
|
Str_16 r = UTF::To_16(str);
|
||||||
|
if (newLine)
|
||||||
|
r += L"\r\n";
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!WriteConsoleW(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < r.Size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Str_8 r = str;
|
||||||
|
if (newLine)
|
||||||
|
r += "\r\n";
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!WriteFile(hdlOut, &r[offset], (DWORD)r.Size() - offset, &written, nullptr))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
offset += written;
|
||||||
|
}
|
||||||
|
while (offset < r.Size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_32 Console::Read_32(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
if (isConsole)
|
||||||
|
{
|
||||||
|
Str_16 result;
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result.Resize(result.Size() + bufferSize);
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
|
||||||
|
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
return U"";
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
while (result[offset - 1] != L'\n');
|
||||||
|
|
||||||
|
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
||||||
|
result.Resize(offset - 2);
|
||||||
|
else
|
||||||
|
result.Resize(offset - 1);
|
||||||
|
|
||||||
|
return UTF::To_32(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Str_8 result;
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result.Resize(result.Size() + bufferSize);
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
|
||||||
|
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
return U"";
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
while (result[offset - 1] != '\n');
|
||||||
|
|
||||||
|
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
||||||
|
result.Resize(offset - 2);
|
||||||
|
else
|
||||||
|
result.Resize(offset - 1);
|
||||||
|
|
||||||
|
return UTF::To_32(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_16 Console::Read_16(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
if (isConsole)
|
||||||
|
{
|
||||||
|
Str_16 result;
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result.Resize(result.Size() + bufferSize);
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
|
||||||
|
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
while (result[offset - 1] != L'\n');
|
||||||
|
|
||||||
|
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
||||||
|
result.Resize(offset - 2);
|
||||||
|
else
|
||||||
|
result.Resize(offset - 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Str_8 result;
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result.Resize(result.Size() + bufferSize);
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
|
||||||
|
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
return L"";
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
while (result[offset - 1] != '\n');
|
||||||
|
|
||||||
|
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
||||||
|
result.Resize(offset - 2);
|
||||||
|
else
|
||||||
|
result.Resize(offset - 1);
|
||||||
|
|
||||||
|
return UTF::To_16(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 Console::Read_8(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
if (isConsole)
|
||||||
|
{
|
||||||
|
Str_16 result;
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result.Resize(result.Size() + bufferSize);
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
|
||||||
|
if (!ReadConsoleW(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
while (result[offset - 1] != L'\n');
|
||||||
|
|
||||||
|
if (offset >= 2 && result[offset - 2] == L'\r' && result[offset - 1] == L'\n')
|
||||||
|
result.Resize(offset - 2);
|
||||||
|
else
|
||||||
|
result.Resize(offset - 1);
|
||||||
|
|
||||||
|
return UTF::To_8(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Str_8 result;
|
||||||
|
|
||||||
|
DWORD offset = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result.Resize(result.Size() + bufferSize);
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
|
||||||
|
if (!ReadFile(hdlIn, &result[offset], (DWORD)bufferSize, &read, nullptr))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += read;
|
||||||
|
}
|
||||||
|
while (result[offset - 1] != '\n');
|
||||||
|
|
||||||
|
if (offset >= 2 && result[offset - 2] == '\r' && result[offset - 1] == '\n')
|
||||||
|
result.Resize(offset - 2);
|
||||||
|
else
|
||||||
|
result.Resize(offset - 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::Clear()
|
||||||
|
{
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO info = {};
|
||||||
|
if (!GetConsoleScreenBufferInfo(hdlOut, &info))
|
||||||
|
return;
|
||||||
|
|
||||||
|
DWORD size = info.dwSize.X * info.dwSize.Y;
|
||||||
|
|
||||||
|
DWORD written = 0;
|
||||||
|
if (!FillConsoleOutputCharacterW(hdlOut, L' ', size, {0, 0}, &written))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!GetConsoleScreenBufferInfo(hdlOut, &info))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!FillConsoleOutputAttribute(hdlOut, info.wAttributes, size, {0, 0}, &written))
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetConsoleCursorPosition(hdlOut, {0, 0});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::SetTitle_32(const Str_32& title)
|
||||||
|
{
|
||||||
|
if (!SetConsoleTitleW(UTF::To_16(title)))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to set console title with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::SetTitle_16(const Str_16& title)
|
||||||
|
{
|
||||||
|
if (!SetConsoleTitleW(title))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::SetTitle_8(const Str_8& title)
|
||||||
|
{
|
||||||
|
if (!SetConsoleTitleW(UTF::To_16(title)))
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_32 Console::GetTitle_32()
|
||||||
|
{
|
||||||
|
Str_16 title(EHS_MAX_PATH);
|
||||||
|
|
||||||
|
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
||||||
|
|
||||||
|
title.Resize(size);
|
||||||
|
|
||||||
|
return UTF::To_32(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_16 Console::GetTitle_16()
|
||||||
|
{
|
||||||
|
Str_16 title(EHS_MAX_PATH);
|
||||||
|
|
||||||
|
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
||||||
|
|
||||||
|
title.Resize(size);
|
||||||
|
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_8 Console::GetTitle_8()
|
||||||
|
{
|
||||||
|
Str_16 title(EHS_MAX_PATH);
|
||||||
|
|
||||||
|
DWORD size = GetConsoleTitleW(&title[0], EHS_MAX_PATH);
|
||||||
|
|
||||||
|
title.Resize(size);
|
||||||
|
|
||||||
|
return UTF::To_8(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_32> Console::GetArgs_32(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return UTF::To_32(GetCommandLineW()).Split(U" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_16> Console::GetArgs_16(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return Str_16(GetCommandLineW()).Split(L" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<Str_8> Console::GetArgs_8(const UInt_64 bufferSize)
|
||||||
|
{
|
||||||
|
return UTF::To_8(GetCommandLineW()).Split(" ");
|
||||||
|
}
|
||||||
|
}
|
@ -7,15 +7,16 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
File::~File()
|
File::~File()
|
||||||
{
|
{
|
||||||
if (map != MAP_FAILED && munmap(map, mapSize) == -1)
|
if (map != MAP_FAILED && syscall(SYS_munmap, map, mapSize) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
if (hdl >= 0 && close(hdl) == -1)
|
if (hdl >= 0 && syscall(SYS_close, hdl) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,22 +62,22 @@ namespace ehs
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdl = open64(path, linuxMode | linuxDisp, S_IRUSR | S_IWUSR);
|
hdl = (int)syscall(SYS_open, &path[0], linuxMode | linuxDisp, S_IRUSR | S_IWUSR);
|
||||||
if (hdl == -1)
|
if (hdl == -1)
|
||||||
{
|
{
|
||||||
SInt_32 code = errno;
|
SInt_32 code = errno;
|
||||||
if (code == EEXIST && (disposition == Disposition::CREATE_PERSISTENT || disposition == Disposition::OPEN_PERSISTENT))
|
if (code == EEXIST && (disposition == Disposition::CREATE_PERSISTENT || disposition == Disposition::OPEN_PERSISTENT))
|
||||||
{
|
{
|
||||||
hdl = open64(path, linuxMode, S_IRUSR | S_IWUSR);
|
hdl = (int)syscall(SYS_open, &path[0], linuxMode, S_IRUSR | S_IWUSR);
|
||||||
if (hdl == -1)
|
if (hdl == -1)
|
||||||
EHS_LOG_INT("Error", 0, strerror(errno));
|
EHS_LOG_INT("Error", 0, "Failed to create file.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (code == ENOENT)
|
if (code == ENOENT)
|
||||||
EHS_LOG_INT("Error", 0, "File at filepath, \"" + filePath + "\" not found.");
|
EHS_LOG_INT("Error", 0, "File at filepath, \"" + filePath + "\" not found.");
|
||||||
else
|
else
|
||||||
EHS_LOG_INT("Error", 0, strerror(code));
|
EHS_LOG_INT("Error", 0, "Failed to open file.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,12 +137,12 @@ namespace ehs
|
|||||||
|
|
||||||
void File::Release()
|
void File::Release()
|
||||||
{
|
{
|
||||||
if (IsMapped() && munmap(map, mapSize) == -1)
|
if (IsMapped() && syscall(SYS_munmap, map, mapSize) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||||
map = MAP_FAILED;
|
map = MAP_FAILED;
|
||||||
mapSize = 0;
|
mapSize = 0;
|
||||||
|
|
||||||
if (IsValid() && close(hdl) == -1)
|
if (IsValid() && syscall(SYS_close, hdl) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to close file handle with error #" + Str_8::FromNum(errno) + ".");
|
||||||
hdl = -1;
|
hdl = -1;
|
||||||
}
|
}
|
||||||
@ -175,7 +176,7 @@ namespace ehs
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
map = mmap64(nullptr, size, linuxMode, MAP_SHARED, hdl, (off64_t)offset);
|
map = (void*)syscall(SYS_mmap, nullptr, size, linuxMode, MAP_SHARED, hdl, (off64_t)offset);
|
||||||
if (map == MAP_FAILED)
|
if (map == MAP_FAILED)
|
||||||
{
|
{
|
||||||
EHS_LOG_INT("Error", 0, "Failed to map with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to map with error #" + Str_8::FromNum(errno) + ".");
|
||||||
@ -190,7 +191,7 @@ namespace ehs
|
|||||||
if (!IsValid() || !IsMapped())
|
if (!IsValid() || !IsMapped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (munmap(map, mapSize) == -1)
|
if (syscall(SYS_munmap, map, mapSize) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to unmap with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
map = MAP_FAILED;
|
map = MAP_FAILED;
|
||||||
@ -202,7 +203,7 @@ namespace ehs
|
|||||||
if (!IsValid() || !IsMapped())
|
if (!IsValid() || !IsMapped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (msync((void*)map, mapSize, MS_SYNC) == -1)
|
if (syscall(SYS_msync, (void*)map, mapSize, MS_SYNC) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to flush view with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to flush view with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +213,7 @@ namespace ehs
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SInt_64 written = 0;
|
SInt_64 written = 0;
|
||||||
written = write(hdl, data, size);
|
written = syscall(SYS_write, hdl, data, size);
|
||||||
if (written == -1)
|
if (written == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to write to file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
@ -225,7 +226,7 @@ namespace ehs
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
SInt_64 read = 0;
|
SInt_64 read = 0;
|
||||||
read = ::read(hdl, data, (size_t)size);
|
read = syscall(SYS_read, hdl, data, (size_t)size);
|
||||||
if (read == -1)
|
if (read == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to read from file, \"" + path + "\", with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
@ -237,7 +238,7 @@ namespace ehs
|
|||||||
if (!IsValid() || IsMapped())
|
if (!IsValid() || IsMapped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lseek64(hdl, (off64_t)index, SEEK_SET) == -1)
|
if (syscall(SYS_lseek, hdl, index, SEEK_SET) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +247,7 @@ namespace ehs
|
|||||||
if (!IsValid() || IsMapped())
|
if (!IsValid() || IsMapped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lseek64(hdl, 0, SEEK_SET) == -1)
|
if (syscall(SYS_lseek, hdl, 0, SEEK_SET) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,7 +256,7 @@ namespace ehs
|
|||||||
if (!IsValid() || IsMapped())
|
if (!IsValid() || IsMapped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (lseek64(hdl, 0, SEEK_END) == -1)
|
if (syscall(SYS_lseek, hdl, 0, SEEK_END) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to seek with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +265,7 @@ namespace ehs
|
|||||||
if (!IsValid() || IsMapped())
|
if (!IsValid() || IsMapped())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ftruncate64(hdl, (off64_t)size) == -1)
|
if (syscall(SYS_ftruncate, hdl, (off64_t)size) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to truncate with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to truncate with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +273,7 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
struct stat64 info = {};
|
struct stat64 info = {};
|
||||||
|
|
||||||
if (fstat64(hdl, &info) == -1)
|
if (syscall(SYS_fstat, hdl, &info) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to retrieve file size with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to retrieve file size with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
return info.st_size;
|
return info.st_size;
|
||||||
@ -301,7 +302,7 @@ namespace ehs
|
|||||||
if (filePath.Find("/", &index, SearchPattern::RIGHT_LEFT) || filePath.Find("\\", &index, SearchPattern::RIGHT_LEFT))
|
if (filePath.Find("/", &index, SearchPattern::RIGHT_LEFT) || filePath.Find("\\", &index, SearchPattern::RIGHT_LEFT))
|
||||||
path = filePath.Sub(0, index);
|
path = filePath.Sub(0, index);
|
||||||
|
|
||||||
if (rename(filePath, path + newName) == -1)
|
if (syscall(SYS_rename, &filePath[0], &(path + newName)[0]) == -1)
|
||||||
EHS_LOG_INT("Error", 0, "Failed to rename file with error #" + Str_8::FromNum(errno) + ".");
|
EHS_LOG_INT("Error", 0, "Failed to rename file with error #" + Str_8::FromNum(errno) + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "ehs/io/Window_W32.h"
|
#include "ehs/io/Window_W32.h"
|
||||||
#include "ehs/io/hid/Keyboard.h"
|
#include "ehs/io/hid/Keyboard.h"
|
||||||
#include "ehs/io/hid/Mouse.h"
|
#include "ehs/io/hid/Mouse.h"
|
||||||
#include "ehs/system/Thread.h"
|
#include "ehs/system/OldThread.h"
|
||||||
|
|
||||||
#include <hidusage.h>
|
#include <hidusage.h>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "io/Window_Way.h"
|
#include "ehs/io/Window_Way.h"
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "ehs/Vec2.h"
|
#include "ehs/Vec2.h"
|
||||||
#include "ehs/io/hid/Keyboard.h"
|
#include "ehs/io/hid/Keyboard.h"
|
||||||
#include "ehs/io/hid/Mouse.h"
|
#include "ehs/io/hid/Mouse.h"
|
||||||
#include "ehs/io/Console.h"
|
#include "ehs/io/BaseConsole.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "ehs/io/socket/rest/TwitchChat.h"
|
#include "ehs/io/socket/rest/TwitchChat.h"
|
||||||
#include "ehs/io/socket/DNS.h"
|
#include "ehs/io/socket/DNS.h"
|
||||||
#include "ehs/io/Console.h"
|
#include "ehs/io/BaseConsole.h"
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
@ -59,13 +59,13 @@ namespace ehs
|
|||||||
|
|
||||||
Str_8 r("PASS oauth:" + token + "\r\n");
|
Str_8 r("PASS oauth:" + token + "\r\n");
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
|
|
||||||
r = "NICK " + username + "\r\n";
|
r = "NICK " + username + "\r\n";
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ namespace ehs
|
|||||||
|
|
||||||
Str_8 r("Join #" + newChannel + "\r\n");
|
Str_8 r("Join #" + newChannel + "\r\n");
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ namespace ehs
|
|||||||
|
|
||||||
Str_8 r("PART #" + channel + "\r\n");
|
Str_8 r("PART #" + channel + "\r\n");
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ namespace ehs
|
|||||||
|
|
||||||
Str_8 r("PONG :tmi.twitch.tv\r\n");
|
Str_8 r("PONG :tmi.twitch.tv\r\n");
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ namespace ehs
|
|||||||
|
|
||||||
Str_8 r("PRIVMSG #" + channel + " :" + msg + "\r\n");
|
Str_8 r("PRIVMSG #" + channel + " :" + msg + "\r\n");
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ namespace ehs
|
|||||||
|
|
||||||
Str_8 r("PRIVMSG #jtv :/w " + user + " " + msg + "\r\n");
|
Str_8 r("PRIVMSG #jtv :/w " + user + " " + msg + "\r\n");
|
||||||
|
|
||||||
Console::Write_8("< " + r, false);
|
BaseConsole::Write_8("< " + r, false);
|
||||||
|
|
||||||
client.Send(r.ToBytes(), (int) r.Size());
|
client.Send(r.ToBytes(), (int) r.Size());
|
||||||
}
|
}
|
||||||
|
93
src/system/BaseThread.cpp
Normal file
93
src/system/BaseThread.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "ehs/system/BaseThread.h"
|
||||||
|
#include "ehs/system/CPU.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
BaseThread::BaseThread()
|
||||||
|
: stackSize(0), id(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseThread::BaseThread(const UInt_64 stackSize)
|
||||||
|
: stackSize(stackSize), id(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseThread::BaseThread(BaseThread&& thread) noexcept
|
||||||
|
: stackSize(thread.stackSize), id(thread.id)
|
||||||
|
{
|
||||||
|
thread.stackSize = 0;
|
||||||
|
thread.id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseThread::BaseThread(const BaseThread& thread)
|
||||||
|
: stackSize(thread.stackSize), id(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseThread& BaseThread::operator=(BaseThread&& thread) noexcept
|
||||||
|
{
|
||||||
|
if (this == &thread)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
stackSize = thread.stackSize;
|
||||||
|
id = thread.id;
|
||||||
|
|
||||||
|
thread.stackSize = 0;
|
||||||
|
thread.id = 0;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseThread& BaseThread::operator=(const BaseThread& thread)
|
||||||
|
{
|
||||||
|
if (this == &thread)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
stackSize = thread.stackSize;
|
||||||
|
id = 0;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BaseThread::Detach()
|
||||||
|
{
|
||||||
|
stackSize = 0;
|
||||||
|
id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_64 BaseThread::GetStackSize() const
|
||||||
|
{
|
||||||
|
return stackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_32 BaseThread::GetId() const
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_32 BaseThread::GetCurrentId()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BaseThread::IsValid() const
|
||||||
|
{
|
||||||
|
return stackSize && id;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BaseThread::SoftSleep(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 BaseThread::HardSleep(const UInt_32 milliseconds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -554,7 +554,7 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
UInt_64 result = GetTSC();
|
UInt_64 result = GetTSC();
|
||||||
|
|
||||||
Thread::SleepFor(10000);
|
Thread::HardSleep(10000);
|
||||||
|
|
||||||
return (GetTSC() - result) / 10;
|
return (GetTSC() - result) / 10;
|
||||||
}
|
}
|
||||||
|
49
src/system/Lock_GCC_AMD64.asm
Normal file
49
src/system/Lock_GCC_AMD64.asm
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
global _ZN3ehs4Lock3AddEPmm
|
||||||
|
global _ZN3ehs4Lock3SubEPmm
|
||||||
|
global _ZN3ehs4Lock7CmpXchgEPmS1_m
|
||||||
|
global _ZN3ehs4Lock3AndEPmm
|
||||||
|
global _ZN3ehs4Lock2OrEPmm
|
||||||
|
global _ZN3ehs4Lock3XOrEPmm
|
||||||
|
global _ZN3ehs4Lock3IncEPm
|
||||||
|
global _ZN3ehs4Lock3DecEPm
|
||||||
|
global _ZN3ehs4Lock3NotEPm
|
||||||
|
|
||||||
|
section .text
|
||||||
|
_ZN3ehs4Lock3AddEPmm:
|
||||||
|
LOCK ADD [RDI], RSI
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock3SubEPmm:
|
||||||
|
LOCK SUB [RDI], RSI
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock7CmpXchgEPmS1_m:
|
||||||
|
MOV RAX, [RDI]
|
||||||
|
LOCK CMPXCHG [RSI], RDX
|
||||||
|
MOV [RDI], RAX
|
||||||
|
SETZ AL
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock3AndEPmm:
|
||||||
|
LOCK AND [RDI], RSI
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock2OrEPmm:
|
||||||
|
LOCK OR [RDI], RSI
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock3XOrEPmm:
|
||||||
|
LOCK XOR [RDI], RSI
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock3IncEPm:
|
||||||
|
LOCK INC QWORD [RDI]
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock3DecEPm:
|
||||||
|
LOCK DEC QWORD [RDI]
|
||||||
|
RET
|
||||||
|
|
||||||
|
_ZN3ehs4Lock3NotEPm:
|
||||||
|
LOCK NOT QWORD [RDI]
|
||||||
|
RET
|
@ -6,17 +6,15 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pthread_mutex_destroy(&hdl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Mutex()
|
Mutex::Mutex()
|
||||||
: hdl{}
|
: state(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Mutex::Mutex(const Mutex& mutex)
|
Mutex::Mutex(const Mutex& mutex)
|
||||||
: BaseMutex(mutex), hdl{}
|
: BaseMutex(mutex), state(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +25,7 @@ namespace ehs
|
|||||||
|
|
||||||
BaseMutex::operator=(mutex);
|
BaseMutex::operator=(mutex);
|
||||||
|
|
||||||
hdl = {};
|
state = 0;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -37,10 +35,6 @@ namespace ehs
|
|||||||
if (initialized)
|
if (initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pthread_mutex_t hdl = {};
|
|
||||||
|
|
||||||
int code = pthread_mutex_init(&hdl, nullptr);
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,28 +43,14 @@ namespace ehs
|
|||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pthread_mutex_destroy(&hdl);
|
|
||||||
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Lock()
|
void Mutex::Lock()
|
||||||
{
|
{
|
||||||
if (locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&hdl);
|
|
||||||
|
|
||||||
locked = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mutex::Unlock()
|
void Mutex::Unlock()
|
||||||
{
|
{
|
||||||
if (!locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&hdl);
|
|
||||||
|
|
||||||
locked = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,8 +15,7 @@ namespace ehs
|
|||||||
|
|
||||||
void System::OpenURI(const Str_8& uri)
|
void System::OpenURI(const Str_8& uri)
|
||||||
{
|
{
|
||||||
Thread xdg;
|
Thread xdg(2, (void*)&uri, XDG_Thread);
|
||||||
xdg.Start(XDG_Thread, (void*)&uri);
|
|
||||||
xdg.Detach();
|
xdg.Detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,284 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
}
|
|
161
src/system/Thread_LNX.cpp
Normal file
161
src/system/Thread_LNX.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#include "ehs/system/Thread_LNX.h"
|
||||||
|
#include "ehs/Serializer.h"
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
Thread::~Thread()
|
||||||
|
{
|
||||||
|
if (detached && !*detached)
|
||||||
|
{
|
||||||
|
if (stack && syscall(SYS_munmap, stack, GetStackSize()) == -1)
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to deallocate stack for thread with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
|
delete detached;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread()
|
||||||
|
: BaseThread(0), stack(nullptr), hdl(0), detached(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread(UInt_64 stackSize, void* args, UInt_32 (*func)(void*))
|
||||||
|
: BaseThread(1024 * stackSize), stack(nullptr), hdl(0), detached(new bool(false))
|
||||||
|
{
|
||||||
|
stack = (void*)syscall(SYS_mmap, nullptr, GetStackSize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
if (stack == MAP_FAILED)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to allocate stack for thread.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serializer<UInt_64>* data = new Serializer<UInt_64>(Endianness::LE);
|
||||||
|
data->Write(GetStackSize());
|
||||||
|
data->Write(stack);
|
||||||
|
data->Write(detached);
|
||||||
|
data->Write(args);
|
||||||
|
data->Write(func);
|
||||||
|
|
||||||
|
hdl = (pid_t)syscall(SYS_clone, Redirect, stackSize, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD, data);
|
||||||
|
id = hdl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread(Thread&& thread) noexcept
|
||||||
|
: BaseThread((BaseThread&&)thread), stack(thread.stack), hdl(thread.hdl), detached(thread.detached)
|
||||||
|
{
|
||||||
|
thread.stack = nullptr;
|
||||||
|
thread.hdl = 0;
|
||||||
|
thread.detached = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread(const Thread& thread)
|
||||||
|
: BaseThread(thread), stack(nullptr), hdl(0), detached(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread& Thread::operator=(Thread&& thread) noexcept
|
||||||
|
{
|
||||||
|
if (this == &thread)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
Join();
|
||||||
|
|
||||||
|
BaseThread::operator=((BaseThread&&)thread);
|
||||||
|
|
||||||
|
stack = thread.stack;
|
||||||
|
hdl = thread.hdl;
|
||||||
|
detached = thread.detached;
|
||||||
|
|
||||||
|
thread.stack = nullptr;
|
||||||
|
thread.hdl = 0;
|
||||||
|
thread.detached = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread& Thread::operator=(const Thread& thread)
|
||||||
|
{
|
||||||
|
if (this == &thread)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
Join();
|
||||||
|
|
||||||
|
BaseThread::operator=(thread);
|
||||||
|
|
||||||
|
stack = nullptr;
|
||||||
|
hdl = 0;
|
||||||
|
detached = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::Detach()
|
||||||
|
{
|
||||||
|
BaseThread::Detach();
|
||||||
|
|
||||||
|
stack = nullptr;
|
||||||
|
*detached = true;
|
||||||
|
detached = nullptr;
|
||||||
|
hdl = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::Join()
|
||||||
|
{
|
||||||
|
if (detached && *detached)
|
||||||
|
return;
|
||||||
|
|
||||||
|
syscall(SYS_wait4, hdl, nullptr, 0, nullptr);
|
||||||
|
hdl = 0;
|
||||||
|
|
||||||
|
if (syscall(SYS_munmap, stack, GetStackSize()) == -1)
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to deallocate stack in detached thread with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
|
||||||
|
stack = nullptr;
|
||||||
|
|
||||||
|
delete detached;
|
||||||
|
detached = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_32 Thread::GetCurrentId()
|
||||||
|
{
|
||||||
|
return syscall(SYS_gettid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::HardSleep(UInt_32 milliseconds)
|
||||||
|
{
|
||||||
|
timespec req = {milliseconds / 1000, milliseconds % 1000 * 1000000};
|
||||||
|
syscall(SYS_nanosleep, &req, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_32 Thread::Redirect(void* args)
|
||||||
|
{
|
||||||
|
Serializer<UInt_64>* data = (Serializer<UInt_64>*)args;
|
||||||
|
UInt_64 stackSize = data->Read<UInt_64>();
|
||||||
|
void* stack = data->Read<void*>();
|
||||||
|
bool* detached = data->Read<bool*>();
|
||||||
|
void* inArgs = data->Read<void*>();
|
||||||
|
UInt_32 (*func)(void*) = data->Read<UInt_32 (*)(void*)>();
|
||||||
|
delete data;
|
||||||
|
|
||||||
|
UInt_32 error = func(inArgs);
|
||||||
|
|
||||||
|
if (*detached)
|
||||||
|
{
|
||||||
|
if (syscall(SYS_munmap, stack, stackSize) == -1)
|
||||||
|
{
|
||||||
|
error = 1;
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to deallocate stack in detached thread with error #" + Str_8::FromNum(errno) + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete detached;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
88
src/system/Thread_W32.cpp
Normal file
88
src/system/Thread_W32.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include "ehs/system/Thread_W32.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
Thread::~Thread()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread(UInt_64 stackSize, void* args, UInt_32 (* func)(void*))
|
||||||
|
{
|
||||||
|
hdl = CreateThread(nullptr, stackSize, (LPTHREAD_START_ROUTINE)func, args, 0, (DWORD*)&id);
|
||||||
|
if (!hdl)
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to start thread with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread(Thread&& thread) noexcept
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread::Thread(const Thread& thread)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread& Thread::operator=(Thread&& thread) noexcept
|
||||||
|
{
|
||||||
|
return <#initializer#>;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread& Thread::operator=(const Thread& thread)
|
||||||
|
{
|
||||||
|
return <#initializer#>;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::Detach()
|
||||||
|
{
|
||||||
|
BaseThread::Detach();
|
||||||
|
|
||||||
|
if (!CloseHandle(hdl))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Failed to detach thread with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::Join()
|
||||||
|
{
|
||||||
|
unsigned int r = WaitForSingleObject(hdl, timeout);
|
||||||
|
if (r == WAIT_ABANDONED)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 0, "Abandoned wait because a mutex was not released.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (r == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (r == WAIT_FAILED)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT("Error", 1, "Failed to wait for thread with error #" + Str_8::FromNum(GetLastError()) + ".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainTaskIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_32 Thread::GetCurrentId()
|
||||||
|
{
|
||||||
|
return GetCurrentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Thread::IsValid() const
|
||||||
|
{
|
||||||
|
return BaseThread::IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Thread::HardSleep(UInt_32 milliseconds)
|
||||||
|
{
|
||||||
|
Sleep(milliseconds);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user