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