Browse Source

add failsafe for querying cache line size on linux

hsnovel 8 months ago
parent
commit
81252eb06d
1 changed files with 29 additions and 4 deletions
  1. 29 4
      src/cpuinfo/SDL_cpuinfo.c

+ 29 - 4
src/cpuinfo/SDL_cpuinfo.c

@@ -85,6 +85,10 @@
 #endif
 #endif
 
+#if defined (__FreeBSD__)
+#include <sys/param.h>
+#endif
+
 #if defined(__ANDROID__) && defined(__arm__) && !defined(HAVE_GETAUXVAL)
 #include <cpu-features.h>
 #endif
@@ -891,6 +895,7 @@ static const char *SDL_GetCPUName(void)
 int SDL_GetCPUCacheLineSize(void)
 {
     const char *cpuType = SDL_GetCPUType();
+    int cacheline_size = SDL_CACHELINE_SIZE; /* initial guess */
     int a, b, c, d;
     (void)a;
     (void)b;
@@ -898,14 +903,34 @@ int SDL_GetCPUCacheLineSize(void)
     (void)d;
     if (SDL_strcmp(cpuType, "GenuineIntel") == 0 || SDL_strcmp(cpuType, "CentaurHauls") == 0 || SDL_strcmp(cpuType, "  Shanghai  ") == 0) {
         cpuid(0x00000001, a, b, c, d);
-        return ((b >> 8) & 0xff) * 8;
+        cacheline_size = ((b >> 8) & 0xff) * 8;
     } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0 || SDL_strcmp(cpuType, "HygonGenuine") == 0) {
         cpuid(0x80000005, a, b, c, d);
-        return c & 0xff;
+        cacheline_size = c & 0xff;
     } else {
-        /* Just make a guess here... */
-        return SDL_CACHELINE_SIZE;
+#if defined(HAVE_SYSCONF) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
+        if ((cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE)) > 0) {
+            return cacheline_size;
+        } else {
+            cacheline_size = SDL_CACHELINE_SIZE;
+        }
+#endif
+#if defined(__LINUX__)
+        {
+            FILE *f = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
+            if (f) {
+                int size;
+                if (fscanf(f, "%d", &size) == 1) {
+                    cacheline_size = size;
+                }
+                fclose(f);
+            }
+        }
+#elif defined(__FreeBSD__) && defined(CACHE_LINE_SIZE)
+        cacheline_size = CACHE_LINE_SIZE;
+#endif
     }
+    return cacheline_size;
 }
 
 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;