SDL: cpuinfo: reset cpu features on SDL_Quit

From 1aa9ef721347e508444ccd3c1d6c60861365ea3f Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Sat, 24 Feb 2024 13:46:06 +0100
Subject: [PATCH] cpuinfo: reset cpu features on SDL_Quit

---
 VisualC-GDK/SDL/SDL.vcxproj           |  1 +
 VisualC-GDK/SDL/SDL.vcxproj.filters   |  1 +
 VisualC-WinRT/SDL-UWP.vcxproj         |  1 +
 VisualC-WinRT/SDL-UWP.vcxproj.filters |  3 +++
 VisualC/SDL/SDL.vcxproj               |  1 +
 VisualC/SDL/SDL.vcxproj.filters       |  3 +++
 src/SDL.c                             |  3 +++
 src/cpuinfo/SDL_cpuinfo.c             | 17 ++++++++++++-----
 src/cpuinfo/SDL_cpuinfo_c.h           | 27 +++++++++++++++++++++++++++
 9 files changed, 52 insertions(+), 5 deletions(-)
 create mode 100644 src/cpuinfo/SDL_cpuinfo_c.h

diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index 872aff162686f..3a812099efb54 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -409,6 +409,7 @@
     <ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
+    <ClInclude Include="..\..\src\cpuinfo\SDL_cpuinfo_c.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi_procs.h" />
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index 1e07dc754ef4b..439e99cfabdec 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -312,6 +312,7 @@
     <ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
+    <ClInclude Include="..\..\src\cpuinfo\SDL_cpuinfo_c.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi_procs.h" />
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj
index 75ffad0c47a69..b0f402218de9a 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj
+++ b/VisualC-WinRT/SDL-UWP.vcxproj
@@ -109,6 +109,7 @@
     <ClInclude Include="..\src\core\winrt\SDL_winrtapp_common.h" />
     <ClInclude Include="..\src\core\winrt\SDL_winrtapp_direct3d.h" />
     <ClInclude Include="..\src\core\winrt\SDL_winrtapp_xaml.h" />
+    <ClInclude Include="..\src\cpuinfo\SDL_cpuinfo_c.h" />
     <ClInclude Include="..\src\dynapi\SDL_dynapi.h" />
     <ClInclude Include="..\src\dynapi\SDL_dynapi_overrides.h" />
     <ClInclude Include="..\src\dynapi\SDL_dynapi_procs.h" />
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters
index 144061e656205..bfad92ef9f7da 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj.filters
+++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters
@@ -243,6 +243,9 @@
     <ClInclude Include="..\src\core\winrt\SDL_winrtapp_xaml.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\src\cpuinfo\SDL_cpuinfo_c.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
     <ClInclude Include="..\src\dynapi\SDL_dynapi.h">
       <Filter>Source Files</Filter>
     </ClInclude>
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index d50987c370a9e..4b02b33e30512 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -330,6 +330,7 @@
     <ClInclude Include="..\..\src\core\windows\SDL_immdevice.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
+    <ClInclude Include="..\..\src\cpuinfo\SDL_cpuinfo_c.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi_overrides.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi_procs.h" />
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index 766c3bc8d4580..26368b1b2af42 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -474,6 +474,9 @@
     <ClInclude Include="..\..\src\core\windows\SDL_directx.h">
       <Filter>core\windows</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\cpuinfo\SDL_cpuinfo_c.h">
+      <Filter>cpuinfo</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h">
       <Filter>dynapi</Filter>
     </ClInclude>
diff --git a/src/SDL.c b/src/SDL.c
index 99b2bf04304e1..f3faf9d59df1a 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -41,6 +41,7 @@
 #include "SDL_log_c.h"
 #include "SDL_properties_c.h"
 #include "audio/SDL_sysaudio.h"
+#include "cpuinfo/SDL_cpuinfo_c.h"
 #include "video/SDL_video_c.h"
 #include "events/SDL_events_c.h"
 #include "haptic/SDL_haptic_c.h"
@@ -551,6 +552,8 @@ void SDL_Quit(void)
     SDL_ClearHints();
     SDL_AssertionsQuit();
 
+    SDL_QuitCPUInfo();
+
     SDL_QuitProperties();
     SDL_QuitLog();
 
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index 49aaf09360476..2270956e182a0 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -18,6 +18,7 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
+
 #include "SDL_internal.h"
 
 #if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK)
@@ -855,7 +856,9 @@ int SDL_GetCPUCacheLineSize(void)
     }
 }
 
-static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
+#define SDL_CPUFEATURES_RESET_VALUE 0xFFFFFFFF
+
+static Uint32 SDL_CPUFeatures = SDL_CPUFEATURES_RESET_VALUE;
 static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF;
 
 static SDL_bool ref_string_equals(const char *ref, const char *test, const char *end_test) {
@@ -865,10 +868,10 @@ static SDL_bool ref_string_equals(const char *ref, const char *test, const char
 
 static Uint32 SDLCALL SDL_CPUFeatureMaskFromHint(void)
 {
-    Uint32 result_mask = 0xFFFFFFFF;
+    Uint32 result_mask = SDL_CPUFEATURES_RESET_VALUE;
 
     const char *hint = SDL_GetHint(SDL_HINT_CPU_FEATURE_MASK);
-    
+
     if (hint) {
         for (const char *spot = hint, *next; *spot; spot = next) {
             const char *end = SDL_strchr(spot, ',');
@@ -889,7 +892,7 @@ static Uint32 SDLCALL SDL_CPUFeatureMaskFromHint(void)
                 spot += 1;
             }
             if (ref_string_equals("all", spot, end)) {
-                spot_mask = 0xFFFFFFFF;
+                spot_mask = SDL_CPUFEATURES_RESET_VALUE;
             } else if (ref_string_equals("altivec", spot, end)) {
                 spot_mask= CPU_HAS_ALTIVEC;
             } else if (ref_string_equals("mmx", spot, end)) {
@@ -934,7 +937,7 @@ static Uint32 SDLCALL SDL_CPUFeatureMaskFromHint(void)
 
 static Uint32 SDL_GetCPUFeatures(void)
 {
-    if (SDL_CPUFeatures == 0xFFFFFFFF) {
+    if (SDL_CPUFeatures == SDL_CPUFEATURES_RESET_VALUE) {
         CPU_calcCPUIDFeatures();
         SDL_CPUFeatures = 0;
         SDL_SIMDAlignment = sizeof(void *); /* a good safe base value */
@@ -999,6 +1002,10 @@ static Uint32 SDL_GetCPUFeatures(void)
     return SDL_CPUFeatures;
 }
 
+void SDL_QuitCPUInfo(void) {
+    SDL_CPUFeatures = SDL_CPUFEATURES_RESET_VALUE;
+}
+
 #define CPU_FEATURE_AVAILABLE(f) ((SDL_GetCPUFeatures() & (f)) ? SDL_TRUE : SDL_FALSE)
 
 SDL_bool SDL_HasAltiVec(void)
diff --git a/src/cpuinfo/SDL_cpuinfo_c.h b/src/cpuinfo/SDL_cpuinfo_c.h
new file mode 100644
index 0000000000000..c64a091ed902a
--- /dev/null
+++ b/src/cpuinfo/SDL_cpuinfo_c.h
@@ -0,0 +1,27 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_cpuinfo_c_h_
+#define SDL_cpuinfo_c_h_
+
+extern void SDL_QuitCPUInfo(void);
+
+#endif /* SDL_cpuinfo_c_h_ */