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