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"
Result pmdmntInitialize(void);
void pmdmntExit(void);
Result pmdmntStartProcess(u64 pid);
Result pmdmntGetTitlePid(u64* pid_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,19 +1,25 @@
#include "types.h"
#include "arm/atomics.h"
#include "services/acc.h"
#include "services/sm.h"
static Service g_accSrv;
static u64 g_refCnt;
Result accountInitialize(void)
{
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_accSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
return 0;
return smGetService(&g_accSrv, "acc:u1");
}
void accountExit(void) {
serviceClose(&g_accSrv);
void accountExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0)
serviceClose(&g_accSrv);
}
Service* accountGetService(void) {

View File

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

View File

@ -1,12 +1,13 @@
#include <string.h>
#include "types.h"
#include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h"
#include "kernel/detect.h"
#include "services/fatal.h"
#include "services/applet.h"
#include "services/apm.h"
#include "services/sm.h"
#include "kernel/detect.h"
__attribute__((weak)) u32 __nx_applet_type = AppletType_Default;
__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_appletProxySession;
static u64 g_refCnt;
// From Get*Functions.
static Service g_appletIFunctions;
@ -69,8 +71,10 @@ static Result _appletSetPerformanceModeChangedNotification(u8 flag);
Result appletInitialize(void)
{
atomicIncrement64(&g_refCnt);
if (serviceIsActive(&g_appletSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
return 0;
if (__nx_applet_type == AppletType_None)
return 0;
@ -234,36 +238,39 @@ Result appletInitialize(void)
void appletExit(void)
{
apmExit();
if (atomicDecrement64(&g_refCnt) == 0)
{
apmExit();
//TODO: Enable this somehow later with more condition(s)?
/*if (__nx_applet_type == AppletType_LibraryApplet)
_appletExitProcessAndReturn();*/
//TODO: Enable this somehow later with more condition(s)?
/*if (__nx_applet_type == AppletType_LibraryApplet)
_appletExitProcessAndReturn();*/
if (g_appletMessageEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_appletMessageEventHandle);
g_appletMessageEventHandle = INVALID_HANDLE;
if (g_appletMessageEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_appletMessageEventHandle);
g_appletMessageEventHandle = INVALID_HANDLE;
}
serviceClose(&g_appletIDebugFunctions);
serviceClose(&g_appletIDisplayController);
serviceClose(&g_appletIAudioController);
serviceClose(&g_appletIWindowController);
serviceClose(&g_appletISelfController);
serviceClose(&g_appletICommonStateGetter);
serviceClose(&g_appletILibraryAppletCreator);
if (__nx_applet_type != AppletType_LibraryApplet)
serviceClose(&g_appletIFunctions);
if (__nx_applet_type == AppletType_LibraryApplet) {
serviceClose(&g_appletIProcessWindingController);
serviceClose(&g_appletILibraryAppletSelfAccessor);
}
serviceClose(&g_appletProxySession);
serviceClose(&g_appletSrv);
g_appletResourceUserId = 0;
}
serviceClose(&g_appletIDebugFunctions);
serviceClose(&g_appletIDisplayController);
serviceClose(&g_appletIAudioController);
serviceClose(&g_appletIWindowController);
serviceClose(&g_appletISelfController);
serviceClose(&g_appletICommonStateGetter);
serviceClose(&g_appletILibraryAppletCreator);
if (__nx_applet_type != AppletType_LibraryApplet)
serviceClose(&g_appletIFunctions);
if (__nx_applet_type == AppletType_LibraryApplet) {
serviceClose(&g_appletIProcessWindingController);
serviceClose(&g_appletILibraryAppletSelfAccessor);
}
serviceClose(&g_appletProxySession);
serviceClose(&g_appletSrv);
g_appletResourceUserId = 0;
}
static void appletCallHook(AppletHookType hookType)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ static Result _nvSetClientPID(u64 AppletResourceUserId);
Result nvInitialize(nvServiceType servicetype, size_t transfermem_size)
{
if(g_nvServiceType!=-1)
if (g_nvServiceType != -1)
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);
Result rc = 0;
@ -70,7 +70,7 @@ Result nvInitialize(nvServiceType servicetype, size_t transfermem_size)
void nvExit(void)
{
if(g_nvServiceType == -1)
if (g_nvServiceType == -1)
return;
g_nvServiceType = -1;

View File

@ -1,16 +1,31 @@
// Copyright 2017 plutoo
#include "types.h"
#include "result.h"
#include "arm/atomics.h"
#include "kernel/ipc.h"
#include "services/pm.h"
#include "services/sm.h"
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");
}
void pmdmntExit(void)
{
if (atomicDecrement64(&g_refCnt) == 0) {
serviceClose(&g_pmdmntSrv);
}
}
Result pmdmntStartProcess(u64 pid) {
IpcCommand c;
ipcInitialize(&c);

View File

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

View File

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

View File

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

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);
Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo) {
Result usbDsInitialize(UsbComplexId complexId, const usbDsDeviceInfo* deviceinfo)
{
if (serviceIsActive(&g_usbDsSrv))
return MAKERESULT(Module_Libnx, LibnxError_AlreadyInitialized);