WindowsHeterogeneousCpuInfo.cpp (3164B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #include "Hal.h" 8 #include "HalTypes.h" 9 #include "nsTArray.h" 10 11 #include <windows.h> 12 13 namespace mozilla::hal_impl { 14 15 static mozilla::Maybe<hal::HeterogeneousCpuInfo> CreateHeterogeneousCpuInfo() { 16 ULONG returnedLength; 17 GetSystemCpuSetInformation(NULL, 0, &returnedLength, NULL, 0); 18 19 if (!returnedLength) { 20 return Nothing(); 21 } 22 23 AutoTArray<uint8_t, 1024> cpuSets; 24 25 cpuSets.SetLength(returnedLength); 26 27 if (!GetSystemCpuSetInformation( 28 reinterpret_cast<SYSTEM_CPU_SET_INFORMATION*>(cpuSets.Elements()), 29 returnedLength, &returnedLength, NULL, 0)) { 30 return Nothing(); 31 } 32 33 hal::HeterogeneousCpuInfo info; 34 info.mTotalNumCpus = 0; 35 36 BYTE maxEfficiencyClass = 0; 37 BYTE minEfficiencyClass = UINT8_MAX; 38 39 size_t currentPosition = 0; 40 41 while (currentPosition < returnedLength) { 42 SYSTEM_CPU_SET_INFORMATION& set = 43 *reinterpret_cast<SYSTEM_CPU_SET_INFORMATION*>(cpuSets.Elements() + 44 currentPosition); 45 currentPosition += set.Size; 46 if (currentPosition > returnedLength) { 47 MOZ_ASSERT(false); 48 return Nothing(); 49 } 50 51 if (set.Type != CpuSetInformation || !set.CpuSet.Id) { 52 continue; 53 } 54 info.mTotalNumCpus += 1; 55 maxEfficiencyClass = 56 std::max(maxEfficiencyClass, set.CpuSet.EfficiencyClass); 57 minEfficiencyClass = 58 std::min(minEfficiencyClass, set.CpuSet.EfficiencyClass); 59 } 60 61 if (!info.mTotalNumCpus) { 62 // This is weird. 63 return Nothing(); 64 } 65 66 currentPosition = 0; 67 size_t currentCPU = 0; 68 69 // The API has currently a limit how many cpu cores it can tell about. 70 while (currentPosition < returnedLength) { 71 if (currentCPU >= 32) { 72 break; 73 } 74 75 SYSTEM_CPU_SET_INFORMATION& set = 76 *reinterpret_cast<SYSTEM_CPU_SET_INFORMATION*>(cpuSets.Elements() + 77 currentPosition); 78 currentPosition += set.Size; 79 80 // If this happens the code above should already have bailed. 81 MOZ_ASSERT(currentPosition <= returnedLength); 82 83 // EfficiencyClass doesn't obviously translate to our model, for now what 84 // we are doing is counting everything of 'max' power use as a big core, 85 // everything of 'min' power use as a little code, and everything else as 86 // medium. 87 if (set.CpuSet.EfficiencyClass == maxEfficiencyClass) { 88 info.mBigCpus[currentCPU++] = true; 89 } else if (set.CpuSet.EfficiencyClass == minEfficiencyClass) { 90 info.mLittleCpus[currentCPU++] = true; 91 } else { 92 info.mMediumCpus[currentCPU++] = true; 93 } 94 } 95 96 return Some(info); 97 } 98 99 const Maybe<hal::HeterogeneousCpuInfo>& GetHeterogeneousCpuInfo() { 100 static const Maybe<hal::HeterogeneousCpuInfo> cpuInfo = 101 CreateHeterogeneousCpuInfo(); 102 return cpuInfo; 103 } 104 105 } // namespace mozilla::hal_impl