| 176 | } |
| 177 | |
| 178 | void * |
| 179 | pages_map(void *addr, size_t size, size_t alignment, bool *commit) { |
| 180 | assert(alignment >= PAGE); |
| 181 | assert(ALIGNMENT_ADDR2BASE(addr, alignment) == addr); |
| 182 | |
| 183 | /* |
| 184 | * Ideally, there would be a way to specify alignment to mmap() (like |
| 185 | * NetBSD has), but in the absence of such a feature, we have to work |
| 186 | * hard to efficiently create aligned mappings. The reliable, but |
| 187 | * slow method is to create a mapping that is over-sized, then trim the |
| 188 | * excess. However, that always results in one or two calls to |
| 189 | * os_pages_unmap(), and it can leave holes in the process's virtual |
| 190 | * memory map if memory grows downward. |
| 191 | * |
| 192 | * Optimistically try mapping precisely the right amount before falling |
| 193 | * back to the slow method, with the expectation that the optimistic |
| 194 | * approach works most of the time. |
| 195 | */ |
| 196 | |
| 197 | void *ret = os_pages_map(addr, size, os_page, commit); |
| 198 | if (ret == NULL || ret == addr) { |
| 199 | return ret; |
| 200 | } |
| 201 | assert(addr == NULL); |
| 202 | if (ALIGNMENT_ADDR2OFFSET(ret, alignment) != 0) { |
| 203 | os_pages_unmap(ret, size); |
| 204 | return pages_map_slow(size, alignment, commit); |
| 205 | } |
| 206 | |
| 207 | assert(PAGE_ADDR2BASE(ret) == ret); |
| 208 | return ret; |
| 209 | } |
| 210 | |
| 211 | void |
| 212 | pages_unmap(void *addr, size_t size) { |
no test coverage detected