os: drop unnecessary memcpy in wl_os_mremap_maymove

FreeBSD doesn't support mremap [1], so we have a fallback
implementation based on munmap+mmap. We memcpy from the old memory
region to the new one, however this is unnecessary because the new
mapping references the same file as the old one.

Use msync to make sure any pending write is flushed to the underlying
file before we map the new region.

[1]: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=59912

Signed-off-by: Simon Ser <contact@emersion.fr>
This commit is contained in:
Simon Ser 2022-03-29 10:16:17 +02:00
parent 6c424e9d4c
commit ff972f85b2

View file

@ -231,21 +231,22 @@ wl_os_mremap_maymove(int fd, void *old_data, ssize_t *old_size,
ssize_t new_size, int prot, int flags) ssize_t new_size, int prot, int flags)
{ {
void *result; void *result;
/*
* We could try mapping a new block immediately after the current one /* Make sure any pending write is flushed. */
if (msync(old_data, *old_size, MS_SYNC) != 0)
return MAP_FAILED;
/* We could try mapping a new block immediately after the current one
* with MAP_FIXED, however that is not guaranteed to work and breaks * with MAP_FIXED, however that is not guaranteed to work and breaks
* on CHERI-enabled architectures since the data pointer will still * on CHERI-enabled architectures since the data pointer will still
* have the bounds of the previous allocation. As this is not a * have the bounds of the previous allocation.
* performance-critical path, we always map a new region and copy the
* old data to the new region.
*/ */
result = mmap(NULL, new_size, prot, flags, fd, 0); result = mmap(NULL, new_size, prot, flags, fd, 0);
if (result != MAP_FAILED) { if (result == MAP_FAILED)
/* Copy the data over and unmap the old mapping. */ return MAP_FAILED;
memcpy(result, old_data, *old_size);
if (munmap(old_data, *old_size) == 0) { if (munmap(old_data, *old_size) == 0)
*old_size = 0; /* successfully unmapped old data. */ *old_size = 0;
}
}
return result; return result;
} }