Skip to content

Commit 44c07a4

Browse files
committed
pm: policy: default: Optimize power state selection
Update power state selection. Previously, it was iterating over states starting from the last one so the most common short sleep periods were taking the longest time to select. Order is now swapped so that short sleeps will get power state as quick as possible. When comparing current sleep time to power mode residency time only min_residency_us is used as exit time can be neglected as typically is much lower. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent fef66f3 commit 44c07a4

File tree

1 file changed

+12
-18
lines changed

1 file changed

+12
-18
lines changed

subsys/pm/policy/policy_default.c

+12-18
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99
#include <zephyr/sys_clock.h>
1010
#include <zephyr/pm/device.h>
1111

12-
extern int32_t max_latency_cyc;
13-
1412
const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
1513
{
1614
int64_t cyc = -1;
1715
uint8_t num_cpu_states;
1816
const struct pm_state_info *cpu_states;
17+
const struct pm_state_info *out_state = NULL;
1918

2019
#ifdef CONFIG_PM_NEED_ALL_DEVICES_IDLE
2120
if (pm_device_is_any_busy()) {
@@ -29,29 +28,24 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
2928

3029
num_cpu_states = pm_state_cpu_get_all(cpu, &cpu_states);
3130

32-
for (int16_t i = (int16_t)num_cpu_states - 1; i >= 0; i--) {
31+
for (uint32_t i = 0; i < num_cpu_states; i++) {
3332
const struct pm_state_info *state = &cpu_states[i];
34-
uint32_t min_residency_cyc, exit_latency_cyc;
33+
uint32_t min_residency_ticks;
3534

36-
/* check if there is a lock on state + substate */
37-
if (pm_policy_state_lock_is_active(state->state, state->substate_id)) {
38-
continue;
39-
}
35+
min_residency_ticks = k_us_to_ticks_ceil32(state->min_residency_us);
4036

41-
min_residency_cyc = k_us_to_cyc_ceil32(state->min_residency_us);
42-
exit_latency_cyc = k_us_to_cyc_ceil32(state->exit_latency_us);
37+
if (ticks < min_residency_ticks) {
38+
/* If current state has higher residency then use the previous state; */
39+
break;
40+
}
4341

44-
/* skip state if it brings too much latency */
45-
if ((max_latency_cyc >= 0) &&
46-
(exit_latency_cyc >= max_latency_cyc)) {
42+
/* check if state is available. */
43+
if (!pm_policy_state_is_available(state->state, state->substate_id)) {
4744
continue;
4845
}
4946

50-
if ((cyc < 0) ||
51-
(cyc >= (min_residency_cyc + exit_latency_cyc))) {
52-
return state;
53-
}
47+
out_state = state;
5448
}
5549

56-
return NULL;
50+
return out_state;
5751
}

0 commit comments

Comments
 (0)