.\" Automatically generated by Pandoc 2.0.6 .\" .TH "PMEM2_GET_MEMMOVE_FN" "3" "2022-08-25" "PMDK - pmem2 API version 1.0" "PMDK Programmer's Manual" .hy .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright 2020, Intel Corporation .SH NAME .PP \f[B]pmem2_get_memmove_fn\f[](), \f[B]pmem2_get_memset_fn\f[](), \f[B]pmem2_get_memcpy_fn\f[]() \- get a function that provides optimized copying to persistent memory .SH SYNOPSIS .IP .nf \f[C] #include\ typedef\ void\ *(*pmem2_memmove_fn)(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); typedef\ void\ *(*pmem2_memcpy_fn)(void\ *pmemdest,\ const\ void\ *src,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); typedef\ void\ *(*pmem2_memset_fn)(void\ *pmemdest,\ int\ c,\ size_t\ len, \ \ \ \ \ \ \ \ unsigned\ flags); struct\ pmem2_map; pmem2_memmove_fn\ pmem2_get_memmove_fn(struct\ pmem2_map\ *map); pmem2_memset_fn\ pmem2_get_memset_fn(struct\ pmem2_map\ *map); pmem2_memcpy_fn\ pmem2_get_memcpy_fn(struct\ pmem2_map\ *map); \f[] .fi .SH DESCRIPTION .PP The \f[B]pmem2_get_memmove_fn\f[](), \f[B]pmem2_get_memset_fn\f[](), \f[B]pmem2_get_memcpy_fn\f[]() functions return a pointer to a function responsible for efficient storing and flushing of data for mapping \f[I]map\f[]. .PP \f[B]pmem2_memmove_fn\f[](), \f[B]pmem2_memset_fn\f[]() and \f[B]pmem2_memcpy_fn\f[]() functions provide the same memory copying functionalities 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]PMEM2_F_MEM_NOFLUSH\f[] flag was used). .PP For example, the following code: .IP .nf \f[C] \ \ \ \ \ \ \ \ memmove(dest,\ src,\ len); \ \ \ \ \ \ \ \ pmem2_persist_fn\ persist_fn\ =\ pmem2_get_persist_fn(map); \ \ \ \ \ \ \ \ persist_fn(dest,\ len); \f[] .fi .PP is functionally equivalent to: .IP .nf \f[C] \ \ \ \ \ \ \ \ pmem2_memmove_fn\ memmove_fn\ =\ pmem2_get_memmove_fn(map); \ \ \ \ \ \ \ \ memmove_fn(dest,\ src,\ len,\ 0); \f[] .fi .PP Unlike libc implementation, \f[B]libpmem2\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[I]persist_fn\f[] can be safely replaced by a single \f[I]memmove_fn\f[] call. .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]PMEM2_F_MEM_NODRAIN\f[] \- modifies the behavior to skip the final \f[I]pmem2_drain_fn\f[] step. This allows applications to optimize cases where several ranges are being copied to persistent memory, followed by a single call to \f[I]pmem2_drain_fn\f[]. The following example illustrates how this flag might be used to avoid multiple calls to \f[I]pmem2_drain_fn\f[] when copying several ranges of memory to pmem: .IP .nf \f[C] pmem2_memcpy_fn\ memcpy_fn\ =\ pmem2_get_memcpy_fn(map); pmem2_drain_fn\ drain_fn\ =\ pmem2_get_drain_fn(map); /*\ ...\ write\ several\ ranges\ to\ pmem\ ...\ */ memcpy_fn(pmemdest1,\ src1,\ len1,\ PMEM2_F_MEM_NODRAIN); memcpy_fn(pmemdest2,\ src2,\ len2,\ PMEM2_F_MEM_NODRAIN); /*\ ...\ */ /*\ wait\ for\ any\ pmem\ stores\ to\ drain\ from\ HW\ buffers\ */ drain_fn(); \f[] .fi .IP \[bu] 2 \f[B]PMEM2_F_MEM_NOFLUSH\f[] \- Don't flush anything. This implies \f[B]PMEM2_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]PMEM2_F_MEM_NONTEMPORAL\f[] \- Use non\-temporal instructions. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_TEMPORAL\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM2_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM2_F_MEM_TEMPORAL\f[] \- Use temporal instructions. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_NONTEMPORAL\f[]. .IP \[bu] 2 \f[B]PMEM2_F_MEM_WC\f[] \- Use write combining mode. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_WB\f[]. On x86_64 this flag is mutually exclusive with \f[B]PMEM2_F_MEM_NOFLUSH\f[]. .IP \[bu] 2 \f[B]PMEM2_F_MEM_WB\f[] \- Use write back mode. This flag is mutually exclusive with \f[B]PMEM2_F_MEM_WC\f[]. On x86_64 this is an alias for \f[B]PMEM2_F_MEM_TEMPORAL\f[]. .PP Using an invalid combination of flags has undefined behavior. .PP Without any of the above flags \f[B]libpmem2\f[] will try to guess the best strategy based on the data size. See \f[B]PMEM_MOVNT_THRESHOLD\f[] description in \f[B]libpmem2\f[](7) for details. .SH RETURN VALUE .PP The \f[B]pmem2_get_memmove_fn\f[](), \f[B]pmem2_get_memset_fn\f[](), \f[B]pmem2_get_memcpy_fn\f[]() functions never return NULL. .PP They return the same function for the same mapping. .PP This means that it's safe to cache their return values. However, these functions are very cheap (because their return values are precomputed), so caching may not be necessary. .PP If two (or more) mappings share the same \f[I]pmem2_memmove_fn\f[], \f[I]pmem2_memset_fn\f[], \f[I]pmem2_memcpy_fn\f[] and they are adjacent to each other, it is safe to call these functions for a range spanning those mappings. .SH SEE ALSO .PP \f[B]memcpy\f[](3), \f[B]memmove\f[](3), \f[B]memset\f[](3), \f[B]pmem2_get_drain_fn\f[](3), \f[B]pmem2_get_memcpy_fn\f[](3), \f[B]pmem2_get_memset_fn\f[](3), \f[B]pmem2_map_new\f[](3), \f[B]pmem2_get_persist_fn\f[](3), \f[B]libpmem2\f[](7) and \f[B]\f[]