]> mj.ucw.cz Git - libucw.git/blob - lib/bigalloc.c
Merge with git+ssh://git.ucw.cz/projects/sherlock/GIT/sherlock.git
[libucw.git] / lib / bigalloc.c
1 /*
2  *      UCW Library -- Allocation of Large Aligned Buffers
3  *
4  *      (c) 2006 Martin Mares <mj@ucw.cz>
5  *      (c) 2007 Pavel Charvat <char@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "lib/lib.h"
12
13 #include <sys/mman.h>
14 #include <string.h>
15
16 void *
17 page_alloc(unsigned int len)
18 {
19   ASSERT(!(len & (CPU_PAGE_SIZE-1)));
20   byte *p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
21   if (p == (byte*) MAP_FAILED)
22     die("Cannot mmap %d bytes of memory: %m", len);
23   return p;
24 }
25
26 void
27 page_free(void *start, unsigned int len)
28 {
29   ASSERT(!(len & (CPU_PAGE_SIZE-1)));
30   ASSERT(!((uintptr_t) start & (CPU_PAGE_SIZE-1)));
31   munmap(start, len);
32 }
33
34 void *
35 page_realloc(void *start, unsigned int old_len, unsigned int new_len)
36 {
37   void *p = page_alloc(new_len);
38   memcpy(p, start, MIN(old_len, new_len));
39   page_free(start, old_len);
40   return p;
41 }
42
43 static unsigned int
44 big_round(unsigned int len)
45 {
46   return ALIGN_TO(len, CPU_PAGE_SIZE);
47 }
48
49 void *
50 big_alloc(unsigned int len)
51 {
52   len = big_round(len);
53 #ifdef CONFIG_DEBUG
54   len += 2*CPU_PAGE_SIZE;
55 #endif
56   byte *p = page_alloc(len);
57 #ifdef CONFIG_DEBUG
58   mprotect(p, CPU_PAGE_SIZE, PROT_NONE);
59   mprotect(p+len-CPU_PAGE_SIZE, CPU_PAGE_SIZE, PROT_NONE);
60   p += CPU_PAGE_SIZE;
61 #endif
62   return p;
63 }
64
65 void
66 big_free(void *start, unsigned int len)
67 {
68   byte *p = start;
69   len = big_round(len);
70 #ifdef CONFIG_DEBUG
71   p -= CPU_PAGE_SIZE;
72   len += 2*CPU_PAGE_SIZE;
73 #endif
74   page_free(start, len);
75 }
76
77 #ifdef TEST
78
79 int main(void)
80 {
81   byte *p = big_alloc(123456);
82   // p[-1] = 1;
83   big_free(p, 123456);
84   return 0;
85 }
86
87 #endif