From af22f273d358e04472aa60797b48ae2bb8c0f4fd Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 26 Aug 2014 14:54:39 -0600 Subject: [PATCH] Add group_addrenv() which will be called during context switches in order to change address environments. Not yet hooked in --- include/nuttx/sched.h | 4 +++- sched/group/Make.defs | 4 ++++ sched/group/group.h | 25 +++++++++++++++++++++++-- sched/group/group_create.c | 20 ++++++++++++-------- sched/group/group_find.c | 4 ++-- sched/group/group_leave.c | 8 +++++--- 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 09d232357b..7a4004d9a8 100644 --- a/include/nuttx/sched.h +++ b/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/sched/group/Make.defs b/sched/group/Make.defs index b884365473..5b90f50efe 100644 --- a/sched/group/Make.defs +++ b/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/sched/group/group.h b/sched/group/group.h index a15919070d..5323bba4ad 100644 --- a/sched/group/group.h +++ b/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/sched/group/group_create.c b/sched/group/group_create.c index 36850f73dd..d8e4bf9428 100644 --- a/sched/group/group_create.c +++ b/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/sched/group/group_find.c b/sched/group/group_find.c index 0e9287e8a8..c0c70bbc75 100644 --- a/sched/group/group_find.c +++ b/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/sched/group/group_leave.c b/sched/group/group_leave.c index a9a133f4ce..e3606f2eeb 100644 --- a/sched/group/group_leave.c +++ b/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)