diff --git a/.cirrus.yml b/.cirrus.yml index 3b337a56950afa7368817ca9d32e720c80e18c2d..4757d0a5625de5a4edbd3bc28c65cf0ef4201372 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -4,7 +4,7 @@ freebsd_instance: task: install_script: ASSUME_ALWAYS_YES=yes pkg bootstrap -f; pkg install -y - autoconf bash binutils coreutils e2fsprogs-libuuid + autoconf bash binutils cmake coreutils e2fsprogs-libuuid git gmake libunwind ncurses pkgconf hs-pandoc script: CFLAGS="-Wno-unused-value" gmake diff --git a/doc/Makefile b/doc/Makefile index edf36b2f13c09420af41ac9c650a6eb30a74a90c..1c03ab892e15b2b998621be2bf04039d01e86d48 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -101,8 +101,8 @@ MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.m libpmem2/pmem2_config_set_length.3.md libpmem2/pmem2_config_set_offset.3.md \ libpmem2/pmem2_map_get_store_granularity.3.md libpmem2/pmem2_get_flush_fn.3.md \ libpmem2/pmem2_get_drain_fn.3.md libpmem2/pmem2_get_persist_fn.3.md \ - libpmem2/pmem2_perror.3.md libpmem2/pmem2_get_memmove_fn.3.md libpmem2/pmem2_config_set_sharing.3.md \ - libpmem2/pmem2_config_set_vm_reservation.3.md libpmem2/pmem2_vm_reservation_new.3.md \ + libpmem2/pmem2_perror.3.md libpmem2/pmem2_get_memmove_fn.3.md libpmem2/pmem2_memcpy_async.3.md\ + libpmem2/pmem2_config_set_sharing.3.md libpmem2/pmem2_config_set_vm_reservation.3.md libpmem2/pmem2_vm_reservation_new.3.md \ libpmem2/pmem2_vm_reservation_get_address.3.md libpmem2/pmem2_vm_reservation_get_size.3.md \ libpmem2/pmem2_badblock_context_new.3.md libpmem2/pmem2_badblock_next.3.md \ libpmem2/pmem2_badblock_clear.3.md libpmem2/pmem2_config_set_protection.3.md \ @@ -113,7 +113,7 @@ MANPAGES_3_MD_PMEM2 = libpmem2/pmem2_errormsg.3.md libpmem2/pmem2_config_new.3.m libpmem2/pmem2_vm_reservation_map_find.3.md libpmem2/pmem2_source_pread_mcsafe.3.md \ MANPAGES_1_MD_PMEM2 = -MANPAGES_3_DUMMY += libpmem2/pmem2_config_delete.3 libpmem2/pmem2_source_from_handle.3 libpmem2/pmem2_source_delete.3 \ +MANPAGES_3_DUMMY += libpmem2/pmem2_config_delete.3 libpmem2/pmem2_config_set_vdm.3 libpmem2/pmem2_source_from_handle.3 libpmem2/pmem2_source_delete.3 \ libpmem2/pmem2_get_memset_fn.3 libpmem2/pmem2_get_memcpy_fn.3 libpmem2/pmem2_vm_reservation_delete.3 \ libpmem2/pmem2_badblock_context_delete.3 libpmem2/pmem2_vm_reservation_shrink.3 \ libpmem2/pmem2_vm_reservation_map_find_first.3 libpmem2/pmem2_vm_reservation_map_find_last.3 \ diff --git a/doc/libpmem2/.gitignore b/doc/libpmem2/.gitignore index a37e30efeaab1c35b8b7753317508a27751c144f..a1b3a358cfaeb4aed5e47516d620811a27b0cd1c 100644 --- a/doc/libpmem2/.gitignore +++ b/doc/libpmem2/.gitignore @@ -22,6 +22,7 @@ pmem2_map_new.3 pmem2_map_get_address.3 pmem2_map_get_size.3 pmem2_map_get_store_granularity.3 +pmem2_memcpy_async.3 pmem2_source_alignment.3 pmem2_source_from_fd.3 pmem2_source_from_anon.3 diff --git a/doc/libpmem2/pmem2_config_set_vdm.3 b/doc/libpmem2/pmem2_config_set_vdm.3 new file mode 100644 index 0000000000000000000000000000000000000000..8e81274f85cd1576b8bc70188ae53d6c0d5fa9cd --- /dev/null +++ b/doc/libpmem2/pmem2_config_set_vdm.3 @@ -0,0 +1 @@ +.so pmem2_memcpy_async.3 diff --git a/doc/libpmem2/pmem2_get_memmove_fn.3.md b/doc/libpmem2/pmem2_get_memmove_fn.3.md index f40063fda38c0ba164145d43aa8f33f658ebb0db..6148ac596c82d70a6d472519d89bb6e757b9ec53 100644 --- a/doc/libpmem2/pmem2_get_memmove_fn.3.md +++ b/doc/libpmem2/pmem2_get_memmove_fn.3.md @@ -44,7 +44,6 @@ pmem2_memcpy_fn pmem2_get_memcpy_fn(struct pmem2_map *map); ``` # DESCRIPTION # - The **pmem2_get_memmove_fn**(), **pmem2_get_memset_fn**(), **pmem2_get_memcpy_fn**() functions return a pointer to a function responsible for efficient storing and flushing of data for mapping *map*. diff --git a/doc/libpmem2/pmem2_memcpy_async.3.md b/doc/libpmem2/pmem2_memcpy_async.3.md new file mode 100644 index 0000000000000000000000000000000000000000..050813bca51f761574a5118f1f5618faaab14b65 --- /dev/null +++ b/doc/libpmem2/pmem2_memcpy_async.3.md @@ -0,0 +1,60 @@ +--- +layout: manual +Content-Style: 'text/css' +title: _MP(PMEM2_MEMCPY_ASYNC, 3) +collection: libpmem2 +header: PMDK +date: pmem2 API version 1.0 +... + +[comment]: <> (SPDX-License-Identifier: BSD-3-Clause +[comment]: <> (Copyright 2022, Intel Corporation) + +[comment]: <> (pmem2_memcpy_async.3 -- man page for pmem2_memcpy_async) + +[NAME](#name)<br /> +[SYNOPSIS](#synopsis)<br /> +[DESCRIPTION](#description)<br /> +[RETURN VALUE](#return-value)<br /> +[SEE ALSO](#see-also)<br /> + +# NAME # +**pmem2_config_set_vdm**(), **pmem2_memcpy_async**() - asynchronous data movement operations + +# SYNOPSIS # + +```c +#define PMEM2_USE_MINIASYNC 1 +#include <libpmem2.h> +int pmem2_config_set_vdm(struct pmem2_config *cfg, struct vdm *vdm); + +struct vdm_operation_future pmem2_memcpy_async(struct pmem2_map *map, + void *pmemdest, const void *src, size_t len, unsigned flags); +``` + +# DESCRIPTION # +To use those functions, you must have *libminiasync* installed. Those functions use futures +and vdm (virtual data mover) concepts from this library. Please check **miniasync**(7) for more details. + +The **pmem2_config_set_vdm** sets a vdm structure in the *pmem2_config*. +This structure will be used by pmem2_memcpy_async function, to create a *vdm_operation_future*. +If vdm is not set in the config, pmem2_map_new will use a default one which uses a +pmem2 memory movement functions to perform memory operations. (**pmem2_get_memcpy_fn**(3), **pmem2_get_memmove_fn**(3), **pmem2_get_memsety_fn**(3)). + +The **pmem2_memcpy_async** uses *vdm* structure held inside of the *pmem2_map* structure to initialise and return **vdm_operation_future**. +This future will perform memcpy operation from *vdm* to copy *len* bytes from *src* to *pmemdest*. In the current implementation *flags* are ignored. + +# RETURN VALUE # + +The **pmem2_config_set_vdm** always return 0. + +The **pmem2_memcpy_async** returns a new instance of **vdm_operation_future** which will copy *len* bytes from *src* to *pmemdest*. +You can execute returned structure using methods from the **libminiasync**() library. + +# SEE ALSO # + +**memcpy**(3), **memmove**(3), **memset**(3), **pmem2_get_drain_fn**(3), +**pmem2_get_memcpy_fn**(3), **pmem2_get_memset_fn**(3), **pmem2_map_new**(3), +**pmem2_get_persist_fn**(3), **vdm_memcpy**(3), **miniasync**(7), **miniasync_future**(7), +**libpmem2**(7) and **<https://pmem.io>** + diff --git a/src/Makefile b/src/Makefile index efc1a81cb83c274e6b8ea94f62b002748cb2887b..ee2fb2e78df7801a32a5ab67321c323d3b823a7b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2021, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/Makefile -- Makefile for PMDK diff --git a/src/PMDK.sln b/src/PMDK.sln index c267aa1d7c8daed0a65b805873175b3b02c45f61..d3a46c5ae7552db54384978666787f0ac2fd37fd 100644 --- a/src/PMDK.sln +++ b/src/PMDK.sln @@ -263,6 +263,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "obj_pool_lookup", "test\obj EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "obj_pool_open_mt", "test\obj_pool_open_mt\obj_pool_open_mt.vcxproj", "{4850F425-9128-4E91-973C-5AE7BD97395C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pmem2_mover", "test\pmem2_mover\pmem2_mover.vcxproj", "{4870E3C3-63A1-4702-9E61-47ABCFF3AB0F}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpmemcommon", "common\libpmemcommon.vcxproj", "{492BAA3D-0D5D-478E-9765-500463AE69AA}" ProjectSection(ProjectDependencies) = postProject {901F04DB-E1A5-4A41-8B81-9D31C19ACD59} = {901F04DB-E1A5-4A41-8B81-9D31C19ACD59} @@ -915,6 +917,9 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "util_vecq", "test\util_vecq\util_vecq.vcxproj", "{FD726AA3-D4FA-4597-B435-08CC7752888E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "basic", "examples\libpmemset\basic\basic.vcxproj", "{FE9C5A1D-7DEB-4549-A25B-2F975F3AD641}" + ProjectSection(ProjectDependencies) = postProject + {FBAEFC34-D221-4203-8BF6-162DE1A5BE1C} = {FBAEFC34-D221-4203-8BF6-162DE1A5BE1C} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mmap_fixed", "test\mmap_fixed\mmap_fixed.vcxproj", "{FEA09B48-34C2-4963-8A5A-F97BDA136D72}" EndProject @@ -980,7 +985,9 @@ Global {07A153D9-DF17-4DE8-A3C2-EBF171B961AE}.Release|x64.ActiveCfg = Release|x64 {07A153D9-DF17-4DE8-A3C2-EBF171B961AE}.Release|x64.Build.0 = Release|x64 {082C1588-003E-4217-B41B-49BF4409BF83}.Debug|x64.ActiveCfg = Debug|x64 + {082C1588-003E-4217-B41B-49BF4409BF83}.Debug|x64.Build.0 = Debug|x64 {082C1588-003E-4217-B41B-49BF4409BF83}.Release|x64.ActiveCfg = Release|x64 + {082C1588-003E-4217-B41B-49BF4409BF83}.Release|x64.Build.0 = Release|x64 {08B62E36-63D2-4FF1-A605-4BBABAEE73FB}.Debug|x64.ActiveCfg = Debug|x64 {08B62E36-63D2-4FF1-A605-4BBABAEE73FB}.Debug|x64.Build.0 = Debug|x64 {08B62E36-63D2-4FF1-A605-4BBABAEE73FB}.Release|x64.ActiveCfg = Release|x64 @@ -1233,6 +1240,10 @@ Global {4850F425-9128-4E91-973C-5AE7BD97395C}.Debug|x64.Build.0 = Debug|x64 {4850F425-9128-4E91-973C-5AE7BD97395C}.Release|x64.ActiveCfg = Release|x64 {4850F425-9128-4E91-973C-5AE7BD97395C}.Release|x64.Build.0 = Release|x64 + {4870E3C3-63A1-4702-9E61-47ABCFF3AB0F}.Debug|x64.ActiveCfg = Debug|x64 + {4870E3C3-63A1-4702-9E61-47ABCFF3AB0F}.Debug|x64.Build.0 = Debug|x64 + {4870E3C3-63A1-4702-9E61-47ABCFF3AB0F}.Release|x64.ActiveCfg = Release|x64 + {4870E3C3-63A1-4702-9E61-47ABCFF3AB0F}.Release|x64.Build.0 = Release|x64 {492BAA3D-0D5D-478E-9765-500463AE69AA}.Debug|x64.ActiveCfg = Debug|x64 {492BAA3D-0D5D-478E-9765-500463AE69AA}.Debug|x64.Build.0 = Debug|x64 {492BAA3D-0D5D-478E-9765-500463AE69AA}.Release|x64.ActiveCfg = Release|x64 @@ -2175,6 +2186,7 @@ Global {47E7DAFC-4EDA-4007-BB7B-4BEB6D63C222} = {6F52D216-031F-4E5D-9E35-2EB517CE7FB4} {4850F425-9128-4E91-973C-5AE7BD97395B} = {63C9B3F8-437D-4AD9-B32D-D04AE38C35B6} {4850F425-9128-4E91-973C-5AE7BD97395C} = {63C9B3F8-437D-4AD9-B32D-D04AE38C35B6} + {4870E3C3-63A1-4702-9E61-47ABCFF3AB0F} = {A14A4556-9092-430D-B9CA-B2B1223D56CB} {492BAA3D-0D5D-478E-9765-500463AE69AA} = {853D45D8-980C-4991-B62A-DAC6FD245402} {49A7CC5A-D5E7-4A07-917F-C6918B982BE8} = {BD6CC700-B36B-435B-BAF9-FC5AFCD766C9} {4C291EEB-3874-4724-9CC2-1335D13FF0EE} = {746BA101-5C93-42A5-AC7A-64DCEB186572} diff --git a/src/common.inc b/src/common.inc index 80ff663028ac0987d980550ca6d9269ebbb4d029..70da589251f3ce627e925cf70d1c77c4e6ce2787 100644 --- a/src/common.inc +++ b/src/common.inc @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2020, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/common.inc -- common Makefile rules for PMDK # @@ -342,6 +342,9 @@ export USE_LIBUNWIND export LIBUNWIND_LIBS endif +export MINIASYNC_CFLAGS := -I$(TOP)/src/deps/miniasync/src/include/ +export MINIASYNC_LIBS := -lminiasync + ifeq ($(OS_KERNEL_NAME),FreeBSD) GLIBC_CXXFLAGS=-D_GLIBCXX_USE_C99 diff --git a/src/common/Makefile b/src/common/Makefile index 2b2e5bfa4b2d1442c4e9e05b134652abbbf074bb..3a9b25ab1160108aca90a783eb9e3c59922bcccb 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -11,7 +11,7 @@ include pmemcommon.inc include ../Makefile.inc -CFLAGS += $(LIBNDCTL_CFLAGS) +CFLAGS += $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) -DPMEM2_USE_MINIASYNC=1 CFLAGS += -DUSE_LIBDL # Librpmem is deprecated. # This flag allows to build tests, examples and benchmarks diff --git a/src/common/libpmemcommon.vcxproj b/src/common/libpmemcommon.vcxproj index 2ea3f8a80a5efb5b8467df66e05a5ceb81c5fb9f..0095e37c55621c99899cf44e215f17d8866ef79e 100644 --- a/src/common/libpmemcommon.vcxproj +++ b/src/common/libpmemcommon.vcxproj @@ -97,12 +97,12 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <LinkIncremental>true</LinkIncremental> <TargetExt>.lib</TargetExt> - <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;</IncludePath> + <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;$(SolutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <LinkIncremental>true</LinkIncremental> <TargetExt>.lib</TargetExt> - <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;</IncludePath> + <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;$(SolutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> @@ -160,4 +160,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/core/libpmemcore.vcxproj b/src/core/libpmemcore.vcxproj index 58269d828cc3465a6d55a71640106cb10ceb679c..ddebb9561e3d6d4fe480562d91ea08b2bbabb4d7 100644 --- a/src/core/libpmemcore.vcxproj +++ b/src/core/libpmemcore.vcxproj @@ -73,12 +73,12 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <LinkIncremental>true</LinkIncremental> <TargetExt>.lib</TargetExt> - <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;</IncludePath> + <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;$(SolutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <LinkIncremental>true</LinkIncremental> <TargetExt>.lib</TargetExt> - <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;</IncludePath> + <IncludePath>$(SolutionDir)\include;$(SolutionDir)\windows\include;$(VC_IncludePath);$(WindowsSDK_IncludePath);.;$(SolutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> @@ -134,4 +134,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/core/membuf.c b/src/core/membuf.c new file mode 100644 index 0000000000000000000000000000000000000000..bd471d4d1b7f7d691f4f3344f1008f6e8dd59d23 --- /dev/null +++ b/src/core/membuf.c @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2022, Intel Corporation */ + +/* + * membuf.c -- membuf implementation + */ + +#include "membuf.h" +#include "os_thread.h" +#include "out.h" + +#define MEMBUF_ALIGNMENT (1 << 21) /* 2MB */ +#define MEMBUF_LEN (1 << 21) /* 2MB */ + +struct threadbuf { + struct threadbuf *next; /* next threadbuf */ + struct threadbuf *unused_next; /* next unused threadbuf */ + + struct membuf *membuf; + + void *user_data; /* user-specified pointer */ + size_t size; /* size of the buf variable */ + size_t offset; /* current allocation offset */ + size_t available; /* free space available in front of the offset */ + size_t leftovers; /* space left unused on wraparound */ + char buf[]; /* buffer with data */ +}; + +struct membuf { + os_mutex_t lists_lock; /* protects both lists */ + struct threadbuf *tbuf_first; /* linked-list of threadbufs, cleanup */ + struct threadbuf *tbuf_unused_first; /* list of threadbufs for reuse */ + + os_tls_key_t bufkey; /* TLS key for threadbuf */ + void *user_data; /* user-provided buffer data */ +}; + +struct membuf_entry { + int32_t allocated; /* 1 - allocated, 0 - unused */ + uint32_t size; /* size of the entry */ + char data[]; /* user data */ +}; + +/* + * membuf_key_destructor -- thread destructor for threadbuf + */ +static void +membuf_key_destructor(void *data) +{ + /* + * Linux TLS calls this callback only when a thread exits, but + * the Windows FLS implementation also calls it when the key itself + * is destroyed. To handle this difference, membuf only actually + * deallocates thread buffers on module delete and this callback + * puts the now unused thread buffer on a list to be reused. + */ + struct threadbuf *tbuf = data; + struct membuf *membuf = tbuf->membuf; + + os_mutex_lock(&membuf->lists_lock); + tbuf->unused_next = membuf->tbuf_unused_first; + membuf->tbuf_unused_first = tbuf; + os_mutex_unlock(&membuf->lists_lock); +} + +/* + * membuf_new -- allocates and initializes a new membuf instance + */ +struct membuf * +membuf_new(void *user_data) +{ + struct membuf *membuf = malloc(sizeof(struct membuf)); + if (membuf == NULL) + return NULL; + + membuf->user_data = user_data; + membuf->tbuf_first = NULL; + membuf->tbuf_unused_first = NULL; + os_mutex_init(&membuf->lists_lock); + + os_tls_key_create(&membuf->bufkey, membuf_key_destructor); + + return membuf; +} + +/* + * membuf_delete -- deallocates and cleans up a membuf instance + */ +void +membuf_delete(struct membuf *membuf) +{ + os_tls_key_delete(membuf->bufkey); + for (struct threadbuf *tbuf = membuf->tbuf_first; tbuf != NULL; ) { + struct threadbuf *next = tbuf->next; + util_aligned_free(tbuf); + tbuf = next; + } + os_mutex_destroy(&membuf->lists_lock); + free(membuf); +} + +/* + * membuf_entry_get_size -- returns the size of an entry + */ +static size_t +membuf_entry_get_size(void *real_ptr) +{ + struct membuf_entry *entry = real_ptr; + + uint32_t size; + util_atomic_load_explicit32(&entry->size, &size, memory_order_acquire); + + return size; +} + +/* + * membuf_entry_is_allocated -- checks whether the entry is allocated + */ +static int +membuf_entry_is_allocated(void *real_ptr) +{ + struct membuf_entry *entry = real_ptr; + int32_t allocated; + util_atomic_load_explicit32(&entry->allocated, + &allocated, memory_order_acquire); + + return allocated; +} + +/* + * membuf_get_threadbuf -- returns thread-local buffer for allocations + */ +static struct threadbuf * +membuf_get_threadbuf(struct membuf *membuf) +{ + struct threadbuf *tbuf = os_tls_get(membuf->bufkey); + if (tbuf != NULL) + return tbuf; + + os_mutex_lock(&membuf->lists_lock); + + if (membuf->tbuf_unused_first != NULL) { + tbuf = membuf->tbuf_unused_first; + membuf->tbuf_unused_first = tbuf->unused_next; + } else { + /* + * Make sure buffer is aligned to 2MB so that we can align down + * from contained pointers to access metadata (like user_data). + */ + tbuf = util_aligned_malloc(MEMBUF_ALIGNMENT, MEMBUF_LEN); + if (tbuf == NULL) { + os_mutex_unlock(&membuf->lists_lock); + return NULL; + } + + tbuf->next = membuf->tbuf_first; + membuf->tbuf_first = tbuf; + } + + tbuf->size = MEMBUF_LEN - sizeof(*tbuf); + tbuf->offset = 0; + tbuf->leftovers = 0; + tbuf->unused_next = NULL; + tbuf->membuf = membuf; + tbuf->available = tbuf->size; + tbuf->user_data = membuf->user_data; + os_tls_set(membuf->bufkey, tbuf); + + os_mutex_unlock(&membuf->lists_lock); + + return tbuf; +} + +/* + * membuf_threadbuf_prune -- reclaims available buffer space + */ +static void +membuf_threadbuf_prune(struct threadbuf *tbuf) +{ + while (tbuf->available != tbuf->size) { + /* reuse leftovers after a wraparound */ + if (tbuf->leftovers != 0 && + (tbuf->size - (tbuf->offset + tbuf->available)) + == tbuf->leftovers) { + tbuf->available += tbuf->leftovers; + tbuf->leftovers = 0; + + continue; + } + + /* check the next object after the available memory */ + size_t next_loc = (tbuf->offset + tbuf->available) % tbuf->size; + void *next = &tbuf->buf[next_loc]; + if (membuf_entry_is_allocated(next)) + return; + + tbuf->available += membuf_entry_get_size(next); + } +} + +/* + * membuf_alloc -- allocate linearly from the available memory location. + */ +void * +membuf_alloc(struct membuf *membuf, size_t size) +{ + struct threadbuf *tbuf = membuf_get_threadbuf(membuf); + if (tbuf == NULL) + return NULL; + + size_t real_size = size + sizeof(struct membuf_entry); + + if (real_size > tbuf->size) + return NULL; + + if (tbuf->offset + real_size > tbuf->size) { + tbuf->leftovers = tbuf->available; + tbuf->offset = 0; + tbuf->available = 0; + } + + /* wait until enough memory becomes available */ + if (real_size > tbuf->available) { + membuf_threadbuf_prune(tbuf); + /* + * Fail if not enough space was reclaimed and no + * memory is available for further reclamation. + */ + if (real_size > tbuf->available) + return NULL; + } + + size_t pos = tbuf->offset; + tbuf->offset += real_size; + tbuf->available -= real_size; + + struct membuf_entry *entry = (struct membuf_entry *)&tbuf->buf[pos]; + entry->size = (uint32_t)real_size; + entry->allocated = 1; + + return &entry->data; +} + +/* + * membuf_free -- deallocates an entry + */ +void +membuf_free(void *ptr) +{ + struct membuf_entry *entry = (struct membuf_entry *) + ((uintptr_t)ptr - sizeof(struct membuf_entry)); + + util_atomic_store_explicit64(&entry->allocated, 0, + memory_order_release); +} + +/* + * membuf_ptr_user_data -- return the user data pointer for membuf associated + * with the given allocation. + */ +void * +membuf_ptr_user_data(void *ptr) +{ + struct threadbuf *tbuf = (struct threadbuf *)ALIGN_DOWN((ptrdiff_t)ptr, + MEMBUF_ALIGNMENT); + + return tbuf->user_data; +} diff --git a/src/core/membuf.h b/src/core/membuf.h new file mode 100644 index 0000000000000000000000000000000000000000..e85264373cc5a8ff9c6e67f5e5a7eec4ae883def --- /dev/null +++ b/src/core/membuf.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright 2022, Intel Corporation */ + +/* + * membuf.h -- definitions for "membuf" module. + * + * Membuf is a circular object buffer. Each instance uses an internal + * per-thread buffer to avoid heavyweight synchronization. + * + * Allocation is linear and very cheap. The expectation is that objects within + * the buffer will be reclaimable long before the linear allocator might need + * to wraparound to reuse memory. + */ + +#ifndef MEMBUF_H +#define MEMBUF_H + +#include <stddef.h> + +struct membuf; + +struct membuf *membuf_new(void *user_data); +void membuf_delete(struct membuf *membuf); + +void *membuf_alloc(struct membuf *membuf, size_t size); +void membuf_free(void *ptr); + +void *membuf_ptr_user_data(void *ptr); + +#endif diff --git a/src/core/pmemcore.inc b/src/core/pmemcore.inc index d701ab0cb97bc25a39419308259c3d7a66018e52..df08c15ae858df8b6ec60465af7ca1f8b05d69be 100644 --- a/src/core/pmemcore.inc +++ b/src/core/pmemcore.inc @@ -34,6 +34,7 @@ SOURCE +=\ $(CORE)/alloc.c\ $(CORE)/fs_posix.c\ + $(CORE)/membuf.c\ $(CORE)/os_posix.c\ $(CORE)/os_thread_posix.c\ $(CORE)/out.c\ diff --git a/src/deps/Makefile b/src/deps/Makefile index 8cad8f73f7906032f1db8a21d5bf99f83643cf7f..69523ba20c40a74e3efa38d98edaeb400b944078 100644 --- a/src/deps/Makefile +++ b/src/deps/Makefile @@ -1,10 +1,14 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2021, Intel Corporation +# Copyright 2022, Intel Corporation # # src/deps/makefile -- build miniasync # +OS_KERNEL_NAME := $(shell uname -s) +# XXX: miniasync works only on Linux (and Windows) all clean clobber: +ifeq ($(OS_KERNEL_NAME),Linux) $(MAKE) -C miniasync $@ +endif cstyle check: diff --git a/src/deps/miniasync/Libminiasync.vcxproj b/src/deps/miniasync/Libminiasync.vcxproj index d2928118b1e4bd1537198b8935c2036ade1e35af..42b5736ef729e35b25a9a300281d0775b145baca 100644 --- a/src/deps/miniasync/Libminiasync.vcxproj +++ b/src/deps/miniasync/Libminiasync.vcxproj @@ -15,18 +15,19 @@ <Keyword>Win32Proj</Keyword> <ProjectGuid>{082c1588-003e-4217-b41b-49bf4409bf83}</ProjectGuid> <RootNamespace>Libminiasync</RootNamespace> + <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <ConfigurationType>Utility</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> + <PlatformToolset>v143</PlatformToolset> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <ConfigurationType>Application</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v142</PlatformToolset> + <PlatformToolset>v143</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> </PropertyGroup> @@ -69,7 +70,7 @@ <Command>(IF NOT EXIST "build\*.sln" ( cmake -H"." -B"build" ))</Command> </PreBuildEvent> <PostBuildEvent> - <Command>cmake --build "build" --config "$(Configuration)"</Command> + <Command>cmake --build "build" --config "Release"</Command> </PostBuildEvent> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -87,11 +88,11 @@ <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> </Link> - <PreBuildEvent> + <PreBuildEvent> <Command>(IF NOT EXIST "build\*.sln" ( cmake -H"." -B"build" ))</Command> </PreBuildEvent> <PostBuildEvent> - <Command>cmake --build "build" --config "$(Configuration)"</Command> + <Command>cmake --build "build" --config "Release"</Command> </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/deps/miniasync/Makefile b/src/deps/miniasync/Makefile index c3f625da41075701b51f3ea8bf9014afc31db4c6..18a5458a8817744474c9bc6501071c3802cb0d87 100644 --- a/src/deps/miniasync/Makefile +++ b/src/deps/miniasync/Makefile @@ -1,12 +1,12 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2021, Intel Corporation +# Copyright 2022, Intel Corporation # -# src/deps/miniasyc/makefile -- build miniasync +# src/deps/miniasync/makefile -- build miniasync # # WARNING: This file is created in the pmdk repository -# and doens't belong to the pmem/miniasyc repository. +# and doesn't belong to the pmem/miniasync repository. # dir = build diff --git a/src/examples/examples_debug.props b/src/examples/examples_debug.props index f0ab61104d402986716996d7f2e660173ba64bb3..651496d2570a8c160e663cb147f9685a57dff707 100644 --- a/src/examples/examples_debug.props +++ b/src/examples/examples_debug.props @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"/> + <ImportGroup Label="PropertySheets" /> <PropertyGroup> <IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir> <TargetName>ex_$(RootNamespace)_$(ProjectName)</TargetName> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\examples\</OutDir> - <IncludePath>.;$(solutionDir)include;$(solutionDir)..\include;$(ProjectDir)..\..\;$(ProjectDir)..\;$(IncludePath);$(WindowsSDK_IncludePath);</IncludePath> + <IncludePath>.;$(solutionDir)include;$(solutionDir)..\include;$(ProjectDir)..\..\;$(ProjectDir)..\;$(IncludePath);$(WindowsSDK_IncludePath)</IncludePath> <LibraryPath>$(ProjectDir)..\..\x64\$(Configuration)\libs;$(ProjectDir)..\..\..\x64\$(Configuration)\libs;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath> </PropertyGroup> <ItemDefinitionGroup> @@ -21,4 +21,4 @@ <TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors> </Link> </ItemDefinitionGroup> -</Project> +</Project> \ No newline at end of file diff --git a/src/examples/examples_release.props b/src/examples/examples_release.props index cabc9f75b57062461dc9999557314cdfb87cae28..a83199e28e01bb66aa41d1bf440e3bd9780d696f 100644 --- a/src/examples/examples_release.props +++ b/src/examples/examples_release.props @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets"/> + <ImportGroup Label="PropertySheets" /> <PropertyGroup> <IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir> <TargetName>ex_$(RootNamespace)_$(ProjectName)</TargetName> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\examples\</OutDir> <LibraryPath>$(ProjectDir)..\..\x64\$(Configuration)\libs;$(ProjectDir)..\..\..\x64\$(Configuration)\libs;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64</LibraryPath> - <IncludePath>.;$(solutionDir)include;$(solutionDir)..\include;$(ProjectDir)..\..\;$(ProjectDir)..\;$(IncludePath);$(WindowsSDK_IncludePath);</IncludePath> + <IncludePath>.;$(solutionDir)include;$(solutionDir)..\include;$(ProjectDir)..\..\;$(ProjectDir)..\;$(IncludePath);$(WindowsSDK_IncludePath)</IncludePath> </PropertyGroup> <ItemDefinitionGroup> <ClCompile> @@ -25,4 +25,4 @@ <TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors> </Link> </ItemDefinitionGroup> -</Project> +</Project> \ No newline at end of file diff --git a/src/include/libpmem2.h b/src/include/libpmem2.h index 1ebab3620af1a06419b65390df9e079d01981899..162c336dfed5dcefd311fcf70dc3d25b27f1b41d 100644 --- a/src/include/libpmem2.h +++ b/src/include/libpmem2.h @@ -16,7 +16,9 @@ #include <stddef.h> #include <stdint.h> - +#ifdef PMEM2_USE_MINIASYNC +#include <libminiasync/vdm.h> +#endif #ifdef _WIN32 #include <pmemcompat.h> @@ -175,7 +177,6 @@ int pmem2_config_set_vm_reservation(struct pmem2_config *cfg, struct pmem2_vm_reservation *rsv, size_t offset); /* mapping */ - struct pmem2_map; int pmem2_map_from_existing(struct pmem2_map **map, const struct pmem2_source *src, void *addr, size_t len, @@ -276,6 +277,13 @@ void pmem2_badblock_context_delete( int pmem2_badblock_clear(struct pmem2_badblock_context *bbctx, const struct pmem2_badblock *bb); +#ifdef PMEM2_USE_MINIASYNC +int pmem2_config_set_vdm(struct pmem2_config *cfg, struct vdm *vdm); + +struct vdm_operation_future pmem2_memcpy_async(struct pmem2_map *map, + void *pmemdest, const void *src, size_t len, unsigned flags); +#endif + /* error handling */ #ifndef _WIN32 diff --git a/src/libpmem/Makefile b/src/libpmem/Makefile index 534bdefbc81764f3b74cc313ced7a08558b4205e..af674e2422dc519d19b1a7cd139b9c91d090cf18 100644 --- a/src/libpmem/Makefile +++ b/src/libpmem/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2020, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/libpmem/Makefile -- Makefile for libpmem @@ -68,5 +68,5 @@ include ../Makefile.inc include $(PMEM2)/$(ARCH)/flags.inc -CFLAGS += -I. +CFLAGS += -I. $(MINIASYNC_CFLAGS) LIBS += -pthread diff --git a/src/libpmem/libpmem.vcxproj b/src/libpmem/libpmem.vcxproj index 7df5ebd890f6d269e92aa6989a8e84ed2c1b3af9..f6da94913240cf4553416ecbc2f46b41e85e0ef7 100644 --- a/src/libpmem/libpmem.vcxproj +++ b/src/libpmem/libpmem.vcxproj @@ -141,10 +141,10 @@ <Import Project="..\windows\libs_release.props" /> </ImportGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\src\libpmem2\x86_64\</IncludePath> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\src\libpmem2\x86_64\;$(solutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\src\libpmem2\x86_64\</IncludePath> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..\..\src\libpmem2\x86_64\;$(solutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ClCompile> diff --git a/src/libpmem2/Makefile b/src/libpmem2/Makefile index cd7e50509ff00ea9b7ec8b523927f6da90271a17..f172b9eff0c7fd3c84ddb48be5aa80c727ad4e31 100644 --- a/src/libpmem2/Makefile +++ b/src/libpmem2/Makefile @@ -19,6 +19,7 @@ SOURCE =\ errormsg.c\ map.c\ map_posix.c\ + mover.c\ mcsafe_ops_posix.c\ memops_generic.c\ persist.c\ @@ -65,5 +66,5 @@ include ../Makefile.inc include $(PMEM2)/$(ARCH)/flags.inc -CFLAGS += -I. $(LIBNDCTL_CFLAGS) +CFLAGS += -I. $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) -DPMEM2_USE_MINIASYNC=1 LIBS += -pthread $(LIBNDCTL_LIBS) diff --git a/src/libpmem2/config.c b/src/libpmem2/config.c index 8f2cdd5e3d175ac406920fe7e79db73becc02055..35a196d362efb77d243481d4210e8368579d8cf5 100644 --- a/src/libpmem2/config.c +++ b/src/libpmem2/config.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2019-2021, Intel Corporation */ +/* Copyright 2019-2022, Intel Corporation */ /* * config.c -- pmem2_config implementation @@ -9,6 +9,7 @@ #include "alloc.h" #include "config.h" #include "libpmem2.h" +#include "libminiasync/vdm.h" #include "out.h" #include "pmem2.h" #include "pmem2_utils.h" @@ -26,6 +27,7 @@ pmem2_config_init(struct pmem2_config *cfg) cfg->protection_flag = PMEM2_PROT_READ | PMEM2_PROT_WRITE; cfg->reserv = NULL; cfg->reserv_offset = 0; + cfg->vdm = NULL; } /* @@ -213,3 +215,15 @@ pmem2_config_set_protection(struct pmem2_config *cfg, cfg->protection_flag = prot; return 0; } + +/* + * pmem2_config_set_vdm -- set virtual data mover in the config struct + */ +int +pmem2_config_set_vdm(struct pmem2_config *cfg, struct vdm *vdm) +{ + PMEM2_ERR_CLR(); + cfg->vdm = vdm; + + return 0; +} diff --git a/src/libpmem2/config.h b/src/libpmem2/config.h index beb693c436de393c1e68fbcf55795b399831dd76..3e5108657d4b269ce0b8419b8e6e79875b42be13 100644 --- a/src/libpmem2/config.h +++ b/src/libpmem2/config.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2019-2020, Intel Corporation */ +/* Copyright 2019-2022, Intel Corporation */ /* * config.h -- internal definitions for pmem2_config @@ -24,6 +24,7 @@ struct pmem2_config { unsigned protection_flag; struct pmem2_vm_reservation *reserv; size_t reserv_offset; + struct vdm *vdm; }; void pmem2_config_init(struct pmem2_config *cfg); diff --git a/src/libpmem2/libpmem2.def b/src/libpmem2/libpmem2.def index b932078bb8134ce788cf45bb8f6268ba795f4376..47692d2bfbcc43bbcbc69fef299fa5f08d11fd9a 100644 --- a/src/libpmem2/libpmem2.def +++ b/src/libpmem2/libpmem2.def @@ -19,6 +19,7 @@ EXPORTS pmem2_config_set_protection pmem2_config_set_required_store_granularity pmem2_config_set_sharing + pmem2_config_set_vdm pmem2_config_set_vm_reservation pmem2_deep_flush pmem2_errormsgU @@ -33,8 +34,9 @@ EXPORTS pmem2_map_get_address pmem2_map_get_size pmem2_map_get_store_granularity - pmem2_map_new pmem2_map_from_existing + pmem2_map_new + pmem2_memcpy_async pmem2_perrorU pmem2_perrorW pmem2_source_alignment diff --git a/src/libpmem2/libpmem2.link.in b/src/libpmem2/libpmem2.link.in index 3017d9b6dbfbfcc5f4b7ae87976a53c21967d7bd..1e59becc84223b50920a19ec83baec67969b19c1 100644 --- a/src/libpmem2/libpmem2.link.in +++ b/src/libpmem2/libpmem2.link.in @@ -17,6 +17,7 @@ LIBPMEM2_1.0 { pmem2_config_set_protection; pmem2_config_set_required_store_granularity; pmem2_config_set_sharing; + pmem2_config_set_vdm; pmem2_config_set_vm_reservation; pmem2_deep_flush; pmem2_errormsg; @@ -32,6 +33,7 @@ LIBPMEM2_1.0 { pmem2_map_get_store_granularity; pmem2_map_new; pmem2_map_from_existing; + pmem2_memcpy_async; pmem2_perror; pmem2_source_alignment; pmem2_source_delete; diff --git a/src/libpmem2/libpmem2.vcxproj b/src/libpmem2/libpmem2.vcxproj index d680afac91d6e347966e348e86bd0583dbe1bce4..12fa556df42d25ca970ad0c80a0ade62eae45c24 100644 --- a/src/libpmem2/libpmem2.vcxproj +++ b/src/libpmem2/libpmem2.vcxproj @@ -12,6 +12,7 @@ </ItemGroup> <ItemGroup> <ClCompile Include="..\core\alloc.c" /> + <ClCompile Include="..\core\membuf.c" /> <ClCompile Include="..\core\os_thread_windows.c" /> <ClCompile Include="..\core\os_windows.c" /> <ClCompile Include="..\core\out.c" /> @@ -31,6 +32,7 @@ <ClCompile Include="map_windows.c" /> <ClCompile Include="mcsafe_ops_windows.c" /> <ClCompile Include="memops_generic.c" /> + <ClCompile Include="mover.c" /> <ClCompile Include="numa_none.c" /> <ClCompile Include="persist.c" /> <ClCompile Include="persist_windows.c" /> @@ -72,6 +74,7 @@ <ClInclude Include="deep_flush.h" /> <ClInclude Include="config.h" /> <ClInclude Include="map.h" /> + <ClInclude Include="mover.h" /> <ClInclude Include="persist.h" /> <ClInclude Include="pmem2.h" /> <ClInclude Include="pmem2_arch.h" /> @@ -135,10 +138,10 @@ <Import Project="..\windows\libs_release.props" /> </ImportGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);x86_64\</IncludePath> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(solutionDir)deps\miniasync\src\include;x86_64\</IncludePath> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);x86_64\</IncludePath> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(solutionDir)deps\miniasync\src\include;x86_64\</IncludePath> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> diff --git a/src/libpmem2/libpmem2.vcxproj.filters b/src/libpmem2/libpmem2.vcxproj.filters index 0358a1f917905f4fa73327695f7f4d80e9043cd4..d8f7c1c76bf038eab963497a59f02203cafb7cc1 100644 --- a/src/libpmem2/libpmem2.vcxproj.filters +++ b/src/libpmem2/libpmem2.vcxproj.filters @@ -141,6 +141,12 @@ <ClCompile Include="mcsafe_ops_windows.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\core\membuf.c"> + <Filter>Source Files\common</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\core\os_thread.h"> @@ -215,6 +221,15 @@ <ClInclude Include="vm_reservation.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="x86_64\memset\memset_movdir64b.h"> + <Filter>Header Files\x86_64</Filter> + </ClInclude> + <ClInclude Include="x86_64\memcpy\memcpy_movdir64b.h"> + <Filter>Header Files\x86_64</Filter> + </ClInclude> + <ClInclude Include="mover.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="libpmem2.def"> diff --git a/src/libpmem2/map.c b/src/libpmem2/map.c index e617093fb3247b264e07d573da0ba0230d132d3a..5ec0b84ea700d34d29d7bdd3b3e8405c326eadd3 100644 --- a/src/libpmem2/map.c +++ b/src/libpmem2/map.c @@ -10,13 +10,14 @@ #include "alloc.h" #include "config.h" #include "map.h" -#include "ravl_interval.h" +#include "mover.h" #include "os.h" #include "os_thread.h" #include "persist.h" #include "pmem2.h" #include "pmem2_utils.h" #include "ravl.h" +#include "ravl_interval.h" #include "sys_util.h" #include "valgrind_internal.h" @@ -269,20 +270,26 @@ pmem2_map_from_existing(struct pmem2_map **map_ptr, pmem2_set_mem_fns(map); map->source = *src; + /* XXX: there is no way to set custom vdm in this function */ + ret = mover_new(map, &map->vdm); + if (ret) { + goto err_map; + } + map->custom_vdm = false; + #ifndef _WIN32 /* fd should not be used after map */ map->source.value.fd = INVALID_FD; #endif ret = pmem2_register_mapping(map); if (ret) { - Free(map); if (ret == -EEXIST) { ERR( "Provided mapping(addr %p len %zu) is already registered by libpmem2", addr, len); - return PMEM2_E_MAP_EXISTS; + ret = PMEM2_E_MAP_EXISTS; } - return ret; + goto err_vdm; } #ifndef _WIN32 if (src->type == PMEM2_SOURCE_FD) { @@ -292,4 +299,10 @@ pmem2_map_from_existing(struct pmem2_map **map_ptr, #endif *map_ptr = map; return 0; +err_vdm: + mover_delete(map->vdm); +err_map: + Free(map); + + return ret; } diff --git a/src/libpmem2/map.h b/src/libpmem2/map.h index 9cc172905208627b1be87d37ad7a8f147c849db0..7f2ff847ab95dcdbcdd825b502d31a78cffe29e5 100644 --- a/src/libpmem2/map.h +++ b/src/libpmem2/map.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2019-2020, Intel Corporation */ +/* Copyright 2019-2022, Intel Corporation */ /* * map.h -- internal definitions for libpmem2 @@ -12,6 +12,7 @@ #include "libpmem2.h" #include "os.h" #include "source.h" +#include "libminiasync/vdm.h" #include "vm_reservation.h" #ifdef _WIN32 @@ -43,6 +44,9 @@ struct pmem2_map { struct pmem2_source source; struct pmem2_vm_reservation *reserv; + + struct vdm *vdm; + bool custom_vdm; }; enum pmem2_granularity get_min_granularity(bool eADR, bool is_pmem, diff --git a/src/libpmem2/map_posix.c b/src/libpmem2/map_posix.c index f6113393815e1bc765c1b7f5a8b06ca4a48498e2..b487655bab7c6e6dedc7840bc04acc95e6c96302 100644 --- a/src/libpmem2/map_posix.c +++ b/src/libpmem2/map_posix.c @@ -17,6 +17,7 @@ #include "config.h" #include "file.h" #include "map.h" +#include "mover.h" #include "out.h" #include "persist.h" #include "pmem2_utils.h" @@ -510,9 +511,25 @@ pmem2_map_new(struct pmem2_map **map_ptr, const struct pmem2_config *cfg, map->source = *src; map->source.value.fd = INVALID_FD; /* fd should not be used after map */ + map->custom_vdm = true; + struct vdm *vdm = cfg->vdm; + + if (vdm == NULL) { + /* + * user did not provided custom vdm, + * so we have to use the fallback one. + */ + ret = mover_new(map, &vdm); + if (ret) + goto err_free_map_struct; + map->custom_vdm = false; + } + + map->vdm = vdm; ret = pmem2_register_mapping(map); + if (ret) { - goto err_free_map_struct; + goto err_free_vdm; } if (rsv) { @@ -533,6 +550,9 @@ pmem2_map_new(struct pmem2_map **map_ptr, const struct pmem2_config *cfg, err_unregister_map: pmem2_unregister_mapping(map); +err_free_vdm: + if (!map->custom_vdm) + mover_delete(map->vdm); err_free_map_struct: Free(map); err_undo_mapping: @@ -598,8 +618,10 @@ pmem2_map_delete(struct pmem2_map **map_ptr) if (ret) goto err_register_map; } - } + if (!map->custom_vdm) + mover_delete(map->vdm); + } Free(map); *map_ptr = NULL; diff --git a/src/libpmem2/map_windows.c b/src/libpmem2/map_windows.c index b5359d3023649904d91f4ac9646c933a26bad726..1473d95d64a2156dd880b84791d6fd4d4e6ade8e 100644 --- a/src/libpmem2/map_windows.c +++ b/src/libpmem2/map_windows.c @@ -13,6 +13,7 @@ #include "auto_flush.h" #include "config.h" #include "map.h" +#include "mover.h" #include "os_thread.h" #include "out.h" #include "persist.h" @@ -381,6 +382,22 @@ pmem2_map_new(struct pmem2_map **map_ptr, const struct pmem2_config *cfg, if (!map) goto err_undo_mapping; + map->custom_vdm = true; + struct vdm *vdm = cfg->vdm; + + if (vdm == NULL) { + /* + * user did not provided custom vdm, + * so we have to use the fallback one. + */ + ret = mover_new(map, &vdm); + if (ret) + goto err_free_map_struct; + map->custom_vdm = false; + } + + map->vdm = vdm; + map->addr = base; /* * XXX probably in some cases the reserved length > the content length. @@ -396,7 +413,7 @@ pmem2_map_new(struct pmem2_map **map_ptr, const struct pmem2_config *cfg, ret = pmem2_register_mapping(map); if (ret) { - goto err_free_map_struct; + goto err_free_vdm; } if (rsv) { @@ -412,6 +429,9 @@ pmem2_map_new(struct pmem2_map **map_ptr, const struct pmem2_config *cfg, err_unregister_map: pmem2_unregister_mapping(map); +err_free_vdm: + if (!map->custom_vdm) + mover_delete(map->vdm); err_free_map_struct: free(map); err_undo_mapping: diff --git a/src/libpmem2/mover.c b/src/libpmem2/mover.c new file mode 100644 index 0000000000000000000000000000000000000000..f57549d2c88ae85726ccc6da99bebe4423b9daf4 --- /dev/null +++ b/src/libpmem2/mover.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2021-2022, Intel Corporation */ + +/* + * mover.c -- default pmem2 data mover + */ + +#include "libpmem2.h" +#include "mover.h" +#include "map.h" +#include "membuf.h" +#include "out.h" +#include "pmem2_utils.h" +#include "util.h" +#include <inttypes.h> +#include <stdlib.h> +#include <unistd.h> + +struct data_mover { + struct vdm base; /* must be first */ + struct pmem2_map *map; + struct membuf *membuf; +}; + +struct data_mover_op { + struct vdm_operation op; + int complete; +}; + +/* + * sync_operation_check -- always returns COMPLETE because sync mover operations + * are complete immediately after starting. + */ +static enum future_state +sync_operation_check(void *data, const struct vdm_operation *operation) +{ + LOG(3, "data %p", data); + SUPPRESS_UNUSED(operation); + + struct data_mover_op *sync_op = data; + + int complete; + util_atomic_load_explicit32(&sync_op->complete, &complete, + memory_order_acquire); + + return complete ? FUTURE_STATE_COMPLETE : FUTURE_STATE_IDLE; +} + +/* + * sync_operation_new -- creates a new sync operation + */ +static void * +sync_operation_new(struct vdm *vdm, const enum vdm_operation_type type) +{ + LOG(3, "vdm %p", vdm); + + SUPPRESS_UNUSED(type); + + struct data_mover *vdm_sync = (struct data_mover *)vdm; + struct data_mover_op *sync_op = membuf_alloc(vdm_sync->membuf, + sizeof(struct data_mover_op)); + + if (sync_op == NULL) + return NULL; + + sync_op->complete = 0; + + return sync_op; +} + +/* + * sync_operation_delete -- deletes sync operation + */ +static void +sync_operation_delete(void *data, const struct vdm_operation *operation, + struct vdm_operation_output *output) +{ + output->result = VDM_SUCCESS; + + switch (operation->type) { + case VDM_OPERATION_MEMCPY: + output->type = VDM_OPERATION_MEMCPY; + output->output.memcpy.dest = + operation->data.memcpy.dest; + break; + case VDM_OPERATION_MEMMOVE: + output->type = VDM_OPERATION_MEMMOVE; + output->output.memmove.dest = + operation->data.memcpy.dest; + break; + default: + FATAL("unsupported operation type"); + + } + membuf_free(data); +} + +/* + * sync_operation_start -- start (and perform) a synchronous memory operation + */ +static int +sync_operation_start(void *data, const struct vdm_operation *operation, + struct future_notifier *n) +{ + LOG(3, "data %p op %p, notifier %p", data, operation, n); + struct data_mover_op *sync_data = + (struct data_mover_op *)data; + struct data_mover *mover = membuf_ptr_user_data(data); + if (n) + n->notifier_used = FUTURE_NOTIFIER_NONE; + + switch (operation->type) { + case VDM_OPERATION_MEMCPY: { + pmem2_memcpy_fn memcpy_fn; + memcpy_fn = pmem2_get_memcpy_fn(mover->map); + + memcpy_fn(operation->data.memcpy.dest, + operation->data.memcpy.src, + operation->data.memcpy.n, + PMEM2_F_MEM_NONTEMPORAL); + break; + } + case VDM_OPERATION_MEMMOVE: { + pmem2_memmove_fn memmove_fn; + memmove_fn = pmem2_get_memmove_fn(mover->map); + + memmove_fn(operation->data.memcpy.dest, + operation->data.memcpy.src, + operation->data.memcpy.n, + PMEM2_F_MEM_NONTEMPORAL); + break; + } + default: + FATAL("unsupported operation type"); + } + util_atomic_store_explicit32(&sync_data->complete, + 1, memory_order_release); + + return 0; +} + +static struct vdm data_mover_vdm = { + .op_new = sync_operation_new, + .op_delete = sync_operation_delete, + .op_check = sync_operation_check, + .op_start = sync_operation_start, +}; + +/* + * mover_new -- creates a new synchronous data mover + */ +int +mover_new(struct pmem2_map *map, struct vdm **vdm) +{ + LOG(3, "map %p, vdm %p", map, vdm); + int ret; + struct data_mover *dms = pmem2_malloc(sizeof(*dms), &ret); + if (dms == NULL) + return ret; + + dms->base = data_mover_vdm; + dms->map = map; + *vdm = (struct vdm *)dms; + + dms->membuf = membuf_new(dms); + if (dms->membuf == NULL) { + ret = PMEM2_E_ERRNO; + goto membuf_failed; + } + + return 0; + +membuf_failed: + free(dms); + return ret; +} + +/* + * mover_delete -- deletes a synchronous data mover + */ +void +mover_delete(struct vdm *dms) +{ + membuf_delete(((struct data_mover *)dms)->membuf); + free((struct data_mover *)dms); +} + +/* + * pmem2_memcpy_async -- returns a memcpy future + */ +struct vdm_operation_future +pmem2_memcpy_async(struct pmem2_map *map, + void *pmemdest, const void *src, size_t len, unsigned flags) +{ + LOG(3, "map %p, pmemdest %p, src %p, len %" PRIu64 ", flags %u", + map, pmemdest, src, len, flags); + SUPPRESS_UNUSED(flags); + return vdm_memcpy(map->vdm, pmemdest, (void *)src, len, 0); +} diff --git a/src/libpmem2/mover.h b/src/libpmem2/mover.h new file mode 100644 index 0000000000000000000000000000000000000000..294f6881e5cd96c04e35b6a4ecb5df5b4a5318d1 --- /dev/null +++ b/src/libpmem2/mover.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright 2022, Intel Corporation */ + +/* + * mover.h -- implementation of default datamover + */ +#ifndef PMEM2_MOVER_H +#define PMEM2_MOVER_H + +#include "libpmem2.h" +#include "libminiasync/vdm.h" + +int mover_new(struct pmem2_map *map, struct vdm **vdm); +void mover_delete(struct vdm *vdm); + +#endif /* PMEM2_MOVER_H */ diff --git a/src/libpmemblk/Makefile b/src/libpmemblk/Makefile index 8f5d99ecd403cbb45eebef31614ae7377c14e015..1181828d992da1cda77c28c3f4b226dc7bf69038 100644 --- a/src/libpmemblk/Makefile +++ b/src/libpmemblk/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2020, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/libpmemblk/Makefile -- Makefile for libpmemblk @@ -18,5 +18,5 @@ SOURCE +=\ include ../Makefile.inc -CFLAGS += $(LIBNDCTL_CFLAGS) +CFLAGS += $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) -DPMEM2_USE_MINIASYNC=1 LIBS += -pthread -lpmem $(LIBNDCTL_LIBS) diff --git a/src/libpmemlog/Makefile b/src/libpmemlog/Makefile index 25fa84d1fe8c4736e969cf03fc0b2c2f42fc198b..dc345d88c3f7358253b879b3cf75a6e8e515425f 100644 --- a/src/libpmemlog/Makefile +++ b/src/libpmemlog/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2020, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/libpmemlog/Makefile -- Makefile for libpmemlog @@ -18,6 +18,6 @@ SOURCE +=\ include ../Makefile.inc -CFLAGS += $(LIBNDCTL_CFLAGS) +CFLAGS += $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) -DPMEM2_USE_MINIASYNC=1 LIBS += -pthread -lpmem $(LIBNDCTL_LIBS) diff --git a/src/libpmemobj/Makefile b/src/libpmemobj/Makefile index 6ad3d73e4899861ec1791cfd900a2efc7fa93e10..808904f0da3bec22169947945320dc8a3476e331 100644 --- a/src/libpmemobj/Makefile +++ b/src/libpmemobj/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2020, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/libpmemobj/Makefile -- Makefile for libpmemobj @@ -36,6 +36,6 @@ SOURCE +=\ include ../Makefile.inc -CFLAGS += -DUSE_LIBDL -D_PMEMOBJ_INTRNL $(LIBNDCTL_CFLAGS) +CFLAGS += -DUSE_LIBDL -D_PMEMOBJ_INTRNL $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) -DPMEM2_USE_MINIASYNC=1 LIBS += -pthread -lpmem $(LIBDL) $(LIBNDCTL_LIBS) diff --git a/src/libpmempool/Makefile b/src/libpmempool/Makefile index 0ae33de4c4d6330520320de1b2f297d3b722ba4f..e34e8bab54e5ea827c84344df0ca2aab07b81d10 100644 --- a/src/libpmempool/Makefile +++ b/src/libpmempool/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2016-2020, Intel Corporation +# Copyright 2016-2022, Intel Corporation # # src/libpmempool/Makefile -- Makefile for libpmempool @@ -51,7 +51,7 @@ LIBPMEMBLK_PRIV_FUNCS=btt_info_set btt_arena_datasize btt_flog_size\ include ../Makefile.inc -CFLAGS += $(LIBNDCTL_CFLAGS) +CFLAGS += $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) -DPMEM2_USE_MINIASYNC=1 LIBS += -pthread -lpmem $(LIBDL) $(LIBNDCTL_LIBS) CFLAGS += -DUSE_LIBDL CFLAGS += -DUSE_RPMEM diff --git a/src/libpmemset/libpmemset.vcxproj b/src/libpmemset/libpmemset.vcxproj index 7cd0b0496dbdceb8ac700b0106d9c8b3fb25711c..d47bbc81b6f7b7fa85333379743b526f0ec8436b 100644 --- a/src/libpmemset/libpmemset.vcxproj +++ b/src/libpmemset/libpmemset.vcxproj @@ -86,10 +86,10 @@ <Import Project="..\windows\libs_release.props" /> </ImportGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);x86_64\</IncludePath> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);x86_64\;$(solutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);x86_64\</IncludePath> + <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);x86_64\;$(solutionDir)deps\miniasync\src\include</IncludePath> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" /> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" /> diff --git a/src/test/Makefile b/src/test/Makefile index d2645bf86c59fdb21225e9d62c54e93f99c4fe2d..31de91fd9147cb7b48954896d226210f5ce58c6a 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -225,7 +225,7 @@ PMEM2_TESTS = \ pmem2_vm_reservation\ pmem2_usc -ifeq ($(OS_DIMM),ndctl) +ifeq ($(OS_DIMM),ndctf) PMEM2_TESTS += \ pmem2_badblock_mocks\ pmem2_source_numa @@ -234,6 +234,13 @@ $(info NOTE: Skipping tests because libndctl is disabled (see NDCTL_ENABLE)\ Skipped tests: pmem2_badblock_mocks pmem2_source_numa) endif +ifeq ($(OS_KERNEL_NAME),Linux) +PMEM2_TESTS += pmem2_mover +else +$(info NOTE: Skipping tests because miniasync is not supported on this os.\ + Skipped tests: pmem2_mover) +endif + PMEMPOOL_TESTS = \ pmempool_check\ pmempool_create\ diff --git a/src/test/Makefile.inc b/src/test/Makefile.inc index 6efea208f0f20b2ffa5b91037fe2f09488a3478e..90ffd5c3e2ebbfb1a6e34d8ef5e7c3f10b5ce906 100644 --- a/src/test/Makefile.inc +++ b/src/test/Makefile.inc @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2021, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # @@ -210,6 +210,7 @@ OBJS +=\ $(TOP)/src/debug/libpmem2/config.o\ $(TOP)/src/debug/libpmem2/errormsg.o\ $(TOP)/src/debug/libpmem2/libpmem2.o\ + $(TOP)/src/debug/libpmem2/mover.o\ $(TOP)/src/debug/libpmem2/map.o\ $(TOP)/src/debug/libpmem2/mcsafe_ops_posix.o\ $(TOP)/src/debug/libpmem2/map_posix.o\ @@ -255,6 +256,8 @@ OBJS += $(addprefix $(TOP)/src/nondebug/libpmem2/, ${OBJS_MEM}) INCS += -I$(TOP)/src/common INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2/$(ARCH) +INCS += $(MINIASYNC_CFLAGS) + endif ifeq ($(LIBPMEM2), internal-nondebug) @@ -268,6 +271,7 @@ OBJS +=\ $(TOP)/src/nondebug/libpmem2/source_posix.o\ $(TOP)/src/nondebug/libpmem2/errormsg.o\ $(TOP)/src/nondebug/libpmem2/map.o\ + $(TOP)/src/nondebug/libpmem2/mover.o\ $(TOP)/src/nondebug/libpmem2/mcsafe_ops_posix.o\ $(TOP)/src/nondebug/libpmem2/map_posix.o\ $(TOP)/src/nondebug/libpmem2/memops_generic.o\ @@ -310,12 +314,14 @@ OBJS += $(addprefix $(TOP)/src/debug/libpmem2/, ${OBJS_MEM}) INCS += -I$(TOP)/src/common INCS += -I$(TOP)/src/libpmem2 INCS += -I$(TOP)/src/libpmem2/$(ARCH) +INCS += $(MINIASYNC_CFLAGS) endif ifeq ($(LIBPMEM2),y) DYNAMIC_LIBS += -lpmem2 STATIC_DEBUG_LIBS += $(LIBS_DIR)/debug/libpmem2.a STATIC_NONDEBUG_LIBS += $(LIBS_DIR)/nondebug/libpmem2.a +INCS += $(MINIASYNC_CFLAGS) endif ifeq ($(LIBPMEMCOMMON), y) @@ -445,12 +451,14 @@ ifeq ($(LIBPMEMCORE), y) LIBPMEM=y OBJS += $(LIBS_DIR)/debug/libpmemcore.a INCS += -I$(TOP)/src/core +INCS += $(MINIASYNC_CFLAGS) endif ifeq ($(LIBPMEMCORE), internal-nondebug) OBJS +=\ $(TOP)/src/nondebug/core/alloc.o\ $(TOP)/src/nondebug/core/fs_posix.o\ + $(TOP)/src/nondebug/core/membuf.o\ $(TOP)/src/nondebug/core/os_posix.o\ $(TOP)/src/nondebug/core/os_thread_posix.o\ $(TOP)/src/nondebug/core/out.o\ @@ -460,12 +468,14 @@ OBJS +=\ $(TOP)/src/nondebug/core/util_posix.o INCS += -I$(TOP)/src/core +INCS += $(MINIASYNC_CFLAGS) endif ifeq ($(LIBPMEMCORE), internal-debug) OBJS +=\ $(TOP)/src/debug/core/alloc.o\ $(TOP)/src/debug/core/fs_posix.o\ + $(TOP)/src/debug/core/membuf.o\ $(TOP)/src/debug/core/os_posix.o\ $(TOP)/src/debug/core/os_thread_posix.o\ $(TOP)/src/debug/core/out.o\ @@ -475,6 +485,7 @@ OBJS +=\ $(TOP)/src/debug/core/util_posix.o INCS += -I$(TOP)/src/core +INCS += $(MINIASYNC_CFLAGS) endif ifeq ($(LIBPMEM),y) @@ -502,6 +513,12 @@ CFLAGS += $(LIBNDCTL_CFLAGS) LIBS += $(LIBNDCTL_LIBS) endif +ifeq ($(LINMINIASYNC),y) +LIBS += -lminiasync +# XXX: remover when we will swich to installed libminiasync +LIBS += -L$(TOP)/src/deps/miniasync/build/out +endif + # # This is a helper function to be combined with usage of macros available # in the unittest framework. It scans the code for functions that should be diff --git a/src/test/pmem2_granularity/pmem2_granularity.vcxproj b/src/test/pmem2_granularity/pmem2_granularity.vcxproj index a908e8f4069060176d6bcbbe562378fca211ea43..27a3974550f065e78f18a65664feb2ec4b936007 100644 --- a/src/test/pmem2_granularity/pmem2_granularity.vcxproj +++ b/src/test/pmem2_granularity/pmem2_granularity.vcxproj @@ -76,6 +76,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\core\ravl.c" /> <ClCompile Include="..\..\libpmem2\auto_flush_windows.c" /> <ClCompile Include="..\..\libpmem2\deep_flush_windows.c" /> @@ -84,6 +85,7 @@ <ClCompile Include="..\..\libpmem2\map.c" /> <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\core\ravl_interval.c" /> @@ -103,6 +105,7 @@ <ClCompile Include="pmem2_granularity.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> <ClInclude Include="..\..\libpmem2\config.h" /> <ClInclude Include="..\..\libpmem2\map.h" /> <ClInclude Include="..\..\core\ravl_interval.h" /> diff --git a/src/test/pmem2_granularity/pmem2_granularity.vcxproj.filters b/src/test/pmem2_granularity/pmem2_granularity.vcxproj.filters index 9824b9990135dee3fc745a6af142042cd255b4a9..5ded3e4fe7cedf1ddeeb4a8c70e0eb02b13a7591 100644 --- a/src/test/pmem2_granularity/pmem2_granularity.vcxproj.filters +++ b/src/test/pmem2_granularity/pmem2_granularity.vcxproj.filters @@ -74,6 +74,12 @@ <ClCompile Include="..\..\core\ravl_interval.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\libpmem2\mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\core\membuf.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\unittest\ut_pmem2_utils.h"> @@ -100,6 +106,9 @@ <ClInclude Include="..\..\core\ravl_interval.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\core\membuf.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="TESTS.py"> diff --git a/src/test/pmem2_map/pmem2_map.c b/src/test/pmem2_map/pmem2_map.c index 95eb79b98c3e171175a99ffa67686622c8b05786..6a2803c12f9bbc3d1ecebeb5a8e571ab6102b8f4 100644 --- a/src/test/pmem2_map/pmem2_map.c +++ b/src/test/pmem2_map/pmem2_map.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2019-2021, Intel Corporation */ +/* Copyright 2019-2022, Intel Corporation */ /* * pmem2_map.c -- pmem2_map unittests @@ -11,6 +11,7 @@ #include "pmem2_utils.h" #include "source.h" #include "map.h" +#include "mover.h" #include "out.h" #include "pmem2.h" #include "unittest.h" @@ -50,6 +51,12 @@ prepare_map(struct pmem2_map **map_ptr, UT_ASSERTne(mh, NULL); UT_ASSERTne(GetLastError(), ERROR_ALREADY_EXISTS); + struct vdm *vdm; + mover_new(map, &vdm); + UT_ASSERTne(map, NULL); + map->custom_vdm = true; + map->vdm = vdm; + map->addr = MapViewOfFileEx(mh, FILE_MAP_ALL_ACCESS, HIDWORD(cfg->offset), @@ -91,6 +98,12 @@ prepare_map(struct pmem2_map **map_ptr, struct pmem2_map *map = malloc(sizeof(*map)); UT_ASSERTne(map, NULL); + struct vdm *vdm; + mover_new(map, &vdm); + UT_ASSERTne(map, NULL); + map->custom_vdm = true; + map->vdm = vdm; + UT_ASSERTeq(src->type, PMEM2_SOURCE_FD); map->addr = mmap(NULL, cfg->length, proto, flags, src->value.fd, offset); diff --git a/src/test/pmem2_map/pmem2_map.vcxproj b/src/test/pmem2_map/pmem2_map.vcxproj index d20080c24979d67b2fde576c05dea6f5eb045c63..ee41737bee068f73d896e7e726201fcf7dc959bc 100644 --- a/src/test/pmem2_map/pmem2_map.vcxproj +++ b/src/test/pmem2_map/pmem2_map.vcxproj @@ -77,6 +77,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\core\ravl.c" /> <ClCompile Include="..\..\libpmem2\config.c" /> <ClCompile Include="..\..\libpmem2\deep_flush_windows.c" /> @@ -85,6 +86,7 @@ <ClCompile Include="..\..\libpmem2\map.c" /> <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\pmem2_utils.c" /> @@ -99,6 +101,7 @@ <ClCompile Include="pmem2_map.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> <ClInclude Include="..\..\libpmem2\config.h" /> <ClInclude Include="..\..\libpmem2\map.h" /> <ClInclude Include="..\..\libpmem2\pmem2.h" /> diff --git a/src/test/pmem2_map/pmem2_map.vcxproj.filters b/src/test/pmem2_map/pmem2_map.vcxproj.filters index 4ada61888341d78ca459791847b18cbe0d6d6886..1bf51fef5768bc51c0541c1e9901f949cc989264 100644 --- a/src/test/pmem2_map/pmem2_map.vcxproj.filters +++ b/src/test/pmem2_map/pmem2_map.vcxproj.filters @@ -74,6 +74,12 @@ <ClCompile Include="..\..\core\ravl_interval.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\libpmem2\mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\core\membuf.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\libpmem2\config.h"> @@ -97,6 +103,9 @@ <ClInclude Include="..\..\core\ravl_interval.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\core\membuf.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="TESTS.py"> diff --git a/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj b/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj index 6fe48e661f0c0080d8913de5a283b22ddf2ba084..5f5c042d94d851239ee4ae04b490397605f98395 100644 --- a/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj +++ b/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj @@ -77,6 +77,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\core\ravl.c" /> <ClCompile Include="..\..\libpmem2\config.c" /> <ClCompile Include="..\..\libpmem2\deep_flush_windows.c" /> @@ -85,6 +86,7 @@ <ClCompile Include="..\..\libpmem2\map.c" /> <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\pmem2_utils.c" /> @@ -99,6 +101,8 @@ <ClCompile Include="pmem2_map_from_existing.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> + <ClInclude Include="..\..\core\os_thread.h" /> <ClInclude Include="..\..\libpmem2\config.h" /> <ClInclude Include="..\..\libpmem2\map.h" /> <ClInclude Include="..\..\libpmem2\pmem2.h" /> diff --git a/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj.filters b/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj.filters index 6e69d84763302ebf7116011060fa94d04d7665e3..35c07a45708b7eb2d4f12957208b1de84a78f10d 100644 --- a/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj.filters +++ b/src/test/pmem2_map_from_existing/pmem2_map_from_existing.vcxproj.filters @@ -74,6 +74,12 @@ <ClCompile Include="..\..\core\ravl_interval.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\libpmem2\mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\core\membuf.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\libpmem2\config.h"> @@ -97,6 +103,12 @@ <ClInclude Include="..\..\core\ravl_interval.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\core\os_thread.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\core\membuf.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="TESTS.py"> diff --git a/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj b/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj index ac8097fec77bcde90501175a8f5dd9546635b7b5..7c9a14a9a7b09c6de90aa0708f16bfd168b54d27 100644 --- a/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj +++ b/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj @@ -77,6 +77,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\core\ravl.c" /> <ClCompile Include="..\..\libpmem2\config.c" /> <ClCompile Include="..\..\libpmem2\deep_flush_windows.c" /> @@ -85,6 +86,7 @@ <ClCompile Include="..\..\libpmem2\map.c" /> <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\pmem2_utils.c" /> @@ -100,6 +102,7 @@ <ClCompile Include="pmem2_map_prot.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> <ClInclude Include="..\..\libpmem2\config.h" /> <ClInclude Include="..\..\libpmem2\map.h" /> <ClInclude Include="..\..\libpmem2\pmem2.h" /> diff --git a/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj.filters b/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj.filters index 7f7ebf89f68a88f4086101b55bb01f4dae75a9c7..6ea043e07868bbf941202723e42e1f0dc6749a76 100644 --- a/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj.filters +++ b/src/test/pmem2_map_prot/pmem2_map_prot.vcxproj.filters @@ -77,6 +77,12 @@ <ClCompile Include="..\..\core\ravl_interval.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\libpmem2\mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\core\membuf.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\libpmem2\config.h"> @@ -97,6 +103,9 @@ <ClInclude Include="..\..\core\ravl_interval.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\core\membuf.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="TESTS.py"> diff --git a/src/test/pmem2_mover/.gitignore b/src/test/pmem2_mover/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1890223048165b35604fb630798de4f7f1b46a0f --- /dev/null +++ b/src/test/pmem2_mover/.gitignore @@ -0,0 +1 @@ +pmem2_mover diff --git a/src/test/pmem2_mover/Makefile b/src/test/pmem2_mover/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..1aed2bcefff0c0ea33fdc0601797bbd986be409f --- /dev/null +++ b/src/test/pmem2_mover/Makefile @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2022, Intel Corporation + +# +# src/test/pmem2_mover/Makefile -- build pmem2_mover test +# +TOP = ../../.. + +vpath %.c $(TOP)/src/test/unittest + +TARGET = pmem2_mover +OBJS = pmem2_mover.o\ + ut_pmem2_utils.o\ + ut_pmem2_config.o\ + ut_pmem2_source.o\ + ut_pmem2_setup_integration.o + +LIBPMEM2=y +LINMINIASYNC=y +include ../Makefile.inc diff --git a/src/test/pmem2_mover/TESTS.py b/src/test/pmem2_mover/TESTS.py new file mode 100644 index 0000000000000000000000000000000000000000..e0243780a6779904d0bac1ba549a466f881897bf --- /dev/null +++ b/src/test/pmem2_mover/TESTS.py @@ -0,0 +1,61 @@ +#!../env.py +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2022, Intel Corporation +# + + +import sys + +import testframework as t +from testframework import granularity as g +from consts import MINIASYNC_LIBDIR + + +@t.freebsd_exclude +class PMEM2_MOVER(t.Test): + test_type = t.Medium + + def setup(self, ctx): + super().setup(ctx) + if sys.platform == 'win32': + env_dir = 'PATH' + path = ctx.env[env_dir] + ctx.env[env_dir] = path + ";" + MINIASYNC_LIBDIR + else: + env_dir = 'LD_LIBRARY_PATH' + path = ctx.env[env_dir] + ctx.env[env_dir] = path + ":" + MINIASYNC_LIBDIR + self.filepath = ctx.create_holey_file(16 * t.MiB, 'testfile') + + def run(self, ctx): + ctx.exec('pmem2_mover', self.test_case, self.filepath) + + +@g.require_granularity(g.BYTE, g.CACHELINE) +class PMEM2_MOVER_MT(PMEM2_MOVER): + thread_num = 2 + + def run(self, ctx): + ctx.exec('pmem2_mover', self.test_case, self.filepath, self.thread_num) + + +class TEST0(PMEM2_MOVER): + """verify pmem2 mover functionality""" + test_case = "test_mover_basic" + + +class TEST1(PMEM2_MOVER_MT): + """verify pmem2 mover multi-threaded functionality""" + test_case = "test_mover_multithreaded" + + +class TEST2(PMEM2_MOVER_MT): + test_type = t.Long + thread_num = 16 + """verify pmem2 mover multi-threaded functionality (Long)""" + test_case = "test_mover_multithreaded" + + +class TEST3(PMEM2_MOVER): + """verify pmem2 mover functionality""" + test_case = "test_miniasync_mover" diff --git a/src/test/pmem2_mover/pmem2_mover.c b/src/test/pmem2_mover/pmem2_mover.c new file mode 100644 index 0000000000000000000000000000000000000000..99db7807b692bee29100acd8fd5240565e52f7d5 --- /dev/null +++ b/src/test/pmem2_mover/pmem2_mover.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* Copyright 2019-2022, Intel Corporation */ + +/* + * pmem2_mover.c -- pmem2 mover tests + */ + +#define PMEM2_USE_MINIASYNC 1 +#include "libpmem2.h" +#include "unittest.h" +#include "ut_pmem2.h" +#include "ut_pmem2_setup_integration.h" + +#include <libminiasync.h> +/* + * map_valid -- return valid mapped pmem2_map + */ +static struct pmem2_map * +map_valid(struct pmem2_config *cfg, struct pmem2_source *src) +{ + struct pmem2_map *map = NULL; + int ret = pmem2_map_new(&map, cfg, src); + UT_PMEM2_EXPECT_RETURN(ret, 0); + UT_ASSERTne(map, NULL); + + return map; +} + +/* + * test_mover_basic -- test basic functionality of pmem2 default mover + */ +static int +test_mover_basic(const struct test_case *tc, int argc, char *argv[]) +{ + if (argc < 1) + UT_FATAL("usage: test_mover_basic <file>"); + + char *file = argv[0]; + int fd = OPEN(file, O_RDWR); + + struct pmem2_source *src; + struct pmem2_config *cfg; + PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, + PMEM2_GRANULARITY_PAGE); + + struct pmem2_map *map = map_valid(cfg, src); + char *data = pmem2_map_get_address(map); + pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); + memset_fn(data, 0xBA, 4096, 0); + memset_fn(data + 4096, 0xAB, 4096, 0); + struct vdm_operation_future cpy = + pmem2_memcpy_async(map, data, data + 4096, 4096, 0); + + FUTURE_BUSY_POLL(&cpy); + + if (memcmp(data, data + 4096, 4096)) + UT_FATAL("data should be equal"); + + pmem2_map_delete(&map); + pmem2_config_delete(&cfg); + pmem2_source_delete(&src); + CLOSE(fd); + return 1; +} + +#define WORKER_RUNS 20000 +#define TEST_SIZE 4096 +struct thread_arg { + struct pmem2_map *map; + void *addr; + unsigned threads; + unsigned thread_id; +}; + +/* + * thread_worker -- thread worker for test_mover_multithread + */ +static void * +thread_worker(void *arg) +{ + struct thread_arg *targ = arg; + unsigned *pattern1, *pattern2; + + UT_COMPILE_ERROR_ON(TEST_SIZE % sizeof(*pattern1) != 0); + unsigned array_size = TEST_SIZE / sizeof(*pattern1); + + pattern1 = MALLOC(array_size * sizeof(*pattern1)); + pattern2 = MALLOC(array_size * sizeof(*pattern2)); + + for (unsigned j = 0; j < array_size; j++) { + pattern1[j] = targ->thread_id + 1 * targ->threads; + pattern2[j] = targ->thread_id + 2 * targ->threads; + } + + for (int i = 0; i < WORKER_RUNS; i++) { + unsigned *pattern = i % 2 ? pattern1 : pattern2; + struct vdm_operation_future cpy = + pmem2_memcpy_async(targ->map, targ->addr, pattern, + TEST_SIZE, 0); + + FUTURE_BUSY_POLL(&cpy); + + if (memcmp(pattern, targ->addr, TEST_SIZE)) + UT_FATAL("data should be equal"); + } + FREE(pattern1); + FREE(pattern2); + return NULL; +} + +/* + * test_mover_multithreaded -- multi-threaded test for the memcpy + */ +static int +test_mover_multithreaded(const struct test_case *tc, int argc, char *argv[]) +{ + if (argc < 2) + UT_FATAL("usage: test_mover_basic <file> <threads>"); + + char *file = argv[0]; + int fd = OPEN(file, O_RDWR); + unsigned long num_threads = STRTOUL(argv[1], NULL, 10); + + struct pmem2_source *src; + struct pmem2_config *cfg; + PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, + PMEM2_GRANULARITY_PAGE); + + struct pmem2_map *map = map_valid(cfg, src); + + UT_ASSERT(pmem2_map_get_size(map) >= TEST_SIZE * num_threads); + + os_thread_t *threads + = MALLOC(num_threads * sizeof(*threads)); + struct thread_arg *args = MALLOC(num_threads * sizeof(*args)); + + char *data = pmem2_map_get_address(map); + for (unsigned i = 0; i < num_threads; i++) { + args[i].map = map; + args[i].addr = data + i * TEST_SIZE; + args[i].threads = num_threads; + args[i].thread_id = i; + + THREAD_CREATE(&threads[i], NULL, thread_worker, + &args[i]); + } + + for (unsigned i = 0; i < num_threads; i++) { + THREAD_JOIN(&threads[i], NULL); + } + + FREE(threads); + FREE(args); + + pmem2_map_delete(&map); + pmem2_config_delete(&cfg); + pmem2_source_delete(&src); + CLOSE(fd); + return 2; +} + +/* + * test_miniasync_mover -- test memcpy async with miniasync mover + */ +static int +test_miniasync_mover(const struct test_case *tc, int argc, char *argv[]) +{ + if (argc < 1) + UT_FATAL("usage: test_miniasync_mover <file>"); + + char *file = argv[0]; + int fd = OPEN(file, O_RDWR); + + struct pmem2_source *src; + struct pmem2_config *cfg; + PMEM2_PREPARE_CONFIG_INTEGRATION(&cfg, &src, fd, + PMEM2_GRANULARITY_PAGE); + struct data_mover_sync *dms = data_mover_sync_new(); + UT_ASSERTne(dms, NULL); + + struct vdm *vdm = data_mover_sync_get_vdm(dms); + UT_ASSERTne(vdm, NULL); + + pmem2_config_set_vdm(cfg, vdm); + struct pmem2_map *map = map_valid(cfg, src); + char *data = pmem2_map_get_address(map); + pmem2_memset_fn memset_fn = pmem2_get_memset_fn(map); + memset_fn(data, 0xBA, 4096, 0); + memset_fn(data + 4096, 0xAB, 4096, 0); + struct vdm_operation_future cpy = + pmem2_memcpy_async(map, data, data + 4096, 4096, 0); + + FUTURE_BUSY_POLL(&cpy); + + if (memcmp(data, data + 4096, 4096)) + UT_FATAL("data should be equal"); + + pmem2_map_delete(&map); + pmem2_config_delete(&cfg); + pmem2_source_delete(&src); + CLOSE(fd); + return 1; +} + +/* + * test_cases -- available test cases + */ +static struct test_case test_cases[] = { + TEST_CASE(test_mover_basic), + TEST_CASE(test_mover_multithreaded), + TEST_CASE(test_miniasync_mover) +}; + +#define NTESTS (sizeof(test_cases) / sizeof(test_cases[0])) + +int +main(int argc, char *argv[]) +{ + START(argc, argv, "pmem2_mover"); + TEST_CASE_PROCESS(argc, argv, test_cases, NTESTS); + DONE(NULL); +} diff --git a/src/test/pmem2_mover/pmem2_mover.vcxproj b/src/test/pmem2_mover/pmem2_mover.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..f3b4ff1d13fd45051aa61d9312422275622f8266 --- /dev/null +++ b/src/test/pmem2_mover/pmem2_mover.vcxproj @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4870E3C3-63A1-4702-9E61-47ABCFF3AB0F}</ProjectGuid> + <RootNamespace>pmem2_mover</RootNamespace> + <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v143</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\test_debug.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\test_release.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LibraryPath>$(solutionDir)deps\miniasync\build\src\Release;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LibraryPath>$(solutionDir)deps\miniasync\build\src\Release;$(LibraryPath)</LibraryPath> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>PMDK_UTF8_API;SDS_ENABLED;NTDDI_VERSION=NTDDI_WIN10_RS1;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalDependencies>miniasync.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <AdditionalIncludeDirectories>$(SolutionDir)\libpmem2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>miniasync.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\unittest\ut_pmem2_config.c" /> + <ClCompile Include="..\unittest\ut_pmem2_source.c" /> + <ClCompile Include="..\unittest\ut_pmem2_utils.c" /> + <ClCompile Include="..\unittest\ut_pmem2_setup_integration.c" /> + <ClCompile Include="pmem2_mover.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\unittest\unittest.h" /> + <ClInclude Include="..\unittest\ut_pmem2.h" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\libpmem2\libpmem2.vcxproj"> + <Project>{f596c36c-5c96-4f08-b420-8908af500954}</Project> + </ProjectReference> + <ProjectReference Include="..\unittest\libut.vcxproj"> + <Project>{ce3f2dfb-8470-4802-ad37-21caf6cb2681}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <None Include="pmemcheck4.log.match" /> + <None Include="TESTS.py" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/test/pmem2_mover/pmem2_mover.vcxproj.filters b/src/test/pmem2_mover/pmem2_mover.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..d4d81fa2b56ebbd569b5d67267de23a2b36357c4 --- /dev/null +++ b/src/test/pmem2_mover/pmem2_mover.vcxproj.filters @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Test Scripts"> + <UniqueIdentifier>{4c1dd0a5-269b-43ca-aadb-69c54b295dc2}</UniqueIdentifier> + </Filter> + <Filter Include="Match Files"> + <UniqueIdentifier>{92f1ac35-e06e-4934-8606-adae8fb61b52}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\unittest\ut_pmem2_utils.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="pmem2_mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\unittest\ut_pmem2_config.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\unittest\ut_pmem2_source.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\unittest\ut_pmem2_setup_integration.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\unittest\unittest.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\unittest\ut_pmem2.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="TESTS.py"> + <Filter>Test Scripts</Filter> + </None> + <None Include="pmemcheck4.log.match"> + <Filter>Match Files</Filter> + </None> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/test/pmem2_source/pmem2_source.vcxproj b/src/test/pmem2_source/pmem2_source.vcxproj index 08467dddbb6a975212c5b4ef22546ee9bb968ef1..9cbc79c87e47d32a3b989764e4025dfe7a04f405 100644 --- a/src/test/pmem2_source/pmem2_source.vcxproj +++ b/src/test/pmem2_source/pmem2_source.vcxproj @@ -77,6 +77,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\libpmem2\config.c" /> <ClCompile Include="..\..\libpmem2\deep_flush_windows.c" /> <ClCompile Include="..\..\libpmem2\libpmem2.c" /> @@ -84,6 +85,7 @@ <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\mcsafe_ops_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\source.c" /> @@ -99,6 +101,7 @@ <ClCompile Include="pmem2_source.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> <ClInclude Include="..\..\libpmem2\config.h" /> <ClInclude Include="..\..\libpmem2\pmem2.h" /> <ClInclude Include="..\..\libpmem2\pmem2_utils.h" /> diff --git a/src/test/pmem2_source/pmem2_source.vcxproj.filters b/src/test/pmem2_source/pmem2_source.vcxproj.filters index cc96ba9957f320fd5f7accf894416a6911afa7b6..034d8fd643d43df46bea5a1d964d208dfb012cf6 100644 --- a/src/test/pmem2_source/pmem2_source.vcxproj.filters +++ b/src/test/pmem2_source/pmem2_source.vcxproj.filters @@ -21,6 +21,8 @@ <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\x86_64\cpu.c" /> <ClCompile Include="..\..\libpmem2\libpmem2.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> + <ClCompile Include="..\..\core\membuf.c" /> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\libpmem2\config.h" /> @@ -28,5 +30,6 @@ <ClInclude Include="..\..\libpmem2\pmem2_utils.h" /> <ClInclude Include="..\unittest\ut_pmem2_config.h" /> <ClInclude Include="..\unittest\ut_pmem2_utils.h" /> + <ClInclude Include="..\..\core\membuf.h" /> </ItemGroup> </Project> \ No newline at end of file diff --git a/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj b/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj index 885fd9eeec0f8890eda09da8a8cabdcd43dc868a..4bb81a2f26a5b36d913cc8243ec7db179e1b74b7 100644 --- a/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj +++ b/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj @@ -77,6 +77,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\core\ravl.c" /> <ClCompile Include="..\..\libpmem2\config.c" /> <ClCompile Include="..\..\libpmem2\deep_flush_windows.c" /> @@ -85,6 +86,7 @@ <ClCompile Include="..\..\libpmem2\map.c" /> <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\pmem2_utils.c" /> @@ -99,6 +101,7 @@ <ClCompile Include="pmem2_vm_reservation.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> <ClInclude Include="..\..\libpmem2\config.h" /> <ClInclude Include="..\..\libpmem2\map.h" /> <ClInclude Include="..\..\libpmem2\pmem2.h" /> diff --git a/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj.filters b/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj.filters index 3a04d1e6e84f2c96a37cbf003b7bf7f2300a9999..0077b85a9e9e0d2317ba83cf7ae864ceb667d7c6 100644 --- a/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj.filters +++ b/src/test/pmem2_vm_reservation/pmem2_vm_reservation.vcxproj.filters @@ -74,6 +74,12 @@ <ClCompile Include="..\..\core\ravl_interval.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\libpmem2\mover.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\core\membuf.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\libpmem2\config.h"> @@ -97,6 +103,9 @@ <ClInclude Include="..\..\core\ravl_interval.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\core\membuf.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="TESTS.py"> diff --git a/src/test/scope/out13.log.match b/src/test/scope/out13.log.match index a611e3206f332fbe9b8f10ae0951323d07d90d05..0cd04d146f37ec950b02696c3bbb98ba2135fd1c 100644 --- a/src/test/scope/out13.log.match +++ b/src/test/scope/out13.log.match @@ -9,6 +9,7 @@ pmem2_config_set_offset$(nW) pmem2_config_set_protection$(nW) pmem2_config_set_required_store_granularity$(nW) pmem2_config_set_sharing$(nW) +pmem2_config_set_vdm$(nW) pmem2_config_set_vm_reservation$(nW) pmem2_deep_flush$(nW) pmem2_errormsg$(nW) @@ -24,6 +25,7 @@ pmem2_map_get_address$(nW) pmem2_map_get_size$(nW) pmem2_map_get_store_granularity$(nW) pmem2_map_new$(nW) +pmem2_memcpy_async$(nW) pmem2_perror$(nW) pmem2_source_alignment$(nW) pmem2_source_delete$(nW) diff --git a/src/test/scope/out14.log.match b/src/test/scope/out14.log.match index 51ce91ee402688632c7115f102baa25ca198eab6..e64fd58b04d723535c18e607bbd1f613e6878adb 100644 --- a/src/test/scope/out14.log.match +++ b/src/test/scope/out14.log.match @@ -10,6 +10,7 @@ pmem2_config_set_offset pmem2_config_set_protection pmem2_config_set_required_store_granularity pmem2_config_set_sharing +pmem2_config_set_vdm pmem2_config_set_vm_reservation pmem2_deep_flush pmem2_errormsgU @@ -26,6 +27,7 @@ pmem2_map_get_address pmem2_map_get_size pmem2_map_get_store_granularity pmem2_map_new +pmem2_memcpy_async pmem2_perrorU pmem2_perrorW pmem2_source_alignment diff --git a/src/test/test_debug.props b/src/test/test_debug.props index b0deaea438f0c1df31730ca4f35bb42d4a6bcf34..7055be2adb0d460bb64d37f0e3cb41f45ae47391 100644 --- a/src/test/test_debug.props +++ b/src/test/test_debug.props @@ -7,6 +7,7 @@ <PropertyGroup> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\tests\</OutDir> <ExecutablePath>$(FrameworkSDKdir)bin\$(TargetPlatformVersion)\$(Platform);$(ExecutablePath)</ExecutablePath> + <IncludePath>$(solutionDir)deps\miniasync\src\include;$(IncludePath)</IncludePath> </PropertyGroup> <ItemDefinitionGroup> <ClCompile> diff --git a/src/test/test_release.props b/src/test/test_release.props index e7876b215b15247236311f58c9c6e27a103dacca..785c963b8c22450ce52e6a84d6b034b3363c5af0 100644 --- a/src/test/test_release.props +++ b/src/test/test_release.props @@ -7,6 +7,7 @@ <PropertyGroup> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\tests\</OutDir> <ExecutablePath>$(FrameworkSDKdir)bin\$(TargetPlatformVersion)\$(Platform);$(ExecutablePath)</ExecutablePath> + <IncludePath>$(solutionDir)deps\miniasync\src\include;$(IncludePath)</IncludePath> </PropertyGroup> <ItemDefinitionGroup> <ClCompile> diff --git a/src/test/unittest/consts.py b/src/test/unittest/consts.py index d8f923d0a2c8a23618bb05b5db07123740e2705f..e90d40c8438ee25a06cc928b452b81dfc19dc829 100644 --- a/src/test/unittest/consts.py +++ b/src/test/unittest/consts.py @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2020, Intel Corporation +# Copyright 2020-2022, Intel Corporation """Test framework constants.""" @@ -21,9 +21,13 @@ WIN_RELEASE_EXEDIR = abspath(join(WIN_RELEASE_BUILDDIR, 'tests')) if sys.platform == 'win32': DEBUG_LIBDIR = abspath(join(WIN_DEBUG_BUILDDIR, 'libs')) RELEASE_LIBDIR = abspath(join(WIN_RELEASE_BUILDDIR, 'libs')) + MINIASYNC_LIBDIR = abspath(join(ROOTDIR, '..', 'deps', 'miniasync', + 'build', 'out', 'Release')) else: DEBUG_LIBDIR = abspath(join(ROOTDIR, '..', 'debug')) RELEASE_LIBDIR = abspath(join(ROOTDIR, '..', 'nondebug')) + MINIASYNC_LIBDIR = abspath(join(ROOTDIR, '..', 'deps', 'miniasync', + 'build', 'out')) HEADER_SIZE = 4096 diff --git a/src/test/util_sds/util_sds.vcxproj b/src/test/util_sds/util_sds.vcxproj index fc3bd218ff94d1e8e1068bc3c8df5938eef8f7d5..fbc7c85f14d6cc25654c69181b76e23046a9e0fc 100644 --- a/src/test/util_sds/util_sds.vcxproj +++ b/src/test/util_sds/util_sds.vcxproj @@ -62,6 +62,7 @@ </ClCompile> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="..\..\core\membuf.c" /> <ClCompile Include="..\..\core\ravl.c" /> <ClCompile Include="..\..\common\shutdown_state.c" /> <ClCompile Include="..\..\libpmem2\auto_flush_windows.c" /> @@ -73,6 +74,7 @@ <ClCompile Include="..\..\libpmem2\map.c" /> <ClCompile Include="..\..\libpmem2\map_windows.c" /> <ClCompile Include="..\..\libpmem2\memops_generic.c" /> + <ClCompile Include="..\..\libpmem2\mover.c" /> <ClCompile Include="..\..\libpmem2\persist.c" /> <ClCompile Include="..\..\libpmem2\persist_windows.c" /> <ClCompile Include="..\..\libpmem2\pmem2_utils.c" /> @@ -124,6 +126,7 @@ </ProjectReference> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\core\membuf.h" /> <ClInclude Include="..\unittest\ut_pmem2.h" /> <ClInclude Include="mocks_windows.h" /> </ItemGroup> diff --git a/src/test/util_sds/util_sds.vcxproj.filters b/src/test/util_sds/util_sds.vcxproj.filters index b072210a4fb7932294f25c9b81a4592febfdb982..a90e98e543d2e77fa9908d0087adebf0bbe840f0 100644 --- a/src/test/util_sds/util_sds.vcxproj.filters +++ b/src/test/util_sds/util_sds.vcxproj.filters @@ -118,6 +118,12 @@ <ClCompile Include="..\..\core\ravl_interval.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\libpmem2\mover.c"> + <Filter>Source Files\pmem2</Filter> + </ClCompile> + <ClCompile Include="..\..\core\membuf.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="mocks_windows.h"> @@ -126,5 +132,8 @@ <ClInclude Include="..\unittest\ut_pmem2.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\core\membuf.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/src/tools/Makefile.inc b/src/tools/Makefile.inc index 4713952cf3615e32b7377b57f81c7388c4eb30ab..509057a8923dcec4749f353c901b0f25313449dd 100644 --- a/src/tools/Makefile.inc +++ b/src/tools/Makefile.inc @@ -1,5 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2014-2020, Intel Corporation +# Copyright 2014-2022, Intel Corporation # # src/tools/Makefile.inc -- Makefile include for all tools # @@ -176,7 +176,7 @@ ifeq ($(LIBPMEM2),y) DYNAMIC_LIBS += -lpmem2 STATIC_DEBUG_LIBS += $(LIBSDIR_DEBUG)/libpmem2.a STATIC_NONDEBUG_LIBS += $(LIBSDIR_NONDEBUG)/libpmem2.a -CFLAGS += $(LIBNDCTL_CFLAGS) +CFLAGS += $(LIBNDCTL_CFLAGS) $(MINIASYNC_CFLAGS) LIBS += $(LIBNDCTL_LIBS) endif diff --git a/src/windows/libs_debug.props b/src/windows/libs_debug.props index 32d4306b00ec28d31c7c5d6cfb14ca8bfa53125f..1f1704fbf501962d8fd1250b455ecf46819162b4 100644 --- a/src/windows/libs_debug.props +++ b/src/windows/libs_debug.props @@ -5,6 +5,7 @@ <PropertyGroup> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\libs\</OutDir> <ExecutablePath>$(FrameworkSDKdir)bin\$(TargetPlatformVersion)\$(Platform);$(ExecutablePath)</ExecutablePath> + <IncludePath>$(solutionDir)deps\miniasync\src\include;$(IncludePath)</IncludePath> </PropertyGroup> <ItemDefinitionGroup> <ClCompile> diff --git a/src/windows/libs_release.props b/src/windows/libs_release.props index 20728c2aa8e1719bc7314c2f31b00c1896b9e177..877536bc9861d9f21c60a484e340fecbac4bd84f 100644 --- a/src/windows/libs_release.props +++ b/src/windows/libs_release.props @@ -5,6 +5,7 @@ <PropertyGroup> <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\libs\</OutDir> <ExecutablePath>$(FrameworkSDKdir)bin\$(TargetPlatformVersion)\$(Platform);$(ExecutablePath)</ExecutablePath> + <IncludePath>$(solutionDir)deps\miniasync\src\include;$(IncludePath)</IncludePath> </PropertyGroup> <ItemDefinitionGroup> <ClCompile>