From 17968b522b8b6992272a09c1cb95521ccb00f456 Mon Sep 17 00:00:00 2001 From: wonghiu45 Date: Thu, 20 Apr 2023 20:58:18 +0800 Subject: [PATCH] add purgeable memory ndk interface category:bugfix issue:#I6XGXI Signed-off-by: wonghiu45 Change-Id: If82ab2b3e32c03176a2ff902cdb2ddef7ec01c4b --- libpurgeablemem/BUILD.gn | 57 ++++ libpurgeablemem/c/src/purgeable_memory.c | 82 +++++ .../interfaces/kits/c/purgeable_memory.h | 217 ++++++++++++++ libpurgeablemem/libpurgeable_memory.ndk.json | 11 + libpurgeablemem/test/BUILD.gn | 13 + .../test/purgeable_memory_test.cpp | 283 ++++++++++++++++++ 6 files changed, 663 insertions(+) create mode 100644 libpurgeablemem/c/src/purgeable_memory.c create mode 100644 libpurgeablemem/interfaces/kits/c/purgeable_memory.h create mode 100644 libpurgeablemem/libpurgeable_memory.ndk.json create mode 100644 libpurgeablemem/test/purgeable_memory_test.cpp diff --git a/libpurgeablemem/BUILD.gn b/libpurgeablemem/BUILD.gn index bec592f..9c52b7d 100644 --- a/libpurgeablemem/BUILD.gn +++ b/libpurgeablemem/BUILD.gn @@ -18,6 +18,7 @@ config("libpurgeable_config") { "c/include", "common/include", "cpp/include", + "interfaces/kits/c", ] cflags_cc = [ "-fexceptions" ] } @@ -26,6 +27,7 @@ ohos_shared_library("libpurgeablemem") { sources = [ "c/src/purgeable_mem_builder_c.c", "c/src/purgeable_mem_c.c", + "c/src/purgeable_memory.c", "common/src/pm_state_c.c", "common/src/ux_page_table_c.c", "cpp/src/purgeable_ashmem.cpp", @@ -43,3 +45,58 @@ ohos_shared_library("libpurgeablemem") { subsystem_name = "commonlibrary" part_name = "memory_utils" } + +ohos_shared_library("libpurgeablemem") { + sources = [ + "c/src/purgeable_mem_builder_c.c", + "c/src/purgeable_mem_c.c", + "c/src/purgeable_memory.c", + "common/src/pm_state_c.c", + "common/src/ux_page_table_c.c", + "cpp/src/purgeable_ashmem.cpp", + "cpp/src/purgeable_mem.cpp", + "cpp/src/purgeable_mem_base.cpp", + "cpp/src/purgeable_mem_builder.cpp", + "cpp/src/ux_page_table.cpp", + ] + include_dirs = [ "include" ] + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] + public_configs = [ ":libpurgeable_config" ] + subsystem_name = "commonlibrary" + part_name = "memory_utils" +} + +ohos_shared_library("purgeable_memory_ndk") { + include_dirs = [ + "interfaces/kits/c", + ] + + sources = [ "c/src/purgeable_memory.c" ] + deps = [ ":libpurgeablemem" ] + external_deps = [ + "c_utils:utils", + "hiviewdfx_hilog_native:libhilog", + ] + + install_images = [ + system_base_dir, + "updater", + ] + innerapi_tags = [ "ndk" ] + subsystem_name = "commonlibrary" + part_name = "memory_utils" +} + +ohos_ndk_headers("purgeable_memory_header") { + dest_dir = "$ndk_headers_out_dir/purgeable_memory" + sources = [ "interfaces/kits/c/purgeable_memory.h" ] +} + +ohos_ndk_library("libpurgeable_memory_ndk") { + output_name = "purgeable_memory" + ndk_description_file = "./libpurgeable_memory.ndk.json" + system_capability = "SystemCapability.CommonLibrary.PurgeableMemory" +} diff --git a/libpurgeablemem/c/src/purgeable_memory.c b/libpurgeablemem/c/src/purgeable_memory.c new file mode 100644 index 0000000..a9af8dd --- /dev/null +++ b/libpurgeablemem/c/src/purgeable_memory.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ux_page_table_c.h" +#include "purgeable_mem_builder_c.h" +#include "purgeable_mem_c.h" +#include "purgeable_memory.h" + +#undef LOG_TAG +#define LOG_TAG "PurgeableMemNDK" + +struct OH_PurgeableMemory { + void *dataPtr; + size_t dataSizeInput; + struct PurgMemBuilder *builder; + UxPageTableStruct *uxPageTable; + pthread_rwlock_t rwlock; + unsigned int buildDataCount; +}; + +typedef bool (*OH_PurgeableMemory_ModifyFunc)(void *, size_t, void *); +typedef struct OH_PurgeableMemory OH_PurgeableMemory; +typedef struct PurgMem PurgMem; + +OH_PurgeableMemory *OH_PurgeableMemory_Create( + size_t size, OH_PurgeableMemory_ModifyFunc func, void *funcPara) +{ + return (OH_PurgeableMemory *)PurgMemCreate(size, func, funcPara); +} + +bool OH_PurgeableMemory_Destroy(OH_PurgeableMemory *purgObj) +{ + return PurgMemDestroy((PurgMem *)purgObj); +} + +bool OH_PurgeableMemory_BeginRead(OH_PurgeableMemory *purgObj) +{ + return PurgMemBeginRead((PurgMem *)purgObj); +} + +void OH_PurgeableMemory_EndRead(OH_PurgeableMemory *purgObj) +{ + PurgMemEndRead((PurgMem *)purgObj); +} + +bool OH_PurgeableMemory_BeginWrite(OH_PurgeableMemory *purgObj) +{ + return PurgMemBeginWrite((PurgMem *)purgObj); +} + +void OH_PurgeableMemory_EndWrite(OH_PurgeableMemory *purgObj) +{ + PurgMemEndWrite((PurgMem *)purgObj); +} + +void *OH_PurgeableMemory_GetContent(OH_PurgeableMemory *purgObj) +{ + return PurgMemGetContent((PurgMem *)purgObj); +} + +size_t OH_PurgeableMemory_ContentSize(OH_PurgeableMemory *purgObj) +{ + return PurgMemGetContentSize((PurgMem *)purgObj); +} + +bool OH_PurgeableMemory_AppendModify(OH_PurgeableMemory *purgObj, + OH_PurgeableMemory_ModifyFunc func, void *funcPara) +{ + return PurgMemAppendModify((PurgMem *)purgObj, func, funcPara); +} \ No newline at end of file diff --git a/libpurgeablemem/interfaces/kits/c/purgeable_memory.h b/libpurgeablemem/interfaces/kits/c/purgeable_memory.h new file mode 100644 index 0000000..e841cb2 --- /dev/null +++ b/libpurgeablemem/interfaces/kits/c/purgeable_memory.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @addtogroup memory + * @{ + * + * @brief provides memory management capabilities + * + * provides features include operations such as memory alloction, memory free, and so on + * + * @since 10 + * @version 1.0 + */ + +/** + * @file purgeable_memory.h + * + * @brief provides memory management capabilities of purgeable memory. + * + * provides features include create, begin read ,end read, begin write, end write, rebuild, and so on + * + * @since 10 + * @version 1.0 + */ + +#ifndef OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H +#define OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H + +#include /* bool */ +#include /* size_t */ + +#ifdef __cplusplus +extern "C" { +#endif /* End of #ifdef __cplusplus */ + +/** + * @brief Purgeable mem struct + * + * @since 10 + * @version 1.0 + */ +struct OH_PurgeableMemory; + +/** + * @brief Provides the function of accessing purgeable memory objects. + * + * + * + * @since 10 + * @version 1.0 + */ +typedef struct OH_PurgeableMemory OH_PurgeableMemory; + +/* + * @brief: function pointer, it points to a function which build content of a PurgMem obj. + * + * + * @param: void *: data ptr, points to start address of a PurgMem obj's content. + * @param: size_t: data size of the content. + * @param: void *: other private parameters. + * @return: build content result, true means success, while false is fail. + * + * @since 10 + * @version 1.0 + */ +typedef bool (*OH_PurgeableMemory_ModifyFunc)(void *, size_t, void *); + +/* + * @brief: create a PurgMem obj. + * + * + * @param size: data size of a PurgMem obj's content. + * @param func: function pointer, it recover data when the PurgMem obj's content is purged. + * @param funcPara: parameters used by @func. + * @return: a PurgMem obj. + * + * @since 10 + * @version 1.0 + */ +OH_PurgeableMemory *OH_PurgeableMemory_Create( + size_t size, OH_PurgeableMemory_ModifyFunc func, void *funcPara); + +/* + * @brief: destroy a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj to be destroyed. + * @return: true is success, while false is fail. return true if @purgObj is NULL. + * If return true, @purgObj will be set to NULL to avoid Use-After-Free. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_Destroy(OH_PurgeableMemory *purgObj); + +/* + * @brief: begin read a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return true if @purgObj's content is present. + * If content is purged(no present), system will recover its data, + * return false if content is purged and recover failed. + * While return true if content recover success. + * OS cannot reclaim the memory of @purgObj's content when this + * function return true, until PurgMemEndRead() is called. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_BeginRead(OH_PurgeableMemory *purgObj); + +/* + * @brief: end read a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * OS may reclaim the memory of @purgObj's content + * at a later time when this function returns. + * + * @since 10 + * @version 1.0 + */ +void OH_PurgeableMemory_EndRead(OH_PurgeableMemory *purgObj); + +/* + * @brief: begin write a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return true if @purgObj's content is present. + * if content is purged(no present), system will recover its data, + * return false if content is purged and recover failed. + * While return true if content recover success. + * OS cannot reclaim the memory of @purgObj's content when this + * function return true, until PurgMemEndWrite() is called. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_BeginWrite(OH_PurgeableMemory *purgObj); + +/* + * @brief: end write a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * OS may reclaim the memory of @purgObj's content + * at a later time when this function returns. + * + * @since 10 + * @version 1.0 + */ +void OH_PurgeableMemory_EndWrite(OH_PurgeableMemory *purgObj); + +/* + * @brief: get content ptr of a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return start address of a PurgMem obj's content. + * Return NULL if @purgObj is NULL. + * This function should be protect by PurgMemBeginRead()/PurgMemEndRead() + * or PurgMemBeginWrite()/PurgMemEndWrite() + * + * @since 10 + * @version 1.0 + */ +void *OH_PurgeableMemory_GetContent(OH_PurgeableMemory *purgObj); + +/* + * @brief: get content size of a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @return: return content size of @purgObj. + * Return 0 if @purgObj is NULL. + * + * @since 10 + * @version 1.0 + */ +size_t OH_PurgeableMemory_ContentSize(OH_PurgeableMemory *purgObj); + +/* + * @brief: append a modify to a PurgMem obj. + * + * + * @param purgObj: a PurgMem obj. + * @param size: data size of a PurgMem obj's content. + * @param func: function pointer, it will modify content of @PurgMem. + * @param funcPara: parameters used by @func. + * @return: append result, true is success, while false is fail. + * + * @since 10 + * @version 1.0 + */ +bool OH_PurgeableMemory_AppendModify(OH_PurgeableMemory *purgObj, + OH_PurgeableMemory_ModifyFunc func, void *funcPara); + +#ifdef __cplusplus +} +#endif /* End of #ifdef __cplusplus */ + +#endif /* OHOS_UTILS_MEMORY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEMORY_H */ \ No newline at end of file diff --git a/libpurgeablemem/libpurgeable_memory.ndk.json b/libpurgeablemem/libpurgeable_memory.ndk.json new file mode 100644 index 0000000..21cf38b --- /dev/null +++ b/libpurgeablemem/libpurgeable_memory.ndk.json @@ -0,0 +1,11 @@ +[ + { "name": "OH_PurgeableMemory_Create" }, + { "name": "OH_PurgeableMemory_Destroy" }, + { "name": "OH_PurgeableMemory_BeginRead" }, + { "name": "OH_PurgeableMemory_EndRead" }, + { "name": "OH_PurgeableMemory_BeginWrite" }, + { "name": "OH_PurgeableMemory_EndWrite" }, + { "name": "OH_PurgeableMemory_GetContent" }, + { "name": "OH_PurgeableMemory_ContentSize" }, + { "name": "OH_PurgeableMemory_AppendModify" } +] \ No newline at end of file diff --git a/libpurgeablemem/test/BUILD.gn b/libpurgeablemem/test/BUILD.gn index 19b8474..71fec15 100644 --- a/libpurgeablemem/test/BUILD.gn +++ b/libpurgeablemem/test/BUILD.gn @@ -68,6 +68,19 @@ ohos_unittest("purgeableashmem_test") { part_name = "memory_utils" } +ohos_unittest("purgeable_memory_test") { + module_out_path = module_output_path + sources = [ "purgeable_memory_test.cpp" ] + deps = purgeable_deps + if (is_standard_system) { + external_deps = purgeable_external_deps + public_deps = purgeable_public_deps + } + + subsystem_name = "commonlibrary" + part_name = "memory_utils" +} + group("libpurgeablemem_test") { testonly = true deps = [ diff --git a/libpurgeablemem/test/purgeable_memory_test.cpp b/libpurgeablemem/test/purgeable_memory_test.cpp new file mode 100644 index 0000000..b9b4589 --- /dev/null +++ b/libpurgeablemem/test/purgeable_memory_test.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "gtest/gtest.h" +#include "purgeable_memory.h" + +namespace { +using namespace testing; +using namespace testing::ext; + +struct AlphabetInitParam { + char start; + char end; +}; + +struct AlphabetModifyParam { + char src; + char dst; +}; + +static constexpr int PRINT_INTERVAL_SECONDS = 1; +static constexpr int RECLAIM_INTERVAL_SECONDS = 1; +static constexpr int MODIFY_INTERVAL_SECONDS = 2; + +bool InitData_(void *data, size_t size, char start, char end); +bool ModifyData_(void *data, size_t size, char src, char dst); +bool InitAlphabet(void *data, size_t size, void *param); +bool ModifyAlphabetX2Y(void *data, size_t size, void *param); +void LoopPrintAlphabet(struct OH_PurgeableMemory *pdata, unsigned int loopCount); +bool ReclaimPurgeable(void); +void LoopReclaimPurgeable(unsigned int loopCount); +void ModifyPurgMemByFunc(struct OH_PurgeableMemory *pdata, OH_PurgeableMemory_ModifyFunc Modfunc, void *param); + +class PurgeableMemoryTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void PurgeableMemoryTest::SetUpTestCase() +{ +} + +void PurgeableMemoryTest::TearDownTestCase() +{ +} + +void PurgeableMemoryTest::SetUp() +{ +} + +void PurgeableMemoryTest::TearDown() +{ +} + +HWTEST_F(PurgeableMemoryTest, MultiObjCreateTest, TestSize.Level1) +{ + const char alphabetFinal[] = "BBCDEFGHIJKLMNOPQRSTUVWXYZ\0"; + struct AlphabetInitParam initPara = {'A', 'Z'}; + struct OH_PurgeableMemory *pobj1 = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara); + LoopPrintAlphabet(pobj1, 1); + struct AlphabetModifyParam a2b = {'A', 'B'}; + ModifyPurgMemByFunc(pobj1, ModifyAlphabetX2Y, static_cast(&a2b)); + LoopPrintAlphabet(pobj1, 1); + LoopReclaimPurgeable(1); + + struct OH_PurgeableMemory *pobj2 = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara); + LoopPrintAlphabet(pobj2, 1); + ModifyPurgMemByFunc(pobj2, ModifyAlphabetX2Y, static_cast(&a2b)); + LoopPrintAlphabet(pobj2, 1); + + if (OH_PurgeableMemory_BeginRead(pobj1)) { + ASSERT_STREQ(alphabetFinal, static_cast(OH_PurgeableMemory_GetContent(pobj1))); + OH_PurgeableMemory_EndRead(pobj1); + } else { + std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl; + } + + if (OH_PurgeableMemory_BeginRead(pobj2)) { + ASSERT_STREQ(alphabetFinal, static_cast(OH_PurgeableMemory_GetContent(pobj2))); + OH_PurgeableMemory_EndRead(pobj2); + } else { + std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl; + } + + OH_PurgeableMemory_Destroy(pobj2); + OH_PurgeableMemory_Destroy(pobj1); +} + +HWTEST_F(PurgeableMemoryTest, ReadTest, TestSize.Level1) +{ + const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\0"; + struct AlphabetInitParam initPara = {'A', 'Z'}; + struct OH_PurgeableMemory *pobj = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara); + LoopReclaimPurgeable(1); + + unsigned int loopCount = 3; + /* loop read content */ + for (unsigned int i = 0; i < loopCount; i++) { + if (!OH_PurgeableMemory_BeginRead(pobj)) { + std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl; + continue; + } + ASSERT_STREQ(alphabet, static_cast(OH_PurgeableMemory_GetContent(pobj))); + OH_PurgeableMemory_EndRead(pobj); + } + + OH_PurgeableMemory_Destroy(pobj); +} + +HWTEST_F(PurgeableMemoryTest, WriteTest, TestSize.Level1) +{ + const char alphabet[] = "CCCDEFGHIJKLMNOPQRSTUVWXYZ\0"; + struct AlphabetInitParam initPara = {'A', 'Z'}; + struct OH_PurgeableMemory *pobj = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara); + LoopReclaimPurgeable(1); + + struct AlphabetModifyParam a2b = {'A', 'B'}; + struct AlphabetModifyParam b2c = {'B', 'C'}; + ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast(&a2b)); + ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast(&b2c)); + + if (OH_PurgeableMemory_BeginRead(pobj)) { + ASSERT_STREQ(alphabet, static_cast(OH_PurgeableMemory_GetContent(pobj))); + OH_PurgeableMemory_EndRead(pobj); + } else { + std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl; + } + + OH_PurgeableMemory_Destroy(pobj); + LoopReclaimPurgeable(3); +} + +HWTEST_F(PurgeableMemoryTest, ReadWriteTest, TestSize.Level1) +{ + const char alphabet[] = "DDDDEFGHIJKLMNOPQRSTUVWXYZ\0"; + struct AlphabetInitParam initPara = {'A', 'Z'}; + struct OH_PurgeableMemory *pobj = OH_PurgeableMemory_Create(27, InitAlphabet, &initPara); + LoopReclaimPurgeable(1); + LoopPrintAlphabet(pobj, 1); + + struct AlphabetModifyParam a2b = {'A', 'B'}; + struct AlphabetModifyParam b2c = {'B', 'C'}; + struct AlphabetModifyParam c2d = {'C', 'D'}; + ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast(&a2b)); + ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast(&b2c)); + ModifyPurgMemByFunc(pobj, ModifyAlphabetX2Y, static_cast(&c2d)); + + if (OH_PurgeableMemory_BeginRead(pobj)) { + ASSERT_STREQ(alphabet, static_cast(OH_PurgeableMemory_GetContent(pobj))); + OH_PurgeableMemory_EndRead(pobj); + } else { + std::cout << __func__ << ": ERROR! BeginRead failed." << std::endl; + } + + OH_PurgeableMemory_Destroy(pobj); +} + +bool InitData_(void *data, size_t size, char start, char end) +{ + char *str = (char *)data; + size_t len = 0; + for (char ch = start; ch <= end && len < size; ch++) { + str[len++] = ch; + } + str[len] = 0; + return true; +} + +bool InitAlphabet(void *data, size_t size, void *param) +{ + struct AlphabetInitParam *para = (struct AlphabetInitParam *)param; + std::cout << "inter " << __func__ << std::endl; + bool ret = InitData_(data, size, para->start, para->end); + std::cout << "quit " << __func__ << ": " << para->start << "-" << para->end << + ", data=[" << (char *)data << "]" << ", ret=" << (ret ? "true" : "false") << std::endl; + return ret; +} + +bool ModifyData_(void *data, size_t size, char src, char dst) +{ + char *str = (char *)data; + size_t i = 0; + for (; i < size && str[i]; i++) { + if (str[i] == src) { + str[i] = dst; + } + } + str[i] = 0; + return true; +} + +bool ModifyAlphabetX2Y(void *data, size_t size, void *param) +{ + struct AlphabetModifyParam *para = (struct AlphabetModifyParam *)param; + std::cout << "inter " << __func__ << ": " << para->src << "->" << para->dst << + ", data=[" << (char *)data << "]" << std::endl; + bool ret = ModifyData_(data, size, para->src, para->dst); + std::cout << "quit , data=[" << (char *)data << "]" << __func__ << + ", ret=" << (ret ? "true" : "false") << std::endl; + return ret; +} + +void LoopPrintAlphabet(struct OH_PurgeableMemory *pdata, unsigned int loopCount) +{ + std::cout << "inter " << __func__ << std::endl; + for (unsigned int i = 0; i < loopCount; i++) { + if (!OH_PurgeableMemory_BeginRead(pdata)) { + std::cout << __func__ << ": " << i << ". ERROR! BeginRead failed." << std::endl; + break; + } + std::cout << __func__ << ": " << i << ". data=[" << + (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl; + OH_PurgeableMemory_EndRead(pdata); + std::this_thread::sleep_for(std::chrono::seconds(PRINT_INTERVAL_SECONDS)); + } + std::cout << "quit " << __func__ << std::endl; +} + +bool ReclaimPurgeable(void) +{ + FILE *f = fopen("/proc/sys/kernel/purgeable", "w"); + if (!f) { + std::cout << __func__ << ": open file failed" << std::endl; + return false; + } + bool succ = true; + if (fputs("1", f) == EOF) { + succ = false; + } + + if (fclose(f) == EOF) { + std::cout << __func__ << ": close file failed" << std::endl; + } + + return succ; +} + +void LoopReclaimPurgeable(unsigned int loopCount) +{ + bool ret = false; + std::cout << "inter " << __func__ << std::endl; + for (unsigned int i = 0; i < loopCount; i++) { + ret = ReclaimPurgeable(); + std::cout << __func__ << ": " << i << ". Reclaim result=" << (ret ? "succ" : "fail") << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(RECLAIM_INTERVAL_SECONDS)); /* wait reclaim finish */ + } + std::cout << "quit " << __func__ << std::endl; +} + +void ModifyPurgMemByFunc(struct OH_PurgeableMemory *pdata, OH_PurgeableMemory_ModifyFunc Modfunc, void *param) +{ + if (!OH_PurgeableMemory_BeginWrite(pdata)) { + std::cout << __func__ << ": ERROR! BeginWrite failed." << std::endl; + return; + } + std::this_thread::sleep_for(std::chrono::seconds(MODIFY_INTERVAL_SECONDS)); + std::cout << __func__ << " before mod data=[" << (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl; + OH_PurgeableMemory_AppendModify(pdata, Modfunc, param); + std::cout<< __func__ << " after mod data=[" << (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl; + + std::cout << __func__ << " data=[" << (char *)OH_PurgeableMemory_GetContent(pdata) << "]" << std::endl; + OH_PurgeableMemory_EndWrite(pdata); +} +} /* namespace */ -- Gitee