1
0
mirror of https://github.com/cathery/sys-con.git synced 2024-10-01 12:22:01 +00:00

Reduce memory usage

by using threadCreate instead of std::thread
This commit is contained in:
cathery 2019-11-06 15:28:56 +03:00
parent c89ff56482
commit 264673d6fc
17 changed files with 112 additions and 88 deletions

3
.gitignore vendored
View File

@ -9,3 +9,6 @@ buildSysmodule/*
.vscode .vscode
*.code-workspace *.code-workspace
*.flag *.flag
*.rar
*.xml
*.png

View File

@ -79,7 +79,7 @@ private:
IUSBEndpoint *m_outPipe = nullptr; IUSBEndpoint *m_outPipe = nullptr;
XboxOneButtonData m_buttonData; XboxOneButtonData m_buttonData;
bool m_GuidePressed; bool m_GuidePressed{false};
int16_t kLeftThumbDeadzone = 2500; //7849; int16_t kLeftThumbDeadzone = 2500; //7849;
int16_t kRightThumbDeadzone = 3500; //8689; int16_t kRightThumbDeadzone = 3500; //8689;

View File

@ -2,7 +2,6 @@
#include "IUSBDevice.h" #include "IUSBDevice.h"
#include "ControllerTypes.h" #include "ControllerTypes.h"
#include <memory> #include <memory>
#include "Status.h"
struct NormalizedButtonData struct NormalizedButtonData
{ {

View File

@ -83,7 +83,7 @@ void Dualshock3Controller::CloseInterfaces()
Status Dualshock3Controller::GetInput() Status Dualshock3Controller::GetInput()
{ {
uint8_t input_bytes[64]; uint8_t input_bytes[49];
Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes)); Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes));
if (S_FAILED(rc)) if (S_FAILED(rc))

View File

@ -88,7 +88,7 @@ void XboxOneController::CloseInterfaces()
Status XboxOneController::GetInput() Status XboxOneController::GetInput()
{ {
uint8_t input_bytes[64]; uint8_t input_bytes[18];
Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes)); Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes));
if (S_FAILED(rc)) if (S_FAILED(rc))

View File

@ -4,10 +4,8 @@
#include "IController.h" #include "IController.h"
#include "SwitchControllerHandler.h" #include "SwitchControllerHandler.h"
#include "SwitchVirtualGamepadHandler.h" #include "SwitchVirtualGamepadHandler.h"
#include <thread>
//Wrapper for AbstractedPad for switch versions [5.0.0 - 8.1.0] //Wrapper for AbstractedPad for switch versions [5.0.0 - 8.1.0]
//DOESN'T WORK PROPERLY. See inside SwitchAbstractedPadHandler::FillAbstractedState()
class SwitchAbstractedPadHandler : public SwitchVirtualGamepadHandler class SwitchAbstractedPadHandler : public SwitchVirtualGamepadHandler
{ {
private: private:

View File

@ -2,7 +2,6 @@
#include "switch.h" #include "switch.h"
#include "IController.h" #include "IController.h"
#include <thread>
class SwitchControllerHandler class SwitchControllerHandler
{ {

View File

@ -4,7 +4,6 @@
#include "IController.h" #include "IController.h"
#include "SwitchControllerHandler.h" #include "SwitchControllerHandler.h"
#include "SwitchVirtualGamepadHandler.h" #include "SwitchVirtualGamepadHandler.h"
#include <thread>
//Wrapper for HDL functions for switch versions [7.0.0+] //Wrapper for HDL functions for switch versions [7.0.0+]
class SwitchHDLHandler : public SwitchVirtualGamepadHandler class SwitchHDLHandler : public SwitchVirtualGamepadHandler

View File

@ -7,8 +7,8 @@ class SwitchUSBEndpoint : public IUSBEndpoint
{ {
private: private:
UsbHsClientEpSession m_epSession{}; UsbHsClientEpSession m_epSession{};
UsbHsClientIfSession m_ifSession; UsbHsClientIfSession *m_ifSession;
usb_endpoint_descriptor m_descriptor; usb_endpoint_descriptor *m_descriptor;
void *m_buffer; void *m_buffer;

View File

@ -2,7 +2,6 @@
#include "switch.h" #include "switch.h"
#include "IController.h" #include "IController.h"
#include "SwitchControllerHandler.h" #include "SwitchControllerHandler.h"
#include <thread>
//This class is a base class for SwitchHDLHandler and SwitchAbstractedPaadHandler. //This class is a base class for SwitchHDLHandler and SwitchAbstractedPaadHandler.
class SwitchVirtualGamepadHandler class SwitchVirtualGamepadHandler
@ -12,10 +11,10 @@ protected:
SwitchControllerHandler m_controllerHandler; SwitchControllerHandler m_controllerHandler;
bool m_keepInputThreadRunning; bool m_keepInputThreadRunning;
std::thread m_inputThread; Thread m_inputThread;
bool m_keepOutputThreadRunning; bool m_keepOutputThreadRunning;
std::thread m_outputThread; Thread m_outputThread;
public: public:
SwitchVirtualGamepadHandler(std::unique_ptr<IController> &&controller); SwitchVirtualGamepadHandler(std::unique_ptr<IController> &&controller);
@ -33,12 +32,12 @@ public:
virtual void Exit(); virtual void Exit();
//Separately init the input-reading thread //Separately init the input-reading thread
void InitInputThread(); Result InitInputThread();
//Separately close the input-reading thread //Separately close the input-reading thread
void ExitInputThread(); void ExitInputThread();
//Separately init the rumble sending thread //Separately init the rumble sending thread
void InitOutputThread(); Result InitOutputThread();
//Separately close the rumble sending thread //Separately close the rumble sending thread
void ExitOutputThread(); void ExitOutputThread();
@ -48,6 +47,8 @@ public:
virtual void UpdateOutput() = 0; virtual void UpdateOutput() = 0;
//Get the raw controller handler pointer //Get the raw controller handler pointer
inline bool *GetInputThreadBool() { return &m_keepInputThreadRunning; }
inline bool *GetOutputThreadBool() { return &m_keepOutputThreadRunning; }
inline SwitchControllerHandler *GetControllerHandler() { return &m_controllerHandler; } inline SwitchControllerHandler *GetControllerHandler() { return &m_controllerHandler; }
inline IController *GetController() { return m_controllerHandler.GetController(); } inline IController *GetController() { return m_controllerHandler.GetController(); }
inline u32 *GetVibrationHandle() { return &m_vibrationDeviceHandle; } inline u32 *GetVibrationHandle() { return &m_vibrationDeviceHandle; }

View File

@ -1,7 +1,6 @@
#include "SwitchAbstractedPadHandler.h" #include "SwitchAbstractedPadHandler.h"
#include <cmath> #include <cmath>
#include <array> #include <array>
#include "../../source/log.h"
SwitchAbstractedPadHandler::SwitchAbstractedPadHandler(std::unique_ptr<IController> &&controller) SwitchAbstractedPadHandler::SwitchAbstractedPadHandler(std::unique_ptr<IController> &&controller)
: SwitchVirtualGamepadHandler(std::move(controller)) : SwitchVirtualGamepadHandler(std::move(controller))
@ -52,7 +51,10 @@ Result SwitchAbstractedPadHandler::Initialize()
WriteToLog("Failed to iniitalize vibration device with error ", rc2); WriteToLog("Failed to iniitalize vibration device with error ", rc2);
*/ */
InitInputThread(); rc = InitInputThread();
if (R_FAILED(rc))
return rc;
return rc; return rc;
} }

