ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/emman.c
Revision: 1.1
Committed: Thu Jun 28 15:19:15 2012 UTC (11 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Log Message:
add emman.h/c and use it for scrollback

File Contents

# Content
1 #include "emman.h"
2
3 #include <ecb.h>
4
5 #include <string.h>
6
7 #ifndef _WIN32
8 # include <unistd.h>
9 #endif
10
11 #if _POSIX_MAPPED_FILES
12 # define USE_MMAP 1
13 # ifdef __linux__
14 # define _GNU_SOURCE
15 # endif
16 # include <sys/mman.h>
17 # ifndef MAP_FAILED
18 # define MAP_FAILED ((void *)-1)
19 # endif
20 # ifndef MAP_ANONYMOUS
21 # ifdef MAP_ANON
22 # define MAP_ANONYMOUS MAP_ANON
23 # else
24 # undef USE_MMAP
25 # endif
26 # endif
27 # include <limits.h>
28 # ifndef PAGESIZE
29 static uint32_t pagesize;
30 # define BOOT_PAGESIZE if (!pagesize) pagesize = sysconf (_SC_PAGESIZE)
31 # define PAGESIZE pagesize
32 # else
33 # define BOOT_PAGESIZE
34 # endif
35 #else
36 # define PAGESIZE 1
37 #endif
38
39 size_t
40 chunk_round (size_t size)
41 {
42 BOOT_PAGESIZE;
43
44 return (size + (PAGESIZE - 1)) & ~(size_t)(PAGESIZE - 1);
45 }
46
47 size_t
48 chunk_fit (size_t header, size_t element_size, size_t max_increase)
49 {
50 uint32_t fill, maximum_fill = 0;
51 size_t minimum_size;
52
53 max_increase += header + element_size;
54
55 BOOT_PAGESIZE;
56
57 do
58 {
59 header += element_size;
60
61 fill = (uint32_t)header & (PAGESIZE - 1);
62
63 if (fill >= maximum_fill)
64 {
65 maximum_fill = fill + 16; /* size increase results in at least 16 bytes improvement */
66 minimum_size = header;
67 }
68 }
69 while (header < max_increase);
70
71 return minimum_size;
72 }
73
74 void *
75 chunk_alloc (size_t size, int populate)
76 {
77 #if USE_MMAP
78 void *ptr = MAP_FAILED;
79
80 #ifdef MAP_POPULATE
81 if (populate & 1)
82 ptr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
83 #endif
84
85 if (ptr == MAP_FAILED)
86 ptr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
87
88 if (ptr == MAP_FAILED)
89 return 0;
90
91 return ptr;
92 #else
93 return malloc (size);
94 #endif
95 }
96
97 void *
98 chunk_realloc (void *ptr, size_t old_size, size_t new_size)
99 {
100 #if USE_MMAP
101 #ifdef MREMAP_MAYMOVE /* requires _GNU_SOURCE */
102 void *ptr2 = mremap (ptr, old_size, new_size, MREMAP_MAYMOVE);
103
104 if (ptr2 == MAP_FAILED)
105 return 0;
106
107 return ptr2;
108 #else
109 void *ptr2 = chunk_alloc (new_size, 0);
110
111 if (!ptr2)
112 return ptr2;
113
114 /* TODO: prepopulate old_size pages instead of faulting them in */
115
116 memcpy (ptr2, ptr, old_size);
117 munmap (ptr, old_size);
118 return ptr2;
119 #endif
120 #else
121 return realloc (ptr, size);
122 #endif
123 }
124
125 void
126 chunk_free (void *ptr, size_t size)
127 {
128 #if USE_MMAP
129 munmap (ptr, size);
130 #else
131 return free (ptr);
132 #endif
133 }
134