tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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