diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index e9650d57b68..8650a6d85fe 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 *************************************************************/ + /* [at|on]exit 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 - -#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 a100d15ae1c..da29b646f51 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 b3f7a1775f3..c393632d8bf 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 c3977ddb078..6b3f17dc080 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 */