mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-23 05:12:39 +02:00
Introducing RwLock, make hid threadsafe
This commit is contained in:
parent
bf89c7526e
commit
7482c849fe
@ -15,6 +15,7 @@ extern "C" {
|
|||||||
#include <switch/kernel/tmem.h>
|
#include <switch/kernel/tmem.h>
|
||||||
#include <switch/kernel/shmem.h>
|
#include <switch/kernel/shmem.h>
|
||||||
#include <switch/kernel/mutex.h>
|
#include <switch/kernel/mutex.h>
|
||||||
|
#include <switch/kernel/rwlock.h>
|
||||||
#include <switch/kernel/thread.h>
|
#include <switch/kernel/thread.h>
|
||||||
#include <switch/kernel/virtmem.h>
|
#include <switch/kernel/virtmem.h>
|
||||||
#include <switch/kernel/detect.h>
|
#include <switch/kernel/detect.h>
|
||||||
|
13
nx/include/switch/kernel/rwlock.h
Normal file
13
nx/include/switch/kernel/rwlock.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2018 plutoo
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
RMutex r;
|
||||||
|
RMutex g;
|
||||||
|
u64 b;
|
||||||
|
} RwLock;
|
||||||
|
|
||||||
|
void rwlockReadLock(RwLock* r);
|
||||||
|
void rwlockReadUnlock(RwLock* r);
|
||||||
|
|
||||||
|
void rwlockWriteLock(RwLock* r);
|
||||||
|
void rwlockWriteUnlock(RwLock* r);
|
28
nx/source/kernel/rwlock.c
Normal file
28
nx/source/kernel/rwlock.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2018 plutoo
|
||||||
|
#include <switch.h>
|
||||||
|
|
||||||
|
void rwlockReadLock(RwLock* r) {
|
||||||
|
rmutexLock(&r->r);
|
||||||
|
|
||||||
|
if (r->b++ == 0)
|
||||||
|
rmutexLock(&r->g);
|
||||||
|
|
||||||
|
rmutexUnlock(&r->r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwlockReadUnlock(RwLock* r) {
|
||||||
|
rmutexLock(&r->r);
|
||||||
|
|
||||||
|
if (r->b-- == 1)
|
||||||
|
rmutexUnlock(&r->g);
|
||||||
|
|
||||||
|
rmutexUnlock(&r->r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwlockWriteLock(RwLock* r) {
|
||||||
|
rmutexLock(&r->g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rwlockWriteUnlock(RwLock* r) {
|
||||||
|
rmutexUnlock(&r->g);
|
||||||
|
}
|
@ -18,25 +18,32 @@ static u64 g_controllerOld[10], g_controllerHeld[10], g_controllerDown[10], g_co
|
|||||||
static HIDControllerLayoutType g_controllerLayout[10];
|
static HIDControllerLayoutType g_controllerLayout[10];
|
||||||
static u64 g_touchTimestamp, g_mouseTimestamp, g_keyboardTimestamp, g_controllerTimestamps[10];
|
static u64 g_touchTimestamp, g_mouseTimestamp, g_keyboardTimestamp, g_controllerTimestamps[10];
|
||||||
|
|
||||||
|
static RwLock g_hidLock;
|
||||||
|
|
||||||
static Result _hidCreateAppletResource(Handle sessionhandle, Handle* handle_out, u64 AppletResourceUserId);
|
static Result _hidCreateAppletResource(Handle sessionhandle, Handle* handle_out, u64 AppletResourceUserId);
|
||||||
static Result _hidGetSharedMemoryHandle(Handle sessionhandle, Handle* handle_out);
|
static Result _hidGetSharedMemoryHandle(Handle sessionhandle, Handle* handle_out);
|
||||||
|
|
||||||
Result hidInitialize(void) {
|
Result hidInitialize(void)
|
||||||
if (g_hidServiceSession != INVALID_HANDLE) return MAKERESULT(MODULE_LIBNX, LIBNX_ALREADYINITIALIZED);
|
{
|
||||||
|
if (g_hidServiceSession != INVALID_HANDLE)
|
||||||
|
return MAKERESULT(MODULE_LIBNX, LIBNX_ALREADYINITIALIZED);
|
||||||
|
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
u64 AppletResourceUserId = 0;
|
u64 AppletResourceUserId = 0;
|
||||||
Handle sharedmem_handle=0;
|
Handle sharedmem_handle=0;
|
||||||
|
|
||||||
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||||
if (R_FAILED(rc)) return rc;
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = smGetService(&g_hidServiceSession, "hid");
|
rc = smGetService(&g_hidServiceSession, "hid");
|
||||||
if (R_FAILED(rc)) return rc;
|
if (R_FAILED(rc))
|
||||||
|
return rc;
|
||||||
|
|
||||||
rc = _hidCreateAppletResource(g_hidServiceSession, &g_hidIAppletResource, AppletResourceUserId);
|
rc = _hidCreateAppletResource(g_hidServiceSession, &g_hidIAppletResource, AppletResourceUserId);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) rc = _hidGetSharedMemoryHandle(g_hidIAppletResource, &sharedmem_handle);
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = _hidGetSharedMemoryHandle(g_hidIAppletResource, &sharedmem_handle);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
shmemLoadRemote(&g_hidSharedmem, sharedmem_handle, 0x40000, PERM_R);
|
shmemLoadRemote(&g_hidSharedmem, sharedmem_handle, 0x40000, PERM_R);
|
||||||
@ -47,8 +54,11 @@ Result hidInitialize(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
if (g_hidServiceSession != INVALID_HANDLE) svcCloseHandle(g_hidServiceSession);
|
if (g_hidServiceSession != INVALID_HANDLE)
|
||||||
if (g_hidIAppletResource != INVALID_HANDLE) svcCloseHandle(g_hidIAppletResource);
|
svcCloseHandle(g_hidServiceSession);
|
||||||
|
|
||||||
|
if (g_hidIAppletResource != INVALID_HANDLE)
|
||||||
|
svcCloseHandle(g_hidIAppletResource);
|
||||||
|
|
||||||
g_hidServiceSession = INVALID_HANDLE;
|
g_hidServiceSession = INVALID_HANDLE;
|
||||||
g_hidIAppletResource = INVALID_HANDLE;
|
g_hidIAppletResource = INVALID_HANDLE;
|
||||||
@ -61,7 +71,8 @@ Result hidInitialize(void) {
|
|||||||
|
|
||||||
void hidExit(void)
|
void hidExit(void)
|
||||||
{
|
{
|
||||||
if (g_hidServiceSession == INVALID_HANDLE) return;
|
if (g_hidServiceSession == INVALID_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
if (g_hidServiceSession != INVALID_HANDLE) {
|
if (g_hidServiceSession != INVALID_HANDLE) {
|
||||||
svcCloseHandle(g_hidServiceSession);
|
svcCloseHandle(g_hidServiceSession);
|
||||||
@ -76,7 +87,10 @@ void hidExit(void)
|
|||||||
shmemClose(&g_hidSharedmem);
|
shmemClose(&g_hidSharedmem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidReset(void) {
|
void hidReset(void)
|
||||||
|
{
|
||||||
|
rwlockWriteLock(&g_hidLock);
|
||||||
|
|
||||||
// Reset internal state
|
// Reset internal state
|
||||||
memset(&g_touchEntry, 0, sizeof(HIDTouchScreenEntry));
|
memset(&g_touchEntry, 0, sizeof(HIDTouchScreenEntry));
|
||||||
memset(&g_mouseEntry, 0, sizeof(HIDMouseEntry));
|
memset(&g_mouseEntry, 0, sizeof(HIDMouseEntry));
|
||||||
@ -96,6 +110,8 @@ void hidReset(void) {
|
|||||||
g_touchTimestamp = g_mouseTimestamp = g_keyboardTimestamp = 0;
|
g_touchTimestamp = g_mouseTimestamp = g_keyboardTimestamp = 0;
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
g_controllerTimestamps[i] = 0;
|
g_controllerTimestamps[i] = 0;
|
||||||
|
|
||||||
|
rwlockWriteUnlock(&g_hidLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle hidGetSessionService(void) {
|
Handle hidGetSessionService(void) {
|
||||||
@ -107,15 +123,25 @@ void* hidGetSharedmemAddr(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void hidSetControllerLayout(HIDControllerID id, HIDControllerLayoutType layoutType) {
|
void hidSetControllerLayout(HIDControllerID id, HIDControllerLayoutType layoutType) {
|
||||||
|
rwlockWriteLock(&g_hidLock);
|
||||||
g_controllerLayout[id] = layoutType;
|
g_controllerLayout[id] = layoutType;
|
||||||
|
rwlockWriteUnlock(&g_hidLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
HIDControllerLayoutType hidGetControllerLayout(HIDControllerID id) {
|
HIDControllerLayoutType hidGetControllerLayout(HIDControllerID id) {
|
||||||
return g_controllerLayout[id];
|
rwlockReadLock(&g_hidLock);
|
||||||
|
HIDControllerLayoutType tmp = g_controllerLayout[id];
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hidScanInput(void) {
|
void hidScanInput(void) {
|
||||||
if (g_hidServiceSession == INVALID_HANDLE) return;
|
if (g_hidServiceSession == INVALID_HANDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rwlockWriteLock(&g_hidLock);
|
||||||
|
|
||||||
HIDSharedMemory *sharedMem = (HIDSharedMemory*)hidGetSharedmemAddr();
|
HIDSharedMemory *sharedMem = (HIDSharedMemory*)hidGetSharedmemAddr();
|
||||||
|
|
||||||
g_mouseOld = g_mouseHeld;
|
g_mouseOld = g_mouseHeld;
|
||||||
@ -185,60 +211,110 @@ void hidScanInput(void) {
|
|||||||
g_controllerDown[i] = (~g_controllerOld[i]) & g_controllerHeld[i];
|
g_controllerDown[i] = (~g_controllerOld[i]) & g_controllerHeld[i];
|
||||||
g_controllerUp[i] = g_controllerOld[i] & (~g_controllerHeld[i]);
|
g_controllerUp[i] = g_controllerOld[i] & (~g_controllerHeld[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rwlockWriteUnlock(&g_hidLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hidKeysHeld(HIDControllerID id) {
|
u64 hidKeysHeld(HIDControllerID id) {
|
||||||
if (id < 0 || id > 9) return 0;
|
if (id < 0 || id > 9) return 0;
|
||||||
|
|
||||||
return g_controllerHeld[id];
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u64 tmp = g_controllerHeld[id];
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hidKeysDown(HIDControllerID id) {
|
u64 hidKeysDown(HIDControllerID id) {
|
||||||
if (id < 0 || id > 9) return 0;
|
if (id < 0 || id > 9) return 0;
|
||||||
|
|
||||||
return g_controllerDown[id];
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u64 tmp = g_controllerDown[id];
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hidKeysUp(HIDControllerID id) {
|
u64 hidKeysUp(HIDControllerID id) {
|
||||||
if (id < 0 || id > 9) return 0;
|
if (id < 0 || id > 9) return 0;
|
||||||
|
|
||||||
return g_controllerUp[id];
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u64 tmp = g_controllerUp[id];
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hidMouseButtonsHeld(void) {
|
u64 hidMouseButtonsHeld(void) {
|
||||||
return g_mouseHeld;
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u64 tmp = g_mouseHeld;
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hidMouseButtonsDown(void) {
|
u64 hidMouseButtonsDown(void) {
|
||||||
return g_mouseDown;
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u64 tmp = g_mouseDown;
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 hidMouseButtonsUp(void) {
|
u64 hidMouseButtonsUp(void) {
|
||||||
return g_mouseUp;
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u64 tmp = g_mouseUp;
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidKeyboardModifierHeld(HIDKeyboardModifier modifier) {
|
bool hidKeyboardModifierHeld(HIDKeyboardModifier modifier) {
|
||||||
return g_keyboardModHeld & modifier;
|
rwlockReadLock(&g_hidLock);
|
||||||
|
bool tmp = g_keyboardModHeld & modifier;
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidKeyboardModifierDown(HIDKeyboardModifier modifier) {
|
bool hidKeyboardModifierDown(HIDKeyboardModifier modifier) {
|
||||||
return g_keyboardModDown & modifier;
|
rwlockReadLock(&g_hidLock);
|
||||||
|
bool tmp = g_keyboardModDown & modifier;
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidKeyboardModifierUp(HIDKeyboardModifier modifier) {
|
bool hidKeyboardModifierUp(HIDKeyboardModifier modifier) {
|
||||||
return g_keyboardModUp & modifier;
|
rwlockReadLock(&g_hidLock);
|
||||||
|
bool tmp = g_keyboardModUp & modifier;
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidKeyboardHeld(HIDKeyboardScancode key) {
|
bool hidKeyboardHeld(HIDKeyboardScancode key) {
|
||||||
return g_keyboardHeld[key / 32] & (1 << (key % 32));
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u32 tmp = g_keyboardHeld[key / 32] & (1 << (key % 32));
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return !!tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidKeyboardDown(HIDKeyboardScancode key) {
|
bool hidKeyboardDown(HIDKeyboardScancode key) {
|
||||||
return g_keyboardDown[key / 32] & (1 << (key % 32));
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u32 tmp = g_keyboardDown[key / 32] & (1 << (key % 32));
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return !!tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hidKeyboardUp(HIDKeyboardScancode key) {
|
bool hidKeyboardUp(HIDKeyboardScancode key) {
|
||||||
return g_keyboardUp[key / 32] & (1 << (key % 32));
|
rwlockReadLock(&g_hidLock);
|
||||||
|
u32 tmp = g_keyboardUp[key / 32] & (1 << (key % 32));
|
||||||
|
rwlockReadUnlock(&g_hidLock);
|
||||||
|
|
||||||
|
return !!tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 hidTouchCount(void) {
|
u32 hidTouchCount(void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user