sched/task: Simplify atexit and onexit implementation

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Change-Id: I3028b74fe4872ae5cb376fa160e3cff79d5ad449
This commit is contained in:
Xiang Xiao 2020-06-03 17:08:25 +08:00 committed by Abdelatif Guettouche
parent 368fbd0dea
commit 3409c989bd
4 changed files with 56 additions and 109 deletions

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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 */