/* * pool_set_part_copy -- make a copy of the poolset part */ int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart, int overwrite) { LOG(3, "dpart %p spart %p", dpart, spart); int result = 0; util_stat_t stat_buf; if (util_stat(spart->path, &stat_buf)) { ERR("!util_stat"); return -1; } size_t smapped = 0; void *saddr = pmem_map_file(spart->path, 0, 0, S_IREAD, &smapped, NULL); if (!saddr) return -1; size_t dmapped = 0; int is_pmem; void *daddr; if (!access(dpart->path, F_OK)) { if (!overwrite) { errno = EEXIST; result = -1; goto out_sunmap; } daddr = pmem_map_file(dpart->path, 0, 0, S_IWRITE, &dmapped, &is_pmem); } else { if (errno == ENOENT) { errno = 0; daddr = pmem_map_file(dpart->path, dpart->filesize, PMEM_FILE_CREATE | PMEM_FILE_EXCL, stat_buf.st_mode, &dmapped, &is_pmem); } else { result = -1; goto out_sunmap; } } if (!daddr) { result = -1; goto out_sunmap; } if (is_pmem) { pmem_memcpy_persist(daddr, saddr, smapped); } else { memcpy(daddr, saddr, smapped); PERSIST_GENERIC(dpart->is_dax, daddr, smapped); } pmem_unmap(daddr, dmapped); out_sunmap: pmem_unmap(saddr, smapped); return result; }
int main(int argc, char *argv[]) { char *pmemaddr; size_t mapped_len; int is_pmem; /* create a pmem file and memory map it */ if ((pmemaddr = pmem_map_file(PATH, PMEM_LEN, PMEM_FILE_CREATE, 0666, &mapped_len, &is_pmem)) == NULL) { perror("pmem_map_file"); exit(1); } /* store a string to the persistent memory */ strcpy(pmemaddr, "hello, persistent memory"); /* flush above strcpy to persistence */ if (is_pmem) pmem_persist(pmemaddr, mapped_len); else pmem_msync(pmemaddr, mapped_len); /* * Delete the mappings. The region is also * automatically unmapped when the process is * terminated. */ pmem_unmap(pmemaddr, mapped_len); }
/* * pool_set_part_copy -- make a copy of the poolset part */ int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart) { LOG(3, "dpart %p spart %p", dpart, spart); int result = 0; util_stat_t stat_buf; if (util_stat(spart->path, &stat_buf)) { ERR("!util_stat"); return -1; } size_t smapped = 0; void *saddr = pmem_map_file(spart->path, 0, 0, S_IREAD, &smapped, NULL); if (!saddr) return -1; size_t dmapped = 0; int is_pmem; void *daddr = pmem_map_file(dpart->path, dpart->filesize, PMEM_FILE_CREATE | PMEM_FILE_EXCL, stat_buf.st_mode, &dmapped, &is_pmem); if (!daddr) { result = -1; goto out_sunmap; } if (is_pmem) { pmem_memcpy_persist(daddr, saddr, smapped); } else { memcpy(daddr, saddr, smapped); pmem_msync(daddr, smapped); } pmem_unmap(daddr, dmapped); out_sunmap: pmem_unmap(saddr, smapped); return result; }
int main(int argc, char *argv[]) { int srcfd; char buf[BUF_LEN]; char *pmemaddr; size_t mapped_len; int is_pmem; int cc; if (argc != 3) { fprintf(stderr, "usage: %s src-file dst-file\n", argv[0]); exit(1); } /* open src-file */ if ((srcfd = open(argv[1], O_RDONLY)) < 0) { perror(argv[1]); exit(1); } /* create a pmem file and memory map it */ if ((pmemaddr = pmem_map_file(argv[2], BUF_LEN, PMEM_FILE_CREATE|PMEM_FILE_EXCL, 0666, &mapped_len, &is_pmem)) == NULL) { perror("pmem_map_file"); exit(1); } /* read up to BUF_LEN from srcfd */ if ((cc = read(srcfd, buf, BUF_LEN)) < 0) { pmem_unmap(pmemaddr, mapped_len); perror("read"); exit(1); } /* write it to the pmem */ if (is_pmem) { pmem_memcpy_persist(pmemaddr, buf, cc); } else { memcpy(pmemaddr, buf, cc); pmem_msync(pmemaddr, cc); } close(srcfd); pmem_unmap(pmemaddr, mapped_len); exit(0); }
int main(int argc, char *argv[]) { int srcfd; struct stat stbuf; char *pmemaddr; size_t mapped_len; int is_pmem; if (argc != 3) { fprintf(stderr, "usage: %s src-file dst-file\n", argv[0]); exit(1); } /* open src-file */ if ((srcfd = open(argv[1], O_RDONLY)) < 0) { perror(argv[1]); exit(1); } /* find the size of the src-file */ if (fstat(srcfd, &stbuf) < 0) { perror("fstat"); exit(1); } /* create a pmem file and memory map it */ if ((pmemaddr = pmem_map_file(argv[2], stbuf.st_size, PMEM_FILE_CREATE|PMEM_FILE_EXCL, 0666, &mapped_len, &is_pmem)) == NULL) { perror("pmem_map_file"); exit(1); } /* determine if range is true pmem, call appropriate copy routine */ if (is_pmem) do_copy_to_pmem(pmemaddr, srcfd, stbuf.st_size); else do_copy_to_non_pmem(pmemaddr, srcfd, stbuf.st_size); close(srcfd); pmem_unmap(pmemaddr, mapped_len); exit(0); }
static PMEMobjpool * pmemobj_open_mock(const char *fname) { size_t size; int is_pmem; void *addr = pmem_map_file(fname, 0, 0, 0, &size, &is_pmem); if (!addr) { UT_OUT("!%s: pmem_map_file", fname); return NULL; } UT_ASSERT(size > PMEMOBJ_POOL_HDR_SIZE); PMEMobjpool *pop = (PMEMobjpool *)addr; VALGRIND_REMOVE_PMEM_MAPPING((char *)addr + sizeof(pop->hdr), 4096); pop->addr = addr; pop->size = size; pop->is_pmem = is_pmem; pop->rdonly = 0; if (pop->is_pmem) { pop->persist_local = pmem_persist; pop->flush_local = pmem_flush; pop->drain_local = pmem_drain; } else { pop->persist_local = (persist_local_fn)pmem_msync; pop->flush_local = (persist_local_fn)pmem_msync; pop->drain_local = pmem_drain_nop; } pop->persist = obj_persist; pop->flush = obj_flush; pop->drain = obj_drain; pop->redo = redo_log_config_new(pop->addr, (redo_persist_fn)pop->persist, (redo_flush_fn)pop->flush, redo_log_check_offset, pop, pop, REDO_NUM_ENTRIES); return pop; }
static PMEMobjpool * pmemobj_open_mock(const char *fname, size_t redo_size) { size_t size; int is_pmem; void *addr = pmem_map_file(fname, 0, 0, 0, &size, &is_pmem); if (!addr) { UT_OUT("!%s: pmem_map_file", fname); return NULL; } UT_ASSERT(size >= PMEMOBJ_POOL_HDR_SIZE + redo_size); PMEMobjpool *pop = (PMEMobjpool *)addr; VALGRIND_REMOVE_PMEM_MAPPING((char *)addr + sizeof(pop->hdr), 4096); pop->addr = addr; pop->is_pmem = is_pmem; pop->rdonly = 0; pop->set = MALLOC(sizeof(*pop->set)); pop->set->poolsize = size; if (pop->is_pmem) { pop->persist_local = pmem_persist; pop->flush_local = pmem_flush; pop->drain_local = pmem_drain; } else { pop->persist_local = obj_msync_nofail; pop->flush_local = obj_msync_nofail; pop->drain_local = pmem_drain_nop; } pop->p_ops.persist = obj_persist; pop->p_ops.flush = obj_flush; pop->p_ops.drain = obj_drain; pop->p_ops.base = pop; pop->heap_offset = PMEMOBJ_POOL_HDR_SIZE + redo_size; pop->heap_size = size - pop->heap_offset; pop->redo = redo_log_config_new(pop->addr, &pop->p_ops, redo_log_check_offset, pop, REDO_NUM_ENTRIES); return pop; }
int main(int argc, char *argv[]) { size_t mapped_len; char *dest; int is_pmem; START(argc, argv, "pmem_valgr_simple"); if (argc != 4) UT_FATAL("usage: %s file offset length", argv[0]); int dest_off = atoi(argv[2]); size_t bytes = strtoul(argv[3], NULL, 0); dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, &is_pmem); if (dest == NULL) UT_FATAL("!Could not mmap %s\n", argv[1]); /* these will not be made persistent */ *(int *)dest = 4; /* this will be made persistent */ uint64_t *tmp64dst = (void *)((uintptr_t)dest + 4096); *tmp64dst = 50; if (is_pmem) { pmem_persist(tmp64dst, sizeof(*tmp64dst)); } else { pmem_msync(tmp64dst, sizeof(*tmp64dst)); } uint16_t *tmp16dst = (void *)((uintptr_t)dest + 1024); *tmp16dst = 21; /* will appear as flushed/fenced in valgrind log */ pmem_flush(tmp16dst, sizeof(*tmp16dst)); /* shows strange behavior of memset in some cases */ memset(dest + dest_off, 0, bytes); pmem_unmap(dest, mapped_len); DONE(NULL); }
/* * init_pool -- map local pool file or allocate memory region */ static void init_pool(struct pool_entry *pool, const char *pool_path, const char *pool_size) { int ret = util_parse_size(pool_size, &pool->size); UT_ASSERTeq(ret, 0); if (strcmp(pool_path, "mem") == 0) { pool->pool = MALLOC(pool->size); pool->is_mem = 1; } else { pool->pool = pmem_map_file(pool_path, pool->size, PMEM_FILE_CREATE | PMEM_FILE_EXCL, 0666, &pool->size, NULL); UT_ASSERTne(pool->pool, NULL); pool->is_mem = 0; unlink(pool_path); } }
int main(int argc, char *argv[]) { START(argc, argv, "pmem_map_file"); int fd; void *addr; size_t mlen; size_t *mlenp; const char *path; unsigned long long len; int flags; unsigned mode; int is_pmem; int *is_pmemp; int use_mlen; int use_is_pmem; int err_code; if (argc < 8) UT_FATAL("usage: %s path len flags mode use_mlen " "use_is_pmem err_code...", argv[0]); for (int i = 1; i + 6 < argc; i += 7) { path = argv[i]; len = strtoull(argv[i + 1], NULL, 0); flags = parse_flags(argv[i + 2]); mode = STRTOU(argv[i + 3], NULL, 8); use_mlen = atoi(argv[i + 4]); use_is_pmem = atoi(argv[i + 5]); err_code = parse_err_code(argv[i + 6]); mlen = SIZE_MAX; if (use_mlen) mlenp = &mlen; else mlenp = NULL; if (use_is_pmem) is_pmemp = &is_pmem; else is_pmemp = NULL; UT_OUT("%s %lld %s %o %d %d %d", path, len, argv[i + 2], mode, use_mlen, use_is_pmem, err_code); addr = pmem_map_file(path, len, flags, mode, mlenp, is_pmemp); if (err_code != 0) { UT_ASSERTeq(errno, err_code); } if (addr == NULL) { UT_OUT("!pmem_map_file"); continue; } if (use_mlen) { UT_ASSERTne(mlen, SIZE_MAX); UT_OUT("mapped_len %zu", mlen); } else { mlen = len; } if (addr) { /* is_pmem must be true for device DAX */ int is_pmem_check = pmem_is_pmem(addr, mlen); UT_ASSERT(!is_dev_dax || is_pmem_check); /* check is_pmem returned from pmem_map_file */ if (use_is_pmem) UT_ASSERTeq(is_pmem, is_pmem_check); if ((flags & PMEM_FILE_TMPFILE) == 0 && !is_dev_dax) { fd = OPEN(argv[i], O_RDWR); if (!use_mlen) { os_stat_t stbuf; FSTAT(fd, &stbuf); mlen = (size_t)stbuf.st_size; } if (fd != -1) { do_check(fd, addr, mlen); (void) CLOSE(fd); } else { UT_OUT("!cannot open file: %s", argv[i]); } } else { UT_ASSERTeq(pmem_unmap(addr, mlen), 0); } } } DONE(NULL); }
/* * memset_init -- initialization function */ static int memset_init(struct benchmark *bench, struct benchmark_args *args) { assert(bench != nullptr); assert(args != nullptr); assert(args->opts != nullptr); int ret = 0; size_t size; size_t large; size_t little; size_t file_size = 0; int flags = 0; enum file_type type = util_file_get_type(args->fname); if (type == OTHER_ERROR) { fprintf(stderr, "could not check type of file %s\n", args->fname); return -1; } int (*warmup_func)(struct memset_bench *) = warmup_persist; auto *mb = (struct memset_bench *)malloc(sizeof(struct memset_bench)); if (!mb) { perror("malloc"); return -1; } mb->pargs = (struct memset_args *)args->opts; mb->pargs->chunk_size = args->dsize; enum operation_mode op_mode = parse_op_mode(mb->pargs->mode); if (op_mode == OP_MODE_UNKNOWN) { fprintf(stderr, "Invalid operation mode argument '%s'\n", mb->pargs->mode); ret = -1; goto err_free_mb; } size = MAX_OFFSET + mb->pargs->chunk_size; large = size * args->n_ops_per_thread * args->n_threads; little = size * args->n_threads; mb->fsize = (op_mode == OP_MODE_STAT) ? little : large; /* initialize offsets[] array depending on benchmark args */ if (init_offsets(args, mb, op_mode) < 0) { ret = -1; goto err_free_mb; } /* initialize memset() value */ mb->const_b = CONST_B; if (type != TYPE_DEVDAX) { file_size = mb->fsize; flags = PMEM_FILE_CREATE | PMEM_FILE_EXCL; } /* create a pmem file and memory map it */ if ((mb->pmem_addr = pmem_map_file(args->fname, file_size, flags, args->fmode, nullptr, nullptr)) == nullptr) { perror(args->fname); ret = -1; goto err_free_offsets; } if (mb->pargs->memset) { if (mb->pargs->persist && mb->pargs->msync) { fprintf(stderr, "Invalid benchmark parameters: persist and msync cannot be specified together\n"); ret = -1; goto err_free_offsets; } if (mb->pargs->persist) { mb->func_op = libc_memset_persist; } else if (mb->pargs->msync) { mb->func_op = libc_memset_msync; warmup_func = warmup_msync; } else { mb->func_op = libc_memset; } } else { mb->func_op = (mb->pargs->persist) ? libpmem_memset_persist : libpmem_memset_nodrain; } if (!mb->pargs->no_warmup && type != TYPE_DEVDAX) { ret = warmup_func(mb); if (ret) { perror("Pool warmup failed"); goto err_free_offsets; } } pmembench_set_priv(bench, mb); return ret; err_free_offsets: free(mb->offsets); err_free_mb: free(mb); return ret; }
/* * pmem_memcpy_init -- benchmark initialization * * Parses command line arguments, allocates persistent memory, and maps it. */ static int pmem_memcpy_init(struct benchmark *bench, struct benchmark_args *args) { assert(bench != NULL); assert(args != NULL); int ret = 0; struct pmem_bench *pmb = malloc(sizeof(struct pmem_bench)); assert(pmb != NULL); pmb->pargs = args->opts; assert(pmb->pargs != NULL); pmb->pargs->chunk_size = args->dsize; enum operation_type op_type; /* * Assign file and buffer size depending on the operation type * (READ from PMEM or WRITE to PMEM) */ if (assign_size(pmb, args, &op_type) != 0) { ret = -1; goto err_free_pmb; } if ((errno = posix_memalign( (void **) &pmb->buf, FLUSH_ALIGN, pmb->bsize)) != 0) { perror("posix_memalign"); ret = -1; goto err_free_pmb; } pmb->n_rand_offsets = args->n_ops_per_thread * args->n_threads; pmb->rand_offsets = malloc(pmb->n_rand_offsets * sizeof(*pmb->rand_offsets)); if (pmb->rand_offsets == NULL) { perror("malloc"); ret = -1; goto err_free_pmb; } for (size_t i = 0; i < pmb->n_rand_offsets; ++i) pmb->rand_offsets[i] = rand() % args->n_ops_per_thread; /* create a pmem file and memory map it */ if ((pmb->pmem_addr = pmem_map_file(args->fname, pmb->fsize, PMEM_FILE_CREATE|PMEM_FILE_EXCL, args->fmode, NULL, NULL)) == NULL) { perror(args->fname); ret = -1; goto err_free_buf; } if (op_type == OP_TYPE_READ) { pmb->src_addr = pmb->pmem_addr; pmb->dest_addr = pmb->buf; } else { pmb->src_addr = pmb->buf; pmb->dest_addr = pmb->pmem_addr; } /* set proper func_src() and func_dest() depending on benchmark args */ if ((pmb->func_src = assign_mode_func(pmb->pargs->src_mode)) == NULL) { fprintf(stderr, "wrong src_mode parameter -- '%s'", pmb->pargs->src_mode); ret = -1; goto err_unmap; } if ((pmb->func_dest = assign_mode_func(pmb->pargs->dest_mode)) == NULL) { fprintf(stderr, "wrong dest_mode parameter -- '%s'", pmb->pargs->dest_mode); ret = -1; goto err_unmap; } if (pmb->pargs->memcpy) { pmb->func_op = pmb->pargs->persist ? libc_memcpy_persist : libc_memcpy; } else { pmb->func_op = pmb->pargs->persist ? libpmem_memcpy_persist : libpmem_memcpy_nodrain; } pmembench_set_priv(bench, pmb); return 0; err_unmap: pmem_unmap(pmb->pmem_addr, pmb->fsize); err_free_buf: free(pmb->buf); err_free_pmb: free(pmb); return ret; }
int main(int argc, char *argv[]) { START(argc, argv, "pmreorder_simple"); util_init(); if ((argc != 3) || (strchr("gbcm", argv[1][0]) == NULL) || argv[1][1] != '\0') UT_FATAL("usage: %s g|b|c|m file", argv[0]); int fd = OPEN(argv[2], O_RDWR); size_t size; /* mmap and register in valgrind pmemcheck */ void *map = pmem_map_file(argv[2], 0, 0, 0, &size, NULL); UT_ASSERTne(map, NULL); struct three_field *structp = map; char opt = argv[1][0]; /* clear the struct to get a consistent start state for writing */ if (strchr("gb", opt)) pmem_memset_persist(structp, 0, sizeof(*structp)); else if (strchr("m", opt)) { /* set test values to log an inconsistent start state */ pmem_memset_persist(&structp->flag, 1, sizeof(int)); pmem_memset_persist(&structp->first_field, 0, sizeof(int) * 2); pmem_memset_persist(&structp->third_field, 1, sizeof(int)); /* clear the struct to get back a consistent start state */ pmem_memset_persist(structp, 0, sizeof(*structp)); } /* verify that DEFAULT_REORDER restores default engine */ VALGRIND_EMIT_LOG("PMREORDER_MARKER_CHANGE.BEGIN"); switch (opt) { case 'g': write_consistent(structp); break; case 'b': write_inconsistent(structp); break; case 'm': write_consistent(structp); break; case 'c': return check_consistency(structp); default: UT_FATAL("Unrecognized option %c", opt); } VALGRIND_EMIT_LOG("PMREORDER_MARKER_CHANGE.END"); /* check if undefined marker will not cause an issue */ VALGRIND_EMIT_LOG("PMREORDER_MARKER_UNDEFINED.BEGIN"); VALGRIND_EMIT_LOG("PMREORDER_MARKER_UNDEFINED.END"); CLOSE(fd); DONE(NULL); }
int main(int argc, char *argv[]) { int fd; size_t mapped_len; char *dest; char *dest1; char *ret; START(argc, argv, "pmem_memset"); if (argc != 4) UT_FATAL("usage: %s file offset length", argv[0]); fd = OPEN(argv[1], O_RDWR); /* open a pmem file and memory map it */ if ((dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL)) == NULL) UT_FATAL("!Could not mmap %s\n", argv[1]); int dest_off = atoi(argv[2]); size_t bytes = strtoul(argv[3], NULL, 0); char *buf = MALLOC(bytes); memset(dest, 0, bytes); util_persist_auto(util_fd_is_device_dax(fd), dest, bytes); dest1 = MALLOC(bytes); memset(dest1, 0, bytes); /* * This is used to verify that the value of what a non persistent * memset matches the outcome of the persistent memset. The * persistent memset will match the file but may not be the * correct or expected value. */ memset(dest1 + dest_off, 0x5A, bytes / 4); memset(dest1 + dest_off + (bytes / 4), 0x46, bytes / 4); /* Test the corner cases */ ret = pmem_memset_persist(dest + dest_off, 0x5A, 0); UT_ASSERTeq(ret, dest + dest_off); UT_ASSERTeq(*(char *)(dest + dest_off), 0); /* * Do the actual memset with persistence. */ ret = pmem_memset_persist(dest + dest_off, 0x5A, bytes / 4); UT_ASSERTeq(ret, dest + dest_off); ret = pmem_memset_persist(dest + dest_off + (bytes / 4), 0x46, bytes / 4); UT_ASSERTeq(ret, dest + dest_off + (bytes / 4)); if (memcmp(dest, dest1, bytes / 2)) UT_ERR("%s: first %zu bytes do not match", argv[1], bytes / 2); LSEEK(fd, (off_t)0, SEEK_SET); if (READ(fd, buf, bytes / 2) == bytes / 2) { if (memcmp(buf, dest, bytes / 2)) UT_ERR("%s: first %zu bytes do not match", argv[1], bytes / 2); } UT_ASSERTeq(pmem_unmap(dest, mapped_len), 0); FREE(dest1); FREE(buf); CLOSE(fd); DONE(NULL); }
/* * pool_set_part_copy -- make a copy of the poolset part */ int pool_set_part_copy(struct pool_set_part *dpart, struct pool_set_part *spart, int overwrite) { LOG(3, "dpart %p spart %p", dpart, spart); int result = 0; os_stat_t stat_buf; if (os_fstat(spart->fd, &stat_buf)) { ERR("!util_stat"); return -1; } size_t smapped = 0; void *saddr = pmem_map_file(spart->path, 0, 0, S_IREAD, &smapped, NULL); if (!saddr) return -1; size_t dmapped = 0; int is_pmem; void *daddr; int exists = util_file_exists(dpart->path); if (exists < 0) { result = -1; goto out_sunmap; } if (exists) { if (!overwrite) { errno = EEXIST; result = -1; goto out_sunmap; } daddr = pmem_map_file(dpart->path, 0, 0, S_IWRITE, &dmapped, &is_pmem); } else { errno = 0; daddr = pmem_map_file(dpart->path, dpart->filesize, PMEM_FILE_CREATE | PMEM_FILE_EXCL, stat_buf.st_mode, &dmapped, &is_pmem); } if (!daddr) { result = -1; goto out_sunmap; } #ifdef DEBUG /* provide extra logging in case of wrong dmapped/smapped value */ if (dmapped < smapped) { LOG(1, "dmapped < smapped: dmapped = %lu, smapped = %lu", dmapped, smapped); ASSERT(0); } #endif if (is_pmem) { pmem_memcpy_persist(daddr, saddr, smapped); } else { memcpy(daddr, saddr, smapped); pmem_msync(daddr, smapped); } pmem_unmap(daddr, dmapped); out_sunmap: pmem_unmap(saddr, smapped); return result; }
int main(int argc, char *argv[]) { int fd; char *dest; char *src; off_t dest_off = 0; off_t src_off = 0; uint64_t bytes = 0; int who = 0; off_t overlap = 0; size_t mapped_len; START(argc, argv, "pmem_memmove"); fd = OPEN(argv[1], O_RDWR); if (argc < 3) USAGE(); for (int arg = 2; arg < argc; arg++) { if (strchr("dsboS", argv[arg][0]) == NULL || argv[arg][1] != ':') UT_FATAL("op must be d: or s: or b: or o: or S:"); off_t val = strtoul(&argv[arg][2], NULL, 0); switch (argv[arg][0]) { case 'd': if (val <= 0) UT_FATAL("bad offset (%lu) with d: option", val); dest_off = val; break; case 's': if (val <= 0) UT_FATAL("bad offset (%lu) with s: option", val); src_off = val; break; case 'b': if (val <= 0) UT_FATAL("bad length (%lu) with b: option", val); bytes = val; break; case 'o': if (val != 1 && val != 2) UT_FATAL("bad val (%lu) with o: option", val); who = (int)val; break; case 'S': overlap = val; break; } } if (who == 0 && overlap != 0) USAGE(); /* for overlap the src and dest must be created differently */ if (who == 0) { /* src > dest */ dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL); if (dest == NULL) UT_FATAL("!could not mmap dest file %s", argv[1]); src = MMAP(dest + mapped_len, mapped_len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); /* * Its very unlikely that src would not be > dest. pmem_map_file * chooses the first unused address >= 1TB, large * enough to hold the give range, and 1GB aligned. Log * the error if the mapped addresses cannot be swapped * but allow the test to continue. */ if (src <= dest) { swap_mappings(&dest, &src, mapped_len, fd); if (src <= dest) UT_ERR("cannot map files in memory order"); } do_memmove(fd, dest, src, argv[1], dest_off, src_off, 0, bytes); /* dest > src */ swap_mappings(&dest, &src, mapped_len, fd); if (dest <= src) UT_ERR("cannot map files in memory order"); do_memmove(fd, dest, src, argv[1], dest_off, src_off, 0, bytes); MUNMAP(dest, mapped_len); MUNMAP(src, mapped_len); } else if (who == 1) { /* src overlap with dest */ dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL); if (dest == NULL) UT_FATAL("!Could not mmap %s: \n", argv[1]); src = dest + overlap; memset(dest, 0, bytes); util_persist_auto(util_fd_is_device_dax(fd), dest, bytes); do_memmove(fd, dest, src, argv[1], dest_off, src_off, overlap, bytes); MUNMAP(dest, mapped_len); } else { /* dest overlap with src */ dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL); if (dest == NULL) { UT_FATAL("!Could not mmap %s: \n", argv[1]); } src = dest; dest = src + overlap; memset(src, 0, bytes); util_persist_auto(util_fd_is_device_dax(fd), src, bytes); do_memmove(fd, dest, src, argv[1], dest_off, src_off, overlap, bytes); MUNMAP(src, mapped_len); } CLOSE(fd); DONE(NULL); }