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

# User Rev Content
1 sf-exg 1.4 /* 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 sf-exg 1.5 # if __STDC_VERSION__ >= 199901L
9 sf-exg 1.4 # define _XOPEN_SOURCE 600
10     # else
11     # define _XOPEN_SOURCE 500
12     # endif
13     #endif
14    
15 root 1.1 #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 sf-exg 1.3 return realloc (ptr, new_size);
133 root 1.1 #endif
134     }
135    
136     void
137     chunk_free (void *ptr, size_t size)
138     {
139     #if USE_MMAP
140 root 1.2 /* we assume the OS never mmaps at address 0 */
141     if (ptr)
142     munmap (ptr, size);
143 root 1.1 #else
144     return free (ptr);
145     #endif
146     }
147