You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/06/05 12:29:34 UTC

[incubator-nuttx] 01/02: sched/task: Simplify atexit and onexit implementation

This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 3409c989bda4f5640b5ad2dbebc839b81fb4ff97
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Wed Jun 3 17:08:25 2020 +0800

    sched/task: Simplify atexit and onexit implementation
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
    Change-Id: I3028b74fe4872ae5cb376fa160e3cff79d5ad449
---
 include/nuttx/sched.h      | 52 ++++++++++++++++++++++++++++----------------
 sched/task/task_atexit.c   | 26 ++++------------------
 sched/task/task_exithook.c | 54 +++++++++++-----------------------------------
 sched/task/task_onexit.c   | 33 ++++++----------------------
 4 files changed, 56 insertions(+), 109 deletions(-)

diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h
index e9650d5..8650a6d 100644
--- a/include/nuttx/sched.h
+++ b/include/nuttx/sched.h
@@ -171,6 +171,18 @@
 #  define _SCHED_ERRVAL(r)           (-errno)
 #endif
 
+/* The number of callback can be saved */
+
+#if defined(CONFIG_SCHED_ONEXIT_MAX)
+#  define CONFIG_SCHED_EXIT_MAX CONFIG_SCHED_ONEXIT_MAX
+#elif defined(CONFIG_SCHED_ATEXIT_MAX)
+#  define CONFIG_SCHED_EXIT_MAX CONFIG_SCHED_ATEXIT_MAX
+#endif
+
+#if defined(CONFIG_SCHED_EXIT_MAX) && CONFIG_SCHED_EXIT_MAX < 1
+#  error "CONFIG_SCHED_EXIT_MAX < 1"
+#endif
+
 /********************************************************************************
  * Public Type Definitions
  ********************************************************************************/
@@ -400,6 +412,24 @@ struct stackinfo_s
                                          /* The initial stack pointer value     */
 };
 
+/* struct exitinfo_s ************************************************************/
+
+struct exitinfo_s
+{
+  union
+  {
+#ifdef CONFIG_SCHED_ATEXIT
+    atexitfunc_t at;
+#endif
+#ifdef CONFIG_SCHED_ONEXIT
+    onexitfunc_t on;
+#endif
+  } func;
+#ifdef CONFIG_SCHED_ONEXIT
+  FAR void *arg;
+#endif
+};
+
 /* struct task_group_s **********************************************************/
 
 /* All threads created by pthread_create belong in the same task group (along
@@ -463,26 +493,10 @@ struct task_group_s
   FAR pid_t *tg_members;            /* Members of the group                     */
 #endif
 
-#if defined(CONFIG_SCHED_ATEXIT) && !defined(CONFIG_SCHED_ONEXIT)
-  /* atexit support *************************************************************/
-
-# if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
-  atexitfunc_t tg_atexitfunc[CONFIG_SCHED_ATEXIT_MAX];
-# else
-  atexitfunc_t tg_atexitfunc;       /* Called when exit is called.              */
-# endif
-#endif
+  /* [at|on]exit support ********************************************************/
 
-#ifdef CONFIG_SCHED_ONEXIT
-  /* on_exit support ************************************************************/
-
-# if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
-  onexitfunc_t tg_onexitfunc[CONFIG_SCHED_ONEXIT_MAX];
-  FAR void *tg_onexitarg[CONFIG_SCHED_ONEXIT_MAX];
-# else
-  onexitfunc_t tg_onexitfunc;       /* Called when exit is called.             */
-  FAR void *tg_onexitarg;           /* The argument passed to the function     */
-# endif
+#ifdef CONFIG_SCHED_EXIT_MAX
+  struct exitinfo_s tg_exit[CONFIG_SCHED_EXIT_MAX];
 #endif
 
 #ifdef CONFIG_BINFMT_LOADABLE
diff --git a/sched/task/task_atexit.c b/sched/task/task_atexit.c
index a100d15..da29b64 100644
--- a/sched/task/task_atexit.c
+++ b/sched/task/task_atexit.c
@@ -97,7 +97,7 @@ int atexit(void (*func)(void))
 
   return on_exit((onexitfunc_t)func, NULL);
 
-#elif defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
+#else
   FAR struct tcb_s *tcb = this_task();
   FAR struct task_group_s *group = tcb->group;
   int index;
@@ -117,11 +117,11 @@ int atexit(void (*func)(void))
        * higher to lower indices.
        */
 
-      for (index = 0; index < CONFIG_SCHED_ATEXIT_MAX; index++)
+      for (index = 0; index < CONFIG_SCHED_EXIT_MAX; index++)
         {
-          if (!group->tg_atexitfunc[index])
+          if (!group->tg_exit[index].func.at)
             {
-              group->tg_atexitfunc[index] = func;
+              group->tg_exit[index].func.at = func;
               ret = OK;
               break;
             }
@@ -131,24 +131,6 @@ int atexit(void (*func)(void))
     }
 
   return ret;
-#else
-  FAR struct tcb_s *tcb = this_task();
-  FAR struct task_group_s *group = tcb->group;
-  int ret = ERROR;
-
-  DEBUGASSERT(group);
-
-  /* The following must be atomic */
-
-  sched_lock();
-  if (func && !group->tg_atexitfunc)
-    {
-      group->tg_atexitfunc = func;
-      ret = OK;
-    }
-
-  sched_unlock();
-  return ret;
 #endif
 }
 
