[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