diff --git a/binfmt/binfmt_execmodule.c b/binfmt/binfmt_execmodule.c index babd5f1f7d..e4ef0b7854 100644 --- a/binfmt/binfmt_execmodule.c +++ b/binfmt/binfmt_execmodule.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include "sched/sched.h" @@ -229,6 +230,18 @@ int exec_module(FAR const struct binary_s *binp) } #endif +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM) + /* Initialize the shared memory virtual page allocator */ + + ret = shm_group_initialize(&tcb->cmn.group); + if (ret < 0) + { + bdbg("ERROR: shm_group_initialize() failed: %d\n", ret); + err = -ret; + goto errout_with_tcbinit; + } +#endif + #ifdef CONFIG_PIC /* Add the D-Space address as the PIC base address. By convention, this * must be the first allocated address space. @@ -244,7 +257,7 @@ int exec_module(FAR const struct binary_s *binp) #ifdef CONFIG_ARCH_ADDRENV /* Assign the address environment to the new task group */ - ret = up_addrenv_clone(&binp->addrenv, &tcb->cmn.group->addrenv); + ret = up_addrenv_clone(&binp->addrenv, &tcb->cmn.group->tg_addrenv); if (ret < 0) { err = -ret; diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 9d1cfbe945..321449f6cd 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -103,6 +104,8 @@ # define HAVE_TASK_GROUP 1 /* Message queues */ # elif defined(CONFIG_ARCH_ADDRENV) # define HAVE_TASK_GROUP 1 /* Address environment */ +# elif defined(CONFIG_MM_SHM) +# define HAVE_TASK_GROUP 1 /* Shared memory */ # endif #endif @@ -418,10 +421,15 @@ struct task_group_s #endif #ifdef CONFIG_ARCH_ADDRENV - /* POSIX Named Message Queue Fields *******************************************/ - /* POSIX Named Message Queue Fields *******************************************/ + /* Address Environment ********************************************************/ - group_addrenv_t addrenv; /* Task group address environment */ + group_addrenv_t tg_addrenv; /* Task group address environment */ +#endif + +#ifdef CONFIG_MM_SHM + /* Shared Memory **************************************************************/ + + struct group_shm_s tg_shm; /* Task shared memory logic */ #endif }; #endif diff --git a/include/nuttx/shm.h b/include/nuttx/shm.h index baff3df9e4..2bd0a7e275 100644 --- a/include/nuttx/shm.h +++ b/include/nuttx/shm.h @@ -44,6 +44,8 @@ #include +#include + #ifdef CONFIG_MM_SHM /**************************************************************************** @@ -95,6 +97,26 @@ * Public Types ****************************************************************************/ +/* This structure describes the virtual page allocator that is use to manage + * the mapping of shared memory into the group/process address space. + */ + +struct group_shm_s +{ + /* Handle returned by gran_initialize() when the virtual page allocator + * was created. + */ + + GRAN_HANDLE gs_handle; + + /* This array is used to do a reverse lookup: Give the virtual address + * of a shared memory region, find the region index that performs that + * mapping. + */ + + uintptr_t gs_vaddr[CONFIG_ARCH_SHM_MAXREGIONS]; +}; + /**************************************************************************** * Public Data ****************************************************************************/ @@ -119,5 +141,41 @@ void shm_initialize(void); +/**************************************************************************** + * Name: shm_group_initialize + * + * Description: + * Initialize the group shared memory data structures when a new task + * group is initialized. + * + * Input Parameters: + * group - A reference to the new group structure to be initialized. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +struct task_group_s; /* Forward reference */ +int shm_group_initialize(FAR struct task_group_s *group); + +/**************************************************************************** + * Name: shm_group_release + * + * Description: + * Release resources used by the group shared memory logic. This function + * is called at the time at the group is destroyed. + * + * Input Parameters: + * group - A reference to the group structure to be un-initialized. + * + * Returned Value: + * None + * + ****************************************************************************/ + +struct task_group_s; /* Forward reference */ +void shm_group_release(FAR struct task_group_s *group); + #endif /* CONFIG_MM_SHM */ #endif /* __INCLUDE_NUTTX_SHM_H */ diff --git a/mm/shm/shm_initialize.c b/mm/shm/shm_initialize.c old mode 100755 new mode 100644 index 2b7d7d406e..de942793c9 --- a/mm/shm/shm_initialize.c +++ b/mm/shm/shm_initialize.c @@ -39,6 +39,15 @@ #include +#include +#include + +#include +#include +#include +#include +#include + #include "shm/shm.h" #ifdef CONFIG_MM_SHM @@ -104,4 +113,64 @@ void shm_initialize(void) #endif } +/**************************************************************************** + * Name: shm_group_initialize + * + * Description: + * Initialize the group shared memory data structures when a new task + * group is initialized. + * + * Input Parameters: + * group - A reference to the new group structure to be initialized. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int shm_group_initialize(FAR struct task_group_s *group) +{ + DEBUGASSERT(group && !group->tg_shm.gs_handle); + + group->tg_shm.gs_handle = + gran_initialize((FAR void *)CONFIG_ARCH_SHM_VBASE, + ARCH_SHM_MAXPAGES << MM_PGSHIFT, + MM_PGSHIFT, MM_PGSHIFT); + + if (!group->tg_shm.gs_handle) + { + shmdbg("gran_initialize() failed\n"); + return -ENOMEM; + } + + return OK; +} + +/**************************************************************************** + * Name: shm_group_release + * + * Description: + * Release resources used by the group shared memory logic. This function + * is called at the time at the group is destroyed. + * + * Input Parameters: + * group - A reference to the group structure to be un-initialized. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void shm_group_release(FAR struct task_group_s *group) +{ + GRAN_HANDLE handle; + DEBUGASSERT(group) + + handle = group->tg_shm.gs_handle; + if (handle) + { + gran_release(handle); + } +} + #endif /* CONFIG_MM_SHM */ diff --git a/sched/group/group_leave.c b/sched/group/group_leave.c index 6b44ba68a0..7fadb31fc4 100644 --- a/sched/group/group_leave.c +++ b/sched/group/group_leave.c @@ -204,10 +204,16 @@ static inline void group_release(FAR struct task_group_s *group) mq_release(group); #endif +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM) + /* Release any resource held by shared memory virtual page allocator */ + + (void)shm_group_release(group); +#endif + #ifdef CONFIG_ARCH_ADDRENV /* Destroy the group address environment */ - (void)up_addrenv_destroy(&group->addrenv); + (void)up_addrenv_destroy(&group->tg_addrenv); /* Mark no address environment */