src/buffer.c

changeset 1291
5942859fd76c
parent 1290
4ac889e14211
child 1292
1e7ee17777f4
--- a/src/buffer.c	Sun Apr 13 13:02:54 2025 +0200
+++ b/src/buffer.c	Sun Apr 13 14:30:51 2025 +0200
@@ -29,6 +29,7 @@
 #include "cx/buffer.h"
 
 #include <stdio.h>
+#include <unistd.h>
 #include <string.h>
 #include <errno.h>
 
@@ -190,6 +191,28 @@
         return 0;
     }
 
+    unsigned long pagesize = sysconf(_SC_PAGESIZE);
+    // if page size is larger than 64 KB - for some reason - truncate to 64 KB
+    if (pagesize > 65536) pagesize = 65536;
+    if (newcap < pagesize) {
+        // when smaller as one page, map to the next power of two
+        newcap--;
+        newcap |= newcap >> 1;
+        newcap |= newcap >> 2;
+        newcap |= newcap >> 4;
+        // last operation only needed for pages larger 4096 bytes
+        // but if/else would be more expensive than just doing this
+        newcap |= newcap >> 8;
+        newcap++;
+    } else {
+        // otherwise, map to a multiple of the page size
+        newcap -= newcap % pagesize;
+        newcap += pagesize;
+        // note: if newcap is already page aligned,
+        // this gives a full additional page (which is good)
+    }
+
+
     const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND;
     if (buffer->flags & force_copy_flags) {
         void *newspace = cxMalloc(buffer->allocator, newcap);

mercurial