From e9c165034e7b3e69f61aea89a662e3e448e5c49f Mon Sep 17 00:00:00 2001 From: armink Date: Thu, 12 Jul 2018 18:37:51 +0800 Subject: [PATCH 1/2] [kernel][idle] Add idle hook list. --- include/rtthread.h | 3 +- src/Kconfig | 9 ++++++ src/idle.c | 80 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/include/rtthread.h b/include/rtthread.h index b3d7ebd949..9042690212 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -173,7 +173,8 @@ void rt_thread_inited_sethook (void (*hook)(rt_thread_t thread)); */ void rt_thread_idle_init(void); #if defined(RT_USING_HOOK) || defined(RT_USING_IDLE_HOOK) -void rt_thread_idle_sethook(void (*hook)(void)); +rt_err_t rt_thread_idle_sethook(void (*hook)(void)); +rt_err_t rt_thread_idle_delhook(void (*hook)(void)); #endif void rt_thread_idle_excute(void); rt_thread_t rt_thread_idle_gethandler(void); diff --git a/src/Kconfig b/src/Kconfig index 89f709478b..dc27e162f0 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -75,6 +75,15 @@ config RT_USING_HOOK Enable the hook function when system running, such as idle thread hook, thread context switch etc. + if RT_USING_HOOK + config RT_IDEL_HOOK_LIST_SIZE + int "The max size of idel hook list" + default 4 + range 1 16 + help + The system has a hook list. This is the hook list size. + endif + config IDLE_THREAD_STACK_SIZE int "The stack size of idle thread" default 256 diff --git a/src/idle.c b/src/idle.c index f636d0fd4c..3ee9c46cf5 100644 --- a/src/idle.c +++ b/src/idle.c @@ -52,7 +52,12 @@ static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE]; extern rt_list_t rt_thread_defunct; #ifdef RT_USING_IDLE_HOOK -static void (*rt_thread_idle_hook)(); + +#ifndef RT_IDEL_HOOK_LIST_SIZE +#define RT_IDEL_HOOK_LIST_SIZE 4 +#endif + +static void (*idle_hook_list[RT_IDEL_HOOK_LIST_SIZE])(); /** * @ingroup Hook @@ -61,12 +66,69 @@ static void (*rt_thread_idle_hook)(); * * @param hook the specified hook function * + * @return RT_EOK: set OK + * -RT_EFULL: hook list is full + * * @note the hook function must be simple and never be blocked or suspend. */ -void rt_thread_idle_sethook(void (*hook)(void)) +rt_err_t rt_thread_idle_sethook(void (*hook)(void)) { - rt_thread_idle_hook = hook; + rt_size_t i; + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++) + { + if (idle_hook_list[i] == RT_NULL) + { + idle_hook_list[i] = hook; + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + return RT_EOK; + } + } + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + return -RT_EFULL; } + +/** + * delete the idle hook on hook list + * + * @param hook the specified hook function + * + * @return RT_EOK: delete OK + * -RT_ENOSYS: hook was not found + */ +rt_err_t rt_thread_idle_delhook(void (*hook)(void)) +{ + rt_size_t i; + rt_base_t level; + + /* disable interrupt */ + level = rt_hw_interrupt_disable(); + + for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++) + { + if (idle_hook_list[i] == hook) + { + idle_hook_list[i] = RT_NULL; + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + return RT_EOK; + } + } + /* enable interrupt */ + rt_hw_interrupt_enable(level); + + return -RT_ENOSYS; +} + #endif /* Return whether there is defunctional thread to be deleted. */ @@ -174,12 +236,20 @@ void rt_thread_idle_excute(void) static void rt_thread_idle_entry(void *parameter) { +#ifdef RT_USING_IDLE_HOOK + rt_size_t i; +#endif + while (1) { + #ifdef RT_USING_IDLE_HOOK - if (rt_thread_idle_hook != RT_NULL) + for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++) { - rt_thread_idle_hook(); + if (idle_hook_list[i] != RT_NULL) + { + idle_hook_list[i](); + } } #endif From d37c289b56fa1ea61c1371be9ea45ed71f63a663 Mon Sep 17 00:00:00 2001 From: armink Date: Fri, 13 Jul 2018 18:13:25 +0800 Subject: [PATCH 2/2] [kernel][idle] Improve rt_thread_idle_sethook and rt_thread_idle_delhook code. --- src/idle.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/idle.c b/src/idle.c index 3ee9c46cf5..d6c2f98a49 100644 --- a/src/idle.c +++ b/src/idle.c @@ -26,6 +26,7 @@ * dead thread. * 2016-08-09 ArdaFu add method to get the handler of the idle thread. * 2018-02-07 Bernard lock scheduler to protect tid->cleanup. + * 2018-07-14 armink add idle hook list */ #include @@ -75,6 +76,7 @@ rt_err_t rt_thread_idle_sethook(void (*hook)(void)) { rt_size_t i; rt_base_t level; + rt_err_t ret = -RT_EFULL; /* disable interrupt */ level = rt_hw_interrupt_disable(); @@ -84,16 +86,14 @@ rt_err_t rt_thread_idle_sethook(void (*hook)(void)) if (idle_hook_list[i] == RT_NULL) { idle_hook_list[i] = hook; - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - return RT_EOK; + ret = RT_EOK; + break; } } /* enable interrupt */ rt_hw_interrupt_enable(level); - return -RT_EFULL; + return ret; } /** @@ -108,6 +108,7 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void)) { rt_size_t i; rt_base_t level; + rt_err_t ret = -RT_ENOSYS; /* disable interrupt */ level = rt_hw_interrupt_disable(); @@ -117,16 +118,14 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void)) if (idle_hook_list[i] == hook) { idle_hook_list[i] = RT_NULL; - /* enable interrupt */ - rt_hw_interrupt_enable(level); - - return RT_EOK; + ret = RT_EOK; + break; } } /* enable interrupt */ rt_hw_interrupt_enable(level); - return -RT_ENOSYS; + return ret; } #endif