Skip to content

Commit 332c07e

Browse files
pm: policy: separate default policy and events
The default policy currently directly references the private variable next_event from policy_events.c to then convert the cycle of said event (if exists) to a kernel tick in the future, something policy_events.c already implements and exposes through pm_policy_next_event_ticks(). Additionally, the implementation of pm_policy_next_state() in policy_default.c already gets the nearest kernel tick, wherein the next event has already been accounted for in, see implementation of pm_system_suspend(). This commit removes the redundant and layer violating computation if the tick of the next event from policy_default.c and updates the test test_pm_policy_events to not use default policy to determine if pm_policy_next_event_ticks() is correct. Signed-off-by: Bjarki Arge Andreasen <[email protected]>
1 parent 807872f commit 332c07e

File tree

2 files changed

+25
-79
lines changed

2 files changed

+25
-79
lines changed

subsys/pm/policy/policy_default.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <zephyr/sys_clock.h>
1010
#include <zephyr/pm/device.h>
1111

12-
extern struct pm_policy_event *next_event;
1312
extern int32_t max_latency_cyc;
1413

1514
const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
@@ -30,27 +29,6 @@ const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
3029

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

33-
if ((next_event) && (next_event->value_cyc >= 0)) {
34-
uint32_t cyc_curr = k_cycle_get_32();
35-
int64_t cyc_evt = next_event->value_cyc - cyc_curr;
36-
37-
/* event happening after cycle counter max value, pad */
38-
if (next_event->value_cyc <= cyc_curr) {
39-
cyc_evt += UINT32_MAX;
40-
}
41-
42-
if (cyc_evt > 0) {
43-
/* if there's no system wakeup event always wins,
44-
* otherwise, who comes earlier wins
45-
*/
46-
if (cyc < 0) {
47-
cyc = cyc_evt;
48-
} else {
49-
cyc = MIN(cyc, cyc_evt);
50-
}
51-
}
52-
}
53-
5432
for (int16_t i = (int16_t)num_cpu_states - 1; i >= 0; i--) {
5533
const struct pm_state_info *state = &cpu_states[i];
5634
uint32_t min_residency_cyc, exit_latency_cyc;

tests/subsys/pm/policy_api/src/main.c

Lines changed: 25 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -304,68 +304,36 @@ ZTEST(policy_api, test_pm_policy_next_state_custom)
304304
}
305305
#endif /* CONFIG_PM_POLICY_CUSTOM */
306306

307-
#ifdef CONFIG_PM_POLICY_DEFAULT
308-
/* note: we can't easily mock k_cycle_get_32(), so test is not ideal */
309307
ZTEST(policy_api, test_pm_policy_events)
310308
{
311-
struct pm_policy_event evt1, evt2;
312-
const struct pm_state_info *next;
313-
uint32_t now;
314-
315-
now = k_cyc_to_ticks_ceil32(k_cycle_get_32());
316-
317-
/* events:
318-
* - 10ms from now (time < runtime idle latency)
319-
* - 200ms from now (time > runtime idle, < suspend to ram latencies)
320-
*
321-
* system wakeup:
322-
* - 2s from now (time > suspend to ram latency)
323-
*
324-
* first event wins, so we must stay active
325-
*/
326-
pm_policy_event_register(&evt1, k_ms_to_cyc_floor32(10) + k_cycle_get_32());
327-
pm_policy_event_register(&evt2, k_ms_to_cyc_floor32(200) + k_cycle_get_32());
328-
next = pm_policy_next_state(0U, now + k_sec_to_ticks_floor32(2));
329-
zassert_is_null(next);
330-
331-
/* remove first event so second event now wins, meaning we can now enter
332-
* runtime idle
333-
*/
309+
struct pm_policy_event evt1;
310+
struct pm_policy_event evt2;
311+
uint32_t now_cycle;
312+
uint32_t evt1_1_cycle;
313+
uint32_t evt1_2_cycle;
314+
uint32_t evt2_cycle;
315+
316+
now_cycle = k_cycle_get_32();
317+
evt1_1_cycle = now_cycle + k_ticks_to_cyc_floor32(100);
318+
evt1_2_cycle = now_cycle + k_ticks_to_cyc_floor32(200);
319+
evt2_cycle = now_cycle + k_ticks_to_cyc_floor32(2000);
320+
321+
zassert_equal(pm_policy_next_event_ticks(), -1);
322+
pm_policy_event_register(&evt1, evt1_1_cycle);
323+
pm_policy_event_register(&evt2, evt2_cycle);
324+
zassert_within(pm_policy_next_event_ticks(), 100, 50);
334325
pm_policy_event_unregister(&evt1);
335-
next = pm_policy_next_state(0U, now + k_sec_to_ticks_floor32(2));
336-
zassert_equal(next->state, PM_STATE_RUNTIME_IDLE);
337-
338-
/* remove second event, now we can enter deepest state */
326+
zassert_within(pm_policy_next_event_ticks(), 2000, 50);
339327
pm_policy_event_unregister(&evt2);
340-
next = pm_policy_next_state(0U, now + k_sec_to_ticks_floor32(2));
341-
zassert_equal(next->state, PM_STATE_SUSPEND_TO_RAM);
342-
343-
/* events:
344-
* - 2s from now (time > suspend to ram latency)
345-
*
346-
* system wakeup:
347-
* - 200ms from now (time > runtime idle, < suspend to ram latencies)
348-
*
349-
* system wakeup wins, so we can go up to runtime idle.
350-
*/
351-
pm_policy_event_register(&evt1, k_sec_to_cyc_floor32(2) + k_cycle_get_32());
352-
next = pm_policy_next_state(0U, now + k_ms_to_ticks_floor32(200));
353-
zassert_equal(next->state, PM_STATE_RUNTIME_IDLE);
354-
355-
/* modify event to occur in 10ms, so it now wins system wakeup and
356-
* requires to stay awake
357-
*/
358-
pm_policy_event_update(&evt1, k_ms_to_cyc_floor32(10) + k_cycle_get_32());
359-
next = pm_policy_next_state(0U, now + k_ms_to_ticks_floor32(200));
360-
zassert_is_null(next);
361-
328+
zassert_equal(pm_policy_next_event_ticks(), -1);
329+
pm_policy_event_register(&evt2, evt2_cycle);
330+
zassert_within(pm_policy_next_event_ticks(), 2000, 50);
331+
pm_policy_event_register(&evt1, evt1_1_cycle);
332+
zassert_within(pm_policy_next_event_ticks(), 100, 50);
333+
pm_policy_event_update(&evt1, evt1_2_cycle);
334+
zassert_within(pm_policy_next_event_ticks(), 200, 50);
362335
pm_policy_event_unregister(&evt1);
336+
pm_policy_event_unregister(&evt2);
363337
}
364-
#else
365-
ZTEST(policy_api, test_pm_policy_events)
366-
{
367-
ztest_test_skip();
368-
}
369-
#endif /* CONFIG_PM_POLICY_CUSTOM */
370338

371339
ZTEST_SUITE(policy_api, NULL, NULL, NULL, NULL, NULL);

0 commit comments

Comments
 (0)