.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM_MEMMOVE_PERSIST" "3" "2022-08-25" "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[](), \f[B]pmem_memcpy\f[](), \f[B]pmem_memset\f[](), \f[B]pmem_memmove_persist\f[](), \f[B]pmem_memcpy_persist\f[](), \f[B]pmem_memset_persist\f[](), \f[B]pmem_memmove_nodrain\f[](), \f[B]pmem_memcpy_nodrain\f[](), \f[B]pmem_memset_nodrain\f[]() \- 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[] .fi .SH DESCRIPTION .PP \f[B]pmem_memmove\f[](), \f[B]pmem_memcpy\f[]() and \f[B]pmem_memset\f[]() functions provide the same memory copying as their namesakes \f[B]memmove\f[](3), \f[B]memcpy\f[](3) and \f[B]memset\f[](3), and ensure that the result has been flushed to persistence before returning (unless \f[B]PMEM_F_MEM_NOFLUSH\f[] flag was used). .PP For example, the following code is functionally equivalent to \f[B]pmem_memmove\f[]() (with flags equal to 0): .IP .nf \f[C] \ \ \ \ memmove(dest,\ src,\ len); \ \ \ \ pmem_persist(dest,\ len); \f[] .fi .PP Calling \f[B]pmem_memmove\f[]() may out\-perform the above code, because \f[B]libpmem\f[](7) implementation may take advantage of the fact that \f[I]pmemdest\f[] is persistent memory and use instructions such as \f[I]non\-temporal\f[] stores to avoid the need to flush processor caches. .RS .PP WARNING: Using these functions where \f[B]pmem_is_pmem\f[](3) returns false may not do anything useful. Use libc functions in that case. .RE .PP Unlike libc implementation, \f[B]libpmem\f[] 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[](3) can be safely replaced by a single call to one of the above functions. .PP The \f[I]flags\f[] 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[] \- modifies the behavior to skip the final \f[B]pmem_drain\f[]() 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[](). The following example illustrates how this flag might be used to avoid multiple calls to \f[B]pmem_drain\f[]() 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[] .fi .IP \[bu] 2 \f[B]PMEM_F_MEM_NOFLUSH\f[] \- Don't flush anything. This implies \f[B]PMEM_F_MEM_NODRAIN\f[]. Using this flag only makes sense when it's followed by any function that flushes data. .PP The remaining flags say \f[I]how\f[] the operation should be done, and are merely hints. .IP \[bu] 2 \f[B]PMEM_F_MEM_NONTEMPORAL\f[] \- Use non\-temporal instructions. This flag is mutually exclusive with \f[B]PMEM_F_MEM_TEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM_F_MEM_TEMPORAL\f[] \- Use temporal instructions. This flag is mutually exclusive with \f[B]PMEM_F_MEM_NONTEMPORAL\f[]. .IP \[bu] 2 \f[B]PMEM_F_MEM_WC\f[] \- Use write combining mode. This flag is mutually exclusive with \f[B]PMEM_F_MEM_WB\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM_F_MEM_WB\f[] \- Use write back mode. This flag is mutually exclusive with \f[B]PMEM_F_MEM_WC\f[]. On x86_64 this is an alias for \f[B]PMEM_F_MEM_TEMPORAL\f[]. .PP Using an invalid combination of flags has undefined behavior. .PP Without any of the above flags \f[B]libpmem\f[] will try to guess the best strategy based on size. See \f[B]PMEM_MOVNT_THRESHOLD\f[] description in \f[B]libpmem\f[](7) for details. .PP \f[B]pmem_memmove_persist\f[]() is an alias for \f[B]pmem_memmove\f[]() with flags equal to 0. .PP \f[B]pmem_memcpy_persist\f[]() is an alias for \f[B]pmem_memcpy\f[]() with flags equal to 0. .PP \f[B]pmem_memset_persist\f[]() is an alias for \f[B]pmem_memset\f[]() with flags equal to 0. .PP \f[B]pmem_memmove_nodrain\f[]() is an alias for \f[B]pmem_memmove\f[]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[]. .PP \f[B]pmem_memcpy_nodrain\f[]() is an alias for \f[B]pmem_memcpy\f[]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[]. .PP \f[B]pmem_memset_nodrain\f[]() is an alias for \f[B]pmem_memset\f[]() with flags equal to \f[B]PMEM_F_MEM_NODRAIN\f[]. .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[] flag you should not expect memory to be visible to other threads before calling \f[B]pmem_drain\f[](3) or any of the \f[I]_persist\f[] 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'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[](3), \f[B]memmove\f[](3), \f[B]memset\f[](3), \f[B]libpmem\f[](7) and \f[B]\f[]