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.

This commit is contained in:
Gregory Nutt 2014-09-23 16:04:39 -06:00
parent b542d1733f
commit 835c91b03a
5 changed files with 159 additions and 5 deletions

View File

@ -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;

View File

@ -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 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

View File

@ -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 */

69
mm/shm/shm_initialize.c Executable file → Normal file
View File

@ -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 */

View File

@ -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 */