diff --git a/sched/task/task_exithook.c b/sched/task/task_exithook.c
index b3f7a17..c393632 100644
--- a/sched/task/task_exithook.c
+++ b/sched/task/task_exithook.c
@@ -86,7 +86,6 @@ static inline void nxtask_atexit(FAR struct tcb_s *tcb)
 
   if (group && group->tg_nmembers == 1)
     {
-#if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
       int index;
 
       /* Call each atexit function in reverse order of registration atexit()
@@ -95,37 +94,22 @@ static inline void nxtask_atexit(FAR struct tcb_s *tcb)
        * group exits, i.e., from higher to lower indices.
        */
 
-      for (index = CONFIG_SCHED_ATEXIT_MAX - 1; index >= 0; index--)
+      for (index = CONFIG_SCHED_EXIT_MAX - 1; index >= 0; index--)
         {
-          if (group->tg_atexitfunc[index])
+          if (group->tg_exit[index].func.at)
             {
               atexitfunc_t func;
 
               /* Nullify the atexit function to prevent its reuse. */
 
-              func = group->tg_atexitfunc[index];
-              group->tg_atexitfunc[index] = NULL;
+              func = group->tg_exit[index].func.at;
+              group->tg_exit[index].func.at = NULL;
 
               /* Call the atexit function */
 
               (*func)();
             }
         }
-#else
-      if (group->tg_atexitfunc)
-        {
-          atexitfunc_t func;
-
-          /* Nullify the atexit function to prevent its reuse. */
-
-          func = group->tg_atexitfunc;
-          group->tg_atexitfunc = NULL;
-
-          /* Call the atexit function */
-
-          (*func)();
-        }
-#endif
     }
 }
 #else
@@ -160,7 +144,6 @@ static inline void nxtask_onexit(FAR struct tcb_s *tcb, int status)
 
   if (group && group->tg_nmembers == 1)
     {
-#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
       int index;
 
       /* Call each on_exit function in reverse order of registration.
@@ -169,37 +152,26 @@ static inline void nxtask_onexit(FAR struct tcb_s *tcb, int status)
        * when the task group exits, i.e., from higher to lower indices.
        */
 
-      for (index = CONFIG_SCHED_ONEXIT_MAX - 1; index >= 0; index--)
+      for (index = CONFIG_SCHED_EXIT_MAX - 1; index >= 0; index--)
         {
-          if (group->tg_onexitfunc[index])
+          if (group->tg_exit[index].func.on)
             {
               onexitfunc_t func;
+              FAR void    *arg;
 
               /* Nullify the on_exit function to prevent its reuse. */
 
-              func = group->tg_onexitfunc[index];
-              group->tg_onexitfunc[index] = NULL;
+              func = group->tg_exit[index].func.on;
+              arg  = group->tg_exit[index].arg;
+
+              group->tg_exit[index].func.on = NULL;
+              group->tg_exit[index].arg     = NULL;
 
               /* Call the on_exit function */
 
-              (*func)(status, group->tg_onexitarg[index]);
+              (*func)(status, arg);
             }
         }
-#else
-      if (group->tg_onexitfunc)
-        {
-          onexitfunc_t func;
-
-          /* Nullify the on_exit function to prevent its reuse. */
-
-          func = group->tg_onexitfunc;
-          group->tg_onexitfunc = NULL;
-
-          /* Call the on_exit function */
-
-          (*func)(status, group->tg_onexitarg);
-        }
-#endif
     }
 }
 #else
diff --git a/sched/task/task_onexit.c b/sched/task/task_onexit.c
index c3977dd..6b3f17d 100644
--- a/sched/task/task_onexit.c
+++ b/sched/task/task_onexit.c
@@ -91,11 +91,10 @@
 
 int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
 {
-#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
   FAR struct tcb_s *tcb = this_task();
   FAR struct task_group_s *group = tcb->group;
-  int   index;
-  int   ret = ENOSPC;
+  int index;
+  int ret = ENOSPC;
 
   DEBUGASSERT(group);
 
@@ -111,12 +110,12 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
        * from higher to lower indices.
        */
 
-      for (index = 0; index < CONFIG_SCHED_ONEXIT_MAX; index++)
+      for (index = 0; index < CONFIG_SCHED_EXIT_MAX; index++)
         {
-          if (!group->tg_onexitfunc[index])
+          if (!group->tg_exit[index].func.on)
             {
-              group->tg_onexitfunc[index] = func;
-              group->tg_onexitarg[index]  = arg;
+              group->tg_exit[index].func.on = func;
+              group->tg_exit[index].arg     = arg;
               ret = OK;
               break;
             }
@@ -126,26 +125,6 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
     }
 
   return ret;
-#else
-  FAR struct tcb_s *tcb = this_task();
-  FAR struct task_group_s *group = tcb->group;
-  int   ret = ENOSPC;
-
-  DEBUGASSERT(group);
-
-  /* The following must be atomic */
-
-  sched_lock();
-  if (func && !group->tg_onexitfunc)
-    {
-      group->tg_onexitfunc = func;
-      group->tg_onexitarg  = arg;
-      ret = OK;
-    }
-
-  sched_unlock();
-  return ret;
-#endif
 }
 
 #endif /* CONFIG_SCHED_ONEXIT */