1
0
mirror of https://github.com/cathery/sys-con.git synced 2024-12-23 21:13:40 +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

5
.gitignore vendored
View File

@ -8,4 +8,7 @@ buildSysmodule/*
*.nso
.vscode
*.code-workspace
*.flag
*.flag
*.rar
*.xml
*.png

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,12 @@
#include "SwitchUSBEndpoint.h"
#include <cstring>
#include <cstdio>
#include <malloc.h>
SwitchUSBEndpoint::SwitchUSBEndpoint(UsbHsClientIfSession &if_session, usb_endpoint_descriptor &desc)
: m_ifSession(if_session),
m_descriptor(desc)
: m_ifSession(&if_session),
m_descriptor(&desc)
{
m_buffer = memalign(0x1000, 0x100);
m_buffer = memalign(0x1000, 64);
}
SwitchUSBEndpoint::~SwitchUSBEndpoint()
@ -18,7 +17,7 @@ SwitchUSBEndpoint::~SwitchUSBEndpoint()
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))
return 73011;
return rc;
@ -69,10 +68,10 @@ Result SwitchUSBEndpoint::Read(void *outBuffer, size_t bufferSize)
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()
{
return reinterpret_cast<IUSBEndpoint::EndpointDescriptor *>(&m_descriptor);
return reinterpret_cast<IUSBEndpoint::EndpointDescriptor *>(m_descriptor);
}

View File

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

View File

@ -18,46 +18,58 @@ void SwitchVirtualGamepadHandler::Exit()
{
}
void inputThreadLoop(bool *keepThreadRunning, SwitchVirtualGamepadHandler *handler)
void inputThreadLoop(void *handler)
{
svcSleepThread(1e+7L);
SwitchVirtualGamepadHandler *switchHandler = static_cast<SwitchVirtualGamepadHandler *>(handler);
bool *keepThreadRunning = switchHandler->GetInputThreadBool();
while (*keepThreadRunning)
{
handler->UpdateInput();
switchHandler->UpdateInput();
}
}
void outputThreadLoop(bool *keepThreadRunning, SwitchVirtualGamepadHandler *handler)
void outputThreadLoop(void *handler)
{
svcSleepThread(1e+7L);
SwitchVirtualGamepadHandler *switchHandler = static_cast<SwitchVirtualGamepadHandler *>(handler);
bool *keepThreadRunning = switchHandler->GetInputThreadBool();
while (*keepThreadRunning)
{
handler->UpdateOutput();
switchHandler->UpdateOutput();
}
}
void SwitchVirtualGamepadHandler::InitInputThread()
Result SwitchVirtualGamepadHandler::InitInputThread()
{
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()
{
m_keepInputThreadRunning = false;
if (m_inputThread.joinable())
m_inputThread.join();
threadWaitForExit(&m_inputThread);
threadClose(&m_inputThread);
}
void SwitchVirtualGamepadHandler::InitOutputThread()
Result SwitchVirtualGamepadHandler::InitOutputThread()
{
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()
{
m_keepOutputThreadRunning = false;
if (m_outputThread.joinable())
m_outputThread.join();
threadWaitForExit(&m_outputThread);
threadClose(&m_outputThread);
}

View File

@ -16,7 +16,7 @@
extern "C"
{
// Adjust size as needed.
#define INNER_HEAP_SIZE 0x100000
#define INNER_HEAP_SIZE 0x40000
#ifndef __APPLET__
u32 __nx_applet_type = AppletType_None;
@ -74,15 +74,6 @@ extern "C"
hiddbgReleaseHdlsWorkBuffer();
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[])

View File

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