From cd1e954ccca691c1d42e2ec47b24b0b9936f48ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Mon, 25 Nov 2024 11:26:40 +0100 Subject: [PATCH] tests: pm: policy_api: Add test for latency immediate action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test for the case where latency change triggers an immediate action. Configuration is using a single threshold for triggering of the action. Signed-off-by: Krzysztof Chruściński --- tests/subsys/pm/policy_api/prj.conf | 2 + tests/subsys/pm/policy_api/src/main.c | 150 ++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) diff --git a/tests/subsys/pm/policy_api/prj.conf b/tests/subsys/pm/policy_api/prj.conf index cf84b4d2dd4882..5e9c57cb1bae7d 100644 --- a/tests/subsys/pm/policy_api/prj.conf +++ b/tests/subsys/pm/policy_api/prj.conf @@ -3,3 +3,5 @@ CONFIG_ZTEST=y CONFIG_PM=y +CONFIG_ONOFF=y +CONFIG_POLL=y diff --git a/tests/subsys/pm/policy_api/src/main.c b/tests/subsys/pm/policy_api/src/main.c index 4543865b76a631..45fb44c35e5ba2 100644 --- a/tests/subsys/pm/policy_api/src/main.c +++ b/tests/subsys/pm/policy_api/src/main.c @@ -244,6 +244,156 @@ ZTEST(policy_api, test_pm_policy_next_state_default_latency) expected_latency = SYS_FOREVER_US; pm_policy_latency_request_remove(&req1); } + +struct test_data { + struct k_timer timer; + struct onoff_manager mgr; + struct onoff_monitor monitor; + int res; + onoff_notify_fn notify; + k_timeout_t timeout; + bool on; +}; + +struct test_req { + struct pm_policy_latency_request req; + volatile int result; +}; + +static void onoff_monitor_cb(struct onoff_manager *mgr, + struct onoff_monitor *mon, + uint32_t state, + int res) +{ + struct test_data *data = CONTAINER_OF(mgr, struct test_data, mgr); + + data->on = (state == ONOFF_STATE_ON); +} + +static void onoff_timeout(struct k_timer *timer) +{ + struct test_data *data = CONTAINER_OF(timer, struct test_data, timer); + + data->notify(&data->mgr, data->res); +} + +K_TIMER_DEFINE(onoff_timer, onoff_timeout, NULL); + +static void onoff_start(struct onoff_manager *mgr, onoff_notify_fn notify) +{ + struct test_data *data = CONTAINER_OF(mgr, struct test_data, mgr); + + data->notify = notify; + k_timer_start(&data->timer, data->timeout, K_NO_WAIT); +} + +static void onoff_stop(struct onoff_manager *mgr, onoff_notify_fn notify) +{ + struct test_data *data = CONTAINER_OF(mgr, struct test_data, mgr); + + data->notify = notify; + k_timer_start(&data->timer, data->timeout, K_NO_WAIT); +} + +static void immediate_ctrl_binary_init(struct test_data *data, uint32_t thr, uint32_t t_op) +{ + static const struct onoff_transitions transitions = { + .start = onoff_start, + .stop = onoff_stop + }; + static struct pm_policy_latency_immediate_binary bin_mgr; + struct pm_policy_latency_immediate_ctrl ctrl; + int rv; + + bin_mgr.mgr = &data->mgr; + bin_mgr.thr = thr; + ctrl.onoff = true; + ctrl.bin_mgr = &bin_mgr; + data->monitor.callback = onoff_monitor_cb; + + data->timeout = K_MSEC(t_op); + k_timer_init(&data->timer, onoff_timeout, NULL); + rv = onoff_manager_init(&data->mgr, &transitions); + zassert_equal(rv, 0); + + rv = onoff_monitor_register(&data->mgr, &data->monitor); + zassert_equal(rv, 0); + + rv = pm_policy_latency_immediate_ctrl_add(&ctrl); + zassert_equal(rv, 0); +} + +static void latency_changed(struct pm_policy_latency_request *req, int32_t result) +{ + struct test_req *test_req = CONTAINER_OF(req, struct test_req, req); + + test_req->result = result; +} + +ZTEST(policy_api, test_pm_policy_latency_immediate_action_bin) +{ + struct test_data data; + uint32_t thr = 1000; + uint32_t t_op = 1; + struct test_req req1, req2; + int rv; + int result = -EAGAIN; + + immediate_ctrl_binary_init(&data, thr, t_op); + + sys_notify_init_spinwait(&req1.req.cli.notify); + + /* Latency above threhold so requirement is already met. */ + rv = pm_policy_latency_request_add(&req1.req, thr + 1); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + zassert_equal(sys_notify_fetch_result(&req1.req.cli.notify, &result), 0); + zassert_equal(result, 0, "Unexpected result: %d", result); + + req2.result = -EIO; + sys_notify_init_callback(&req2.req.cli.notify, latency_changed); + rv = pm_policy_latency_request_add(&req2.req, thr + 2); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + zassert_equal(req2.result, 0, "Unexpected rv: %d", req2.result); + + req2.result = -EIO; + sys_notify_init_callback(&req2.req.cli.notify, latency_changed); + /* Below the threshold, it triggers asynchronous action. */ + rv = pm_policy_latency_request_update(&req2.req, thr - 1); + zassert_equal(rv, 1, "Unexpected rv: %d", rv); + /* Not finished yet. */ + zassert_equal(req2.result, -EIO, "Unexpected rv: %d", req2.result); + k_msleep(t_op); + zassert_equal(req2.result, 0, "Unexpected rv: %d", req2.result); + + rv = pm_policy_latency_request_remove(&req1.req); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + + rv = pm_policy_latency_request_remove(&req2.req); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + + zassert_false(data.on); + rv = pm_policy_latency_request_add_sync(&req1.req, thr - 1); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + /* Synchronous request blocks until immediate action is completed. */ + zassert_true(data.on); + + rv = pm_policy_latency_request_remove(&req1.req); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + + /* Add request below the threshold. */ + rv = pm_policy_latency_request_add(&req1.req, thr + 1); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + zassert_false(data.on); + + /* Synchronous request for update that trigger the immediate action. */ + rv = pm_policy_latency_request_update_sync(&req1.req, thr - 1); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); + zassert_true(data.on); + + rv = pm_policy_latency_request_remove(&req1.req); + zassert_equal(rv, 0, "Unexpected rv: %d", rv); +} + #else ZTEST(policy_api, test_pm_policy_next_state_default) {