#include "unittest.h"
#include "util_pmem.h"
#include "file.h"
static void
swap_mappings(char **dest, char **src, size_t size, int fd)
{
char *d = *dest;
char *s = *src;
char *td, *ts;
MUNMAP(*src, size);
td = MMAP(s, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
MUNMAP(*dest, size);
*dest = td;
ts = MMAP(d, size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS,
-1, 0);
*src = ts;
}
static void
do_memcpy(int fd, char *dest, int dest_off, char *src, int src_off,
size_t bytes, char *file_name)
{
void *ret;
char *buf = MALLOC(bytes);
memset(buf, 0, bytes);
memset(dest, 0, bytes);
memset(src, 0, bytes);
util_persist_auto(util_fd_is_device_dax(fd), src, bytes);
memset(src, 0x5A, bytes / 4);
util_persist_auto(util_fd_is_device_dax(fd), src, bytes / 4);
memset(src + bytes / 4, 0x46, bytes / 4);
util_persist_auto(util_fd_is_device_dax(fd), src + bytes / 4,
bytes / 4);
ret = pmem_memcpy_persist(dest + dest_off, dest + dest_off, bytes / 2);
UT_ASSERTeq(ret, dest + dest_off);
UT_ASSERTeq(*(char *)(dest + dest_off), 0);
ret = pmem_memcpy_persist(dest + dest_off, src, 0);
UT_ASSERTeq(ret, dest + dest_off);
UT_ASSERTeq(*(char *)(dest + dest_off), 0);
ret = pmem_memcpy_persist(dest + dest_off, src + src_off, bytes / 2);
UT_ASSERTeq(ret, dest + dest_off);
if (memcmp(src + src_off, dest + dest_off, bytes / 2))
UT_ERR("%s: first %zu bytes do not match",
file_name, bytes / 2);
LSEEK(fd, (os_off_t)dest_off, SEEK_SET);
if (READ(fd, buf, bytes / 2) == bytes / 2) {
if (memcmp(src + src_off, buf, bytes / 2))
UT_ERR("%s: first %zu bytes do not match",
file_name, bytes / 2);
}
FREE(buf);
}
int
main(int argc, char *argv[])
{
int fd;
char *dest;
char *src;
size_t mapped_len;
START(argc, argv, "pmem_memcpy");
if (argc != 5)
UT_FATAL("usage: %s file srcoff destoff length", argv[0]);
fd = OPEN(argv[1], O_RDWR);
int dest_off = atoi(argv[2]);
int src_off = atoi(argv[3]);
size_t bytes = strtoul(argv[4], NULL, 0);
dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL);
if (dest == NULL)
UT_FATAL("!could not map file: %s", argv[1]);
src = MMAP(dest + mapped_len, mapped_len, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if (src <= dest) {
swap_mappings(&dest, &src, mapped_len, fd);
if (src <= dest)
UT_ERR("cannot map files in memory order");
}
memset(dest, 0, (2 * bytes));
util_persist_auto(util_fd_is_device_dax(fd), dest, 2 * bytes);
memset(src, 0, (2 * bytes));
do_memcpy(fd, dest, dest_off, src, src_off, bytes, argv[1]);
swap_mappings(&dest, &src, mapped_len, fd);
if (dest <= src) {
UT_ERR("cannot map files in memory order");
}
do_memcpy(fd, dest, dest_off, src, src_off, bytes, argv[1]);
MUNMAP(dest, mapped_len);
MUNMAP(src, mapped_len);
CLOSE(fd);
DONE(NULL);
}