summaryrefslogtreecommitdiff
path: root/nuttx/sched
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-02-04 15:29:19 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2013-02-04 15:29:19 +0000
commitc13bd69be3d117b359275bcf3b2d631bb19bd597 (patch)
tree9c91903e231aef3df957485f489d9ebac2fa330d /nuttx/sched
parent309ad4ddf471013483b1775e2438562b91a44653 (diff)
downloadpx4-nuttx-c13bd69be3d117b359275bcf3b2d631bb19bd597.tar.gz
px4-nuttx-c13bd69be3d117b359275bcf3b2d631bb19bd597.tar.bz2
px4-nuttx-c13bd69be3d117b359275bcf3b2d631bb19bd597.zip
Move atexit/on_exit data structures to task group; Now callbacks only occur when the final member of the task group exits
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5607 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/sched')
-rw-r--r--nuttx/sched/atexit.c28
-rw-r--r--nuttx/sched/group_leave.c3
-rw-r--r--nuttx/sched/on_exit.c24
-rw-r--r--nuttx/sched/task_exithook.c103
4 files changed, 95 insertions, 63 deletions
diff --git a/nuttx/sched/atexit.c b/nuttx/sched/atexit.c
index b0559b01b..f60598884 100644
--- a/nuttx/sched/atexit.c
+++ b/nuttx/sched/atexit.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/atexit.c
*
- * Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007, 2009, 2011-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -117,12 +117,15 @@ int atexit(void (*func)(void))
* can handle a callback function that recieves more parameters than it expects).
*/
- 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
- _TCB *tcb = (_TCB*)g_readytorun.head;
- int index;
- int ret = ERROR;
+ FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct task_group_s *group = tcb->group;
+ int index;
+ int ret = ERROR;
+
+ DEBUGASSERT(group);
/* The following must be atomic */
@@ -139,9 +142,9 @@ int atexit(void (*func)(void))
available = -1;
for (index = 0; index < CONFIG_SCHED_ATEXIT_MAX; index++)
{
- if (!tcb->atexitfunc[index])
+ if (!group->tg_atexitfunc[index])
{
- tcb->atexitfunc[index] = func;
+ group->tg_atexitfunc[index] = func;
ret = OK;
break;
}
@@ -152,15 +155,18 @@ int atexit(void (*func)(void))
return ret;
#else
- _TCB *tcb = (_TCB*)g_readytorun.head;
- int ret = ERROR;
+ FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct task_group_s *group = tcb->group;
+ int ret = ERROR;
+
+ DEBUGASSERT(group);
/* The following must be atomic */
sched_lock();
- if (func && !tcb->atexitfunc)
+ if (func && !group->tg_atexitfunc)
{
- tcb->atexitfunc = func;
+ group->tg_atexitfunc = func;
ret = OK;
}
diff --git a/nuttx/sched/group_leave.c b/nuttx/sched/group_leave.c
index 1373a25a2..e56952a7b 100644
--- a/nuttx/sched/group_leave.c
+++ b/nuttx/sched/group_leave.c
@@ -48,8 +48,9 @@
#include <nuttx/net/net.h>
#include <nuttx/lib.h>
-#include "group_internal.h"
#include "env_internal.h"
+#include "pthread_internal.h"
+#include "group_internal.h"
#ifdef HAVE_TASK_GROUP
diff --git a/nuttx/sched/on_exit.c b/nuttx/sched/on_exit.c
index 19a4f9196..89c4a2d57 100644
--- a/nuttx/sched/on_exit.c
+++ b/nuttx/sched/on_exit.c
@@ -1,7 +1,7 @@
/****************************************************************************
* sched/on_exit.c
*
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -115,10 +115,13 @@
int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
{
#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
- _TCB *tcb = (_TCB*)g_readytorun.head;
+ FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct task_group_s *group = tcb->group;
int index;
int ret = ENOSPC;
+ DEBUGASSERT(group);
+
/* The following must be atomic */
if (func)
@@ -133,10 +136,10 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
for (index = 0; index < CONFIG_SCHED_ONEXIT_MAX; index++)
{
- if (!tcb->onexitfunc[index])
+ if (!group->tg_onexitfunc[index])
{
- tcb->onexitfunc[index] = func;
- tcb->onexitarg[index] = arg;
+ group->tg_onexitfunc[index] = func;
+ group->tg_onexitarg[index] = arg;
ret = OK;
break;
}
@@ -147,16 +150,19 @@ int on_exit(CODE void (*func)(int, FAR void *), FAR void *arg)
return ret;
#else
- _TCB *tcb = (_TCB*)g_readytorun.head;
+ FAR _TCB *tcb = (FAR _TCB*)g_readytorun.head;
+ FAR struct task_group_s *group = tcb->group;
int ret = ENOSPC;
+ DEBUGASSERT(group);
+
/* The following must be atomic */
sched_lock();
- if (func && !tcb->onexitfunc)
+ if (func && !group->tg_onexitfunc)
{
- tcb->onexitfunc = func;
- tcb->onexitarg = arg;
+ group->tg_onexitfunc = func;
+ group->tg_onexitarg = arg;
ret = OK;
}
diff --git a/nuttx/sched/task_exithook.c b/nuttx/sched/task_exithook.c
index 889df25e0..20162c0d6 100644
--- a/nuttx/sched/task_exithook.c
+++ b/nuttx/sched/task_exithook.c
@@ -87,41 +87,50 @@
#if defined(CONFIG_SCHED_ATEXIT) && !defined(CONFIG_SCHED_ONEXIT)
static inline void task_atexit(FAR _TCB *tcb)
{
-#if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
- int index;
+ FAR struct task_group_s *group = tcb->group;
- /* Call each atexit function in reverse order of registration atexit()
- * functions are registered from lower to higher arry indices; they must
- * be called in the reverse order of registration when task exists, i.e.,
- * from higher to lower indices.
+ /* Make sure that we have not already left the group. Only the final
+ * exitting thread in the task group should trigger the atexit()
+ * callbacks.
*/
- for (index = CONFIG_SCHED_ATEXIT_MAX-1; index >= 0; index--)
+ if (group && group->tg_nmembers == 1)
{
- if (tcb->atexitfunc[index])
+#if defined(CONFIG_SCHED_ATEXIT_MAX) && CONFIG_SCHED_ATEXIT_MAX > 1
+ int index;
+
+ /* Call each atexit function in reverse order of registration atexit()
+ * functions are registered from lower to higher arry indices; they
+ * must be called in the reverse order of registration when the task
+ * group exits, i.e., from higher to lower indices.
+ */
+
+ for (index = CONFIG_SCHED_ATEXIT_MAX-1; index >= 0; index--)
{
- /* Call the atexit function */
+ if (group->tg_atexitfunc[index])
+ {
+ /* Call the atexit function */
- (*tcb->atexitfunc[index])();
+ (*group->tg_atexitfunc[index])();
- /* Nullify the atexit function to prevent its reuse. */
+ /* Nullify the atexit function to prevent its reuse. */
- tcb->atexitfunc[index] = NULL;
+ group->tg_atexitfunc[index] = NULL;
+ }
}
- }
-
#else
- if (tcb->atexitfunc)
- {
- /* Call the atexit function */
+ if (group->tg_atexitfunc)
+ {
+ /* Call the atexit function */
- (*tcb->atexitfunc)();
+ (*group->tg_atexitfunc)();
- /* Nullify the atexit function to prevent its reuse. */
+ /* Nullify the atexit function to prevent its reuse. */
- tcb->atexitfunc = NULL;
- }
+ group->tg_atexitfunc = NULL;
+ }
#endif
+ }
}
#else
# define task_atexit(tcb)
@@ -138,40 +147,50 @@ static inline void task_atexit(FAR _TCB *tcb)
#ifdef CONFIG_SCHED_ONEXIT
static inline void task_onexit(FAR _TCB *tcb, int status)
{
-#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
- int index;
+ FAR struct task_group_s *group = tcb->group;
- /* Call each on_exit function in reverse order of registration. on_exit()
- * functions are registered from lower to higher arry indices; they must
- * be called in the reverse order of registration when task exists, i.e.,
- * from higher to lower indices.
+ /* Make sure that we have not already left the group. Only the final
+ * exitting thread in the task group should trigger the atexit()
+ * callbacks.
*/
- for (index = CONFIG_SCHED_ONEXIT_MAX-1; index >= 0; index--)
+ if (group && group->tg_nmembers == 1)
{
- if (tcb->onexitfunc[index])
+#if defined(CONFIG_SCHED_ONEXIT_MAX) && CONFIG_SCHED_ONEXIT_MAX > 1
+ int index;
+
+ /* Call each on_exit function in reverse order of registration.
+ * on_exit() functions are registered from lower to higher arry
+ * indices; they must be called in the reverse order of registration
+ * when the task grroup exits, i.e., from higher to lower indices.
+ */
+
+ for (index = CONFIG_SCHED_ONEXIT_MAX-1; index >= 0; index--)
{
- /* Call the on_exit function */
+ if (group->tg_onexitfunc[index])
+ {
+ /* Call the on_exit function */
- (*tcb->onexitfunc[index])(status, tcb->onexitarg[index]);
+ (*group->tg_onexitfunc[index])(status, group->tg_onexitarg[index]);
- /* Nullify the on_exit function to prevent its reuse. */
+ /* Nullify the on_exit function to prevent its reuse. */
- tcb->onexitfunc[index] = NULL;
+ group->tg_onexitfunc[index] = NULL;
+ }
}
- }
#else
- if (tcb->onexitfunc)
- {
- /* Call the on_exit function */
+ if (group->tg_onexitfunc)
+ {
+ /* Call the on_exit function */
- (*tcb->onexitfunc)(status, tcb->onexitarg);
+ (*group->tg_onexitfunc)(status, group->tg_onexitarg);
- /* Nullify the on_exit function to prevent its reuse. */
+ /* Nullify the on_exit function to prevent its reuse. */
- tcb->onexitfunc = NULL;
- }
+ group->tg_onexitfunc = NULL;
+ }
#endif
+ }
}
#else
# define task_onexit(tcb,status)
@@ -490,7 +509,7 @@ static inline void task_exitwakeup(FAR _TCB *tcb, int status)
* Description:
* This function implements some of the internal logic of exit() and
* task_delete(). This function performs some cleanup and other actions
- * required when a task exists:
+ * required when a task exits:
*
* - All open streams are flushed and closed.
* - All functions registered with atexit() and on_exit() are called, in