Bug #5901 » bad-patch-never-apply.diff
gc.c (working copy) | ||
---|---|---|
#if defined _WIN32 || defined __CYGWIN__
|
||
#include <windows.h>
|
||
#elif defined(__OpenBSD__)
|
||
/* workaround for OpenBSD broken posix_memalign() */
|
||
#include <sys/mman.h>
|
||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||
#elif defined(HAVE_MEMALIGN)
|
||
#include <malloc.h>
|
||
... | ... | |
}
|
||
}
|
||
#if defined(__OpenBSD__)
|
||
/* workaround for OpenBSD broken posix_memalign() */
|
||
static st_table *am_size_table = NULL;
|
||
#endif
|
||
static void *
|
||
aligned_malloc(size_t alignment, size_t size)
|
||
{
|
||
... | ... | |
res = __mingw_aligned_malloc(size, alignment);
|
||
#elif _WIN32 || defined __CYGWIN__
|
||
res = _aligned_malloc(size, alignment);
|
||
#elif defined(__OpenBSD__)
|
||
/* OpenBSD posix_memalign() is broken. Quoting BUGS in manual:
|
||
* "Only alignments up to the page size can be specified."
|
||
* This workaround assumes that
|
||
* 1. Ruby wants large alignment and large size.
|
||
* 2. OpenBSD mmap() tends to return random addresses.
|
||
* 3. OpenBSD mmap() tends to obey address hints. */
|
||
{
|
||
size_t mask;
|
||
int tries;
|
||
void *target;
|
||
mask = alignment - 1;
|
||
if (alignment & mask)
|
||
return NULL; /* alignment is not power of 2 */
|
||
tries = 10;
|
||
while (tries--) {
|
||
/* find a random place in memory */
|
||
target = mmap(NULL, 1, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
|
||
if (target == NULL)
|
||
return NULL;
|
||
munmap(target, 1);
|
||
/* align target */
|
||
target = (void *)((size_t)target & ~mask);
|
||
res = mmap(target, size, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
|
||
if (res == target) {
|
||
/* success! */
|
||
if (!am_size_table)
|
||
am_size_table = st_init_numtable();
|
||
st_insert(am_size_table, (st_data_t)res, size);
|
||
return res;
|
||
}
|
||
if (res != MAP_FAILED)
|
||
munmap(res, size);
|
||
}
|
||
return NULL; /* no more tries */
|
||
}
|
||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||
if (posix_memalign(&res, alignment, size) == 0) {
|
||
return res;
|
||
... | ... | |
__mingw_aligned_free(ptr);
|
||
#elif _WIN32 || defined __CYGWIN__
|
||
_aligned_free(ptr);
|
||
#elif defined(__OpenBSD__)
|
||
/* workaround for OpenBSD broken posix_memalign() */
|
||
{
|
||
st_data_t res, val;
|
||
res = (st_data_t)ptr;
|
||
if (am_size_table && st_delete(am_size_table, &res, &val))
|
||
munmap(ptr, (size_t)val);
|
||
}
|
||
#else
|
||
free(ptr);
|
||
#endif
|