mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 14:27:37 +08:00
Add mm/mm_map virtual memory mapping list
The task_group specific list can be used to store information about mmappings. For a driver or filesystem performing mmap can also enable munmap by adding an item to this list using mm_map_add(). The item is then returned in the corresponding munmap call. Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
committed by
Xiang Xiao
parent
6e4ddf78bb
commit
7f8bec7070
+152
-4
@@ -44,7 +44,7 @@ struct task_group_s;
|
|||||||
struct mm_map_entry_s
|
struct mm_map_entry_s
|
||||||
{
|
{
|
||||||
FAR struct mm_map_entry *flink; /* this is used as sq_entry_t */
|
FAR struct mm_map_entry *flink; /* this is used as sq_entry_t */
|
||||||
FAR const void *vaddr;
|
FAR void *vaddr;
|
||||||
size_t length;
|
size_t length;
|
||||||
off_t offset;
|
off_t offset;
|
||||||
int prot;
|
int prot;
|
||||||
@@ -63,7 +63,7 @@ struct mm_map_entry_s
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int (*munmap)(FAR struct task_group_s *group,
|
int (*munmap)(FAR struct task_group_s *group,
|
||||||
FAR struct mm_map_entry_s *map,
|
FAR struct mm_map_entry_s *entry,
|
||||||
FAR void *start,
|
FAR void *start,
|
||||||
size_t length);
|
size_t length);
|
||||||
};
|
};
|
||||||
@@ -73,11 +73,159 @@ struct mm_map_entry_s
|
|||||||
struct mm_map_s
|
struct mm_map_s
|
||||||
{
|
{
|
||||||
sq_queue_t mm_map_sq;
|
sq_queue_t mm_map_sq;
|
||||||
mutex_t mm_map_mutex;
|
rmutex_t mm_map_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#endif /* __INCLUDE_NUTTX_MM_MM_MAP_H */
|
/****************************************************************************
|
||||||
|
* Name: mm_map_lock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get exclusive access current task_group's mm_map
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK on success
|
||||||
|
* A negated errno value on failure
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mm_map_lock(void);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_unlock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Relinquish exclusive access to current task_group's mm_map
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mm_map_unlock(void);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initialization function, called only by group_initialize
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mm - Pointer to the mm_map structure to be initialized
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mm_map_initialize(FAR struct mm_map_s *mm);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_destroy
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Uninitialization function, called only by group_release
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mm - Pointer to the mm_map structure to be initialized
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mm_map_destroy(FAR struct mm_map_s *mm);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_add
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Adds a virtual memory area into the list of mappings
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* entry - A pointer to mm_map_entry_s, mapping info to be added
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK Added successfully
|
||||||
|
* -EINVAL: Invalid attempt to get the semaphore
|
||||||
|
* -EINTR: The wait was interrupted by the receipt of a signal.
|
||||||
|
* -ENOMEM: Out of memory
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mm_map_add(FAR struct mm_map_entry_s *entry);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_next
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Returns the next mapping in the list, following the argument.
|
||||||
|
* Can be used to iterate through all the mappings. Returns the first
|
||||||
|
* mapping when the argument "entry" is NULL.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* entry - Pointer to a single mapping in this task group or NULL to get
|
||||||
|
* the first one
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Pointer to the next mapping
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct mm_map_entry_s *mm_map_next(
|
||||||
|
FAR const struct mm_map_entry_s *entry);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_find
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find the first mapping matching address and length
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* vaddr - Start address of the mapped area
|
||||||
|
* length - Length of the mapping
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Pointer to the mapping, NULL if not found
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_remove
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Removes a virtual memory area from the list of mappings
|
||||||
|
* Sets the given pointer argument to NULL after successful removal
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* mm - Pointer to the list of entries, from which the entry is
|
||||||
|
* removed. If passed mm is NULL, the function doesn't do
|
||||||
|
* anything, but just returns OK.
|
||||||
|
*
|
||||||
|
* entry - Pointer to the entry to be removed. If the passed entry is
|
||||||
|
* NULL the function doesn't do anything but just returns OK
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* OK: Removed successfully
|
||||||
|
* -EINVAL: Invalid attempt to get the semaphore
|
||||||
|
* -EINTR: The wait was interrupted by the receipt of a signal.
|
||||||
|
* -ENOENT: Memory area not found
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mm_map_remove(FAR struct mm_map_s *mm,
|
||||||
|
FAR struct mm_map_entry_s *entry);
|
||||||
|
|
||||||
|
#endif /* __INCLUDE_NUTTX_MM_MAP_H */
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#include <nuttx/mm/shm.h>
|
#include <nuttx/mm/shm.h>
|
||||||
#include <nuttx/fs/fs.h>
|
#include <nuttx/fs/fs.h>
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
|
#include <nuttx/mm/map.h>
|
||||||
|
|
||||||
#include <arch/arch.h>
|
#include <arch/arch.h>
|
||||||
|
|
||||||
@@ -180,6 +181,14 @@
|
|||||||
# define TCB_REG_OFF(reg) (reg * sizeof(uint32_t))
|
# define TCB_REG_OFF(reg) (reg * sizeof(uint32_t))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Get a pointer to the process' memory map struct from the task_group */
|
||||||
|
|
||||||
|
#define get_group_mm(group) (group ? &group->tg_mm_map : NULL)
|
||||||
|
|
||||||
|
/* Get a pointer to current the process' memory map struct */
|
||||||
|
|
||||||
|
#define get_current_mm() (get_group_mm(nxsched_self()->group))
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Type Definitions
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -506,6 +515,10 @@ struct task_group_s
|
|||||||
|
|
||||||
struct group_shm_s tg_shm; /* Task shared memory logic */
|
struct group_shm_s tg_shm; /* Task shared memory logic */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Virtual memory mapping info ********************************************/
|
||||||
|
|
||||||
|
struct mm_map_s tg_mm_map; /* Task mmappings */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* struct tcb_s *************************************************************/
|
/* struct tcb_s *************************************************************/
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ include circbuf/Make.defs
|
|||||||
include mempool/Make.defs
|
include mempool/Make.defs
|
||||||
include kasan/Make.defs
|
include kasan/Make.defs
|
||||||
include ubsan/Make.defs
|
include ubsan/Make.defs
|
||||||
|
include map/Make.defs
|
||||||
|
|
||||||
BINDIR ?= bin
|
BINDIR ?= bin
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
############################################################################
|
||||||
|
# mm/map/Make.defs
|
||||||
|
#
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
# contributor license agreements. See the NOTICE file distributed with
|
||||||
|
# this work for additional information regarding copyright ownership. The
|
||||||
|
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance with the
|
||||||
|
# License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
# Virtual memory map list support
|
||||||
|
|
||||||
|
CSRCS += mm_map.c
|
||||||
|
|
||||||
|
# Add the shared memory directory to the build
|
||||||
|
|
||||||
|
DEPPATH += --dep-path map
|
||||||
|
VPATH += :map
|
||||||
+315
@@ -0,0 +1,315 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* mm/map/mm_map.c
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Included Files
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/mm/map.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <nuttx/sched.h>
|
||||||
|
#include <nuttx/kmalloc.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#if defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static bool in_range(FAR const void *start, size_t length,
|
||||||
|
FAR const void *range_start, size_t range_length)
|
||||||
|
{
|
||||||
|
FAR const char *u_start = (FAR const char *)start;
|
||||||
|
FAR const char *u_end = u_start + length;
|
||||||
|
FAR const char *r_start = (FAR const char *)range_start;
|
||||||
|
FAR const char *r_end = r_start + range_length;
|
||||||
|
|
||||||
|
return (u_start >= r_start && u_start < r_end && /* Start is in range. */
|
||||||
|
u_end >= r_start && u_end <= r_end); /* End is in range. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_lock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get exclusive access to task_group's mm_map
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mm_map_lock(void)
|
||||||
|
{
|
||||||
|
return nxrmutex_lock(&get_current_mm()->mm_map_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_unlock
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Relinquish exclusive access to task_group's mm_map
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mm_map_unlock(void)
|
||||||
|
{
|
||||||
|
DEBUGVERIFY(nxrmutex_unlock(&get_current_mm()->mm_map_mutex));
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_initialize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Allocates a task group specific mm_map stucture. Called when the group
|
||||||
|
* is initialized
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mm_map_initialize(FAR struct mm_map_s *mm)
|
||||||
|
{
|
||||||
|
sq_init(&mm->mm_map_sq);
|
||||||
|
nxrmutex_init(&mm->mm_map_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_destroy
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* De-allocates a task group specific mm_map stucture and the mm_map_mutex
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void mm_map_destroy(FAR struct mm_map_s *mm)
|
||||||
|
{
|
||||||
|
FAR struct mm_map_entry_s *entry;
|
||||||
|
|
||||||
|
while ((entry = (FAR struct mm_map_entry_s *)sq_remfirst(&mm->mm_map_sq)))
|
||||||
|
{
|
||||||
|
/* Pass null as group argument to indicate that actual MMU mappings
|
||||||
|
* must not be touched. The process is being deleted and we don't
|
||||||
|
* know in which context we are. Only kernel memory allocations
|
||||||
|
* need to be freed by drivers
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Unmap the whole region */
|
||||||
|
|
||||||
|
if (entry->munmap)
|
||||||
|
{
|
||||||
|
if (entry->munmap(NULL, entry, entry->vaddr, entry->length) < 0)
|
||||||
|
{
|
||||||
|
/* This would be an error in the driver. It has defined munmap,
|
||||||
|
* but is not able to munmap the full area which it has mapped
|
||||||
|
*/
|
||||||
|
|
||||||
|
merr("Driver munmap failed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kmm_free(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
nxrmutex_destroy(&mm->mm_map_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_add
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Add a mapping to task group's mm_map list
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mm_map_add(FAR struct mm_map_entry_s *entry)
|
||||||
|
{
|
||||||
|
FAR struct mm_map_s *mm = get_current_mm();
|
||||||
|
FAR struct mm_map_entry_s *new_entry;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the provided mapping and add to the list */
|
||||||
|
|
||||||
|
new_entry = kmm_malloc(sizeof(struct mm_map_entry_s));
|
||||||
|
if (!new_entry)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_entry = *entry;
|
||||||
|
|
||||||
|
ret = nxrmutex_lock(&mm->mm_map_mutex);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
kmm_free(new_entry);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sq_addfirst((sq_entry_t *)new_entry, &mm->mm_map_sq);
|
||||||
|
|
||||||
|
nxrmutex_unlock(&mm->mm_map_mutex);
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_next
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Returns the next mapping in the list.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct mm_map_entry_s *mm_map_next(
|
||||||
|
FAR const struct mm_map_entry_s *entry)
|
||||||
|
{
|
||||||
|
FAR struct mm_map_s *mm = get_current_mm();
|
||||||
|
FAR struct mm_map_entry_s *next_entry = NULL;
|
||||||
|
|
||||||
|
if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
|
||||||
|
{
|
||||||
|
if (entry == NULL)
|
||||||
|
{
|
||||||
|
next_entry = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next_entry = (struct mm_map_entry_s *)
|
||||||
|
sq_next(((sq_entry_t *)entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
nxrmutex_unlock(&mm->mm_map_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return next_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_find
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Find the first mapping containing the range from the task group's list
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
FAR struct mm_map_entry_s *mm_map_find(FAR const void *vaddr, size_t length)
|
||||||
|
{
|
||||||
|
FAR struct mm_map_s *mm = get_current_mm();
|
||||||
|
FAR struct mm_map_entry_s *found_entry = NULL;
|
||||||
|
|
||||||
|
if (nxrmutex_lock(&mm->mm_map_mutex) == OK)
|
||||||
|
{
|
||||||
|
found_entry = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
|
||||||
|
|
||||||
|
while (found_entry && !in_range(vaddr, length,
|
||||||
|
found_entry->vaddr,
|
||||||
|
found_entry->length))
|
||||||
|
{
|
||||||
|
found_entry = (struct mm_map_entry_s *)
|
||||||
|
sq_next(((sq_entry_t *)found_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
nxrmutex_unlock(&mm->mm_map_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return found_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mm_map_remove
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Remove a mapping from the task group's list
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int mm_map_remove(FAR struct mm_map_s *mm,
|
||||||
|
FAR struct mm_map_entry_s *entry)
|
||||||
|
{
|
||||||
|
FAR struct mm_map_entry_s *prev_entry;
|
||||||
|
FAR struct mm_map_entry_s *removed_entry = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!mm || !entry)
|
||||||
|
{
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = nxrmutex_lock(&mm->mm_map_mutex);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_entry = (struct mm_map_entry_s *)sq_peek(&mm->mm_map_sq);
|
||||||
|
|
||||||
|
/* Check if the list was empty */
|
||||||
|
|
||||||
|
if (!prev_entry)
|
||||||
|
{
|
||||||
|
nxrmutex_unlock(&mm->mm_map_mutex);
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if removing the first item */
|
||||||
|
|
||||||
|
if (entry == prev_entry)
|
||||||
|
{
|
||||||
|
sq_remfirst(&mm->mm_map_sq);
|
||||||
|
removed_entry = prev_entry;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Loop through the remaining items to find the one to be removed */
|
||||||
|
|
||||||
|
while ((removed_entry = (struct mm_map_entry_s *)
|
||||||
|
sq_next(((sq_entry_t *)prev_entry))))
|
||||||
|
{
|
||||||
|
if (entry == removed_entry)
|
||||||
|
{
|
||||||
|
sq_remafter((sq_entry_t *)prev_entry, &mm->mm_map_sq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_entry = removed_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nxrmutex_unlock(&mm->mm_map_mutex);
|
||||||
|
|
||||||
|
/* If the item was removed, also delete the entry struct */
|
||||||
|
|
||||||
|
if (removed_entry)
|
||||||
|
{
|
||||||
|
kmm_free(removed_entry);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined(CONFIG_BUILD_FLAT) || defined(__KERNEL__) */
|
||||||
@@ -245,6 +245,10 @@ void group_initialize(FAR struct task_tcb_s *tcb)
|
|||||||
DEBUGASSERT(tcb && tcb->cmn.group);
|
DEBUGASSERT(tcb && tcb->cmn.group);
|
||||||
group = tcb->cmn.group;
|
group = tcb->cmn.group;
|
||||||
|
|
||||||
|
/* Allocate mm_map list if required */
|
||||||
|
|
||||||
|
mm_map_initialize(&group->tg_mm_map);
|
||||||
|
|
||||||
#ifdef HAVE_GROUP_MEMBERS
|
#ifdef HAVE_GROUP_MEMBERS
|
||||||
/* Assign the PID of this new task as a member of the group. */
|
/* Assign the PID of this new task as a member of the group. */
|
||||||
|
|
||||||
|
|||||||
@@ -176,6 +176,10 @@ static inline void group_release(FAR struct task_group_s *group)
|
|||||||
env_release(group);
|
env_release(group);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Destroy the mm_map list */
|
||||||
|
|
||||||
|
mm_map_destroy(&group->tg_mm_map);
|
||||||
|
|
||||||
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM)
|
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_SHM)
|
||||||
/* Release any resource held by shared memory virtual page allocator */
|
/* Release any resource held by shared memory virtual page allocator */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user