1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/pm/pm.h>
9 #include <zephyr/irq_offload.h>
10 #include <zephyr/debug/stack.h>
11 
12 #define SLEEP_MS 100
13 #define NUM_OF_WORK 2
14 #define TEST_STRING "TEST"
15 
16 static struct k_work work[NUM_OF_WORK];
17 static struct k_sem sync_sema;
18 
19 /**TESTPOINT: stack analyze*/
tdata_dump_callback(const struct k_thread * thread,void * user_data)20 static void tdata_dump_callback(const struct k_thread *thread, void *user_data)
21 {
22 	log_stack_usage(thread);
23 }
24 
25 /* Our PM policy handler */
pm_policy_next_state(uint8_t cpu,int32_t ticks)26 const struct pm_state_info *pm_policy_next_state(uint8_t cpu, int32_t ticks)
27 {
28 	static bool test_flag;
29 
30 	ARG_UNUSED(cpu);
31 
32 	/* Call k_thread_foreach only once otherwise it will
33 	 * flood the console with stack dumps.
34 	 */
35 	if (!test_flag) {
36 		k_thread_foreach(tdata_dump_callback, NULL);
37 		test_flag = true;
38 	}
39 
40 	return NULL;
41 }
42 
43 /*work handler*/
work_handler(struct k_work * w)44 static void work_handler(struct k_work *w)
45 {
46 	k_thread_foreach(tdata_dump_callback, NULL);
47 	k_sem_give(&sync_sema);
48 }
49 
50 /**
51  * @brief Tests for kernel profiling
52  * @defgroup kernel_profiling_tests Profiling
53  * @ingroup all_tests
54  * @{
55  * @}
56  */
57 
58 /**
59  * @brief Test stack usage through main thread
60  *
61  * This test prints the main, idle, interrupt and system workqueue
62  * stack usage through main thread.
63  *
64  * @ingroup kernel_profiling_tests
65  *
66  * @see k_thread_foreach(), log_stack_usage()
67  */
ZTEST(profiling_api,test_call_stacks_analyze_main)68 ZTEST(profiling_api, test_call_stacks_analyze_main)
69 {
70 	TC_PRINT("from main thread:\n");
71 	k_thread_foreach(tdata_dump_callback, NULL);
72 }
73 
74 /**
75  * @brief Test stack usage through idle thread
76  *
77  * This test prints the main, idle, interrupt and system workqueue
78  * stack usage through idle thread.
79  *
80  * @ingroup kernel_profiling_tests
81  *
82  * @see k_thread_foreach(), pm_system_suspend(), pm_system_resume(),
83  * log_stack_usage()
84  */
ZTEST(profiling_api_1cpu,test_call_stacks_analyze_idle)85 ZTEST(profiling_api_1cpu, test_call_stacks_analyze_idle)
86 {
87 	TC_PRINT("from idle thread:\n");
88 	k_msleep(SLEEP_MS);
89 }
90 
91 /**
92  * @brief Test stack usage through system workqueue
93  *
94  * This test prints the main, idle, interrupt and system workqueue
95  * stack usage through system workqueue.
96  *
97  * @ingroup kernel_profiling_tests
98  *
99  * @see k_thread_foreach(), k_work_init(), k_work_submit(),
100  * log_stack_usage()
101  */
ZTEST(profiling_api_1cpu,test_call_stacks_analyze_workq)102 ZTEST(profiling_api_1cpu, test_call_stacks_analyze_workq)
103 {
104 	TC_PRINT("from workq:\n");
105 	k_sem_init(&sync_sema, 0, NUM_OF_WORK);
106 	for (int i = 0; i < NUM_OF_WORK; i++) {
107 		k_work_init(&work[i], work_handler);
108 		k_work_submit(&work[i]);
109 		k_sem_take(&sync_sema, K_FOREVER);
110 	}
111 }
112 
113 /*TODO: add test case to capture the usage of interrupt call stack*/
114 
115 ZTEST_SUITE(profiling_api, NULL, NULL, NULL, NULL, NULL);
116 
117 ZTEST_SUITE(profiling_api_1cpu, NULL, NULL,
118 		ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
119