| 
									
										
										
										
											2024-08-12 10:30:59 +01:00
										 |  |  | # typed: true # rubocop:disable Sorbet/StrictSigil | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-23 14:11:05 +01:00
										 |  |  | require "macho" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  | module OS | 
					
						
							|  |  |  |   module Mac | 
					
						
							|  |  |  |     module Hardware | 
					
						
							|  |  |  |       module CPU | 
					
						
							|  |  |  |         extend T::Helpers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # These methods use info spewed out by sysctl. | 
					
						
							|  |  |  |         # Look in <mach/machine.h> for decoding info. | 
					
						
							|  |  |  |         def type | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |           case ::Hardware::CPU.sysctl_int("hw.cputype") | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |           when MachO::Headers::CPU_TYPE_I386 | 
					
						
							|  |  |  |             :intel | 
					
						
							|  |  |  |           when MachO::Headers::CPU_TYPE_ARM64 | 
					
						
							|  |  |  |             :arm | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             :dunno | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         def family | 
					
						
							|  |  |  |           if ::Hardware::CPU.arm? | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |             ::Hardware::CPU.arm_family | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |           elsif ::Hardware::CPU.intel? | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |             ::Hardware::CPU.intel_family | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |           else | 
					
						
							|  |  |  |             :dunno | 
					
						
							|  |  |  |           end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         # True when running under an Intel-based shell via Rosetta 2 on an | 
					
						
							|  |  |  |         # Apple Silicon Mac. This can be detected via seeing if there's a | 
					
						
							|  |  |  |         # conflict between what `uname` reports and the underlying `sysctl` flags, | 
					
						
							|  |  |  |         # since the `sysctl` flags don't change behaviour under Rosetta 2. | 
					
						
							|  |  |  |         def in_rosetta2? | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |           ::Hardware::CPU.sysctl_bool("sysctl.proc_translated") | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2020-07-13 11:00:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         def features | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |           @features ||= ::Hardware::CPU.sysctl_n( | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |             "machdep.cpu.features", | 
					
						
							|  |  |  |             "machdep.cpu.extfeatures", | 
					
						
							|  |  |  |             "machdep.cpu.leaf7_features", | 
					
						
							|  |  |  |           ).split.map { |s| s.downcase.to_sym } | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         def sse4? | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |           ::Hardware::CPU.sysctl_bool("hw.optional.sse4_1") | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							| 
									
										
										
										
											2018-04-07 20:28:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  | Hardware::CPU.singleton_class.prepend(OS::Mac::Hardware::CPU) | 
					
						
							| 
									
										
										
										
											2018-04-07 20:28:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  | module Hardware | 
					
						
							|  |  |  |   class CPU | 
					
						
							|  |  |  |     class << self | 
					
						
							|  |  |  |       def extmodel | 
					
						
							|  |  |  |         sysctl_int("machdep.cpu.extmodel") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def aes? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.aes") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def altivec? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.altivec") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def avx? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.avx1_0") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def avx2? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.avx2_0") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def sse3? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.sse3") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def ssse3? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.supplementalsse3") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def sse4_2? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.sse4_2") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-07-13 11:00:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       # NOTE: This is more reliable than checking `uname`. `sysctl` returns | 
					
						
							|  |  |  |       #       the right answer even when running in Rosetta 2. | 
					
						
							|  |  |  |       def physical_cpu_arm64? | 
					
						
							|  |  |  |         sysctl_bool("hw.optional.arm64") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2024-01-18 14:18:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def virtualized? | 
					
						
							|  |  |  |         sysctl_bool("kern.hv_vmm_present") | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-11-17 09:34:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def arm_family | 
					
						
							|  |  |  |         case sysctl_int("hw.cpufamily") | 
					
						
							|  |  |  |         when 0x2c91a47e             # ARMv8.0-A (Typhoon) | 
					
						
							|  |  |  |           :arm_typhoon | 
					
						
							|  |  |  |         when 0x92fb37c8             # ARMv8.0-A (Twister) | 
					
						
							|  |  |  |           :arm_twister | 
					
						
							|  |  |  |         when 0x67ceee93             # ARMv8.1-A (Hurricane, Zephyr) | 
					
						
							|  |  |  |           :arm_hurricane_zephyr | 
					
						
							|  |  |  |         when 0xe81e7ef6             # ARMv8.2-A (Monsoon, Mistral) | 
					
						
							|  |  |  |           :arm_monsoon_mistral | 
					
						
							|  |  |  |         when 0x07d34b9f             # ARMv8.3-A (Vortex, Tempest) | 
					
						
							|  |  |  |           :arm_vortex_tempest | 
					
						
							|  |  |  |         when 0x462504d2             # ARMv8.4-A (Lightning, Thunder) | 
					
						
							|  |  |  |           :arm_lightning_thunder | 
					
						
							|  |  |  |         when 0x573b5eec, 0x1b588bb3 # ARMv8.4-A (Firestorm, Icestorm) | 
					
						
							|  |  |  |           :arm_firestorm_icestorm | 
					
						
							|  |  |  |         when 0xda33d83d             # ARMv8.5-A (Blizzard, Avalanche) | 
					
						
							|  |  |  |           :arm_blizzard_avalanche | 
					
						
							|  |  |  |         when 0xfa33415e             # ARMv8.6-A (M3, Ibiza) | 
					
						
							|  |  |  |           :arm_ibiza | 
					
						
							|  |  |  |         when 0x5f4dea93             # ARMv8.6-A (M3 Pro, Lobos) | 
					
						
							|  |  |  |           :arm_lobos | 
					
						
							|  |  |  |         when 0x72015832             # ARMv8.6-A (M3 Max, Palma) | 
					
						
							|  |  |  |           :arm_palma | 
					
						
							| 
									
										
										
										
											2024-11-16 09:28:44 -08:00
										 |  |  |         when 0x6f5129ac             # ARMv9.2-A (M4, Donan) | 
					
						
							|  |  |  |           :arm_donan | 
					
						
							| 
									
										
										
										
											2024-12-06 16:06:09 +08:00
										 |  |  |         when 0x17d5b93a             # ARMv9.2-A (M4 Pro / M4 Max, Brava) | 
					
						
							|  |  |  |           :arm_brava | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |         else | 
					
						
							|  |  |  |           # When adding new ARM CPU families, please also update | 
					
						
							|  |  |  |           # test/hardware/cpu_spec.rb to include the new families. | 
					
						
							|  |  |  |           :dunno | 
					
						
							| 
									
										
										
										
											2020-11-17 09:34:00 +01:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2020-11-17 09:34:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def intel_family(_family = nil, _cpu_model = nil) | 
					
						
							|  |  |  |         case sysctl_int("hw.cpufamily") | 
					
						
							|  |  |  |         when 0x73d67300 # Yonah: Core Solo/Duo | 
					
						
							|  |  |  |           :core | 
					
						
							|  |  |  |         when 0x426f69ef # Merom: Core 2 Duo | 
					
						
							|  |  |  |           :core2 | 
					
						
							|  |  |  |         when 0x78ea4fbc # Penryn | 
					
						
							|  |  |  |           :penryn | 
					
						
							|  |  |  |         when 0x6b5a4cd2 # Nehalem | 
					
						
							|  |  |  |           :nehalem | 
					
						
							|  |  |  |         when 0x573b5eec # Westmere | 
					
						
							|  |  |  |           :westmere | 
					
						
							|  |  |  |         when 0x5490b78c # Sandy Bridge | 
					
						
							|  |  |  |           :sandybridge | 
					
						
							|  |  |  |         when 0x1f65e835 # Ivy Bridge | 
					
						
							|  |  |  |           :ivybridge | 
					
						
							|  |  |  |         when 0x10b282dc # Haswell | 
					
						
							|  |  |  |           :haswell | 
					
						
							|  |  |  |         when 0x582ed09c # Broadwell | 
					
						
							|  |  |  |           :broadwell | 
					
						
							|  |  |  |         when 0x37fc219f # Skylake | 
					
						
							|  |  |  |           :skylake | 
					
						
							|  |  |  |         when 0x0f817246 # Kaby Lake | 
					
						
							|  |  |  |           :kabylake | 
					
						
							|  |  |  |         when 0x38435547 # Ice Lake | 
					
						
							|  |  |  |           :icelake | 
					
						
							|  |  |  |         when 0x1cf8a03e # Comet Lake | 
					
						
							|  |  |  |           :cometlake | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           :dunno | 
					
						
							| 
									
										
										
										
											2024-09-21 12:24:21 -07:00
										 |  |  |         end | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def sysctl_bool(key) | 
					
						
							|  |  |  |         sysctl_int(key) == 1
 | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 11:10:40 -07:00
										 |  |  |       def sysctl_int(key) | 
					
						
							|  |  |  |         sysctl_n(key).to_i & 0xffffffff
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       def sysctl_n(*keys) | 
					
						
							|  |  |  |         (@properties ||= {}).fetch(keys) do | 
					
						
							|  |  |  |           @properties[keys] = Utils.popen_read("/usr/sbin/sysctl", "-n", *keys) | 
					
						
							| 
									
										
										
										
											2016-04-25 18:00:01 +01:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |