187 size_t newcap |
188 size_t newcap |
188 ) { |
189 ) { |
189 if (newcap <= buffer->capacity) { |
190 if (newcap <= buffer->capacity) { |
190 return 0; |
191 return 0; |
191 } |
192 } |
|
193 |
|
194 unsigned long pagesize = sysconf(_SC_PAGESIZE); |
|
195 // if page size is larger than 64 KB - for some reason - truncate to 64 KB |
|
196 if (pagesize > 65536) pagesize = 65536; |
|
197 if (newcap < pagesize) { |
|
198 // when smaller as one page, map to the next power of two |
|
199 newcap--; |
|
200 newcap |= newcap >> 1; |
|
201 newcap |= newcap >> 2; |
|
202 newcap |= newcap >> 4; |
|
203 // last operation only needed for pages larger 4096 bytes |
|
204 // but if/else would be more expensive than just doing this |
|
205 newcap |= newcap >> 8; |
|
206 newcap++; |
|
207 } else { |
|
208 // otherwise, map to a multiple of the page size |
|
209 newcap -= newcap % pagesize; |
|
210 newcap += pagesize; |
|
211 // note: if newcap is already page aligned, |
|
212 // this gives a full additional page (which is good) |
|
213 } |
|
214 |
192 |
215 |
193 const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND; |
216 const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND; |
194 if (buffer->flags & force_copy_flags) { |
217 if (buffer->flags & force_copy_flags) { |
195 void *newspace = cxMalloc(buffer->allocator, newcap); |
218 void *newspace = cxMalloc(buffer->allocator, newcap); |
196 if (NULL == newspace) return -1; |
219 if (NULL == newspace) return -1; |