From 2c19f13f74b11b6604d8a7766c2990435643ed08 Mon Sep 17 00:00:00 2001
From: fincs <fincs@devkitpro.org>
Date: Mon, 16 Mar 2020 12:48:08 +0100
Subject: [PATCH] nvFence/nvGpu/nvMap: use service guard instead of unsafe
 atomic refcnt

---
 nx/source/nvidia/fence.c | 34 ++++++++++++----------------------
 nx/source/nvidia/gpu.c   | 27 ++++++++-------------------
 nx/source/nvidia/map.c   | 31 +++++++++----------------------
 3 files changed, 29 insertions(+), 63 deletions(-)

diff --git a/nx/source/nvidia/fence.c b/nx/source/nvidia/fence.c
index 1847a6ef..6fe9bfe7 100644
--- a/nx/source/nvidia/fence.c
+++ b/nx/source/nvidia/fence.c
@@ -1,6 +1,4 @@
-#include "types.h"
-#include "result.h"
-#include "arm/atomics.h"
+#include "../services/service_guard.h"
 #include "kernel/svc.h"
 #include "kernel/event.h"
 #include "runtime/hosversion.h"
@@ -8,11 +6,13 @@
 #include "nvidia/fence.h"
 
 static u32 g_ctrl_fd = -1;
-static u64 g_refCnt;
 
 static u64 g_NvEventUsedMask;
 static Event g_NvEvents[64];
 
+#define nvFenceInitialize nvFenceInit
+NX_GENERATE_SERVICE_GUARD(nvFence);
+
 static int _nvGetEventSlot(void)
 {
     int slot;
@@ -66,28 +66,18 @@ static void _nvFreeEvent(int event_id)
     nvioctlNvhostCtrl_EventUnregister(g_ctrl_fd, event_id);
 }
 
-Result nvFenceInit(void)
+Result _nvFenceInitialize(void)
 {
-    Result rc;
-
-    if (atomicIncrement64(&g_refCnt) > 0)
-        return 0;
-
-    rc = nvOpen(&g_ctrl_fd, "/dev/nvhost-ctrl");
-
-    if (R_FAILED(rc))
-        g_ctrl_fd = -1;
-
-    return rc;
+    return nvOpen(&g_ctrl_fd, "/dev/nvhost-ctrl");
 }
 
-void nvFenceExit(void)
+void _nvFenceCleanup(void)
 {
-    if (atomicDecrement64(&g_refCnt) == 0) {
-        for (int i = 0; i < 64; i ++)
-            _nvFreeEvent(i);
-        if (g_ctrl_fd != -1)
-            nvClose(g_ctrl_fd);
+    for (int i = 0; i < 64; i ++)
+        _nvFreeEvent(i);
+
+    if (g_ctrl_fd != -1) {
+        nvClose(g_ctrl_fd);
         g_ctrl_fd = -1;
     }
 }
diff --git a/nx/source/nvidia/gpu.c b/nx/source/nvidia/gpu.c
index 534ebed1..8b153d76 100644
--- a/nx/source/nvidia/gpu.c
+++ b/nx/source/nvidia/gpu.c
@@ -1,7 +1,5 @@
 #include <string.h>
-#include "types.h"
-#include "result.h"
-#include "arm/atomics.h"
+#include "../services/service_guard.h"
 #include "kernel/svc.h"
 #include "services/nv.h"
 #include "nvidia/ioctl.h"
@@ -11,25 +9,21 @@
 #define NUM_TPC_MASKS 1
 
 static u32 g_ctrlgpu_fd = -1;
-static u64 g_refCnt;
 
 static nvioctl_gpu_characteristics g_gpu_characteristics;
 static u32 g_zcull_ctx_size;
 static nvioctl_zcull_info g_zcull_info;
 static u32 g_tpc_masks[NUM_TPC_MASKS];
 
-Result nvGpuInit(void)
+#define nvGpuInitialize nvGpuInit
+NX_GENERATE_SERVICE_GUARD(nvGpu);
+
+Result _nvGpuInitialize(void)
 {
     Result rc;
 
-    if (atomicIncrement64(&g_refCnt) > 0)
-        return 0;
-
     rc = nvOpen(&g_ctrlgpu_fd, "/dev/nvhost-ctrl-gpu");
 
-    if (R_FAILED(rc))
-        g_ctrlgpu_fd = -1;
-
     if (R_SUCCEEDED(rc))
         rc = nvioctlNvhostCtrlGpu_GetCharacteristics(g_ctrlgpu_fd, &g_gpu_characteristics);
 
@@ -42,18 +36,13 @@ Result nvGpuInit(void)
     if (R_SUCCEEDED(rc))
         rc = nvioctlNvhostCtrlGpu_GetTpcMasks(g_ctrlgpu_fd, g_tpc_masks, sizeof(g_tpc_masks));
 
-    if (R_FAILED(rc))
-        nvGpuExit();
-
     return rc;
 }
 
-void nvGpuExit(void)
+void _nvGpuCleanup(void)
 {
-    if (atomicDecrement64(&g_refCnt) == 0) {
-        if (g_ctrlgpu_fd != -1)
-            nvClose(g_ctrlgpu_fd);
-
+    if (g_ctrlgpu_fd != -1) {
+        nvClose(g_ctrlgpu_fd);
         g_ctrlgpu_fd = -1;
     }
 }
diff --git a/nx/source/nvidia/map.c b/nx/source/nvidia/map.c
index fc137d32..9ba23751 100644
--- a/nx/source/nvidia/map.c
+++ b/nx/source/nvidia/map.c
@@ -1,7 +1,5 @@
 #include <string.h>
-#include "types.h"
-#include "result.h"
-#include "arm/atomics.h"
+#include "../services/service_guard.h"
 #include "arm/cache.h"
 #include "kernel/svc.h"
 #include "services/nv.h"
@@ -9,30 +7,19 @@
 #include "nvidia/map.h"
 
 static u32 g_nvmap_fd = -1;
-static u64 g_refCnt;
 
-Result nvMapInit(void)
+#define nvMapInitialize nvMapInit
+NX_GENERATE_SERVICE_GUARD(nvMap);
+
+Result _nvMapInitialize(void)
 {
-    Result rc;
-
-    if (atomicIncrement64(&g_refCnt) > 0)
-        return 0;
-
-    rc = nvOpen(&g_nvmap_fd, "/dev/nvmap");
-
-    if (R_FAILED(rc))
-        atomicDecrement64(&g_refCnt);
-
-    return rc;
+    return nvOpen(&g_nvmap_fd, "/dev/nvmap");
 }
 
-void nvMapExit(void)
+void _nvMapCleanup(void)
 {
-    if (atomicDecrement64(&g_refCnt) == 0)
-    {
-        if (g_nvmap_fd != -1)
-            nvClose(g_nvmap_fd);
-
+    if (g_nvmap_fd != -1) {
+        nvClose(g_nvmap_fd);
         g_nvmap_fd = -1;
     }
 }