[PATCH 1/5] Cygwin: mmap: refactor mmap_record::match
Ken Brown
kbrown@cornell.edu
Wed Jan 8 23:03:37 GMT 2025
Patch attached.
-------------- next part --------------
From 4387a73d5593ddad4cf7592865b5b257e6a9d6de Mon Sep 17 00:00:00 2001
From: Ken Brown <kbrown@cornell.edu>
Date: Fri, 27 Dec 2024 15:30:12 -0500
Subject: [PATCH 1/5] Cygwin: mmap: refactor mmap_record::match
Slightly simplify the code and add comments to explain what the
function does. Add a new reference parameter "contains" that is set
to true if the chunk of this mmap_record contains the given address
range.
Signed-off-by: Ken Brown <kbrown@cornell.edu>
---
winsup/cygwin/mm/mmap.cc | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/winsup/cygwin/mm/mmap.cc b/winsup/cygwin/mm/mmap.cc
index 0224779458ef..acab85d19cf0 100644
--- a/winsup/cygwin/mm/mmap.cc
+++ b/winsup/cygwin/mm/mmap.cc
@@ -338,7 +338,8 @@ class mmap_record
void init_page_map (mmap_record &r);
SIZE_T find_unused_pages (SIZE_T pages) const;
- bool match (caddr_t addr, SIZE_T len, caddr_t &m_addr, SIZE_T &m_len);
+ bool match (caddr_t addr, SIZE_T len, caddr_t &m_addr, SIZE_T &m_len,
+ bool &contains);
off_t map_pages (SIZE_T len, int new_prot);
bool map_pages (caddr_t addr, SIZE_T len, int new_prot);
bool unmap_pages (caddr_t addr, SIZE_T len);
@@ -418,20 +419,30 @@ mmap_record::find_unused_pages (SIZE_T pages) const
return (SIZE_T) -1;
}
+/* Return true if the interval I from addr to addr + len intersects
+ the interval J of this mmap_record. The endpoint of the latter is
+ first rounded up to a page boundary. If there is an intersection,
+ then it is the interval from m_addr to m_addr + m_len. The
+ variable 'contains' is set to true if J contains I.
+*/
bool
-mmap_record::match (caddr_t addr, SIZE_T len, caddr_t &m_addr, SIZE_T &m_len)
+mmap_record::match (caddr_t addr, SIZE_T len, caddr_t &m_addr, SIZE_T &m_len,
+ bool &contains)
{
- caddr_t low = (addr >= get_address ()) ? addr : get_address ();
+ contains = false;
+ caddr_t low = MAX (addr, get_address ());
caddr_t high = get_address ();
if (filler ())
high += get_len ();
else
high += (PAGE_CNT (get_len ()) * wincap.page_size ());
- high = (addr + len < high) ? addr + len : high;
+ high = MIN (addr + len, high);
if (low < high)
{
m_addr = low;
m_len = high - low;
+ /* I is contained in J iff their intersection equals I. */
+ contains = (addr == m_addr && len == m_len);
return true;
}
return false;
@@ -653,14 +664,14 @@ mmap_list::try_map (void *addr, size_t len, int new_prot, int flags, off_t off)
request, try to reset the protection on the requested area. */
caddr_t u_addr;
SIZE_T u_len;
+ bool contains;
LIST_FOREACH (rec, &recs, mr_next)
- if (rec->match ((caddr_t) addr, len, u_addr, u_len))
+ if (rec->match ((caddr_t) addr, len, u_addr, u_len, contains))
break;
if (rec)
{
- if (u_addr > (caddr_t) addr || u_addr + u_len < (caddr_t) addr + len
- || !rec->compatible_flags (flags))
+ if (!contains || !rec->compatible_flags (flags))
{
/* Partial match only, or access mode doesn't match. */
/* FIXME: Handle partial mappings gracefully if adjacent
@@ -730,11 +741,12 @@ is_mmapped_region (caddr_t start_addr, caddr_t end_address)
mmap_record *rec;
caddr_t u_addr;
SIZE_T u_len;
+ bool contains;
bool ret = false;
LIST_FOREACH (rec, &map_list->recs, mr_next)
{
- if (rec->match (start_addr, len, u_addr, u_len))
+ if (rec->match (start_addr, len, u_addr, u_len, contains))
{
ret = true;
break;
@@ -786,10 +798,11 @@ mmap_is_attached_or_noreserve (void *addr, size_t len)
if (map_list == NULL)
goto out;
+ bool contains;
LIST_FOREACH (rec, &map_list->recs, mr_next)
{
- if (!rec->match (start_addr, len, u_addr, u_len))
+ if (!rec->match (start_addr, len, u_addr, u_len, contains))
continue;
if (rec->attached ())
{
@@ -1177,10 +1190,11 @@ munmap (void *addr, size_t len)
mmap_record *rec, *next_rec;
caddr_t u_addr;
SIZE_T u_len;
+ bool contains;
LIST_FOREACH_SAFE (rec, &map_list->recs, mr_next, next_rec)
{
- if (!rec->match ((caddr_t) addr, len, u_addr, u_len))
+ if (!rec->match ((caddr_t) addr, len, u_addr, u_len, contains))
continue;
if (rec->unmap_pages (u_addr, u_len))
{
@@ -1299,10 +1313,11 @@ mprotect (void *addr, size_t len, int prot)
mmap_record *rec;
caddr_t u_addr;
SIZE_T u_len;
+ bool contains;
LIST_FOREACH (rec, &map_list->recs, mr_next)
{
- if (!rec->match ((caddr_t) addr, len, u_addr, u_len))
+ if (!rec->match ((caddr_t) addr, len, u_addr, u_len, contains))
continue;
in_mapped = true;
if (rec->attached ())
--
2.45.1
More information about the Cygwin-patches
mailing list