Introduce atomics.c, refcounting on all services

This commit is contained in:
plutoo 2018-03-10 14:33:40 +01:00
parent d54db1ac16
commit a102c64341
17 changed files with 219 additions and 105 deletions

View File

@ -0,0 +1,6 @@
#include "../types.h"
u32 atomicIncrement32(u32* p);
u32 atomicDecrement32(u32* p);
u64 atomicIncrement64(u64* p);
u64 atomicDecrement64(u64* p);

View File

@ -8,6 +8,8 @@
#include "../types.h" #include "../types.h"
Result pmdmntInitialize(void); Result pmdmntInitialize(void);
void pmdmntExit(void);
Result pmdmntStartProcess(u64 pid); Result pmdmntStartProcess(u64 pid);
Result pmdmntGetTitlePid(u64* pid_out, u64 title_id); Result pmdmntGetTitlePid(u64* pid_out, u64 title_id);
Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id); Result pmdmntEnableDebugForTitleId(Handle* handle_out, u64 title_id);

17
nx/source/arm/atomics.c Normal file
View File

@ -0,0 +1,17 @@
#include "types.h"
u32 atomicIncrement32(u32* p) {
return __sync_fetch_and_add(p, 1);
}
u32 atomicDecrement32(u32* p) {
return __sync_sub_and_fetch(p, 1);
}
u64 atomicIncrement64(u64* p) {
return __sync_fetch_and_add(p, 1);
}
u64 atomicDecrement64(u64* p) {
return __sync_sub_and_fetch(p, 1);
}

View File

@ -1,18 +1,24 @@
#include "types.h" #include "types.h"
#include "arm/atomics.h"
#include "services/acc.h" #include "services/acc.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_accSrv; static Service g_accSrv;
static u64 g_refCnt;
Result accountInitialize(void) Result accountInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_accSrv)) if (serviceIsActive(&g_accSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
return smGetService(&g_accSrv, "acc:u1"); return smGetService(&g_accSrv, "acc:u1");
} }
void accountExit(void) { void accountExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0)
serviceClose(&g_accSrv); serviceClose(&g_accSrv);
} }

View File