View File

@ -1,6 +1,5 @@
#include "SwitchHDLHandler.h" #include "SwitchHDLHandler.h"
#include <cmath> #include <cmath>
#include "../../source/log.h"
SwitchHDLHandler::SwitchHDLHandler(std::unique_ptr<IController> &&controller) SwitchHDLHandler::SwitchHDLHandler(std::unique_ptr<IController> &&controller)
: SwitchVirtualGamepadHandler(std::move(controller)) : SwitchVirtualGamepadHandler(std::move(controller))
@ -50,7 +49,9 @@ Result SwitchHDLHandler::Initialize()
WriteToLog("Failed to iniitalize vibration with error ", rc2); WriteToLog("Failed to iniitalize vibration with error ", rc2);
*/ */
InitInputThread(); rc = InitInputThread();
if (R_FAILED(rc))
return rc;
return rc; return rc;
} }
@ -75,8 +76,8 @@ Result SwitchHDLHandler::InitHdlState()
// Set the controller colors. The grip colors are for Pro-Controller on [9.0.0+]. // Set the controller colors. The grip colors are for Pro-Controller on [9.0.0+].
m_deviceInfo.singleColorBody = RGBA8_MAXALPHA(107, 107, 107); m_deviceInfo.singleColorBody = RGBA8_MAXALPHA(107, 107, 107);
m_deviceInfo.singleColorButtons = RGBA8_MAXALPHA(0, 0, 0); m_deviceInfo.singleColorButtons = RGBA8_MAXALPHA(0, 0, 0);
m_deviceInfo.colorLeftGrip = RGBA8_MAXALPHA(23, 125, 62); m_deviceInfo.colorLeftGrip = RGBA8_MAXALPHA(70, 70, 70);
m_deviceInfo.colorRightGrip = RGBA8_MAXALPHA(23, 125, 62); m_deviceInfo.colorRightGrip = RGBA8_MAXALPHA(70, 70, 70);
m_hdlState.batteryCharge = 4; // Set battery charge to full. m_hdlState.batteryCharge = 4; // Set battery charge to full.
m_hdlState.joysticks[JOYSTICK_LEFT].dx = 0x1234; m_hdlState.joysticks[JOYSTICK_LEFT].dx = 0x1234;
@ -95,19 +96,39 @@ Result SwitchHDLHandler::ExitHdlState()
Result SwitchHDLHandler::UpdateHdlState() Result SwitchHDLHandler::UpdateHdlState()
{ {
//Checks if the virtual device was erased, in which case re-attach the device //Checks if the virtual device was erased, in which case re-attach the device
bool found_flag = false;
HiddbgHdlsStateList list; if (R_SUCCEEDED(serviceDispatch(hiddbgGetServiceSession(), 327)))
hiddbgDumpHdlsStates(&list);
for (int i = 0; i != list.total_entries; ++i)
{ {
if (list.entries[i].HdlsHandle == m_hdlHandle) bool found_flag = false;
if (hosversionBefore(9, 0, 0))
{ {
found_flag = true; HiddbgHdlsStateListV7 *stateList = static_cast<HiddbgHdlsStateListV7 *>(hiddbgGetWorkBufferTransferMemoryAddress()->src_addr);
break; for (int i = 0; i != stateList->total_entries; ++i)
{
if (stateList->entries[i].HdlsHandle == m_hdlHandle)
{
found_flag = true;
break;
}
}
} }
else
{
HiddbgHdlsStateList *stateList = static_cast<HiddbgHdlsStateList *>(hiddbgGetWorkBufferTransferMemoryAddress()->src_addr);
for (int i = 0; i != stateList->total_entries; ++i)
{
if (stateList->entries[i].HdlsHandle == m_hdlHandle)
{
found_flag = true;
break;
}
}
}
if (!found_flag)
hiddbgAttachHdlsVirtualDevice(&m_hdlHandle, &m_deviceInfo);
} }
if (!found_flag)
hiddbgAttachHdlsVirtualDevice(&m_hdlHandle, &m_deviceInfo);
return hiddbgSetHdlsState(m_hdlHandle, &m_hdlState); return hiddbgSetHdlsState(m_hdlHandle, &m_hdlState);
} }

