tor-browser

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

AndroidPerformanceHintManager.cpp (4017B)


      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 "HalLog.h"
      9 #include "HalTypes.h"
     10 
     11 #include "AndroidBuild.h"
     12 
     13 #include <stdint.h>
     14 #include <sys/types.h>
     15 
     16 #include <android/performance_hint.h>
     17 
     18 typedef struct APerformanceHintManager APerformanceHintManager;
     19 typedef struct APerformanceHintSession APerformanceHintSession;
     20 
     21 namespace mozilla {
     22 namespace hal_impl {
     23 
     24 class __attribute__((
     25    availability(android, introduced = 33))) AndroidPerformanceHintSession final
     26    : public hal::PerformanceHintSession {
     27  // Creates a PerformanceHintSession wrapping the provided NDK
     28  // APerformanceHintSession instance. This assumes ownership of aSession,
     29  // therefore the caller must not close the session itself.
     30  explicit AndroidPerformanceHintSession(APerformanceHintSession* aSession)
     31      : mSession(aSession) {}
     32 
     33 public:
     34  AndroidPerformanceHintSession(AndroidPerformanceHintSession& aOther) = delete;
     35  AndroidPerformanceHintSession(AndroidPerformanceHintSession&& aOther) {
     36    mSession = aOther.mSession;
     37    aOther.mSession = nullptr;
     38  }
     39 
     40  static UniquePtr<AndroidPerformanceHintSession> Create(
     41      APerformanceHintManager* manager, const nsTArray<pid_t>& threads,
     42      int64_t initialTargetWorkDurationNanos) {
     43    if (APerformanceHintSession* session = APerformanceHint_createSession(
     44            manager, threads.Elements(), threads.Length(),
     45            initialTargetWorkDurationNanos)) {
     46      return WrapUnique(new AndroidPerformanceHintSession(session));
     47    } else {
     48      return nullptr;
     49    }
     50  }
     51 
     52  ~AndroidPerformanceHintSession() {
     53    if (mSession) {
     54      APerformanceHint_closeSession(mSession);
     55    }
     56  }
     57 
     58  void UpdateTargetWorkDuration(TimeDuration aDuration) override {
     59    APerformanceHint_updateTargetWorkDuration(
     60        mSession, aDuration.ToMicroseconds() * 1000);
     61  }
     62 
     63  void ReportActualWorkDuration(TimeDuration aDuration) override {
     64    APerformanceHint_reportActualWorkDuration(
     65        mSession, aDuration.ToMicroseconds() * 1000);
     66  }
     67 
     68 private:
     69  APerformanceHintSession* mSession;
     70 };
     71 
     72 static APerformanceHintManager* InitManager() {
     73  if (__builtin_available(android 33, *)) {
     74    // At the time of writing we are only aware of PerformanceHintManager being
     75    // implemented on Tensor devices (Pixel 6 and 7 families). On most devices
     76    // createSession() will simply return null. However, on some devices
     77    // createSession() does return a session but scheduling does not appear to
     78    // be affected in any way. Rather than pretending to the caller that
     79    // PerformanceHintManager is available on such devices, return null allowing
     80    // them to use another means of achieving the performance they require.
     81    const auto socManufacturer =
     82        java::sdk::Build::SOC_MANUFACTURER()->ToString();
     83    if (!socManufacturer.EqualsASCII("Google")) {
     84      return nullptr;
     85    }
     86 
     87    return APerformanceHint_getManager();
     88  } else {
     89    return nullptr;
     90  }
     91 }
     92 
     93 UniquePtr<hal::PerformanceHintSession> CreatePerformanceHintSession(
     94    const nsTArray<PlatformThreadHandle>& aThreads,
     95    mozilla::TimeDuration aTargetWorkDuration) {
     96  // C++ guarantees local static variable initialization is thread safe
     97  static APerformanceHintManager* manager = InitManager();
     98 
     99  if (!manager) {
    100    return nullptr;
    101  }
    102 
    103  nsTArray<pid_t> tids(aThreads.Length());
    104  std::transform(aThreads.cbegin(), aThreads.cend(), MakeBackInserter(tids),
    105                 [](pthread_t handle) { return pthread_gettid_np(handle); });
    106 
    107  if (__builtin_available(android 33, *)) {
    108    return AndroidPerformanceHintSession::Create(
    109        manager, tids, aTargetWorkDuration.ToMicroseconds() * 1000);
    110  } else {
    111    return nullptr;
    112  }
    113 }
    114 
    115 }  // namespace hal_impl
    116 }  // namespace mozilla