@ -1,18 +1,22 @@
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/apm.h" #include "services/apm.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_apmSrv; static Service g_apmSrv;
static Service g_apmISession; static Service g_apmISession;
static u64 g_refCnt;
static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id); static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id);
Result apmInitialize(void) Result apmInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_apmSrv)) if (serviceIsActive(&g_apmSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc = 0; Result rc = 0;
@ -34,9 +38,11 @@ Result apmInitialize(void)
void apmExit(void) void apmExit(void)
{ {
if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_apmISession); serviceClose(&g_apmISession);
serviceClose(&g_apmSrv); serviceClose(&g_apmSrv);
} }
}
static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id) { static Result _apmGetSession(Service* srv, Service* srv_out, u64 cmd_id) {
IpcCommand c; IpcCommand c;

View File

@ -1,12 +1,13 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/detect.h"
#include "services/fatal.h" #include "services/fatal.h"
#include "services/applet.h" #include "services/applet.h"
#include "services/apm.h" #include "services/apm.h"
#include "services/sm.h" #include "services/sm.h"
#include "kernel/detect.h"
__attribute__((weak)) u32 __nx_applet_type = AppletType_Default; __attribute__((weak)) u32 __nx_applet_type = AppletType_Default;
__attribute__((weak)) bool __nx_applet_auto_notifyrunning = true; __attribute__((weak)) bool __nx_applet_auto_notifyrunning = true;
@ -15,6 +16,7 @@ __attribute__((weak)) u32 __nx_applet_PerformanceConfiguration[2] = {/*0x9222000
static Service g_appletSrv; static Service g_appletSrv;
static Service g_appletProxySession; static Service g_appletProxySession;
static u64 g_refCnt;
// From Get*Functions. // From Get*Functions.
static Service g_appletIFunctions; static Service g_appletIFunctions;
@ -69,8 +71,10 @@ static Result _appletSetPerformanceModeChangedNotification(u8 flag);
Result appletInitialize(void) Result appletInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_appletSrv)) if (serviceIsActive(&g_appletSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
if (__nx_applet_type == AppletType_None) if (__nx_applet_type == AppletType_None)
return 0; return 0;
@ -233,6 +237,8 @@ Result appletInitialize(void)
} }
void appletExit(void) void appletExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0)
{ {
apmExit(); apmExit();
@ -265,6 +271,7 @@ void appletExit(void)
serviceClose(&g_appletSrv); serviceClose(&g_appletSrv);
g_appletResourceUserId = 0; g_appletResourceUserId = 0;
} }
}
static void appletCallHook(AppletHookType hookType) static void appletCallHook(AppletHookType hookType)
{ {

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/audin.h" #include "services/audin.h"
#include "services/sm.h" #include "services/sm.h"
@ -11,6 +12,7 @@
static Service g_audinSrv; static Service g_audinSrv;
static Service g_audinIAudioIn; static Service g_audinIAudioIn;
static u64 g_refCnt;
static Handle g_audinBufferEventHandle = INVALID_HANDLE; static Handle g_audinBufferEventHandle = INVALID_HANDLE;
@ -23,8 +25,10 @@ static Result _audinRegisterBufferEvent(Handle *BufferEvent);
Result audinInitialize(void) Result audinInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_audinSrv)) if (serviceIsActive(&g_audinSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc = 0; Result rc = 0;
rc = smGetService(&g_audinSrv, "audin:u"); rc = smGetService(&g_audinSrv, "audin:u");
@ -51,6 +55,8 @@ Result audinInitialize(void)
} }
void audinExit(void) void audinExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0)
{ {
if (g_audinBufferEventHandle != INVALID_HANDLE) { if (g_audinBufferEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_audinBufferEventHandle); svcCloseHandle(g_audinBufferEventHandle);
@ -65,6 +71,7 @@ void audinExit(void)
serviceClose(&g_audinIAudioIn); serviceClose(&g_audinIAudioIn);
serviceClose(&g_audinSrv); serviceClose(&g_audinSrv);
} }
}
u32 audinGetSampleRate(void) { u32 audinGetSampleRate(void) {
return g_sampleRate; return g_sampleRate;

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/audout.h" #include "services/audout.h"
#include "services/sm.h" #include "services/sm.h"
@ -11,6 +12,7 @@
static Service g_audoutSrv; static Service g_audoutSrv;
static Service g_audoutIAudioOut; static Service g_audoutIAudioOut;
static u64 g_refCnt;
static Handle g_audoutBufferEventHandle = INVALID_HANDLE; static Handle g_audoutBufferEventHandle = INVALID_HANDLE;
@ -23,8 +25,10 @@ static Result _audoutRegisterBufferEvent(Handle *BufferEvent);
Result audoutInitialize(void) Result audoutInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_audoutSrv)) if (serviceIsActive(&g_audoutSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc = 0; Result rc = 0;
rc = smGetService(&g_audoutSrv, "audout:u"); rc = smGetService(&g_audoutSrv, "audout:u");
@ -51,6 +55,8 @@ Result audoutInitialize(void)
} }
void audoutExit(void) void audoutExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0)
{ {
if (g_audoutBufferEventHandle != INVALID_HANDLE) { if (g_audoutBufferEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_audoutBufferEventHandle); svcCloseHandle(g_audoutBufferEventHandle);
@ -65,6 +71,7 @@ void audoutExit(void)
serviceClose(&g_audoutIAudioOut); serviceClose(&g_audoutIAudioOut);
serviceClose(&g_audoutSrv); serviceClose(&g_audoutSrv);
} }
}
u32 audoutGetSampleRate(void) { u32 audoutGetSampleRate(void) {
return g_sampleRate; return g_sampleRate;

View File

@ -2,13 +2,18 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/fs.h" #include "services/fs.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_fsSrv; static Service g_fsSrv;
static u64 g_refCnt;
Result fsInitialize(void)
{
atomicIncrement64(&g_refCnt);
Result fsInitialize(void) {
if (serviceIsActive(&g_fsSrv)) if (serviceIsActive(&g_fsSrv))
return 0; return 0;
@ -49,7 +54,9 @@ Result fsInitialize(void) {
return rc; return rc;
} }
void fsExit(void) { void fsExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0)
serviceClose(&g_fsSrv); serviceClose(&g_fsSrv);
} }

View File

@ -1,15 +1,17 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/shmem.h"
#include "kernel/rwlock.h"
#include "services/applet.h" #include "services/applet.h"
#include "services/hid.h" #include "services/hid.h"
#include "services/sm.h" #include "services/sm.h"
#include "kernel/shmem.h"
#include "kernel/rwlock.h"
static Service g_hidSrv; static Service g_hidSrv;
static Service g_hidIAppletResource; static Service g_hidIAppletResource;
static u64 g_refCnt;
static SharedMemory g_hidSharedmem; static SharedMemory g_hidSharedmem;
static HidTouchScreenEntry g_touchEntry; static HidTouchScreenEntry g_touchEntry;
@ -36,8 +38,10 @@ static Result _hidSetDualModeAll(void);
Result hidInitialize(void) Result hidInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_hidSrv)) if (serviceIsActive(&g_hidSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc; Result rc;
Handle sharedmem_handle; Handle sharedmem_handle;
@ -75,15 +79,15 @@ Result hidInitialize(void)
void hidExit(void) void hidExit(void)
{ {
if (!serviceIsActive(&g_hidSrv)) if (atomicDecrement64(&g_refCnt) == 0)
return; {
_hidSetDualModeAll(); _hidSetDualModeAll();
serviceClose(&g_hidIAppletResource); serviceClose(&g_hidIAppletResource);
serviceClose(&g_hidSrv); serviceClose(&g_hidSrv);
shmemClose(&g_hidSharedmem); shmemClose(&g_hidSharedmem);
} }
}
void hidReset(void) void hidReset(void)
{ {
@ -367,7 +371,7 @@ void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoy
} }
static Result _hidSetDualModeAll(void) { static Result _hidSetDualModeAll(void) {
Result rc=0; Result rc;
int i; int i;
for (i=0; i<8; i++) { for (i=0; i<8; i++) {

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/shmem.h" #include "kernel/shmem.h"
#include "kernel/tmem.h" #include "kernel/tmem.h"
@ -16,6 +17,7 @@ typedef struct {
} irsCameraEntry; } irsCameraEntry;
static Service g_irsSrv; static Service g_irsSrv;
static u64 g_refCnt;
static SharedMemory g_irsSharedmem; static SharedMemory g_irsSharedmem;
static bool g_irsSensorActivated; static bool g_irsSensorActivated;
@ -25,8 +27,10 @@ static Result _irsGetIrsensorSharedMemoryHandle(Handle* handle_out, u64 AppletRe
Result irsInitialize(void) Result irsInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_irsSrv)) if (serviceIsActive(&g_irsSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc; Result rc;
Handle sharedmem_handle; Handle sharedmem_handle;
@ -60,10 +64,12 @@ Result irsInitialize(void)
void irsExit(void) void irsExit(void)
{ {
int i; if (atomicDecrement64(&g_refCnt) == 0)
{
size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry); size_t entrycount = sizeof(g_irsCameras)/sizeof(irsCameraEntry);
irsCameraEntry *entry; irsCameraEntry *entry;
int i;
for(i=0; i<entrycount; i++) { for(i=0; i<entrycount; i++) {
entry = &g_irsCameras[i]; entry = &g_irsCameras[i];
if (!entry->initialized) continue; if (!entry->initialized) continue;
@ -75,6 +81,7 @@ void irsExit(void)
serviceClose(&g_irsSrv); serviceClose(&g_irsSrv);
shmemClose(&g_irsSharedmem); shmemClose(&g_irsSharedmem);
} }
}
static Result _irsCameraEntryAlloc(u32 IrCameraHandle, irsCameraEntry **out_entry) { static Result _irsCameraEntryAlloc(u32 IrCameraHandle, irsCameraEntry **out_entry) {
int i; int i;

View File

@ -1,16 +1,31 @@
// Copyright 2017 plutoo // Copyright 2017 plutoo
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/pm.h" #include "services/pm.h"
#include "services/sm.h" #include "services/sm.h"
static Service g_pmdmntSrv; static Service g_pmdmntSrv;
static u64 g_refCnt;
Result pmdmntInitialize(void)
{
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_pmdmntSrv))
return 0;
Result pmdmntInitialize(void) {
return smGetService(&g_pmdmntSrv, "pm:dmnt"); return smGetService(&g_pmdmntSrv, "pm:dmnt");
} }
void pmdmntExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_pmdmntSrv);
}
}
Result pmdmntStartProcess(u64 pid) { Result pmdmntStartProcess(u64 pid) {
IpcCommand c; IpcCommand c;
ipcInitialize(&c); ipcInitialize(&c);

View File

@ -7,6 +7,7 @@
*/ */
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "kernel/detect.h" #include "kernel/detect.h"
#include "services/set.h" #include "services/set.h"
@ -15,6 +16,8 @@
static Service g_setSrv; static Service g_setSrv;
static Service g_setsysSrv; static Service g_setsysSrv;
static u64 g_refCnt;
static u64 g_refCntSys;
static bool g_setLanguageCodesInitialized; static bool g_setLanguageCodesInitialized;
static u64 g_setLanguageCodes[0x40]; static u64 g_setLanguageCodes[0x40];
@ -24,8 +27,10 @@ static Result _setMakeLanguageCode(s32 Language, u64 *LanguageCode);
Result setInitialize(void) Result setInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_setSrv)) if (serviceIsActive(&g_setSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
g_setLanguageCodesInitialized = 0; g_setLanguageCodesInitialized = 0;
@ -34,11 +39,15 @@ Result setInitialize(void)
void setExit(void) void setExit(void)
{ {
if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_setSrv); serviceClose(&g_setSrv);
} }
}
Result setsysInitialize(void) Result setsysInitialize(void)
{ {
atomicIncrement64(&g_refCntSys);
if (serviceIsActive(&g_setsysSrv)) if (serviceIsActive(&g_setsysSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
@ -47,8 +56,10 @@ Result setsysInitialize(void)
void setsysExit(void) void setsysExit(void)
{ {
if (atomicDecrement64(&g_refCntSys) == 0) {
serviceClose(&g_setsysSrv); serviceClose(&g_setsysSrv);
} }
}
static Result setInitializeLanguageCodesCache(void) { static Result setInitializeLanguageCodesCache(void) {
if (g_setLanguageCodesInitialized) return 0; if (g_setLanguageCodesInitialized) return 0;

View File

@ -1,11 +1,13 @@
// Copyright 2017 plutoo // Copyright 2017 plutoo
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/fatal.h" #include "services/fatal.h"
#include "services/sm.h" #include "services/sm.h"
static Handle g_smHandle = INVALID_HANDLE; static Handle g_smHandle = INVALID_HANDLE;
static u64 g_refCnt;
#define MAX_OVERRIDES 32 #define MAX_OVERRIDES 32
@ -48,6 +50,8 @@ bool smHasInitialized(void) {
Result smInitialize(void) Result smInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (smHasInitialized()) if (smHasInitialized())
return 0; return 0;
@ -93,10 +97,13 @@ Result smInitialize(void)
return rc; return rc;
} }
void smExit(void) { void smExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0) {
svcCloseHandle(g_smHandle); svcCloseHandle(g_smHandle);
g_smHandle = INVALID_HANDLE; g_smHandle = INVALID_HANDLE;
} }
}
u64 smEncodeName(const char* name) u64 smEncodeName(const char* name)
{ {

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include "types.h" #include "types.h"
#include "result.h" #include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h" #include "kernel/ipc.h"
#include "services/time.h" #include "services/time.h"
#include "services/sm.h" #include "services/sm.h"
@ -10,13 +11,16 @@ static Service g_timeUserSystemClock;
static Service g_timeNetworkSystemClock; static Service g_timeNetworkSystemClock;
static Service g_timeTimeZoneService; static Service g_timeTimeZoneService;
static Service g_timeLocalSystemClock; static Service g_timeLocalSystemClock;
static u64 g_refCnt;
static Result _timeGetSession(Service* srv_out, u64 cmd_id); static Result _timeGetSession(Service* srv_out, u64 cmd_id);
Result timeInitialize(void) Result timeInitialize(void)
{ {
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_timeSrv)) if (serviceIsActive(&g_timeSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return 0;
Result rc; Result rc;
@ -46,15 +50,15 @@ Result timeInitialize(void)
void timeExit(void) void timeExit(void)
{ {
if (!serviceIsActive(&g_timeSrv)) if (atomicDecrement64(&g_refCnt) == 0)
return; {
serviceClose(&g_timeLocalSystemClock); serviceClose(&g_timeLocalSystemClock);
serviceClose(&g_timeTimeZoneService); serviceClose(&g_timeTimeZoneService);
serviceClose(&g_timeNetworkSystemClock); serviceClose(&g_timeNetworkSystemClock);
serviceClose(&g_timeUserSystemClock); serviceClose(&g_timeUserSystemClock);
serviceClose(&g_timeSrv); serviceClose(&g_timeSrv);
} }
}
Service* timeGetSessionService(void) { Service* timeGetSessionService(void) {
return &g_timeSrv; return &g_timeSrv;

View File

@ -25,7 +25,8 @@ static Result _usbDsSetVidPidBcd(const usbDsDeviceInfo* deviceinfo);
static Result _usbDsGetSession(Service* srv, Service* srv_out, u64 cmd_id, const void* buf0, size_t buf0size, const void* buf1, size_t buf1size); static Result _usbDsGetSession(Service* srv, Service* srv_out, u64 cmd_id, const void* buf0, size_t buf0size, const void* buf1, size_t buf1size);
Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo) { Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo)
{
if (serviceIsActive(&g_usbDsSrv)) if (serviceIsActive(&g_usbDsSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized); return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);