1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * @defgroup APerformanceHint Performance Hint Manager 19 * 20 * APerformanceHint allows apps to create performance hint sessions for groups 21 * of threads, and provide hints to the system about the workload of those threads, 22 * to help the system more accurately allocate power for them. It is the NDK 23 * counterpart to the Java PerformanceHintManager SDK API. 24 * 25 * @{ 26 */ 27 28 /** 29 * @file performance_hint.h 30 * @brief API for creating and managing a hint session. 31 */ 32 33 34 #ifndef ANDROID_NATIVE_PERFORMANCE_HINT_H 35 #define ANDROID_NATIVE_PERFORMANCE_HINT_H 36 37 #include <sys/cdefs.h> 38 39 /****************************************************************** 40 * 41 * IMPORTANT NOTICE: 42 * 43 * This file is part of Android's set of stable system headers 44 * exposed by the Android NDK (Native Development Kit). 45 * 46 * Third-party source AND binary code relies on the definitions 47 * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. 48 * 49 * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) 50 * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS 51 * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY 52 * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES 53 */ 54 55 #include <android/api-level.h> 56 #include <stdint.h> 57 #include <unistd.h> 58 59 __BEGIN_DECLS 60 61 struct APerformanceHintManager; 62 struct APerformanceHintSession; 63 struct AWorkDuration; 64 65 /** 66 * {@link AWorkDuration} is an opaque type that represents the breakdown of the 67 * actual workload duration in each component internally. 68 * 69 * A new {@link AWorkDuration} can be obtained using 70 * {@link AWorkDuration_create()}, when the client finishes using 71 * {@link AWorkDuration}, {@link AWorkDuration_release()} must be 72 * called to destroy and free up the resources associated with 73 * {@link AWorkDuration}. 74 * 75 * This file provides a set of functions to allow clients to set the measured 76 * work duration of each component on {@link AWorkDuration}. 77 * 78 * - AWorkDuration_setWorkPeriodStartTimestampNanos() 79 * - AWorkDuration_setActualTotalDurationNanos() 80 * - AWorkDuration_setActualCpuDurationNanos() 81 * - AWorkDuration_setActualGpuDurationNanos() 82 */ 83 typedef struct AWorkDuration AWorkDuration; 84 85 /** 86 * An opaque type representing a handle to a performance hint manager. 87 * It must be released after use. 88 * 89 * To use:<ul> 90 * <li>Obtain the performance hint manager instance by calling 91 * {@link APerformanceHint_getManager} function.</li> 92 * <li>Create an {@link APerformanceHintSession} with 93 * {@link APerformanceHint_createSession}.</li> 94 * <li>Get the preferred update rate in nanoseconds with 95 * {@link APerformanceHint_getPreferredUpdateRateNanos}.</li> 96 */ 97 typedef struct APerformanceHintManager APerformanceHintManager; 98 99 /** 100 * An opaque type representing a handle to a performance hint session. 101 * A session can only be acquired from a {@link APerformanceHintManager} 102 * with {@link APerformanceHint_createSession}. It must be 103 * freed with {@link APerformanceHint_closeSession} after use. 104 * 105 * A Session represents a group of threads with an inter-related workload such that hints for 106 * their performance should be considered as a unit. The threads in a given session should be 107 * long-lived and not created or destroyed dynamically. 108 * 109 * The work duration API can be used with periodic workloads to dynamically adjust thread 110 * performance and keep the work on schedule while optimizing the available power budget. 111 * When using the work duration API, the starting target duration should be specified 112 * while creating the session, and can later be adjusted with 113 * {@link APerformanceHint_updateTargetWorkDuration}. While using the work duration 114 * API, the client is expected to call {@link APerformanceHint_reportActualWorkDuration} each 115 * cycle to report the actual time taken to complete to the system. 116 * 117 * Note, methods of {@link APerformanceHintSession_*} are not thread safe so callers must 118 * ensure thread safety. 119 * 120 * All timings should be from `std::chrono::steady_clock` or `clock_gettime(CLOCK_MONOTONIC, ...)` 121 */ 122 typedef struct APerformanceHintSession APerformanceHintSession; 123 124 /** 125 * Acquire an instance of the performance hint manager. 126 * 127 * @return APerformanceHintManager instance on success, nullptr on failure. 128 */ 129 APerformanceHintManager* _Nullable APerformanceHint_getManager() 130 __INTRODUCED_IN(__ANDROID_API_T__); 131 132 /** 133 * Creates a session for the given set of threads and sets their initial target work 134 * duration. 135 * 136 * @param manager The performance hint manager instance. 137 * @param threadIds The list of threads to be associated with this session. They must be part of 138 * this process' thread group. 139 * @param size The size of the list of threadIds. 140 * @param initialTargetWorkDurationNanos The target duration in nanoseconds for the new session. 141 * This must be positive if using the work duration API, or 0 otherwise. 142 * @return APerformanceHintManager instance on success, nullptr on failure. 143 */ 144 APerformanceHintSession* _Nullable APerformanceHint_createSession( 145 APerformanceHintManager* _Nonnull manager, 146 const int32_t* _Nonnull threadIds, size_t size, 147 int64_t initialTargetWorkDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__); 148 149 /** 150 * Get preferred update rate information for this device. 151 * 152 * @param manager The performance hint manager instance. 153 * @return the preferred update rate supported by device software. 154 */ 155 int64_t APerformanceHint_getPreferredUpdateRateNanos( 156 APerformanceHintManager* _Nonnull manager) __INTRODUCED_IN(__ANDROID_API_T__); 157 158 /** 159 * Updates this session's target duration for each cycle of work. 160 * 161 * @param session The performance hint session instance to update. 162 * @param targetDurationNanos The new desired duration in nanoseconds. This must be positive. 163 * @return 0 on success. 164 * EINVAL if targetDurationNanos is not positive. 165 * EPIPE if communication with the system service has failed. 166 */ 167 int APerformanceHint_updateTargetWorkDuration( 168 APerformanceHintSession* _Nonnull session, 169 int64_t targetDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__); 170 171 /** 172 * Reports the actual duration for the last cycle of work. 173 * 174 * The system will attempt to adjust the scheduling and performance of the 175 * threads within the thread group to bring the actual duration close to the target duration. 176 * 177 * @param session The performance hint session instance to update. 178 * @param actualDurationNanos The duration of time the thread group took to complete its last 179 * task in nanoseconds. This must be positive. 180 * @return 0 on success. 181 * EINVAL if actualDurationNanos is not positive. 182 * EPIPE if communication with the system service has failed. 183 */ 184 int APerformanceHint_reportActualWorkDuration( 185 APerformanceHintSession* _Nonnull session, 186 int64_t actualDurationNanos) __INTRODUCED_IN(__ANDROID_API_T__); 187 188 /** 189 * Release the performance hint manager pointer acquired via 190 * {@link APerformanceHint_createSession}. 191 * 192 * @param session The performance hint session instance to release. 193 */ 194 void APerformanceHint_closeSession( 195 APerformanceHintSession* _Nonnull session) __INTRODUCED_IN(__ANDROID_API_T__); 196 197 /** 198 * Set a list of threads to the performance hint session. This operation will replace 199 * the current list of threads with the given list of threads. 200 * 201 * @param session The performance hint session instance to update. 202 * @param threadIds The list of threads to be associated with this session. They must be part of 203 * this app's thread group. 204 * @param size The size of the list of threadIds. 205 * @return 0 on success. 206 * EINVAL if the list of thread ids is empty or if any of the thread ids are not part of 207 the thread group. 208 * EPIPE if communication with the system service has failed. 209 * EPERM if any thread id doesn't belong to the application. 210 */ 211 int APerformanceHint_setThreads( 212 APerformanceHintSession* _Nonnull session, 213 const pid_t* _Nonnull threadIds, 214 size_t size) __INTRODUCED_IN(__ANDROID_API_U__); 215 216 /** 217 * This tells the session that these threads can be 218 * safely scheduled to prefer power efficiency over performance. 219 * 220 * @param session The performance hint session instance to update. 221 * @param enabled The flag which sets whether this session will use power-efficient scheduling. 222 * @return 0 on success. 223 * EPIPE if communication with the system service has failed. 224 */ 225 int APerformanceHint_setPreferPowerEfficiency( 226 APerformanceHintSession* _Nonnull session, 227 bool enabled) __INTRODUCED_IN(__ANDROID_API_V__); 228 229 /** 230 * Reports the durations for the last cycle of work. 231 * 232 * The system will attempt to adjust the scheduling and performance of the 233 * threads within the thread group to bring the actual duration close to the target duration. 234 * 235 * @param session The {@link APerformanceHintSession} instance to update. 236 * @param workDuration The {@link AWorkDuration} structure of times the thread group took to 237 * complete its last task in nanoseconds breaking down into different components. 238 * 239 * The work period start timestamp and actual total duration must be greater than zero. 240 * 241 * The actual CPU and GPU durations must be greater than or equal to zero, and at least one 242 * of them must be greater than zero. When one of them is equal to zero, it means that type 243 * of work was not measured for this workload. 244 * 245 * @return 0 on success. 246 * EINVAL if any duration is an invalid number. 247 * EPIPE if communication with the system service has failed. 248 */ 249 int APerformanceHint_reportActualWorkDuration2( 250 APerformanceHintSession* _Nonnull session, 251 AWorkDuration* _Nonnull workDuration) __INTRODUCED_IN(__ANDROID_API_V__); 252 253 /** 254 * Creates a new AWorkDuration. When the client finishes using {@link AWorkDuration}, it should 255 * call {@link AWorkDuration_release()} to destroy {@link AWorkDuration} and release all resources 256 * associated with it. 257 * 258 * @return AWorkDuration on success and nullptr otherwise. 259 */ 260 AWorkDuration* _Nonnull AWorkDuration_create() __INTRODUCED_IN(__ANDROID_API_V__); 261 262 /** 263 * Destroys {@link AWorkDuration} and free all resources associated to it. 264 * 265 * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()} 266 */ 267 void AWorkDuration_release(AWorkDuration* _Nonnull aWorkDuration) 268 __INTRODUCED_IN(__ANDROID_API_V__); 269 270 /** 271 * Sets the work period start timestamp in nanoseconds. 272 * 273 * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()} 274 * @param workPeriodStartTimestampNanos The work period start timestamp in nanoseconds based on 275 * CLOCK_MONOTONIC about when the work starts. This timestamp must be greater than zero. 276 */ 277 void AWorkDuration_setWorkPeriodStartTimestampNanos(AWorkDuration* _Nonnull aWorkDuration, 278 int64_t workPeriodStartTimestampNanos) __INTRODUCED_IN(__ANDROID_API_V__); 279 280 /** 281 * Sets the actual total work duration in nanoseconds. 282 * 283 * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()} 284 * @param actualTotalDurationNanos The actual total work duration in nanoseconds. This number must 285 * be greater than zero. 286 */ 287 void AWorkDuration_setActualTotalDurationNanos(AWorkDuration* _Nonnull aWorkDuration, 288 int64_t actualTotalDurationNanos) __INTRODUCED_IN(__ANDROID_API_V__); 289 290 /** 291 * Sets the actual CPU work duration in nanoseconds. 292 * 293 * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()} 294 * @param actualCpuDurationNanos The actual CPU work duration in nanoseconds. This number must be 295 * greater than or equal to zero. If it is equal to zero, that means the CPU was not 296 * measured. 297 */ 298 void AWorkDuration_setActualCpuDurationNanos(AWorkDuration* _Nonnull aWorkDuration, 299 int64_t actualCpuDurationNanos) __INTRODUCED_IN(__ANDROID_API_V__); 300 301 /** 302 * Sets the actual GPU work duration in nanoseconds. 303 * 304 * @param aWorkDuration The {@link AWorkDuration} created by calling {@link AWorkDuration_create()}. 305 * @param actualGpuDurationNanos The actual GPU work duration in nanoseconds, the number must be 306 * greater than or equal to zero. If it is equal to zero, that means the GPU was not 307 * measured. 308 */ 309 void AWorkDuration_setActualGpuDurationNanos(AWorkDuration* _Nonnull aWorkDuration, 310 int64_t actualGpuDurationNanos) __INTRODUCED_IN(__ANDROID_API_V__); 311 312 __END_DECLS 313 314 #endif // ANDROID_NATIVE_PERFORMANCE_HINT_H 315 316 /** @} */ 317