sched/task: Simplify atexit and onexit implementation
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I3028b74fe4872ae5cb376fa160e3cff79d5ad449
This commit is contained in:
parent
368fbd0dea
commit
3409c989bd
4 changed files with 56 additions and 109 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue