ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/emman.c
Revision: 1.8
Committed: Tue Jun 25 03:35:01 2019 UTC (4 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rxvt-unicode-rel-9_29, rxvt-unicode-rel-9_26, rxvt-unicode-rel-9_25, rxvt-unicode-rel-9_30, HEAD
Changes since 1.7: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

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