summaryrefslogtreecommitdiff
path: root/src/idle.c
diff options
context:
space:
mode:
authorarmink <[email protected]>2018-07-12 18:37:51 +0800
committerarmink <[email protected]>2018-07-13 10:02:27 +0800
commite9c165034e7b3e69f61aea89a662e3e448e5c49f (patch)
treeca21d463c1406194fc7ba6bbc6aaab27e413c285 /src/idle.c
parent60435316ac40c84faa734333870068ba9522e6b2 (diff)
[kernel][idle] Add idle hook list.
Diffstat (limited to 'src/idle.c')
-rw-r--r--src/idle.c80
1 files changed, 75 insertions, 5 deletions
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