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
+33 -19
View File
@@ -171,6 +171,18 @@
# define _SCHED_ERRVAL(r) (-errno) # define _SCHED_ERRVAL(r) (-errno)
#endif #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 * Public Type Definitions
********************************************************************************/ ********************************************************************************/
@@ -400,6 +412,24 @@ struct stackinfo_s
/* The initial stack pointer value */ /* 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 **********************************************************/ /* struct task_group_s **********************************************************/
/* All threads created by pthread_create belong in the same task group (along /* 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 */ FAR pid_t *tg_members; /* Members of the group */
#endif #endif
#if defined(CONFIG_SCHED_ATEXIT) && !defined(CONFIG_SCHED_ONEXIT) /* [at|on]exit support ********************************************************/
/* atexit support *************************************************************/
# if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1 #ifdef CONFIG_SCHED_EXIT_MAX
atexitfunc_t tg_atexitfunc[CONFIG_SCHED_ATEXIT_MAX]; struct exitinfo_s tg_exit[CONFIG_SCHED_EXIT_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
#endif #endif
#ifdef CONFIG_BINFMT_LOADABLE #ifdef CONFIG_BINFMT_LOADABLE
+4 -22
View File
@@ -97,7 +97,7 @@ int atexit(void (*func)(void))
return on_exit((onexitfunc_t)func, NULL); 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 tcb_s *tcb = this_task();
FAR struct task_group_s *group = tcb->group; FAR struct task_group_s *group = tcb->group;
int index; int index;
@@ -117,11 +117,11 @@ int atexit(void (*func)(void))
* higher to lower indices. * 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; ret = OK;
break; break;
} }
@@ -131,24 +131,6 @@ int atexit(void (*func)(void))
} }
return ret; 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 #endif
} }
+13 -41
View File
@@ -86,7 +86,6 @@ static inline void nxtask_atexit(FAR struct tcb_s *tcb)
if (group && group->tg_nmembers == 1) if (group && group->tg_nmembers == 1)
{ {
#if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
int index; int index;
/* Call each atexit function in reverse order of registration atexit() /* 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. * 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; atexitfunc_t func;
/* Nullify the atexit function to prevent its reuse. */ /* Nullify the atexit function to prevent its reuse. */
func = group->tg_atexitfunc[index]; func = group->tg_exit[index].func.at;
group->tg_atexitfunc[index] = NULL; group->tg_exit[index].func.at = NULL;
/* Call the atexit function */ /* Call the atexit function */
(*func)(); (*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 #else
@@ -160,7 +144,6 @@ static inline void nxtask_onexit(FAR struct tcb_s *tcb, int status)
if (group && group->tg_nmembers == 1) if (group && group->tg_nmembers == 1)
{ {
#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
int index; int index;
/* Call each on_exit function in reverse order of registration. /* 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. * 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; onexitfunc_t func;
FAR void *arg;
/* Nullify the on_exit function to prevent its reuse. */ /* Nullify the on_exit function to prevent its reuse. */
func = group->tg_onexitfunc[index]; func = group->tg_exit[index].func.on;
group->tg_onexitfunc[index] = NULL; arg = group->tg_exit[index].arg;
group->tg_exit[index].func.on = NULL;
group->tg_exit[index].arg = NULL;
/* Call the on_exit function */ /* 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 #else
+6 -27
View File
@@ -91,11 +91,10 @@
int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg) 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 tcb_s *tcb = this_task();
FAR struct task_group_s *group = tcb->group; FAR struct task_group_s *group = tcb->group;
int index; int index;
int ret = ENOSPC; int ret = ENOSPC;
DEBUGASSERT(group); DEBUGASSERT(group);
@@ -111,12 +110,12 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
* from higher to lower indices. * 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_exit[index].func.on = func;
group->tg_onexitarg[index] = arg; group->tg_exit[index].arg = arg;
ret = OK; ret = OK;
break; break;
} }
@@ -126,26 +125,6 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
} }
return ret; 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 */ #endif /* CONFIG_SCHED_ONEXIT */