View File

@ -1,13 +1,12 @@
#include "SwitchUSBEndpoint.h" #include "SwitchUSBEndpoint.h"
#include <cstring> #include <cstring>
#include <cstdio>
#include <malloc.h> #include <malloc.h>
SwitchUSBEndpoint::SwitchUSBEndpoint(UsbHsClientIfSession &if_session, usb_endpoint_descriptor &desc) SwitchUSBEndpoint::SwitchUSBEndpoint(UsbHsClientIfSession &if_session, usb_endpoint_descriptor &desc)
: m_ifSession(if_session), : m_ifSession(&if_session),
m_descriptor(desc) m_descriptor(&desc)
{ {
m_buffer = memalign(0x1000, 0x100); m_buffer = memalign(0x1000, 64);
} }
SwitchUSBEndpoint::~SwitchUSBEndpoint() SwitchUSBEndpoint::~SwitchUSBEndpoint()
@ -18,7 +17,7 @@ SwitchUSBEndpoint::~SwitchUSBEndpoint()
Result SwitchUSBEndpoint::Open() Result SwitchUSBEndpoint::Open()
{ {
Result rc = usbHsIfOpenUsbEp(&m_ifSession, &m_epSession, 1, m_descriptor.wMaxPacketSize, &m_descriptor); Result rc = usbHsIfOpenUsbEp(m_ifSession, &m_epSession, 1, m_descriptor->wMaxPacketSize, m_descriptor);
if (R_FAILED(rc)) if (R_FAILED(rc))
return 73011; return 73011;
return rc; return rc;
@ -69,10 +68,10 @@ Result SwitchUSBEndpoint::Read(void *outBuffer, size_t bufferSize)
IUSBEndpoint::Direction SwitchUSBEndpoint::GetDirection() IUSBEndpoint::Direction SwitchUSBEndpoint::GetDirection()
{ {
return ((m_descriptor.bEndpointAddress & USB_ENDPOINT_IN) ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT); return ((m_descriptor->bEndpointAddress & USB_ENDPOINT_IN) ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT);
} }
IUSBEndpoint::EndpointDescriptor *SwitchUSBEndpoint::GetDescriptor() IUSBEndpoint::EndpointDescriptor *SwitchUSBEndpoint::GetDescriptor()
{ {
return reinterpret_cast<IUSBEndpoint::EndpointDescriptor *>(&m_descriptor); return reinterpret_cast<IUSBEndpoint::EndpointDescriptor *>(m_descriptor);
} }

View File

@ -6,7 +6,7 @@
SwitchUSBInterface::SwitchUSBInterface(UsbHsInterface &interface) SwitchUSBInterface::SwitchUSBInterface(UsbHsInterface &interface)
: m_interface(interface) : m_interface(interface)
{ {
m_controlTransferBuffer = memalign(0x1000, 0x100); m_controlTransferBuffer = memalign(0x1000, 64);
} }
SwitchUSBInterface::~SwitchUSBInterface() SwitchUSBInterface::~SwitchUSBInterface()

View File

@ -18,46 +18,58 @@ void SwitchVirtualGamepadHandler::Exit()
{ {
} }
void inputThreadLoop(bool *keepThreadRunning, SwitchVirtualGamepadHandler *handler) void inputThreadLoop(void *handler)
{ {
svcSleepThread(1e+7L); svcSleepThread(1e+7L);
SwitchVirtualGamepadHandler *switchHandler = static_cast<SwitchVirtualGamepadHandler *>(handler);
bool *keepThreadRunning = switchHandler->GetInputThreadBool();
while (*keepThreadRunning) while (*keepThreadRunning)
{ {
handler->UpdateInput(); switchHandler->UpdateInput();
} }
} }
void outputThreadLoop(bool *keepThreadRunning, SwitchVirtualGamepadHandler *handler) void outputThreadLoop(void *handler)
{ {
svcSleepThread(1e+7L); svcSleepThread(1e+7L);
SwitchVirtualGamepadHandler *switchHandler = static_cast<SwitchVirtualGamepadHandler *>(handler);
bool *keepThreadRunning = switchHandler->GetInputThreadBool();
while (*keepThreadRunning) while (*keepThreadRunning)
{ {
handler->UpdateOutput(); switchHandler->UpdateOutput();
} }
} }
void SwitchVirtualGamepadHandler::InitInputThread() Result SwitchVirtualGamepadHandler::InitInputThread()
{ {
m_keepInputThreadRunning = true; m_keepInputThreadRunning = true;
m_inputThread = std::thread(inputThreadLoop, &m_keepInputThreadRunning, this); Result rc = threadCreate(&m_inputThread, inputThreadLoop, this, NULL, 0x400, 0x3B, -2);
if (R_FAILED(rc))
return rc;
return threadStart(&m_inputThread);
} }
void SwitchVirtualGamepadHandler::ExitInputThread() void SwitchVirtualGamepadHandler::ExitInputThread()
{ {
m_keepInputThreadRunning = false; m_keepInputThreadRunning = false;
if (m_inputThread.joinable()) threadWaitForExit(&m_inputThread);
m_inputThread.join(); threadClose(&m_inputThread);
} }
void SwitchVirtualGamepadHandler::InitOutputThread() Result SwitchVirtualGamepadHandler::InitOutputThread()
{ {
m_keepOutputThreadRunning = true; m_keepOutputThreadRunning = true;
m_outputThread = std::thread(outputThreadLoop, &m_keepOutputThreadRunning, this); Result rc = threadCreate(&m_outputThread, outputThreadLoop, this, NULL, 0x400, 0x3B, -2);
if (R_FAILED(rc))
return rc;
return threadStart(&m_outputThread);
} }
void SwitchVirtualGamepadHandler::ExitOutputThread() void SwitchVirtualGamepadHandler::ExitOutputThread()
{ {
m_keepOutputThreadRunning = false; m_keepOutputThreadRunning = false;
if (m_outputThread.joinable()) threadWaitForExit(&m_outputThread);
m_outputThread.join(); threadClose(&m_outputThread);
} }

View File

@ -16,7 +16,7 @@
extern "C" extern "C"
{ {
// Adjust size as needed. // Adjust size as needed.
#define INNER_HEAP_SIZE 0x100000 #define INNER_HEAP_SIZE 0x40000
#ifndef __APPLET__ #ifndef __APPLET__
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
@ -74,15 +74,6 @@ extern "C"
hiddbgReleaseHdlsWorkBuffer(); hiddbgReleaseHdlsWorkBuffer();
hiddbgExit(); hiddbgExit();
} }
alignas(16) u8 __nx_exception_stack[0x1000];
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
__attribute__((weak)) u32 __nx_exception_ignoredebug = 1;
void __libnx_exception_handler(ThreadExceptionDump *ctx)
{
WriteToLog("Sysmodule crashed with error ", ctx->error_desc);
}
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

@ -16,38 +16,35 @@ struct VendorEvent
Result mainLoop() Result mainLoop()
{ {
Result rc = 0; Result rc = 0;
UsbHsInterface interfaces[16];
s32 total_entries;
std::vector<uint16_t> vendors = GetVendors();
bool useAbstractedPad = hosversionBetween(5, 7); bool useAbstractedPad = hosversionBetween(5, 7);
//hidPermitVibration(false); //hidPermitVibration(false);
//hidPermitVibration(true); //hidPermitVibration(true);
VendorEvent events[vendors.size()]; VendorEvent events[2];
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>> controllerInterfaces; std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>> controllerInterfaces;
WriteToLog("\n\nNew sysmodule session started"); WriteToLog("\n\nNew sysmodule session started");
{ {
int i = 0; UsbHsInterfaceFilter filter;
for (auto &&vendor : vendors) filter.Flags = UsbHsInterfaceFilterFlags_idVendor;
{ filter.idVendor = VENDOR_MICROSOFT;
UsbHsInterfaceFilter filter; events[0] = {VENDOR_MICROSOFT, Event()};
filter.Flags = UsbHsInterfaceFilterFlags_idVendor; rc = usbHsCreateInterfaceAvailableEvent(&events[0].event, true, 0, &filter);
filter.idVendor = vendor; if (R_FAILED(rc))
if (vendor == VENDOR_SONY) WriteToLog("Failed to open event for microsoft");
{ else
filter.Flags |= UsbHsInterfaceFilterFlags_idProduct; WriteToLog("Successfully created event for microsoft");
filter.idProduct = PRODUCT_DUALSHOCK3;
}
auto &&event = events[i] = {vendor, Event()};
rc = usbHsCreateInterfaceAvailableEvent(&event.event, true, i, &filter); filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct;
if (R_FAILED(rc)) filter.idVendor = VENDOR_SONY;
WriteToLog("Failed to open event ", event.vendor); filter.idProduct = PRODUCT_DUALSHOCK3;
else events[1] = {VENDOR_SONY, Event()};
WriteToLog("Successfully created event ", event.vendor); rc = usbHsCreateInterfaceAvailableEvent(&events[1].event, true, 1, &filter);
++i; if (R_FAILED(rc))
} WriteToLog("Failed to open event for sony dualshock 3");
else
WriteToLog("Successfully created event for sony dualshock 3");
} }
controllerInterfaces.reserve(8); controllerInterfaces.reserve(8);
@ -58,7 +55,7 @@ Result mainLoop()
#ifdef __APPLET__ #ifdef __APPLET__
hidScanInput(); hidScanInput();
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO); u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
/*
if (kDown & KEY_Y) if (kDown & KEY_Y)
{ {
for (int i = 0; i != 8; ++i) for (int i = 0; i != 8; ++i)
@ -72,7 +69,6 @@ Result mainLoop()
} }
} }
} }
/*
if (kDown & KEY_X) if (kDown & KEY_X)
{ {
@ -117,14 +113,15 @@ Result mainLoop()
WriteToLog("Succeeded event ", event.vendor); WriteToLog("Succeeded event ", event.vendor);
WriteToLog("Interfaces size: ", controllerInterfaces.size(), "; capacity: ", controllerInterfaces.capacity()); WriteToLog("Interfaces size: ", controllerInterfaces.size(), "; capacity: ", controllerInterfaces.capacity());
auto &&products = GetVendorProducts(event.vendor); for (auto &&product : GetVendorProducts(event.vendor))
for (auto &&product : products)
{ {
if (controllerInterfaces.size() == 8) if (controllerInterfaces.size() == 8)
{ {
WriteToLog("Reached controller limit! skipping initialization"); WriteToLog("Reached controller limit! skipping initialization");
break; break;
} }
UsbHsInterface interfaces[4];
s32 total_entries;
UsbHsInterfaceFilter tempFilter; UsbHsInterfaceFilter tempFilter;
tempFilter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; tempFilter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct;
@ -164,6 +161,9 @@ Result mainLoop()
WriteToLog("Interface state was changed"); WriteToLog("Interface state was changed");
eventClear(usbHsGetInterfaceStateChangeEvent()); eventClear(usbHsGetInterfaceStateChangeEvent());
UsbHsInterface interfaces[4];
s32 total_entries;
rc = usbHsQueryAcquiredInterfaces(interfaces, sizeof(interfaces), &total_entries); rc = usbHsQueryAcquiredInterfaces(interfaces, sizeof(interfaces), &total_entries);
if (R_SUCCEEDED(rc)) if (R_SUCCEEDED(rc))
{ {