ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/emman.c
Revision: 1.5
Committed: Tue Oct 28 09:10:33 2014 UTC (9 years, 6 months ago) by sf-exg
Content type: text/plain
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
Simplify.

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 #endif
49
50 size_t
51 chunk_round (size_t size)
52 {
53 BOOT_PAGESIZE;
54
55 return (size + (PAGESIZE - 1)) & ~(size_t)(PAGESIZE - 1);
56 }
57
58 size_t
59 chunk_fit (size_t header, size_t element_size, size_t max_increase)
60 {
61 uint32_t fill, maximum_fill = 0;
62 size_t minimum_size;
63
64 max_increase += header + element_size;
65
66 BOOT_PAGESIZE;
67
68 do
69 {
70 header += element_size;
71
72 fill = (uint32_t)header & (PAGESIZE - 1);
73
74 if (fill >= maximum_fill)
75 {
76 maximum_fill = fill + 16; /* size increase results in at least 16 bytes improvement */
77 minimum_size = header;
78 }
79 }
80 while (header < max_increase);
81
82 return minimum_size;
83 }
84
85 void *
86 chunk_alloc (size_t size, int populate)
87 {
88 #if USE_MMAP
89 void *ptr = MAP_FAILED;
90
91 #ifdef MAP_POPULATE
92 if (populate & 1)
93 ptr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
94 #endif
95
96 if (ptr == MAP_FAILED)
97 ptr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
98
99 if (ptr == MAP_FAILED)
100 return 0;
101
102 return ptr;
103 #else
104 return malloc (size);
105 #endif
106 }
107
108 void *
109 chunk_realloc (void *ptr, size_t old_size, size_t new_size)
110 {
111 #if USE_MMAP
112 #ifdef MREMAP_MAYMOVE /* requires _GNU_SOURCE */
113 void *ptr2 = mremap (ptr, old_size, new_size, MREMAP_MAYMOVE);
114
115 if (ptr2 == MAP_FAILED)
116 return 0;
117
118 return ptr2;
119 #else
120 void *ptr2 = chunk_alloc (new_size, 0);
121
122 if (!ptr2)
123 return ptr2;
124
125 /* TODO: prepopulate old_size pages instead of faulting them in */
126
127 memcpy (ptr2, ptr, old_size);
128 munmap (ptr, old_size);
129 return ptr2;
130 #endif
131 #else
132 return realloc (ptr, new_size);
133 #endif
134 }
135
136 void
137 chunk_free (void *ptr, size_t size)
138 {
139 #if USE_MMAP
140 /* we assume the OS never mmaps at address 0 */
141 if (ptr)
142 munmap (ptr, size);
143 #else
144 return free (ptr);
145 #endif
146 }
147