[lttng-dev] [PATCH urcu] Fix: don't use overlapping mmap mappings on Cygwin

Michael Jeanson mjeanson at efficios.com
Tue Jul 25 22:56:34 UTC 2017


On cygwin, overlapping memory mappings are not allowed. However, it's
possible to use the MAP_NORESERVE flag which won't allocate memory for a
protected mapping and then use mprotect() on chunks of this mapping to
change the protection and allocate/deallocate the memory.

Signed-off-by: Michael Jeanson <mjeanson at efficios.com>
---
 src/rculfhash-mm-mmap.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/src/rculfhash-mm-mmap.c b/src/rculfhash-mm-mmap.c
index 3cc3fa0..46150bd 100644
--- a/src/rculfhash-mm-mmap.c
+++ b/src/rculfhash-mm-mmap.c
@@ -28,23 +28,52 @@
 #define MAP_ANONYMOUS		MAP_ANON
 #endif
 
+#ifdef __CYGWIN__
+/*
+ * On cygwin, overlapping memory mappings are not allowed. However, it's
+ * possible to use the MAP_NORESERVE flag which won't allocate memory for a
+ * protected mapping and then use mprotect() on chunks of this mapping to
+ * change the protection and allocate/deallocate the memory.
+ */
+
 /* reserve inaccessible memory space without allocation any memory */
 static void *memory_map(size_t length)
 {
 	void *ret = mmap(NULL, length, PROT_NONE,
-			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+			MAP_NORESERVE | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
 	assert(ret != MAP_FAILED);
 	return ret;
 }
 
-static void memory_unmap(void *ptr, size_t length)
+/* Set protection to read/write which allocated memory */
+static void memory_populate(void *ptr, size_t length)
 {
 	int ret __attribute__((unused));
 
-	ret = munmap(ptr, length);
+	ret = mprotect(ptr, length, PROT_READ | PROT_WRITE);
 
-	assert(ret == 0);
+	assert(!ret);
+}
+
+/* Set protection to none which reclaims memory */
+static void memory_discard(void *ptr, size_t length)
+{
+	int ret __attribute__((unused));
+
+	ret = mprotect(ptr, length, PROT_NONE);
+
+	assert(!ret);
+}
+#else /* __CYGWIN__ */
+/* reserve inaccessible memory space without allocation any memory */
+static void *memory_map(size_t length)
+{
+	void *ret = mmap(NULL, length, PROT_NONE,
+			MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+	assert(ret != MAP_FAILED);
+	return ret;
 }
 
 static void memory_populate(void *ptr, size_t length)
@@ -70,6 +99,16 @@ static void memory_discard(void *ptr, size_t length)
 
 	assert(ret == ptr);
 }
+#endif /* __CYGWIN__ */
+
+static void memory_unmap(void *ptr, size_t length)
+{
+	int ret __attribute__((unused));
+
+	ret = munmap(ptr, length);
+
+	assert(ret == 0);
+}
 
 static
 void cds_lfht_alloc_bucket_table(struct cds_lfht *ht, unsigned long order)
-- 
2.7.4



More information about the lttng-dev mailing list