aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/memorypool.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/memorypool.c')
-rw-r--r--src/microhttpd/memorypool.c87
1 files changed, 69 insertions, 18 deletions
diff --git a/src/microhttpd/memorypool.c b/src/microhttpd/memorypool.c
index a6053fb2..5067e950 100644
--- a/src/microhttpd/memorypool.c
+++ b/src/microhttpd/memorypool.c
@@ -35,6 +35,14 @@
35#ifdef _WIN32 35#ifdef _WIN32
36#include <windows.h> 36#include <windows.h>
37#endif 37#endif
38#ifdef HAVE_SYSCONF
39#include <unistd.h>
40#if defined(_SC_PAGE_SIZE)
41#define MHD_SC_PAGESIZE _SC_PAGE_SIZE
42#elif defined(_SC_PAGESIZE)
43#define MHD_SC_PAGESIZE _SC_PAGESIZE
44#endif /* _SC_PAGESIZE */
45#endif /* HAVE_SYSCONF */
38 46
39/* define MAP_ANONYMOUS for Mac OS X */ 47/* define MAP_ANONYMOUS for Mac OS X */
40#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) 48#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
@@ -56,6 +64,40 @@
56 */ 64 */
57#define ROUND_TO_ALIGN(n) (((n)+(ALIGN_SIZE-1)) / (ALIGN_SIZE) * (ALIGN_SIZE)) 65#define ROUND_TO_ALIGN(n) (((n)+(ALIGN_SIZE-1)) / (ALIGN_SIZE) * (ALIGN_SIZE))
58 66
67#if defined(PAGE_SIZE)
68#define MHD_DEF_PAGE_SIZE_ PAGE_SIZE
69#elif defined(PAGESIZE)
70#define MHD_DEF_PAGE_SIZE_ PAGE_SIZE
71#else /* ! PAGESIZE */
72#define MHD_DEF_PAGE_SIZE_ (4096)
73#endif /* ! PAGESIZE */
74
75/**
76 * Size of memory page
77 */
78static size_t MHD_sys_page_size_ = MHD_DEF_PAGE_SIZE_; /* Default fallback value */
79
80/**
81 * Initilise values for memory pools
82 */
83void
84MHD_init_mem_pools_ (void)
85{
86#ifdef MHD_SC_PAGESIZE
87 long result;
88 result = sysconf (MHD_SC_PAGESIZE);
89 if (-1 != result)
90 MHD_sys_page_size_ = (size_t) result;
91 else
92 MHD_sys_page_size_ = MHD_DEF_PAGE_SIZE_;
93#elif defined(_WIN32)
94 SYSTEM_INFO si;
95 GetSystemInfo (&si);
96 MHD_sys_page_size_ = (size_t)si.dwPageSize;
97#else
98 MHD_sys_page_size_ = MHD_DEF_PAGE_SIZE_;
99#endif /* _WIN32 */
100}
59 101
60/** 102/**
61 * Handle for a memory pool. Pools are not reentrant and must not be 103 * Handle for a memory pool. Pools are not reentrant and must not be
@@ -101,34 +143,41 @@ struct MemoryPool *
101MHD_pool_create (size_t max) 143MHD_pool_create (size_t max)
102{ 144{
103 struct MemoryPool *pool; 145 struct MemoryPool *pool;
146 size_t alloc_size;
104 147
105 max = ROUND_TO_ALIGN(max);
106 pool = malloc (sizeof (struct MemoryPool)); 148 pool = malloc (sizeof (struct MemoryPool));
107 if (NULL == pool) 149 if (NULL == pool)
108 return NULL; 150 return NULL;
109#if defined(MAP_ANONYMOUS) || defined(_WIN32) 151#if defined(MAP_ANONYMOUS) || defined(_WIN32)
110 if (max <= 32 * 1024) 152 if ( (max <= 32 * 1024) ||
153 (max < MHD_sys_page_size_ * 4 / 3) )
111 pool->memory = MAP_FAILED; 154 pool->memory = MAP_FAILED;
112 else 155 else
156 {
157 /* Round up allocation to page granularity. */
158 alloc_size = max + MHD_sys_page_size_ - 1;
159 alloc_size -= alloc_size % MHD_sys_page_size_;
113#if defined(MAP_ANONYMOUS) && !defined(_WIN32) 160#if defined(MAP_ANONYMOUS) && !defined(_WIN32)
114 pool->memory = mmap (NULL, 161 pool->memory = mmap (NULL,
115 max, 162 alloc_size,
116 PROT_READ | PROT_WRITE, 163 PROT_READ | PROT_WRITE,
117 MAP_PRIVATE | MAP_ANONYMOUS, 164 MAP_PRIVATE | MAP_ANONYMOUS,
118 -1, 165 -1,
119 0); 166 0);
120#elif defined(_WIN32) 167#elif defined(_WIN32)
121 pool->memory = VirtualAlloc (NULL, 168 pool->memory = VirtualAlloc (NULL,
122 max, 169 alloc_size,
123 MEM_COMMIT | MEM_RESERVE, 170 MEM_COMMIT | MEM_RESERVE,
124 PAGE_READWRITE); 171 PAGE_READWRITE);
125#endif 172#endif /* _WIN32 */
126#else 173 }
174#else /* ! _WIN32 && ! MAP_ANONYMOUS */
127 pool->memory = MAP_FAILED; 175 pool->memory = MAP_FAILED;
128#endif 176#endif /* ! _WIN32 && ! MAP_ANONYMOUS */
129 if (MAP_FAILED == pool->memory) 177 if (MAP_FAILED == pool->memory)
130 { 178 {
131 pool->memory = malloc (max); 179 alloc_size = ROUND_TO_ALIGN(max);
180 pool->memory = malloc (alloc_size);
132 if (NULL == pool->memory) 181 if (NULL == pool->memory)
133 { 182 {
134 free (pool); 183 free (pool);
@@ -136,13 +185,15 @@ MHD_pool_create (size_t max)
136 } 185 }
137 pool->is_mmap = false; 186 pool->is_mmap = false;
138 } 187 }
188#if defined(MAP_ANONYMOUS) || defined(_WIN32)
139 else 189 else
140 { 190 {
141 pool->is_mmap = true; 191 pool->is_mmap = true;
142 } 192 }
193#endif /* _WIN32 || MAP_ANONYMOUS */
143 pool->pos = 0; 194 pool->pos = 0;
144 pool->end = max; 195 pool->end = alloc_size;
145 pool->size = max; 196 pool->size = alloc_size;
146 return pool; 197 return pool;
147} 198}
148 199