Skip to content

Commit e7dd4c6

Browse files
committed
tests: pm: policy_api: Add test for latency immediate action
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 <[email protected]>
1 parent b995c2c commit e7dd4c6

File tree

1 file changed

+150
-0
lines changed
  • tests/subsys/pm/policy_api/src

1 file changed

+150
-0
lines changed

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

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,156 @@ ZTEST(policy_api, test_pm_policy_next_state_default_latency)
244244
expected_latency = SYS_FOREVER_US;
245245
pm_policy_latency_request_remove(&req1);
246246
}
247+
248+
struct test_data {
249+
struct k_timer timer;
250+
struct onoff_manager mgr;
251+
struct onoff_monitor monitor;
252+
int res;
253+
onoff_notify_fn notify;
254+
k_timeout_t timeout;
255+
bool on;
256+
};
257+
258+
struct test_req {
259+
struct pm_policy_latency_request req;
260+
volatile int result;
261+
};
262+
263+
static void onoff_monitor_cb(struct onoff_manager *mgr,
264+
struct onoff_monitor *mon,
265+
uint32_t state,
266+
int res)
267+
{
268+
struct test_data *data = CONTAINER_OF(mgr, struct test_data, mgr);
269+
270+
data->on = (state == ONOFF_STATE_ON);
271+
}
272+
273+
static void onoff_timeout(struct k_timer *timer)
274+
{
275+
struct test_data *data = CONTAINER_OF(timer, struct test_data, timer);
276+
277+
data->notify(&data->mgr, data->res);
278+
}
279+
280+
K_TIMER_DEFINE(onoff_timer, onoff_timeout, NULL);
281+
282+
static void onoff_start(struct onoff_manager *mgr, onoff_notify_fn notify)
283+
{
284+
struct test_data *data = CONTAINER_OF(mgr, struct test_data, mgr);
285+
286+
data->notify = notify;
287+
k_timer_start(&data->timer, data->timeout, K_NO_WAIT);
288+
}
289+
290+
static void onoff_stop(struct onoff_manager *mgr, onoff_notify_fn notify)
291+
{
292+
struct test_data *data = CONTAINER_OF(mgr, struct test_data, mgr);
293+
294+
data->notify = notify;
295+
k_timer_start(&data->timer, data->timeout, K_NO_WAIT);
296+
}
297+
298+
static void immediate_ctrl_binary_init(struct test_data *data, uint32_t thr, uint32_t t_op)
299+
{
300+
static const struct onoff_transitions transitions = {
301+
.start = onoff_start,
302+
.stop = onoff_stop
303+
};
304+
static struct pm_policy_latency_immediate_binary bin_mgr;
305+
struct pm_policy_latency_immediate_ctrl ctrl;
306+
int rv;
307+
308+
bin_mgr.mgr = &data->mgr;
309+
bin_mgr.thr = thr;
310+
ctrl.onoff = true;
311+
ctrl.bin_mgr = &bin_mgr;
312+
data->monitor.callback = onoff_monitor_cb;
313+
314+
data->timeout = K_MSEC(t_op);
315+
k_timer_init(&data->timer, onoff_timeout, NULL);
316+
rv = onoff_manager_init(&data->mgr, &transitions);
317+
zassert_equal(rv, 0);
318+
319+
rv = onoff_monitor_register(&data->mgr, &data->monitor);
320+
zassert_equal(rv, 0);
321+
322+
rv = pm_policy_latency_immediate_ctrl_add(&ctrl);
323+
zassert_equal(rv, 0);
324+
}
325+
326+
static void latency_changed(struct pm_policy_latency_request *req, int32_t result)
327+
{
328+
struct test_req *test_req = CONTAINER_OF(req, struct test_req, req);
329+
330+
test_req->result = result;
331+
}
332+
333+
ZTEST(policy_api, test_pm_policy_latency_immediate_action_bin)
334+
{
335+
struct test_data data;
336+
uint32_t thr = 1000;
337+
uint32_t t_op = 1;
338+
struct test_req req1, req2;
339+
int rv;
340+
int result = -EAGAIN;
341+
342+
immediate_ctrl_binary_init(&data, thr, t_op);
343+
344+
sys_notify_init_spinwait(&req1.req.cli.notify);
345+
346+
/* Latency above threhold so requirement is already met. */
347+
rv = pm_policy_latency_request_add(&req1.req, thr + 1);
348+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
349+
zassert_equal(sys_notify_fetch_result(&req1.req.cli.notify, &result), 0);
350+
zassert_equal(result, 0, "Unexpected result: %d", result);
351+
352+
req2.result = -EIO;
353+
sys_notify_init_callback(&req2.req.cli.notify, latency_changed);
354+
rv = pm_policy_latency_request_add(&req2.req, thr + 2);
355+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
356+
zassert_equal(req2.result, 0, "Unexpected rv: %d", req2.result);
357+
358+
req2.result = -EIO;
359+
sys_notify_init_callback(&req2.req.cli.notify, latency_changed);
360+
/* Below the threshold, it triggers asynchronous action. */
361+
rv = pm_policy_latency_request_update(&req2.req, thr - 1);
362+
zassert_equal(rv, 1, "Unexpected rv: %d", rv);
363+
/* Not finished yet. */
364+
zassert_equal(req2.result, -EIO, "Unexpected rv: %d", req2.result);
365+
k_msleep(t_op);
366+
zassert_equal(req2.result, 0, "Unexpected rv: %d", req2.result);
367+
368+
rv = pm_policy_latency_request_remove(&req1.req);
369+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
370+
371+
rv = pm_policy_latency_request_remove(&req2.req);
372+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
373+
374+
zassert_false(data.on);
375+
rv = pm_policy_latency_request_add_sync(&req1.req, thr - 1);
376+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
377+
/* Synchronous request blocks until immediate action is completed. */
378+
zassert_true(data.on);
379+
380+
rv = pm_policy_latency_request_remove(&req1.req);
381+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
382+
383+
/* Add request below the threshold. */
384+
rv = pm_policy_latency_request_add(&req1.req, thr + 1);
385+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
386+
zassert_false(data.on);
387+
388+
/* Synchronous request for update that trigger the immediate action. */
389+
rv = pm_policy_latency_request_update_sync(&req1.req, thr - 1);
390+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
391+
zassert_true(data.on);
392+
393+
rv = pm_policy_latency_request_remove(&req1.req);
394+
zassert_equal(rv, 0, "Unexpected rv: %d", rv);
395+
}
396+
247397
#else
248398
ZTEST(policy_api, test_pm_policy_next_state_default)
249399
{

0 commit comments

Comments
 (0)