]> mj.ucw.cz Git - libucw.git/commitdiff
Added big_alloc() for allocating large, page-aligned buffers.
authorMartin Mares <mj@ucw.cz>
Thu, 23 Nov 2006 23:17:17 +0000 (00:17 +0100)
committerMartin Mares <mj@ucw.cz>
Thu, 23 Nov 2006 23:17:17 +0000 (00:17 +0100)
lib/Makefile
lib/bigalloc.c [new file with mode: 0644]
lib/lib.h

index 15dc0a246d60df199676c55244b9cce182ae0052..604e61d5a88a04277f64be0fbf90393be5e932ca 100644 (file)
@@ -7,7 +7,7 @@ PROGS+=$(o)/lib/db-tool
 endif
 
 LIBUCW_MODS= \
-       alloc alloc_str realloc mempool mempool-str mempool-fmt \
+       alloc alloc_str realloc bigalloc mempool mempool-str mempool-fmt \
        mmap pagecache partmap hashfunc \
        lists slists simple-lists sorter bitsig \
        log log-file proctitle \
@@ -80,6 +80,7 @@ $(o)/lib/binheap-test: $(o)/lib/binheap-test.o $(LIBUCW)
 $(o)/lib/lizard-test: $(o)/lib/lizard-test.o $(LIBUCW)
 $(o)/lib/kmp-test: $(o)/lib/kmp-test.o $(LIBUCW) $(LIBCHARSET)
 $(o)/lib/ipaccess-test: $(o)/lib/ipaccess-test.o $(LIBUCW)
+$(o)/lib/bigalloc-test: $(o)/lib/bigalloc-test.o $(LIBUCW)
 
 TESTS+=$(addprefix $(o)/lib/,regex.test unicode-utf8.test hash-test.test mempool.test stkstring.test slists.test kmp-test.test bbuf.test)
 $(o)/lib/regex.test: $(o)/lib/regex-t
diff --git a/lib/bigalloc.c b/lib/bigalloc.c
new file mode 100644 (file)
index 0000000..b4589c4
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *     UCW Library -- Allocation of Large Aligned Buffers
+ *
+ *     (c) 2006 Martin Mares <mj@ucw.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include "lib/lib.h"
+
+#include <sys/mman.h>
+#include <sys/user.h>
+
+static unsigned int
+big_round(unsigned int len)
+{
+  return ALIGN_TO(len, PAGE_SIZE);
+}
+
+void *
+big_alloc(unsigned int len)
+{
+  len = big_round(len);
+#ifdef CONFIG_DEBUG
+  len += 2*PAGE_SIZE;
+#endif
+  byte *p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+  if (p == (byte*) MAP_FAILED)
+    die("Cannot mmap %d bytes of memory: %m", len);
+#ifdef CONFIG_DEBUG
+  mprotect(p, PAGE_SIZE, PROT_NONE);
+  mprotect(p+len-PAGE_SIZE, PAGE_SIZE, PROT_NONE);
+  p += PAGE_SIZE;
+#endif
+  return p;
+}
+
+void
+big_free(void *start, unsigned int len)
+{
+  byte *p = start;
+  ASSERT(!((addr_int_t) p & (PAGE_SIZE-1)));
+  len = big_round(len);
+#ifdef CONFIG_DEBUG
+  p -= PAGE_SIZE;
+  len += 2*PAGE_SIZE;
+#endif
+  munmap(p, len);
+}
+
+#ifdef TEST
+
+int main(void)
+{
+  byte *p = big_alloc(123456);
+  // p[-1] = 1;
+  big_free(p, 123456);
+  return 0;
+}
+
+#endif
index 43135c6cc27f5409ece71fd5cd4c3a7376bbc6c1..21fe4773d517821d735a06bf666b7c1467b1b433 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -271,4 +271,9 @@ void unhandle_signal(int signum, struct sigaction *oldact);
 
 byte *str_unesc(byte *dest, byte *src);
 
+/* bigalloc.c */
+
+void *big_alloc(unsigned int len);
+void big_free(void *start, unsigned int len);
+
 #endif