blob: 4494e328156f3d4abc0db8f56dafeb86e5ffab50 [file]
/*
* 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 <sys/cdefs.h>
/******************************************************************
*
* 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 <stdint.h>
#include <sys/types.h>
#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
/** @} */