ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/emman.c
Revision: 1.6
Committed: Thu Oct 30 21:55:15 2014 UTC (9 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

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