• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 SystemHealth
19 *
20  * SystemHealth provides access to data about how various system resources are used by applications.
21  *
22  * CPU/GPU headroom APIs are designed to be best used by applications with consistent and intense
23  * workload such as games to query the remaining capacity headroom over a short period and perform
24  * optimization accordingly. Due to the nature of the fast job scheduling and frequency scaling of
25  * CPU and GPU, the headroom by nature will have "TOCTOU" problem which makes it less suitable for
26  * apps with inconsistent or low workload to take any useful action but simply monitoring. And to
27  * avoid oscillation it's not recommended to adjust workload too frequent (on each polling request)
28  * or too aggressively. As the headroom calculation is more based on reflecting past history usage
29  * than predicting future capacity. Take game as an example, if the API returns CPU headroom of 0 in
30  * one scenario (especially if it's constant across multiple calls), or some value significantly
31  * smaller than other scenarios, then it can reason that the recent performance result is more CPU
32  * bottlenecked. Then reducing the CPU workload intensity can help reserve some headroom to handle
33  * the load variance better, which can result in less frame drops or smooth FPS value. On the other
34  * hand, if the API returns large CPU headroom constantly, the app can be more confident to increase
35  * the workload and expect higher possibility of device meeting its performance expectation.
36  * App can also use thermal APIs to read the current thermal status and headroom first, then poll
37  * the CPU and GPU headroom if the device is (about to) getting thermal throttled. If the CPU/GPU
38  * headrooms provide enough significance such as one valued at 0 while the other at 100, then it can
39  * be used to infer that reducing CPU workload could be more efficient to cool down the device.
40  * There is a caveat that the power controller may scale down the frequency of the CPU and GPU due
41  * to thermal and other reasons, which can result in a higher than usual percentage usage of the
42  * capacity.
43  *
44 * @{
45 */
46 
47 /**
48  * @file system_health.h
49  */
50 
51 #ifndef _ANDROID_SYSTEM_HEALTH_H
52 #define _ANDROID_SYSTEM_HEALTH_H
53 
54 #include <sys/cdefs.h>
55 
56 /******************************************************************
57  *
58  * IMPORTANT NOTICE:
59  *
60  *   This file is part of Android's set of stable system headers
61  *   exposed by the Android NDK (Native Development Kit).
62  *
63  *   Third-party source AND binary code relies on the definitions
64  *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
65  *
66  *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
67  *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
68  *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
69  *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
70  */
71 
72 
73 #include <stdint.h>
74 #include <sys/types.h>
75 
76 #if !defined(__INTRODUCED_IN)
77 #define __INTRODUCED_IN(__api_level) /* nothing */
78 #endif
79 
80 #ifdef __cplusplus
81 extern "C" {
82 #endif
83 
84 /**
85  * Params used to customize the calculation of CPU headroom.
86  *
87  * Also see {@link ASystemHealth_getCpuHeadroom}.
88  */
89 typedef struct ACpuHeadroomParams ACpuHeadroomParams;
90 
91 /**
92  * Params used to customize the calculation of GPU headroom.
93  *
94  * Also see {@link ASystemHealth_getGpuHeadroom}.
95  */
96 typedef struct AGpuHeadroomParams AGpuHeadroomParams;
97 
98 typedef enum ACpuHeadroomCalculationType : int32_t {
99     /**
100      * The headroom calculation type bases on minimum value over a specified window.
101      * Introduced in API level 36.
102      */
103     ACPU_HEADROOM_CALCULATION_TYPE_MIN = 0,
104     /**
105      * The headroom calculation type bases on average value over a specified window.
106      * Introduced in API level 36.
107      */
108     ACPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1,
109 } ACpuHeadroomCalculationType;
110 
111 typedef enum AGpuHeadroomCalculationType : int32_t {
112     /**
113      * The headroom calculation type bases on minimum value over a specified window.
114      * Introduced in API level 36.
115      */
116     AGPU_HEADROOM_CALCULATION_TYPE_MIN = 0,
117     /**
118      * The headroom calculation type bases on average value over a specified window.
119      * Introduced in API level 36.
120      */
121     AGPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1,
122 } AGpuHeadroomCalculationType;
123 
124 /**
125  * Sets the CPU headroom calculation window size in milliseconds.
126  *
127  * Available since API level 36.
128  *
129  * @param params The params to be set.
130  * @param windowMillis The window size in milliseconds ranges from
131  *                     {@link ASystemHealth_getCpuHeadroomCalculationWindowRange}. The smaller the
132  *                     window size, the larger fluctuation in the headroom value should be expected.
133  *                     The default value can be retrieved from the
134  *                     {@link #ACpuHeadroomParams_getCalculationWindowMillis} if not set. The device
135  *                     will try to use the closest feasible window size to this param.
136  */
137 void ACpuHeadroomParams_setCalculationWindowMillis(ACpuHeadroomParams *_Nonnull params,
138                                                    int windowMillis)
139 __INTRODUCED_IN(36);
140 
141 /**
142  * Gets the CPU headroom calculation window size in milliseconds.
143  *
144  * This will return the default value chosen by the device if not set.
145  *
146  * Available since API level 36.
147  *
148  * @param params The params to read from.
149  * @return This will return the default value chosen by the device if the params is not set.
150  */
151 int ACpuHeadroomParams_getCalculationWindowMillis(ACpuHeadroomParams* _Nonnull params)
152 __INTRODUCED_IN(36);
153 
154 /**
155  * Sets the GPU headroom calculation window size in milliseconds.
156  *
157  * Available since API level 36.
158  *
159  * @param params The params to be set.
160  * @param windowMillis The window size in milliseconds ranges from
161  *                     {@link ASystemHealth_getGpuHeadroomCalculationWindowRange}. The smaller the
162  *                     window size, the larger fluctuation in the headroom value should be expected.
163  *                     The default value can be retrieved from the
164  *                     {@link #AGpuHeadroomParams_getCalculationWindowMillis} if not set. The device
165  *                     will try to use the closest feasible window size to this param.
166  */
167 void AGpuHeadroomParams_setCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params,
168                                                    int windowMillis)
169 __INTRODUCED_IN(36);
170 
171 /**
172  * Gets the GPU headroom calculation window size in milliseconds.
173  *
174  * This will return the default value chosen by the device if not set.
175  *
176  * Available since API level 36.
177  *
178  * @param params The params to read from.
179  * @return This will return the default value chosen by the device if the params is not set.
180  */
181 int AGpuHeadroomParams_getCalculationWindowMillis(AGpuHeadroomParams* _Nonnull params)
182 __INTRODUCED_IN(36);
183 
184 /**
185  * Sets the CPU headroom calculation type in {@link ACpuHeadroomParams}.
186  *
187  * Available since API level 36.
188  *
189  * @param params The params to be set.
190  * @param calculationType The headroom calculation type.
191  */
192 void ACpuHeadroomParams_setCalculationType(ACpuHeadroomParams* _Nonnull params,
193                                            ACpuHeadroomCalculationType calculationType)
194 __INTRODUCED_IN(36);
195 
196 /**
197  * Gets the CPU headroom calculation type in {@link ACpuHeadroomParams}.
198  *
199  * This will return the default value chosen by the device if not set.
200  *
201  * Available since API level 36.
202  *
203  * @param params The params to read from.
204  * @return The headroom calculation type.
205  */
206 ACpuHeadroomCalculationType
207 ACpuHeadroomParams_getCalculationType(ACpuHeadroomParams* _Nonnull params)
208 __INTRODUCED_IN(36);
209 
210 /**
211  * Sets the GPU headroom calculation type in {@link AGpuHeadroomParams}.
212  *
213  * Available since API level 36.
214  *
215  * @param params The params to be set.
216  * @param calculationType The headroom calculation type.
217  */
218 void AGpuHeadroomParams_setCalculationType(AGpuHeadroomParams* _Nonnull params,
219                                            AGpuHeadroomCalculationType calculationType)
220 __INTRODUCED_IN(36);
221 
222 /**
223  * Gets the GPU headroom calculation type in {@link AGpuHeadroomParams}.
224  *
225  * This will return the default value chosen by the device if not set.
226  *
227  * Available since API level 36.
228  *
229  * @param params The params to read from.
230  * @return The headroom calculation type.
231  */
232 AGpuHeadroomCalculationType
233 AGpuHeadroomParams_getCalculationType(AGpuHeadroomParams* _Nonnull params)
234 __INTRODUCED_IN(36);
235 
236 /**
237  * Sets the thread TIDs to track in {@link ACpuHeadroomParams}.
238  *
239  * The TIDs should belong to the same of the process that will make the headroom call. And they
240  * should not have different core affinity.
241  *
242  * If not set or set to empty, the headroom will be based on the PID of the process making the call.
243  *
244  * Available since API level 36.
245  *
246  * @param params The params to be set.
247  * @param tids Non-null array of TIDs, where maximum size can be read from
248  *             {@link ASystemHealth_getMaxCpuHeadroomTidsSize}.
249  * @param tidsSize The size of the tids array.
250  */
251 void ACpuHeadroomParams_setTids(ACpuHeadroomParams* _Nonnull params, const int* _Nonnull tids,
252                                 size_t tidsSize)
253 __INTRODUCED_IN(36);
254 
255 /**
256  * Creates a new instance of {@link ACpuHeadroomParams}.
257  *
258  * When the client finishes using {@link ACpuHeadroomParams},
259  * {@link ACpuHeadroomParams_destroy} must be called to destroy
260  * and free up the resources associated with {@link ACpuHeadroomParams}.
261  *
262  * Available since API level 36.
263  *
264  * @return A new instance of {@link ACpuHeadroomParams}.
265  */
266 ACpuHeadroomParams* _Nonnull ACpuHeadroomParams_create(void)
267 __INTRODUCED_IN(36);
268 
269 /**
270  * Creates a new instance of {@link AGpuHeadroomParams}.
271  *
272  * When the client finishes using {@link AGpuHeadroomParams},
273  * {@link AGpuHeadroomParams_destroy} must be called to destroy
274  * and free up the resources associated with {@link AGpuHeadroomParams}.
275  *
276  * Available since API level 36.
277  *
278  * @return A new instance of {@link AGpuHeadroomParams}.
279  */
280 AGpuHeadroomParams* _Nonnull AGpuHeadroomParams_create(void)
281 __INTRODUCED_IN(36);
282 
283 /**
284  * Deletes the {@link ACpuHeadroomParams} instance.
285  *
286  * Available since API level 36.
287  *
288  * @param params The params to be deleted.
289  */
290 void ACpuHeadroomParams_destroy(ACpuHeadroomParams* _Nullable params)
291 __INTRODUCED_IN(36);
292 
293 /**
294  * Deletes the {@link AGpuHeadroomParams} instance.
295  *
296  * Available since API level 36.
297  *
298  * @param params The params to be deleted.
299  */
300 void AGpuHeadroomParams_destroy(AGpuHeadroomParams* _Nullable params)
301 __INTRODUCED_IN(36);
302 
303 /**
304  * Gets the maximum number of TIDs this device supports for getting CPU headroom.
305  *
306  * See {@link ACpuHeadroomParams_setTids}.
307  *
308  * Available since API level 36.
309  *
310  * @param outSize Non-null output pointer to the max size.
311  * @return 0 on success.
312  *         ENOTSUP if the CPU headroom API is unsupported.
313  */
314 int ASystemHealth_getMaxCpuHeadroomTidsSize(size_t* _Nonnull outSize);
315 
316 /**
317  * Gets the range of the calculation window size for CPU headroom.
318  *
319  * Available since API level 36.
320  *
321  * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds.
322  * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds.
323  * @return 0 on success.
324  *         ENOTSUP if API is unsupported.
325  */
326 int ASystemHealth_getCpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
327                                                        int32_t* _Nonnull outMaxMillis)
328 __INTRODUCED_IN(36);
329 
330 /**
331  * Gets the range of the calculation window size for GPU headroom.
332  *
333  * Available since API level 36.
334  *
335  * @param outMinMillis Non-null output pointer to be set to the minimum window size in milliseconds.
336  * @param outMaxMillis Non-null output pointer to be set to the maximum window size in milliseconds.
337  * @return 0 on success.
338  *         ENOTSUP if API is unsupported.
339  */
340 int ASystemHealth_getGpuHeadroomCalculationWindowRange(int32_t* _Nonnull outMinMillis,
341                                                        int32_t* _Nonnull outMaxMillis)
342 __INTRODUCED_IN(36);
343 
344 /**
345  * Provides an estimate of available CPU capacity headroom of the device.
346  *
347  * The value can be used by the calling application to determine if the workload was CPU bound and
348  * then take action accordingly to ensure that the workload can be completed smoothly. It can also
349  * be used with the thermal status and headroom to determine if reducing the CPU bound workload can
350  * help reduce the device temperature to avoid thermal throttling.
351  *
352  * If the params are valid, each call will perform at least one synchronous binder transaction that
353  * can take more than 1ms. So it's not recommended to call or wait for this on critical threads.
354  * Some devices may implement this as an on-demand API with lazy initialization, so the caller
355  * should expect higher latency when making the first call (especially with non-default params)
356  * since app starts or after changing params, as the device may need to change its data collection.
357  *
358  * Available since API level 36.
359  *
360  * @param params The params to customize the CPU headroom calculation, or nullptr to use default.
361  * @param outHeadroom Non-null output pointer to a single float, which will be set to the CPU
362  *                    headroom value. The value will be a single value or `Float.NaN` if it's
363  *                    temporarily unavailable due to server error or not enough user CPU workload.
364  *                    Each valid value ranges from [0, 100], where 0 indicates no more cpu resources
365  *                    can be granted.
366  * @return 0 on success.
367  *         EPIPE if failed to get the CPU headroom.
368  *         EPERM if the TIDs do not belong to the same process.
369  *         ENOTSUP if API or requested params is unsupported.
370  */
371 int ASystemHealth_getCpuHeadroom(const ACpuHeadroomParams* _Nullable params,
372                                  float* _Nonnull outHeadroom)
373 __INTRODUCED_IN(36);
374 
375 /**
376  * Provides an estimate of available GPU capacity headroom of the device.
377  *
378  * The value can be used by the calling application to determine if the workload was GPU bound and
379  * then take action accordingly to ensure that the workload can be completed smoothly. It can also
380  * be used with the thermal status and headroom to determine if reducing the GPU bound workload can
381  * help reduce the device temperature to avoid thermal throttling.
382  *
383  * If the params are valid, each call will perform at least one synchronous binder transaction that
384  * can take more than 1ms. So it's not recommended to call or wait for this on critical threads.
385  * Some devices may implement this as an on-demand API with lazy initialization, so the caller
386  * should expect higher latency when making the first call (especially with non-default params)
387  * since app starts or after changing params, as the device may need to change its data collection.
388  *
389  * Available since API level 36
390  *
391  * @param params The params to customize the GPU headroom calculation, or nullptr to use default
392  * @param outHeadroom Non-null output pointer to a single float, which will be set to the GPU
393  *                    headroom value. The value will be a single value or `Float.NaN` if it's
394  *                    temporarily unavailable.
395  *                    Each valid value ranges from [0, 100], where 0 indicates no more gpu resources
396  *                    can be granted.
397  * @return 0 on success.
398  *         EPIPE if failed to get the GPU headroom.
399  *         ENOTSUP if API or requested params is unsupported.
400  */
401 int ASystemHealth_getGpuHeadroom(const AGpuHeadroomParams* _Nullable params,
402                                  float* _Nonnull outHeadroom)
403 __INTRODUCED_IN(36);
404 
405 /**
406  * Gets minimum polling interval for calling {@link ASystemHealth_getCpuHeadroom} in milliseconds.
407  *
408  * The {@link ASystemHealth_getCpuHeadroom} API may return cached result if called more frequently
409  * than the interval.
410  *
411  * Available since API level 36.
412  *
413  * @param outMinIntervalMillis Non-null output pointer to a int64_t, which
414  *                will be set to the minimum polling interval in milliseconds.
415  * @return 0 on success.
416  *         ENOTSUP if API is unsupported.
417  */
418 int ASystemHealth_getCpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis)
419 __INTRODUCED_IN(36);
420 
421 /**
422  * Gets minimum polling interval for calling {@link ASystemHealth_getGpuHeadroom} in milliseconds.
423  *
424  * The {@link ASystemHealth_getGpuHeadroom} API may return cached result if called more frequently
425  * than the interval.
426  *
427  * Available since API level 36.
428  *
429  * @param outMinIntervalMillis Non-null output pointer to a int64_t, which
430  *                will be set to the minimum polling interval in milliseconds.
431  * @return 0 on success.
432  *         ENOTSUP if API is unsupported.
433  */
434 int ASystemHealth_getGpuHeadroomMinIntervalMillis(int64_t* _Nonnull outMinIntervalMillis)
435 __INTRODUCED_IN(36);
436 
437 #ifdef __cplusplus
438 }
439 #endif
440 
441 #endif // _ANDROID_SYSTEM_HEALTH_H
442 
443 /** @} */
444