18
18
#include " gcenv.structs.h"
19
19
#include " gcenv.base.h"
20
20
#include " gcenv.os.h"
21
+ #include " gcenv.ee.h"
21
22
#include " gcenv.unix.inl"
22
23
#include " volatile.h"
24
+ #include " gcconfig.h"
23
25
#include " numasupport.h"
24
26
25
27
#if HAVE_SWAPCTL
@@ -862,10 +864,10 @@ bool ReadMemoryValueFromFile(const char* filename, uint64_t* val)
862
864
return result;
863
865
}
864
866
865
- static size_t GetLogicalProcessorCacheSizeFromOS ( )
867
+ static void GetLogicalProcessorCacheSizeFromSysConf ( size_t * cacheLevel, size_t * cacheSize )
866
868
{
867
- size_t cacheLevel = 0 ;
868
- size_t cacheSize = 0 ;
869
+ assert ( cacheLevel != nullptr ) ;
870
+ assert ( cacheSize != nullptr ) ;
869
871
870
872
#if defined(_SC_LEVEL1_DCACHE_SIZE) || defined(_SC_LEVEL2_CACHE_SIZE) || defined(_SC_LEVEL3_CACHE_SIZE) || defined(_SC_LEVEL4_CACHE_SIZE)
871
873
const int cacheLevelNames[] =
@@ -881,47 +883,105 @@ static size_t GetLogicalProcessorCacheSizeFromOS()
881
883
long size = sysconf (cacheLevelNames[i]);
882
884
if (size > 0 )
883
885
{
884
- cacheSize = (size_t )size;
885
- cacheLevel = i + 1 ;
886
+ * cacheSize = (size_t )size;
887
+ * cacheLevel = i + 1 ;
886
888
break ;
887
889
}
888
890
}
889
891
#endif
892
+ }
893
+
894
+ static void GetLogicalProcessorCacheSizeFromSysFs (size_t * cacheLevel, size_t * cacheSize)
895
+ {
896
+ assert (cacheLevel != nullptr );
897
+ assert (cacheSize != nullptr );
890
898
891
899
#if defined(TARGET_LINUX) && !defined(HOST_ARM) && !defined(HOST_X86)
892
- if (cacheSize == 0 )
900
+ //
901
+ // Retrieve cachesize via sysfs by reading the file /sys/devices/system/cpu/cpu0/cache/index{LastLevelCache}/size
902
+ // for the platform. Currently musl and arm64 should be only cases to use
903
+ // this method to determine cache size.
904
+ //
905
+ size_t level;
906
+ char path_to_size_file[] = " /sys/devices/system/cpu/cpu0/cache/index-/size" ;
907
+ char path_to_level_file[] = " /sys/devices/system/cpu/cpu0/cache/index-/level" ;
908
+ int index = 40 ;
909
+ assert (path_to_size_file[index] == ' -' );
910
+ assert (path_to_level_file[index] == ' -' );
911
+
912
+ for (int i = 0 ; i < 5 ; i++)
893
913
{
894
- //
895
- // Fallback to retrieve cachesize via /sys/.. if sysconf was not available
896
- // for the platform. Currently musl and arm64 should be only cases to use
897
- // this method to determine cache size.
898
- //
899
- size_t level;
900
- char path_to_size_file[] = " /sys/devices/system/cpu/cpu0/cache/index-/size" ;
901
- char path_to_level_file[] = " /sys/devices/system/cpu/cpu0/cache/index-/level" ;
902
- int index = 40 ;
903
- assert (path_to_size_file[index] == ' -' );
904
- assert (path_to_level_file[index] == ' -' );
905
-
906
- for (int i = 0 ; i < 5 ; i++)
907
- {
908
- path_to_size_file[index] = (char )(48 + i);
914
+ path_to_size_file[index] = (char )(48 + i);
909
915
910
- uint64_t cache_size_from_sys_file = 0 ;
916
+ uint64_t cache_size_from_sys_file = 0 ;
911
917
912
- if (ReadMemoryValueFromFile (path_to_size_file, &cache_size_from_sys_file))
913
- {
914
- cacheSize = std::max (cacheSize, (size_t )cache_size_from_sys_file);
918
+ if (ReadMemoryValueFromFile (path_to_size_file, &cache_size_from_sys_file))
919
+ {
920
+ * cacheSize = std::max (* cacheSize, (size_t )cache_size_from_sys_file);
915
921
916
- path_to_level_file[index] = (char )(48 + i);
917
- if (ReadMemoryValueFromFile (path_to_level_file, &level))
918
- {
919
- cacheLevel = level;
920
- }
922
+ path_to_level_file[index] = (char )(48 + i);
923
+ if (ReadMemoryValueFromFile (path_to_level_file, &level))
924
+ {
925
+ *cacheLevel = level;
921
926
}
922
927
}
923
928
}
929
+ #endif
930
+ }
931
+
932
+ static void GetLogicalProcessorCacheSizeFromHeuristic (size_t * cacheLevel, size_t * cacheSize)
933
+ {
934
+ assert (cacheLevel != nullptr );
935
+ assert (cacheSize != nullptr );
936
+
937
+ #if (defined(TARGET_LINUX) && !defined(TARGET_APPLE))
938
+ {
939
+ // Use the following heuristics at best depending on the CPU count
940
+ // 1 ~ 4 : 4 MB
941
+ // 5 ~ 16 : 8 MB
942
+ // 17 ~ 64 : 16 MB
943
+ // 65+ : 32 MB
944
+ DWORD logicalCPUs = g_processAffinitySet.Count ();
945
+ if (logicalCPUs < 5 )
946
+ {
947
+ *cacheSize = 4 ;
948
+ }
949
+ else if (logicalCPUs < 17 )
950
+ {
951
+ *cacheSize = 8 ;
952
+ }
953
+ else if (logicalCPUs < 65 )
954
+ {
955
+ *cacheSize = 16 ;
956
+ }
957
+ else
958
+ {
959
+ *cacheSize = 32 ;
960
+ }
961
+
962
+ *cacheSize *= (1024 * 1024 );
963
+ }
924
964
#endif
965
+ }
966
+
967
+ static size_t GetLogicalProcessorCacheSizeFromOS ()
968
+ {
969
+ size_t cacheLevel = 0 ;
970
+ size_t cacheSize = 0 ;
971
+
972
+ if (GCConfig::GetGCCacheSizeFromSysConf ())
973
+ {
974
+ GetLogicalProcessorCacheSizeFromSysConf (&cacheLevel, &cacheSize);
975
+ }
976
+
977
+ if (cacheSize == 0 )
978
+ {
979
+ GetLogicalProcessorCacheSizeFromSysFs (&cacheLevel, &cacheSize);
980
+ if (cacheSize == 0 )
981
+ {
982
+ GetLogicalProcessorCacheSizeFromHeuristic (&cacheLevel, &cacheSize);
983
+ }
984
+ }
925
985
926
986
#if HAVE_SYSCTLBYNAME
927
987
if (cacheSize == 0 )
@@ -948,32 +1008,7 @@ static size_t GetLogicalProcessorCacheSizeFromOS()
948
1008
#if (defined(HOST_ARM64) || defined(HOST_LOONGARCH64)) && !defined(TARGET_APPLE)
949
1009
if (cacheLevel != 3 )
950
1010
{
951
- // We expect to get the L3 cache size for Arm64 but currently expected to be missing that info
952
- // from most of the machines.
953
- // Hence, just use the following heuristics at best depending on the CPU count
954
- // 1 ~ 4 : 4 MB
955
- // 5 ~ 16 : 8 MB
956
- // 17 ~ 64 : 16 MB
957
- // 65+ : 32 MB
958
- DWORD logicalCPUs = g_processAffinitySet.Count ();
959
- if (logicalCPUs < 5 )
960
- {
961
- cacheSize = 4 ;
962
- }
963
- else if (logicalCPUs < 17 )
964
- {
965
- cacheSize = 8 ;
966
- }
967
- else if (logicalCPUs < 65 )
968
- {
969
- cacheSize = 16 ;
970
- }
971
- else
972
- {
973
- cacheSize = 32 ;
974
- }
975
-
976
- cacheSize *= (1024 * 1024 );
1011
+ GetLogicalProcessorCacheSizeFromHeuristic (&cacheLevel, &cacheSize);
977
1012
}
978
1013
#endif
979
1014
0 commit comments