summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-26 14:54:39 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-26 14:54:39 -0600
commitb5230b9fd02662dba637d5a58f456e8d012b6458 (patch)
treeda7e344cb6dbe969d0278e2cd95f84b19563ce2d
parent9cfae56f922ee209ab1147a95cdefbbc7abc43c2 (diff)
downloadnuttx-b5230b9fd02662dba637d5a58f456e8d012b6458.tar.gz
nuttx-b5230b9fd02662dba637d5a58f456e8d012b6458.tar.bz2
nuttx-b5230b9fd02662dba637d5a58f456e8d012b6458.zip
Add group_addrenv() which will be called during context switches in order to change address environments. Not yet hooked in
-rw-r--r--nuttx/include/nuttx/sched.h4
-rw-r--r--nuttx/sched/group/Make.defs4
-rw-r--r--nuttx/sched/group/group.h25
-rw-r--r--nuttx/sched/group/group_create.c20
-rw-r--r--nuttx/sched/group/group_find.c4
-rw-r--r--nuttx/sched/group/group_leave.c8
6 files changed, 49 insertions, 16 deletions
diff --git a/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h
index 09d232357..7a4004d9a 100644
--- a/nuttx/include/nuttx/sched.h
+++ b/nuttx/include/nuttx/sched.h
@@ -298,9 +298,11 @@ struct join_s; /* Forward reference
struct task_group_s
{
-#ifdef HAVE_GROUP_MEMBERS
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
struct task_group_s *flink; /* Supports a singly linked list */
gid_t tg_gid; /* The ID of this task group */
+#endif
+#ifdef HAVE_GROUP_MEMBERS
gid_t tg_pgid; /* The ID of the parent task group */
#endif
#if !defined(CONFIG_DISABLE_PTHREAD) && defined(CONFIG_SCHED_HAVE_PARENT)
diff --git a/nuttx/sched/group/Make.defs b/nuttx/sched/group/Make.defs
index b88436547..5b90f50ef 100644
--- a/nuttx/sched/group/Make.defs
+++ b/nuttx/sched/group/Make.defs
@@ -44,6 +44,10 @@ GRP_SRCS += group_childstatus.c
endif
endif
+ifeq ($(CONFIG_ARCH_ADDRENV),y)
+GRP_SRCS += group_addrenv.c
+endif
+
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
GRP_SRCS += group_signal.c
endif
diff --git a/nuttx/sched/group/group.h b/nuttx/sched/group/group.h
index a15919070..5323bba4a 100644
--- a/nuttx/sched/group/group.h
+++ b/nuttx/sched/group/group.h
@@ -66,12 +66,24 @@ typedef int (*foreachchild_t)(pid_t pid, FAR void *arg);
/****************************************************************************
* Public Data
****************************************************************************/
+
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
/* This is the head of a list of all group members */
-#ifdef HAVE_GROUP_MEMBERS
extern FAR struct task_group_s *g_grouphead;
#endif
+#ifdef CONFIG_ARCH_ADDRENV
+/* This variable holds the group ID of the current task group. This ID is
+ * zero if the current task is a kernel thread that has no address
+ * environment (other than the kernel context).
+ *
+ * This must only be accessed with interrupts disabled.
+ */
+
+extern gid_t g_gid_current;
+#endif
+
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
@@ -91,14 +103,23 @@ int group_join(FAR struct pthread_tcb_s *tcb);
#endif
void group_leave(FAR struct tcb_s *tcb);
-#ifdef HAVE_GROUP_MEMBERS
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
FAR struct task_group_s *group_findbygid(gid_t gid);
+#endif
+
+#ifdef HAVE_GROUP_MEMBERS
FAR struct task_group_s *group_findbypid(pid_t pid);
int group_foreachchild(FAR struct task_group_s *group,
foreachchild_t handler, FAR void *arg);
int group_killchildren(FAR struct task_tcb_s *tcb);
#endif
+#ifdef CONFIG_ARCH_ADDRENV
+/* Group address environment management */
+
+int group_addrenv(FAR struct tcb_s *tcb);
+#endif
+
/* Convenience functions */
FAR struct task_group_s *task_getgroup(pid_t pid);
diff --git a/nuttx/sched/group/group_create.c b/nuttx/sched/group/group_create.c
index 36850f73d..d8e4bf942 100644
--- a/nuttx/sched/group/group_create.c
+++ b/nuttx/sched/group/group_create.c
@@ -67,16 +67,17 @@
*****************************************************************************/
/* This is counter that is used to generate unique task group IDs */
-#ifdef HAVE_GROUP_MEMBERS
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
static gid_t g_gidcounter;
#endif
/*****************************************************************************
* Public Data
*****************************************************************************/
+
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
/* This is the head of a list of all group members */
-#ifdef HAVE_GROUP_MEMBERS
FAR struct task_group_s *g_grouphead;
#endif
@@ -102,8 +103,8 @@ FAR struct task_group_s *g_grouphead;
*
*****************************************************************************/
-#ifdef HAVE_GROUP_MEMBERS
-void group_assigngid(FAR struct task_group_s *group)
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
+static void group_assigngid(FAR struct task_group_s *group)
{
irqstate_t flags;
gid_t gid;
@@ -116,7 +117,7 @@ void group_assigngid(FAR struct task_group_s *group)
for (;;)
{
- /* Increment the ID counter. This is global data so be extra paraoid. */
+ /* Increment the ID counter. This is global data so be extra paranoid. */
flags = irqsave();
gid = ++g_gidcounter;
@@ -212,15 +213,15 @@ int group_allocate(FAR struct task_tcb_s *tcb)
tcb->cmn.group = group;
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
/* Assign the group a unique ID. If g_gidcounter were to wrap before we
* finish with task creation, that would be a problem.
*/
-#ifdef HAVE_GROUP_MEMBERS
group_assigngid(group);
#endif
- /* Duplicate the parent tasks envionment */
+ /* Duplicate the parent tasks environment */
ret = env_dup(group);
if (ret < 0)
@@ -267,7 +268,7 @@ int group_allocate(FAR struct task_tcb_s *tcb)
int group_initialize(FAR struct task_tcb_s *tcb)
{
FAR struct task_group_s *group;
-#ifdef HAVE_GROUP_MEMBERS
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
irqstate_t flags;
#endif
@@ -294,6 +295,9 @@ int group_initialize(FAR struct task_tcb_s *tcb)
group->tg_mxmembers = GROUP_INITIAL_MEMBERS; /* Number of members in allocation */
+#endif
+
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
/* Add the initialized entry to the list of groups */
flags = irqsave();
diff --git a/nuttx/sched/group/group_find.c b/nuttx/sched/group/group_find.c
index 0e9287e8a..c0c70bbc7 100644
--- a/nuttx/sched/group/group_find.c
+++ b/nuttx/sched/group/group_find.c
@@ -99,7 +99,7 @@
*
*****************************************************************************/
-#ifdef HAVE_GROUP_MEMBERS
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
FAR struct task_group_s *group_findbygid(gid_t gid)
{
FAR struct task_group_s *group;
@@ -123,7 +123,7 @@ FAR struct task_group_s *group_findbygid(gid_t gid)
#endif
/*****************************************************************************
- * Name: group_findbygid
+ * Name: group_findbypid
*
* Description:
* Given a task ID, find the group task structure with was started by that
diff --git a/nuttx/sched/group/group_leave.c b/nuttx/sched/group/group_leave.c
index a9a133f4c..e3606f2ee 100644
--- a/nuttx/sched/group/group_leave.c
+++ b/nuttx/sched/group/group_leave.c
@@ -90,8 +90,8 @@
*
*****************************************************************************/
-#ifdef HAVE_GROUP_MEMBERS
-void group_remove(FAR struct task_group_s *group)
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
+static void group_remove(FAR struct task_group_s *group)
{
FAR struct task_group_s *curr;
FAR struct task_group_s *prev;
@@ -214,11 +214,13 @@ static inline void group_release(FAR struct task_group_s *group)
(void)up_addrenv_destroy(&group->addrenv);
#endif
-#ifdef HAVE_GROUP_MEMBERS
+#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
/* Remove the group from the list of groups */
group_remove(group);
+#endif
+#ifdef HAVE_GROUP_MEMBERS
/* Release the members array */
if (group->tg_members)