1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-12-22     Shell        Support hook list
9  */
10 
11 #include <rtthread.h>
12 #include "rtconfig.h"
13 #include "utest.h"
14 #include "utest_assert.h"
15 
16 static int hooker1_ent_count;
17 static int hooker2_ent_count;
18 static struct rt_thread thr_tobe_inited;
19 
thread_inited_hooker1(rt_thread_t thread)20 static void thread_inited_hooker1(rt_thread_t thread)
21 {
22     LOG_D("%s: count %d", __func__, hooker1_ent_count);
23     hooker1_ent_count += 1;
24 }
25 RT_OBJECT_HOOKLIST_DEFINE_NODE(rt_thread_inited, hooker1_node, thread_inited_hooker1);
26 
thread_inited_hooker2(rt_thread_t thread)27 static void thread_inited_hooker2(rt_thread_t thread)
28 {
29     LOG_D("%s: count %d", __func__, hooker2_ent_count);
30     hooker2_ent_count += 1;
31 }
32 RT_OBJECT_HOOKLIST_DEFINE_NODE(rt_thread_inited, hooker2_node, thread_inited_hooker2);
33 
34 static char _thr_stack[UTEST_THR_STACK_SIZE];
thr_tobe_inited_entry(void * param)35 static void thr_tobe_inited_entry(void *param)
36 {
37     rt_kprintf("Hello!\n");
38 }
39 
hooklist_test(void)40 static void hooklist_test(void)
41 {
42     hooker1_ent_count = 0;
43     hooker2_ent_count = 0;
44     rt_thread_inited_sethook(&hooker1_node);
45     rt_thread_inited_sethook(&hooker2_node);
46 
47     /* run 1 */
48     rt_thread_init(&thr_tobe_inited,
49                    "thr_tobe_inited",
50                    thr_tobe_inited_entry,
51                    NULL,
52                    _thr_stack,
53                    sizeof(_thr_stack),
54                    25,
55                    100);
56 
57     uassert_int_equal(hooker1_ent_count, 1);
58     uassert_int_equal(hooker2_ent_count, 1);
59 
60     rt_thread_detach(&thr_tobe_inited);
61     rt_thread_mdelay(1); /* wait recycling done */
62 
63     /* run 2 */
64     rt_thread_inited_rmhook(&hooker2_node);
65 
66     rt_thread_init(&thr_tobe_inited,
67                    "thr_tobe_inited",
68                    thr_tobe_inited_entry,
69                    NULL,
70                    _thr_stack,
71                    sizeof(_thr_stack),
72                    25,
73                    100);
74 
75     uassert_int_equal(hooker1_ent_count, 2);
76     uassert_int_equal(hooker2_ent_count, 1);
77 }
78 
utest_tc_init(void)79 static rt_err_t utest_tc_init(void)
80 {
81     hooker1_ent_count = 0;
82     hooker2_ent_count = 0;
83     return RT_EOK;
84 }
85 
utest_tc_cleanup(void)86 static rt_err_t utest_tc_cleanup(void)
87 {
88     rt_thread_detach(&thr_tobe_inited);
89     rt_thread_inited_rmhook(&hooker1_node);
90     rt_thread_inited_rmhook(&hooker2_node);
91     return RT_EOK;
92 }
93 
testcase(void)94 static void testcase(void)
95 {
96     UTEST_UNIT_RUN(hooklist_test);
97 }
98 UTEST_TC_EXPORT(testcase, "testcases.kernel.hooklist_tc", utest_tc_init, utest_tc_cleanup, 10);
99