summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-09-23 16:04:39 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-09-23 16:04:39 -0600
commitbda6baf012802a5748bbec3f5d3d8fc0ea398245 (patch)
tree70a7246e73e685637d9320e19608cc6140c50ff8
parentf78a387b5ccea2d459a913b018c5a3fe1c24fac6 (diff)
downloadnuttx-bda6baf012802a5748bbec3f5d3d8fc0ea398245.tar.gz
nuttx-bda6baf012802a5748bbec3f5d3d8fc0ea398245.tar.bz2
nuttx-bda6baf012802a5748bbec3f5d3d8fc0ea398245.zip
Add support for a per-process virtual page allocator. This is a new member of the task_group_s structure. The allocaor must be initialized when a new user process is started and uninitialize when the process group is finally destroyed. It is used by shmat() and shmdt() to pick the virtual address onto which to map the shared physical memory.
-rw-r--r--nuttx/binfmt/binfmt_execmodule.c15
-rw-r--r--nuttx/include/nuttx/sched.h14
-rw-r--r--nuttx/include/nuttx/shm.h58
-rw-r--r--[-rwxr-xr-x]nuttx/mm/shm/shm_initialize.c69
-rw-r--r--nuttx/sched/group/group_leave.c8
5 files changed, 159 insertions, 5 deletions
diff --git a/nuttx/binfmt/binfmt_execmodule.c b/nuttx/binfmt/binfmt_execmodule.c
index babd5f1f7..e4ef0b785 100644
--- a/nuttx/binfmt/binfmt_execmodule.c
+++ b/nuttx/binfmt/binfmt_execmodule.c
@@ -49,6 +49,7 @@
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mm.h>
+#include <nuttx/shm.h>
#include <nuttx/binfmt/binfmt.h>
#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/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h
index 9d1cfbe94..321449f6c 100644
--- a/nuttx/include/nuttx/sched.h
+++ b/nuttx/include/nuttx/sched.h
@@ -52,6 +52,7 @@
#include <time.h>
#include <nuttx/irq.h>
+#include <nuttx/shm.h>
#include <nuttx/fs/fs.h>
#include <nuttx/net/net.h>
@@ -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 tg_addrenv; /* Task group address environment */
+#endif
+
+#ifdef CONFIG_MM_SHM
+ /* Shared Memory **************************************************************/
- group_addrenv_t addrenv; /* Task group address environment */
+ struct group_shm_s tg_shm; /* Task shared memory logic */
#endif
};
#endif
diff --git a/nuttx/include/nuttx/shm.h b/nuttx/include/nuttx/shm.h
index baff3df9e..2bd0a7e27 100644
--- a/nuttx/include/nuttx/shm.h
+++ b/nuttx/include/nuttx/shm.h
@@ -44,6 +44,8 @@
#include <debug.h>
+#include <nuttx/gran.h>
+
#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/nuttx/mm/shm/shm_initialize.c b/nuttx/mm/shm/shm_initialize.c
index 2b7d7d406..de942793c 100755..100644
--- a/nuttx/mm/shm/shm_initialize.c
+++ b/nuttx/mm/shm/shm_initialize.c
@@ -39,6 +39,15 @@
#include <nuttx/config.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/addrenv.h>
+#include <nuttx/sched.h>
+#include <nuttx/gran.h>
+#include <nuttx/pgalloc.h>
+#include <nuttx/shm.h>
+
#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/nuttx/sched/group/group_leave.c b/nuttx/sched/group/group_leave.c
index 6b44ba68a..7fadb31fc 100644
--- a/nuttx/sched/group/group_leave.c
+++ b/nuttx/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 */