/* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @defgroup SystemHealth * * SystemHealth provides access to data about how various system resources are used by applications. * * CPU/GPU headroom APIs are designed to be best used by applications with consistent and intense * workload such as games to query the remaining capacity headroom over a short period and perform * optimization accordingly. Due to the nature of the fast job scheduling and frequency scaling of * CPU and GPU, the headroom by nature will have "TOCTOU" problem which makes it less suitable for * apps with inconsistent or low workload to take any useful action but simply monitoring. And to * avoid oscillation it's not recommended to adjust workload too frequent (on each polling request) * or too aggressively. As the headroom calculation is more based on reflecting past history usage * than predicting future capacity. Take game as an example, if the API returns CPU headroom of 0 in * one scenario (especially if it's constant across multiple calls), or some value significantly * smaller than other scenarios, then it can reason that the recent performance result is more CPU * bottlenecked. Then reducing the CPU workload intensity can help reserve some headroom to handle * the load variance better, which can result in less frame drops or smooth FPS value. On the other * hand, if the API returns large CPU headroom constantly, the app can be more confident to increase * the workload and expect higher possibility of device meeting its performance expectation. * App can also use thermal APIs to read the current thermal status and headroom first, then poll * the CPU and GPU headroom if the device is (about to) getting thermal throttled. If the CPU/GPU * headrooms provide enough significance such as one valued at 0 while the other at 100, then it can * be used to infer that reducing CPU workload could be more efficient to cool down the device. * There is a caveat that the power controller may scale down the frequency of the CPU and GPU due * to thermal and other reasons, which can result in a higher than usual percentage usage of the * capacity. * * @{ */ /** * @file system_health.h */ #ifndef _ANDROID_SYSTEM_HEALTH_H #define _ANDROID_SYSTEM_HEALTH_H #include /****************************************************************** * * IMPORTANT NOTICE: * * This file is part of Android's set of stable system headers * exposed by the Android NDK (Native Development Kit). * * Third-party source AND binary code relies on the definitions * here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES. * * - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES) * - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS * - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY * - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES */ #include #include #if !defined(__INTRODUCED_IN) #define __INTRODUCED_IN(__api_level) /* nothing */ #endif #ifdef __cplusplus extern "C" { #endif /** * Params used to customize the calculation of CPU headroom. * * Also see {@link ASystemHealth_getCpuHeadroom}. */ typedef struct ACpuHeadroomParams ACpuHeadroomParams; /** * Params used to customize the calculation of GPU headroom. * * Also see {@link ASystemHealth_getGpuHeadroom}. */ typedef struct AGpuHeadroomParams AGpuHeadroomParams; typedef enum ACpuHeadroomCalculationType : int32_t { /** * The headroom calculation type bases on minimum value over a specified window. * Introduced in API level 36. */ ACPU_HEADROOM_CALCULATION_TYPE_MIN = 0, /** * The headroom calculation type bases on average value over a specified window. * Introduced in API level 36. */ ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, } ACpuHeadroomCalculationType; typedef enum AGpuHeadroomCalculationType : int32_t { /** * The headroom calculation type bases on minimum value over a specified window. * Introduced in API level 36. */ AGPU_HEADROOM_CALCULATION_TYPE_MIN = 0, /** * The headroom calculation type bases on average value over a specified window. * Introduced in API level 36. */ AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1, } AGpuHeadroomCalculationType; /** * Sets the CPU headroom calculation window size in milliseconds. * * Available since API level 36. * * @param params The params to be set. * @param windowMillis The window size in milliseconds ranges from * {@link ASystemHealth_getCpuHeadroomCalculationWindowRange}. The smaller the * window size, the larger fluctuation in the headroom value should be expected. * The default value can be retrieved from the * {@link #ACpuHeadroomParams_getCalculationWindowMillis} if not set. The device * will try to use the closest feasible window size to this param. */ void ACpuHeadroomParams_setCalculationWindowMillis(ACpuHeadroomParams *_Nonnull params, int windowMillis) __INTRODUCED_IN(36); /** * Gets the CPU headroom calculation window size in milliseconds. * * This will return the default value chosen by the device if not set. * * Available since API level 36. * * @param params The params to read from. * @return This will return the default value chosen by the device if the params is not set. */ int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** * Sets the GPU headroom calculation window size in milliseconds. * * Available since API level 36. * * @param params The params to be set. * @param windowMillis The window size in milliseconds ranges from * {@link ASystemHealth_getGpuHeadroomCalculationWindowRange}. The smaller the * window size, the larger fluctuation in the headroom value should be expected. * The default value can be retrieved from the * {@link #AGpuHeadroomParams_getCalculationWindowMillis} if not set. The device * will try to use the closest feasible window size to this param. */ void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params, int windowMillis) __INTRODUCED_IN(36); /** * Gets the GPU headroom calculation window size in milliseconds. * * This will return the default value chosen by the device if not set. * * Available since API level 36. * * @param params The params to read from. * @return This will return the default value chosen by the device if the params is not set. */ int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** * Sets the CPU headroom calculation type in {@link ACpuHeadroomParams}. * * Available since API level 36. * * @param params The params to be set. * @param calculationType The headroom calculation type. */ void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams* _Nonnull params, ACpuHeadroomCalculationType calculationType) __INTRODUCED_IN(36); /** * Gets the CPU headroom calculation type in {@link ACpuHeadroomParams}. * * This will return the default value chosen by the device if not set. * * Available since API level 36. * * @param params The params to read from. * @return The headroom calculation type. */ ACpuHeadroomCalculationType ACpuHeadroomParams_getCalculationType(ACpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** * Sets the GPU headroom calculation type in {@link AGpuHeadroomParams}. * * Available since API level 36. * * @param params The params to be set. * @param calculationType The headroom calculation type. */ void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams* _Nonnull params, AGpuHeadroomCalculationType calculationType) __INTRODUCED_IN(36); /** * Gets the GPU headroom calculation type in {@link AGpuHeadroomParams}. * * This will return the default value chosen by the device if not set. * * Available since API level 36. * * @param params The params to read from. * @return The headroom calculation type. */ AGpuHeadroomCalculationType AGpuHeadroomParams_getCalculationType(AGpuHeadroomParams* _Nonnull params) __INTRODUCED_IN(36); /** * Sets the thread TIDs to track in {@link ACpuHeadroomParams}. * * The TIDs should belong to the same of the process that will make the headroom call. And they * should not have different core affinity. * * If not set or set to empty, the headroom will be based on the PID of the process making the call. * * Available since API level 36. * * @param params The params to be set. * @param tids Non-null array of TIDs, where maximum size can be read from * {@link ASystemHealth_getMaxCpuHeadroomTidsSize}. * @param tidsSize The size of the tids array. */ void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* _Nonnull tids, size_t tidsSize) __INTRODUCED_IN(36); /** * Creates a new instance of {@link ACpuHeadroomParams}. * * When the client finishes using {@link ACpuHeadroomParams}, * {@link ACpuHeadroomParams_destroy} must be called to destroy * and free up the resources associated with {@link ACpuHeadroomParams}. * * Available since API level 36. * * @return A new instance of {@link ACpuHeadroomParams}. */ ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create(void) __INTRODUCED_IN(36); /** * Creates a new instance of {@link AGpuHeadroomParams}. * * When the client finishes using {@link AGpuHeadroomParams}, * {@link AGpuHeadroomParams_destroy} must be called to destroy * and free up the resources associated with {@link AGpuHeadroomParams}. * * Available since API level 36. * * @return A new instance of {@link AGpuHeadroomParams}. */ AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create(void) __INTRODUCED_IN(36); /** * Deletes the {@link ACpuHeadroomParams} instance. * * Available since API level 36. * * @param params The params to be deleted. */ void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params) __INTRODUCED_IN(36); /** * Deletes the {@link AGpuHeadroomParams} instance. * * Available since API level 36. * * @param params The params to be deleted. */ void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params) __INTRODUCED_IN(36); /** * Gets the maximum number of TIDs this device supports for getting CPU headroom. * * See {@link ACpuHeadroomParams_setTids}. * * Available since API level 36. * * @param outSize Non-null output pointer to the max size. * @return 0 on success. * ENOTSUP if the CPU headroom API is unsupported. */ int ASystemHealth_getMaxCpuHeadroomTidsSize(size_t* _Nonnull outSize); /** * Gets the range of the calculation window size for CPU headroom. * * Available since API level 36. * * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds. * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds. * @return 0 on success. * ENOTSUP if API is unsupported. */ int ASystemHealth_getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis, int32_t* _Nonnull outMaxMillis) __INTRODUCED_IN(36); /** * Gets the range of the calculation window size for GPU headroom. * * Available since API level 36. * * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds. * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds. * @return 0 on success. * ENOTSUP if API is unsupported. */ int ASystemHealth_getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis, int32_t* _Nonnull outMaxMillis) __INTRODUCED_IN(36); /** * Provides an estimate of available CPU capacity headroom of the device. * * The value can be used by the calling application to determine if the workload was CPU bound and * then take action accordingly to ensure that the workload can be completed smoothly. It can also * be used with the thermal status and headroom to determine if reducing the CPU bound workload can * help reduce the device temperature to avoid thermal throttling. * * If the params are valid, each call will perform at least one synchronous binder transaction that * can take more than 1ms. So it's not recommended to call or wait for this on critical threads. * Some devices may implement this as an on-demand API with lazy initialization, so the caller * should expect higher latency when making the first call (especially with non-default params) * since app starts or after changing params, as the device may need to change its data collection. * * Available since API level 36. * * @param params The params to customize the CPU headroom calculation, or nullptr to use default. * @param outHeadroom Non-null output pointer to a single float, which will be set to the CPU * headroom value. The value will be a single value or `Float.NaN` if it's * temporarily unavailable due to server error or not enough user CPU workload. * Each valid value ranges from [0, 100], where 0 indicates no more cpu resources * can be granted. * @return 0 on success. * EPIPE if failed to get the CPU headroom. * EPERM if the TIDs do not belong to the same process. * ENOTSUP if API or requested params is unsupported. */ int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams* _Nullable params, float* _Nonnull outHeadroom) __INTRODUCED_IN(36); /** * Provides an estimate of available GPU capacity headroom of the device. * * The value can be used by the calling application to determine if the workload was GPU bound and * then take action accordingly to ensure that the workload can be completed smoothly. It can also * be used with the thermal status and headroom to determine if reducing the GPU bound workload can * help reduce the device temperature to avoid thermal throttling. * * If the params are valid, each call will perform at least one synchronous binder transaction that * can take more than 1ms. So it's not recommended to call or wait for this on critical threads. * Some devices may implement this as an on-demand API with lazy initialization, so the caller * should expect higher latency when making the first call (especially with non-default params) * since app starts or after changing params, as the device may need to change its data collection. * * Available since API level 36 * * @param params The params to customize the GPU headroom calculation, or nullptr to use default * @param outHeadroom Non-null output pointer to a single float, which will be set to the GPU * headroom value. The value will be a single value or `Float.NaN` if it's * temporarily unavailable. * Each valid value ranges from [0, 100], where 0 indicates no more gpu resources * can be granted. * @return 0 on success. * EPIPE if failed to get the GPU headroom. * ENOTSUP if API or requested params is unsupported. */ int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams* _Nullable params, float* _Nonnull outHeadroom) __INTRODUCED_IN(36); /** * Gets minimum polling interval for calling {@link ASystemHealth_getCpuHeadroom} in milliseconds. * * The {@link ASystemHealth_getCpuHeadroom} API may return cached result if called more frequently * than the interval. * * Available since API level 36. * * @param outMinIntervalMillis Non-null output pointer to a int64_t, which * will be set to the minimum polling interval in milliseconds. * @return 0 on success. * ENOTSUP if API is unsupported. */ int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) __INTRODUCED_IN(36); /** * Gets minimum polling interval for calling {@link ASystemHealth_getGpuHeadroom} in milliseconds. * * The {@link ASystemHealth_getGpuHeadroom} API may return cached result if called more frequently * than the interval. * * Available since API level 36. * * @param outMinIntervalMillis Non-null output pointer to a int64_t, which * will be set to the minimum polling interval in milliseconds. * @return 0 on success. * ENOTSUP if API is unsupported. */ int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis) __INTRODUCED_IN(36); #ifdef __cplusplus } #endif #endif // _ANDROID_SYSTEM_HEALTH_H /** @} */