[kernel] support for hook list

Signed-off-by: Shell <smokewood@qq.com>
This commit is contained in:
Shell
2024-01-02 19:42:46 +08:00
committed by Meco Man
parent 3a7903b799
commit e7880a9713
17 changed files with 280 additions and 124 deletions
+6 -1
View File
@@ -59,5 +59,10 @@ config UTEST_THREAD_TC
config UTEST_ATOMIC_TC
bool "atomic test"
default n
config UTEST_HOOKLIST_TC
bool "hook list test"
select RT_USING_HOOKLIST
default n
endmenu
@@ -44,6 +44,9 @@ if GetDepend(['UTEST_THREAD_TC']):
if GetDepend(['UTEST_ATOMIC_TC']):
src += ['atomic_tc.c']
if GetDepend(['UTEST_HOOKLIST_TC']):
src += ['hooklist_tc.c']
group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH)
Return('group')
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-12-22 Shell Support hook list
*/
#include <rtthread.h>
#include "rtconfig.h"
#include "utest.h"
#include "utest_assert.h"
static int hooker1_ent_count;
static int hooker2_ent_count;
static struct rt_thread thr_tobe_inited;
static void thread_inited_hooker1(rt_thread_t thread)
{
LOG_D("%s: count %d", __func__, hooker1_ent_count);
hooker1_ent_count += 1;
}
RT_OBJECT_HOOKLIST_DEFINE_NODE(rt_thread_inited, hooker1_node, thread_inited_hooker1);
static void thread_inited_hooker2(rt_thread_t thread)
{
LOG_D("%s: count %d", __func__, hooker2_ent_count);
hooker2_ent_count += 1;
}
RT_OBJECT_HOOKLIST_DEFINE_NODE(rt_thread_inited, hooker2_node, thread_inited_hooker2);
static char _thr_stack[UTEST_THR_STACK_SIZE];
static void thr_tobe_inited_entry(void *param)
{
rt_kprintf("Hello!\n");
}
static void hooklist_test(void)
{
hooker1_ent_count = 0;
hooker2_ent_count = 0;
rt_thread_inited_sethook(&hooker1_node);
rt_thread_inited_sethook(&hooker2_node);
/* run 1 */
rt_thread_init(&thr_tobe_inited,
"thr_tobe_inited",
thr_tobe_inited_entry,
NULL,
_thr_stack,
sizeof(_thr_stack),
25,
100);
uassert_int_equal(hooker1_ent_count, 1);
uassert_int_equal(hooker2_ent_count, 1);
rt_thread_detach(&thr_tobe_inited);
rt_thread_mdelay(1); /* wait recycling done */
/* run 2 */
rt_thread_inited_rmhook(&hooker2_node);
rt_thread_init(&thr_tobe_inited,
"thr_tobe_inited",
thr_tobe_inited_entry,
NULL,
_thr_stack,
sizeof(_thr_stack),
25,
100);
uassert_int_equal(hooker1_ent_count, 2);
uassert_int_equal(hooker2_ent_count, 1);
}
static rt_err_t utest_tc_init(void)
{
hooker1_ent_count = 0;
hooker2_ent_count = 0;
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
rt_thread_detach(&thr_tobe_inited);
rt_thread_inited_rmhook(&hooker1_node);
rt_thread_inited_rmhook(&hooker2_node);
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(hooklist_test);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.hooklist_tc", utest_tc_init, utest_tc_cleanup, 10);
+147 -18
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -151,9 +151,9 @@ rt_inline unsigned int rt_list_len(const rt_list_t *l)
* @param member the name of the list_struct within the struct.
*/
#define rt_list_for_each_entry(pos, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member); \
for (pos = rt_list_entry((head)->next, rt_typeof(*pos), member); \
&pos->member != (head); \
pos = rt_list_entry(pos->member.next, typeof(*pos), member))
pos = rt_list_entry(pos->member.next, rt_typeof(*pos), member))
/**
* rt_list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
@@ -163,10 +163,10 @@ rt_inline unsigned int rt_list_len(const rt_list_t *l)
* @param member the name of the list_struct within the struct.
*/
#define rt_list_for_each_entry_safe(pos, n, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
n = rt_list_entry(pos->member.next, typeof(*pos), member); \
for (pos = rt_list_entry((head)->next, rt_typeof(*pos), member), \
n = rt_list_entry(pos->member.next, rt_typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))
pos = n, n = rt_list_entry(n->member.next, rt_typeof(*n), member))
/**
* rt_list_first_entry - get the first element from a list
@@ -280,9 +280,9 @@ rt_inline int rt_slist_isempty(rt_slist_t *l)
* @param member the name of the list_struct within the struct.
*/
#define rt_slist_for_each_entry(pos, head, member) \
for (pos = ((head)->next == (RT_NULL) ? (RT_NULL) : rt_slist_entry((head)->next, typeof(*pos), member)); \
for (pos = ((head)->next == (RT_NULL) ? (RT_NULL) : rt_slist_entry((head)->next, rt_typeof(*pos), member)); \
pos != (RT_NULL) && &pos->member != (RT_NULL); \
pos = (pos->member.next == (RT_NULL) ? (RT_NULL) : rt_slist_entry(pos->member.next, typeof(*pos), member)))
pos = (pos->member.next == (RT_NULL) ? (RT_NULL) : rt_slist_entry(pos->member.next, rt_typeof(*pos), member)))
/**
* rt_slist_first_entry - get the first element from a slist
+9 -1
View File
@@ -179,7 +179,15 @@ int rt_thread_kill(rt_thread_t tid, int sig);
#ifdef RT_USING_HOOK
void rt_thread_suspend_sethook(void (*hook)(rt_thread_t thread));
void rt_thread_resume_sethook (void (*hook)(rt_thread_t thread));
void rt_thread_inited_sethook (void (*hook)(rt_thread_t thread));
/**
* @brief Sets a hook function when a thread is initialized.
*
* @param thread is the target thread that initializing
*/
typedef void (*rt_thread_inited_hookproto_t)(rt_thread_t thread);
RT_OBJECT_HOOKLIST_DECLARE(rt_thread_inited_hookproto_t, rt_thread_inited);
#endif /* RT_USING_HOOK */
/*
+7
View File
@@ -132,6 +132,13 @@ config RT_USING_HOOK
default y
endif
config RT_USING_HOOKLIST
bool "Enable hook list"
default n
help
Enable the hook list feature for rt-thread packages. With this, they can
plug in to the system on run-time.
config RT_USING_IDLE_HOOK
bool "Enable IDLE Task hook"
default y if RT_USING_HOOK
-4
View File
@@ -29,10 +29,6 @@
static volatile rt_atomic_t rt_tick = 0;
#endif /* RT_USING_SMP */
#ifndef __on_rt_tick_hook
#define __on_rt_tick_hook() __ON_HOOK_ARGS(rt_tick_hook, ())
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_tick_hook)(void);
-10
View File
@@ -55,16 +55,6 @@
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifndef __on_rt_object_trytake_hook
#define __on_rt_object_trytake_hook(parent) __ON_HOOK_ARGS(rt_object_trytake_hook, (parent))
#endif
#ifndef __on_rt_object_take_hook
#define __on_rt_object_take_hook(parent) __ON_HOOK_ARGS(rt_object_take_hook, (parent))
#endif
#ifndef __on_rt_object_put_hook
#define __on_rt_object_put_hook(parent) __ON_HOOK_ARGS(rt_object_put_hook, (parent))
#endif
#define GET_MESSAGEBYTE_ADDR(msg) ((struct rt_mq_message *) msg + 1)
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
extern void (*rt_object_trytake_hook)(struct rt_object *object);
-7
View File
@@ -22,13 +22,6 @@
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifndef __on_rt_interrupt_enter_hook
#define __on_rt_interrupt_enter_hook() __ON_HOOK_ARGS(rt_interrupt_enter_hook, ())
#endif
#ifndef __on_rt_interrupt_leave_hook
#define __on_rt_interrupt_leave_hook() __ON_HOOK_ARGS(rt_interrupt_leave_hook, ())
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_interrupt_enter_hook)(void);
+1 -5
View File
@@ -1579,7 +1579,7 @@ rt_err_t rt_backtrace_frame(struct rt_hw_backtrace_frame *frame)
{
long nesting = 0;
rt_kprintf("please use: addr2line -e rtthread.elf -a -f\n");
rt_kprintf("please use: addr2line -e rtthread.elf -a -f");
while (nesting < RT_BACKTRACE_LEVEL_MAX_NR)
{
@@ -2177,10 +2177,6 @@ int __rt_ffs(int value)
#endif /* RT_USING_TINY_FFS */
#endif /* RT_USING_CPU_FFS */
#ifndef __on_rt_assert_hook
#define __on_rt_assert_hook(ex, func, line) __ON_HOOK_ARGS(rt_assert_hook, (ex, func, line))
#endif
#ifdef RT_USING_DEBUG
/* RT_ASSERT(EX)'s hook */
-7
View File
@@ -24,13 +24,6 @@
#ifdef RT_USING_MEMPOOL
#ifndef __on_rt_mp_alloc_hook
#define __on_rt_mp_alloc_hook(mp, block) __ON_HOOK_ARGS(rt_mp_alloc_hook, (mp, block))
#endif
#ifndef __on_rt_mp_free_hook
#define __on_rt_mp_free_hook(mp, block) __ON_HOOK_ARGS(rt_mp_free_hook, (mp, block))
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_mp_alloc_hook)(struct rt_mempool *mp, void *block);
static void (*rt_mp_free_hook)(struct rt_mempool *mp, void *block);
-16
View File
@@ -137,22 +137,6 @@ static struct rt_object_information _object_container[RT_Object_Info_Unknown] =
#endif
};
#ifndef __on_rt_object_attach_hook
#define __on_rt_object_attach_hook(obj) __ON_HOOK_ARGS(rt_object_attach_hook, (obj))
#endif
#ifndef __on_rt_object_detach_hook
#define __on_rt_object_detach_hook(obj) __ON_HOOK_ARGS(rt_object_detach_hook, (obj))
#endif
#ifndef __on_rt_object_trytake_hook
#define __on_rt_object_trytake_hook(parent) __ON_HOOK_ARGS(rt_object_trytake_hook, (parent))
#endif
#ifndef __on_rt_object_take_hook
#define __on_rt_object_take_hook(parent) __ON_HOOK_ARGS(rt_object_take_hook, (parent))
#endif
#ifndef __on_rt_object_put_hook
#define __on_rt_object_put_hook(parent) __ON_HOOK_ARGS(rt_object_put_hook, (parent))
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_object_attach_hook)(struct rt_object *object);
static void (*rt_object_detach_hook)(struct rt_object *object);
-7
View File
@@ -48,13 +48,6 @@ rt_uint32_t rt_thread_ready_priority_group;
rt_uint8_t rt_thread_ready_table[32];
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
#ifndef __on_rt_scheduler_hook
#define __on_rt_scheduler_hook(from, to) __ON_HOOK_ARGS(rt_scheduler_hook, (from, to))
#endif
#ifndef __on_rt_scheduler_switch_hook
#define __on_rt_scheduler_switch_hook(tid) __ON_HOOK_ARGS(rt_scheduler_switch_hook, (tid))
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to);
static void (*rt_scheduler_switch_hook)(struct rt_thread *tid);
-7
View File
@@ -51,13 +51,6 @@ static rt_int16_t rt_scheduler_lock_nest;
struct rt_thread *rt_current_thread = RT_NULL;
rt_uint8_t rt_current_priority;
#ifndef __on_rt_scheduler_hook
#define __on_rt_scheduler_hook(from, to) __ON_HOOK_ARGS(rt_scheduler_hook, (from, to))
#endif
#ifndef __on_rt_scheduler_switch_hook
#define __on_rt_scheduler_switch_hook(tid) __ON_HOOK_ARGS(rt_scheduler_switch_hook, (tid))
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to);
static void (*rt_scheduler_switch_hook)(struct rt_thread *tid);
+2 -21
View File
@@ -45,20 +45,9 @@
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifndef __on_rt_thread_inited_hook
#define __on_rt_thread_inited_hook(thread) __ON_HOOK_ARGS(rt_thread_inited_hook, (thread))
#endif
#ifndef __on_rt_thread_suspend_hook
#define __on_rt_thread_suspend_hook(thread) __ON_HOOK_ARGS(rt_thread_suspend_hook, (thread))
#endif
#ifndef __on_rt_thread_resume_hook
#define __on_rt_thread_resume_hook(thread) __ON_HOOK_ARGS(rt_thread_resume_hook, (thread))
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_thread_suspend_hook)(rt_thread_t thread);
static void (*rt_thread_resume_hook) (rt_thread_t thread);
static void (*rt_thread_inited_hook) (rt_thread_t thread);
/**
* @brief This function sets a hook function when the system suspend a thread.
@@ -84,15 +73,7 @@ void rt_thread_resume_sethook(void (*hook)(rt_thread_t thread))
rt_thread_resume_hook = hook;
}
/**
* @brief This function sets a hook function when a thread is initialized.
*
* @param hook is the specified hook function.
*/
void rt_thread_inited_sethook(void (*hook)(rt_thread_t thread))
{
rt_thread_inited_hook = hook;
}
RT_OBJECT_HOOKLIST_DEFINE(rt_thread_inited);
#endif /* defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR) */
static void _thread_exit(void)
@@ -313,7 +294,7 @@ static rt_err_t _thread_init(struct rt_thread *thread,
rt_atomic_store(&thread->ref_count, 0);
rt_spin_lock_init(&thread->spinlock);
RT_OBJECT_HOOK_CALL(rt_thread_inited_hook, (thread));
RT_OBJECT_HOOKLIST_CALL(rt_thread_inited, (thread));
return RT_EOK;
}
-13
View File
@@ -57,19 +57,6 @@ rt_align(RT_ALIGN_SIZE)
static rt_uint8_t _timer_thread_stack[RT_TIMER_THREAD_STACK_SIZE];
#endif /* RT_USING_TIMER_SOFT */
#ifndef __on_rt_object_take_hook
#define __on_rt_object_take_hook(parent) __ON_HOOK_ARGS(rt_object_take_hook, (parent))
#endif
#ifndef __on_rt_object_put_hook
#define __on_rt_object_put_hook(parent) __ON_HOOK_ARGS(rt_object_put_hook, (parent))
#endif
#ifndef __on_rt_timer_enter_hook
#define __on_rt_timer_enter_hook(t) __ON_HOOK_ARGS(rt_timer_enter_hook, (t))
#endif
#ifndef __on_rt_timer_exit_hook
#define __on_rt_timer_exit_hook(t) __ON_HOOK_ARGS(rt_timer_exit_hook, (t))
#endif
#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
extern void (*rt_object_take_hook)(struct rt_object *object);
extern void (*rt_object_put_hook)(struct rt_object *object);