.\" Automatically generated by Pandoc 2.10.1 .\" .TH "PMEM_MEMMOVE_PERSIST" "3" "2020-10-28" "PMDK - pmem API version 1.1" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2017-2020, Intel Corporation .SH NAME .PP \f[B]pmem_memmove\f[R](), \f[B]pmem_memcpy\f[R](), \f[B]pmem_memset\f[R](), \f[B]pmem_memmove_persist\f[R](), \f[B]pmem_memcpy_persist\f[R](), \f[B]pmem_memset_persist\f[R](), \f[B]pmem_memmove_nodrain\f[R](), \f[B]pmem_memcpy_nodrain\f[R](), \f[B]pmem_memset_nodrain\f[R]() - functions that provide optimized copying to persistent memory .SH SYNOPSIS .IP .nf \f[C] #include void *pmem_memmove(void *pmemdest, const void *src, size_t len, unsigned flags); void *pmem_memcpy(void *pmemdest, const void *src, size_t len, unsigned flags); void *pmem_memset(void *pmemdest, int c, size_t len, unsigned flags); void *pmem_memmove_persist(void *pmemdest, const void *src, size_t len); void *pmem_memcpy_persist(void *pmemdest, const void *src, size_t len); void *pmem_memset_persist(void *pmemdest, int c, size_t len); void *pmem_memmove_nodrain(void *pmemdest, const void *src, size_t len); void *pmem_memcpy_nodrain(void *pmemdest, const void *src, size_t len); void *pmem_memset_nodrain(void *pmemdest, int c, size_t len); \f[R] .fi .SH DESCRIPTION .PP \f[B]pmem_memmove\f[R](), \f[B]pmem_memcpy\f[R]() and \f[B]pmem_memset\f[R]() functions provide the same memory copying as their namesakes \f[B]memmove\f[R](3), \f[B]memcpy\f[R](3) and \f[B]memset\f[R](3), and ensure that the result has been flushed to persistence before returning (unless \f[B]PMEM_F_MEM_NOFLUSH\f[R] flag was used). .PP For example, the following code is functionally equivalent to \f[B]pmem_memmove\f[R]() (with flags equal to 0): .IP .nf \f[C] memmove(dest, src, len); pmem_persist(dest, len); \f[R] .fi .PP Calling \f[B]pmem_memmove\f[R]() may out-perform the above code, because \f[B]libpmem\f[R](7) implementation may take advantage of the fact that \f[I]pmemdest\f[R] is persistent memory and use instructions such as \f[I]non-temporal\f[R] stores to avoid the need to flush processor caches. .RS .PP WARNING: Using these functions where \f[B]pmem_is_pmem\f[R](3) returns false may not do anything useful. Use libc functions in that case. .RE .PP Unlike libc implementation, \f[B]libpmem\f[R] functions guarantee that if destination buffer address and length are 8 byte aligned then all stores will be performed using at least 8 byte store instructions. This means that a series of 8 byte stores followed by \f[B]pmem_persist\f[R](3) can be safely replaced by a single call to one of the above functions. .PP The \f[I]flags\f[R] argument of all of the above functions has the same meaning. It can be 0 or a bitwise OR of one or more of the following flags: .IP \[bu] 2 \f[B]PMEM_F_MEM_NODRAIN\f[R] - modifies the behavior to skip the final \f[B]pmem_drain\f[R]() step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to \f[B]pmem_drain\f[R](). The following example illustrates how this flag might be used to avoid multiple calls to \f[B]pmem_drain\f[R]() when copying several ranges of memory to pmem: .IP .nf \f[C] /* ... write several ranges to pmem ... */ pmem_memcpy(pmemdest1, src1, len1, PMEM_F_MEM_NODRAIN); pmem_memcpy(pmemdest2, src2, len2, PMEM_F_MEM_NODRAIN); /* ... */ /* wait for any pmem stores to drain from HW buffers */ pmem_drain(); \f[R] .fi .IP \[bu] 2 \f[B]PMEM_F_MEM_NOFLUSH\f[R] - Don\[cq]t flush anything. This implies \f[B]PMEM_F_MEM_NODRAIN\f[R]. Using this flag only makes sense when it\[cq]s followed by any function that flushes data. .PP The remaining flags say \f[I]how\f[R] the operation should be done, and are merely hints. .IP \[bu] 2 \f[B]PMEM_F_MEM_NONTEMPORAL\f[R] - Use non-temporal instructions. This flag is mutually exclusive with \f[B]PMEM_F_MEM_TEMPORAL\f[R]. On x86_64 this flag is mutually exclusive with \f[B]PMEM_F_MEM_NOFLUSH\f[R]. .IP \[bu] 2 \f[B]PMEM_F_MEM_TEMPORAL\f[R] - Use temporal instructions. This flag is mutually exclusive with \f[B]PMEM_F_MEM_NONTEMPORAL\f[R]. .IP \[bu] 2 \f[B]PMEM_F_MEM_WC\f[R] - Use write combining mode. This flag is mutually exclusive with \f[B]PMEM_F_MEM_WB\f[R]. On x86_64 this flag is mutually exclusive with \f[B]PMEM_F_MEM_NOFLUSH\f[R]. .IP \[bu] 2 \f[B]PMEM_F_MEM_WB\f[R] - Use write back mode. This flag is mutually exclusive with \f[B]PMEM_F_MEM_WC\f[R]. On x86_64 this is an alias for \f[B]PMEM_F_MEM_TEMPORAL\f[R]. .PP Using an invalid combination of flags has undefined behavior. .PP Without any of the above flags \f[B]libpmem\f[R] will try to guess the best strategy based on size. See \f[B]PMEM_MOVNT_THRESHOLD\f[R] description in \f[B]libpmem\f[R](7) for details. .PP \f[B]pmem_memmove_persist\f[R]() is an alias for \f[B]pmem_memmove\f[R]() with flags equal to 0. .PP \f[B]pmem_memcpy_persist\f[R]() is an alias for \f[B]pmem_memcpy\f[R]() with flags equal to 0. .PP \f[B]pmem_memset_persist\f[R]() is an alias for \f[B]pmem_memset\f[R]() with flags equal to 0. .PP \f[B]pmem_memmove_nodrain\f[R]() is an alias for \f[B]pmem_memmove\f[R]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[R]. .PP \f[B]pmem_memcpy_nodrain\f[R]() is an alias for \f[B]pmem_memcpy\f[R]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[R]. .PP \f[B]pmem_memset_nodrain\f[R]() is an alias for \f[B]pmem_memset\f[R]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[R]. .SH RETURN VALUE .PP All of the above functions return address of the destination buffer. .SH CAVEATS .PP After calling any of the functions with \f[B]PMEM_F_MEM_NODRAIN\f[R] flag you should not expect memory to be visible to other threads before calling \f[B]pmem_drain\f[R](3) or any of the \f[I]_persist\f[R] functions. This is because on x86_64 those functions may use non-temporal store instructions, which are weakly ordered. See \[lq]Intel 64 and IA-32 Architectures Software Developer\[cq]s Manual\[rq], Volume 1, \[lq]Caching of Temporal vs.\ Non-Temporal Data\[rq] section for details. .SH SEE ALSO .PP \f[B]memcpy\f[R](3), \f[B]memmove\f[R](3), \f[B]memset\f[R](3), \f[B]libpmem\f[R](7) and \f[B]\f[R]