ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/emman.c
Revision: 1.3
Committed: Sun Jul 14 08:42:51 2013 UTC (10 years, 10 months ago) by sf-exg
Content type: text/plain
Branch: MAIN
CVS Tags: rxvt-unicode-rel-9_19, rxvt-unicode-rel-9_20
Changes since 1.2: +1 -1 lines
Log Message:
Fix build with USE_MMAP undefined.

File Contents

# User Rev Content
1 root 1.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 sf-exg 1.3 return realloc (ptr, new_size);
122 root 1.1 #endif
123     }
124    
125     void
126     chunk_free (void *ptr, size_t size)
127     {
128     #if USE_MMAP
129 root 1.2 /* we assume the OS never mmaps at address 0 */
130     if (ptr)
131     munmap (ptr, size);
132 root 1.1 #else
133     return free (ptr);
134     #endif
135     }
136