From b2b811d84a5e5b09bbdd76d07d899041e5f96337 Mon Sep 17 00:00:00 2001 From: lijiawei Date: Thu, 9 Jun 2022 15:52:00 +0800 Subject: [PATCH] code refactor Signed-off-by: Chengke Wang Signed-off-by: lijiawei --- libpurgeablemem/BUILD.gn | 12 +- .../include/purgeable_mem_builder_c.h} | 6 +- .../include/purgeable_mem_c.h} | 7 +- .../src/purgeable_mem_builder_c.c} | 10 +- .../src/purgeable_mem_c.c} | 65 ++++----- .../{ => common}/include/pm_ptr_util.h | 6 +- .../include/pm_state_c.h} | 6 +- .../include/pm_util.h} | 44 +++--- .../common/include/ux_page_table_c.h | 50 +++++++ .../src/ux_page_table_c.c} | 127 ++++++++++++------ libpurgeablemem/test/purgeable_c_test.cpp | 5 +- 11 files changed, 210 insertions(+), 128 deletions(-) rename libpurgeablemem/{include/pm_builder.h => c/include/purgeable_mem_builder_c.h} (86%) rename libpurgeablemem/{include/purgeable_mem.h => c/include/purgeable_mem_c.h} (94%) rename libpurgeablemem/{src/pm_builder.c => c/src/purgeable_mem_builder_c.c} (94%) rename libpurgeablemem/{src/purgeable_mem.c => c/src/purgeable_mem_c.c} (88%) rename libpurgeablemem/{ => common}/include/pm_ptr_util.h (85%) rename libpurgeablemem/{include/pm_state.h => common/include/pm_state_c.h} (90%) rename libpurgeablemem/{include/ux_page_table.h => common/include/pm_util.h} (57%) create mode 100644 libpurgeablemem/common/include/ux_page_table_c.h rename libpurgeablemem/{src/ux_page_table.c => common/src/ux_page_table_c.c} (70%) diff --git a/libpurgeablemem/BUILD.gn b/libpurgeablemem/BUILD.gn index c8ec138..27330c8 100644 --- a/libpurgeablemem/BUILD.gn +++ b/libpurgeablemem/BUILD.gn @@ -14,14 +14,18 @@ import("//build/ohos.gni") config("libpurgeable_config") { - include_dirs = [ "include" ] + include_dirs = [ + "c/include", + "common/include", + ] + cflags_cc = [ "-fexceptions" ] } ohos_shared_library("libpurgeablemem") { sources = [ - "src/pm_builder.c", - "src/purgeable_mem.c", - "src/ux_page_table.c", + "c/src/purgeable_mem_builder_c.c", + "c/src/purgeable_mem_c.c", + "common/src/ux_page_table_c.c", ] include_dirs = [ "include" ] deps = [ "//utils/native/base:utils" ] diff --git a/libpurgeablemem/include/pm_builder.h b/libpurgeablemem/c/include/purgeable_mem_builder_c.h similarity index 86% rename from libpurgeablemem/include/pm_builder.h rename to libpurgeablemem/c/include/purgeable_mem_builder_c.h index 68804f0..2ccd331 100644 --- a/libpurgeablemem/include/pm_builder.h +++ b/libpurgeablemem/c/include/purgeable_mem_builder_c.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef LIB_PURGEABLE_MEM_PM_BUILDER_H -#define LIB_PURGEABLE_MEM_PM_BUILDER_H +#ifndef OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEM_BUILDER_C_H +#define OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEM_BUILDER_C_H #include @@ -49,4 +49,4 @@ bool PurgMemBuilderBuildAll(struct PurgMemBuilder *builder, void *data, size_t s #endif /* End of #if __cplusplus */ #endif /* End of #ifdef __cplusplus */ -#endif /* LIB_PURGEABLE_MEM_PM_BUILDER_H */ +#endif /* OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEM_BUILDER_C_H */ diff --git a/libpurgeablemem/include/purgeable_mem.h b/libpurgeablemem/c/include/purgeable_mem_c.h similarity index 94% rename from libpurgeablemem/include/purgeable_mem.h rename to libpurgeablemem/c/include/purgeable_mem_c.h index 517c751..2446845 100644 --- a/libpurgeablemem/include/purgeable_mem.h +++ b/libpurgeablemem/c/include/purgeable_mem_c.h @@ -13,10 +13,11 @@ * limitations under the License. */ -#ifndef LIB_PURGEABLE_MEM_PURGEABLE_MEM_H -#define LIB_PURGEABLE_MEM_PURGEABLE_MEM_H +#ifndef OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEM_C_H +#define OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEM_C_H #include +#include /* size_t */ #ifdef __cplusplus #if __cplusplus @@ -125,4 +126,4 @@ bool PurgMemAppendModify(struct PurgMem *purgObj, PurgMemModifyFunc func, void * #endif /* End of #if __cplusplus */ #endif /* End of #ifdef __cplusplus */ -#endif /* LIB_PURGEABLE_MEM_PURGEABLE_MEM_H */ +#endif /* OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_C_INCLUDE_PURGEABLE_MEM_C_H */ diff --git a/libpurgeablemem/src/pm_builder.c b/libpurgeablemem/c/src/purgeable_mem_builder_c.c similarity index 94% rename from libpurgeablemem/src/pm_builder.c rename to libpurgeablemem/c/src/purgeable_mem_builder_c.c index 88e81cd..e0faf23 100644 --- a/libpurgeablemem/src/pm_builder.c +++ b/libpurgeablemem/c/src/purgeable_mem_builder_c.c @@ -18,11 +18,11 @@ #include /* malloc */ #include "hilog/log.h" -#include "pm_ptr_util.h" -#include "pm_builder.h" +#include "../../common/include/pm_ptr_util.h" +#include "purgeable_mem_builder_c.h" #undef LOG_TAG -#define LOG_TAG "libpurgeablemem: builder" +#define LOG_TAG "PurgeableMemC: Builder" /* purgeable mem builder */ struct PurgMemBuilder { @@ -84,11 +84,11 @@ bool PurgMemBuilderAppendFunc(struct PurgMemBuilder *builder, PurgMemBuilderFunc /* build @data content from @builder */ bool PurgMemBuilderBuildAll(struct PurgMemBuilder *builder, void *data, size_t size) { - if (!builder->Build) { + if (!(builder->Build)) { HILOG_ERROR(LOG_CORE, "builder has no Build(), %{public}s", builder->name); return true; } - if (!builder->Build(data, size, builder->param)) { + if (!(builder->Build(data, size, builder->param))) { HILOG_ERROR(LOG_CORE, "build data failed, name %{public}s", builder->name ?: "NULL"); return false; } diff --git a/libpurgeablemem/src/purgeable_mem.c b/libpurgeablemem/c/src/purgeable_mem_c.c similarity index 88% rename from libpurgeablemem/src/purgeable_mem.c rename to libpurgeablemem/c/src/purgeable_mem_c.c index 43cb976..03dedea 100644 --- a/libpurgeablemem/src/purgeable_mem.c +++ b/libpurgeablemem/c/src/purgeable_mem_c.c @@ -20,39 +20,25 @@ #include /* FILE */ #include -#include "pm_builder.h" -#include "pm_ptr_util.h" -#include "pm_state.h" -#include "ux_page_table.h" -#include "purgeable_mem.h" - -#define MAP_PURGEABLE 0x40 - -/* - * When UXPT is not used, In order not to affect the normal function - * of user programs, this lib will provide normal anon memory. So - * MAP_PURGEABLE is set to 0x0. - */ -#if (USE_UXPT == false) -#undef MAP_PURGEABLE -#define MAP_PURGEABLE 0x0 -#endif +#include "../../common/include/pm_ptr_util.h" +#include "../../common/include/pm_util.h" +#include "../../common/include/pm_state_c.h" +#include "../../common/include/ux_page_table_c.h" +#include "purgeable_mem_builder_c.h" +#include "purgeable_mem_c.h" #undef LOG_TAG -#define LOG_TAG "libpurgeablemem" +#define LOG_TAG "PurgeableMemC" struct PurgMem { void *dataPtr; size_t dataSizeInput; struct PurgMemBuilder *builder; - struct UxPageTable *uxPageTable; + UxPageTableStruct *uxPageTable; pthread_rwlock_t rwlock; unsigned int buildDataCount; }; -static const size_t PAGE_SHIFT = 12; -static const size_t PAGE_SIZE = 1 << PAGE_SHIFT; - static inline void LogPurgMemInfo_(struct PurgMem *obj) { HILOG_INFO(LOG_CORE, "purgMemObj(%{public}lx) dataPtr(%{public}lx) dataSizeInput(%{public}zu)" @@ -89,12 +75,12 @@ static struct PurgMem *PurgMemCreate_(size_t len, struct PurgMemBuilder *builder goto free_pug_obj; } - pugObj->uxPageTable = (struct UxPageTable *)malloc(UxPageTableSize()); + pugObj->uxPageTable = (UxPageTableStruct *)malloc(UxPageTableSize()); if (!(pugObj->uxPageTable)) { - HILOG_ERROR(LOG_CORE, "%{public}s: malloc struct UxPageTable fail", __func__); + HILOG_ERROR(LOG_CORE, "%{public}s: malloc UxPageTableStruct fail", __func__); goto unmap_data; } - PMState err = InitUxPageTable(pugObj->uxPageTable, pugObj->dataPtr, size); /* dataPtr is aligned */ + PMState err = InitUxPageTable(pugObj->uxPageTable, (uint64_t)(pugObj->dataPtr), size); /* dataPtr is aligned */ if (err != PM_OK) { HILOG_ERROR(LOG_CORE, "%{public}s: InitUxPageTable fail, %{public}s", __func__, PMStateNames[err]); goto free_uxpt; @@ -182,7 +168,7 @@ bool PurgMemDestroy(struct PurgMem *purgObj) err = PM_UNMAP_PURG_FAIL; } else { /* double check munmap result: if uxpte is set to no_present */ - if (UxpteIsEnabled() && !IsPurged_(purgObj)) { + if (USE_UXPT && !IsPurged_(purgObj)) { HILOG_ERROR(LOG_CORE, "%{public}s: munmap dataPtr succ, but uxpte present", __func__); err = PM_UXPT_PRESENT_DATA_PURGED; } @@ -216,15 +202,17 @@ static bool IsPurgMemPtrValid_(struct PurgMem *purgObj) IF_NULL_LOG_ACTION(purgObj, "obj is NULL", return false); IF_NULL_LOG_ACTION(purgObj->dataPtr, "dataPtr is NULL", return false); IF_NULL_LOG_ACTION(purgObj->uxPageTable, "pageTable is NULL", return false); - IF_NULL_LOG_ACTION(purgObj->builder, "builder is NULL", return false); return true; } static inline bool PurgMemBuildData_(struct PurgMem *purgObj) { - bool succ = false; - succ = PurgMemBuilderBuildAll(purgObj->builder, purgObj->dataPtr, purgObj->dataSizeInput); + bool succ = true; + /* succ is true when purgObj has no builder */ + if (purgObj->builder) { + succ = PurgMemBuilderBuildAll(purgObj->builder, purgObj->dataPtr, purgObj->dataSizeInput); + } if (succ) { purgObj->buildDataCount++; } @@ -290,7 +278,7 @@ bool PurgMemBeginRead(struct PurgMem *purgObj) LogPurgMemInfo_(purgObj); bool ret = false; PMState err = PM_OK; - UxpteGet(purgObj->uxPageTable, purgObj->dataPtr, purgObj->dataSizeInput); + UxpteGet(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); while (true) { err = TryBeginRead_(purgObj); if (err == PM_DATA_NO_PURGED) { @@ -309,7 +297,7 @@ bool PurgMemBeginRead(struct PurgMem *purgObj) if (!ret) { HILOG_ERROR(LOG_CORE, "%{public}s: %{public}s, UxptePut.", __func__, PMStateNames[err]); - UxptePut(purgObj->uxPageTable, purgObj->dataPtr, purgObj->dataSizeInput); + UxptePut(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); } return ret; } @@ -326,7 +314,7 @@ bool PurgMemBeginWrite(struct PurgMem *purgObj) bool rebuildRet = false; PMState err = PM_OK; - UxpteGet(purgObj->uxPageTable, purgObj->dataPtr, purgObj->dataSizeInput); + UxpteGet(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); rwlockRet = pthread_rwlock_wrlock(&(purgObj->rwlock)); if (rwlockRet) { @@ -354,7 +342,7 @@ bool PurgMemBeginWrite(struct PurgMem *purgObj) uxpte_put: HILOG_ERROR(LOG_CORE, "%{public}s: %{public}s, return false, UxptePut.", __func__, PMStateNames[err]); - UxptePut(purgObj->uxPageTable, purgObj->dataPtr, purgObj->dataSizeInput); + UxptePut(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); return false; succ: return true; @@ -371,7 +359,7 @@ static inline void EndAccessPurgMem_(struct PurgMem *purgObj) if (rwlockRet) { HILOG_ERROR(LOG_CORE, "%{public}s: unlock fail. %{public}d", __func__, rwlockRet); } - UxptePut(purgObj->uxPageTable, purgObj->dataPtr, purgObj->dataSizeInput); + UxptePut(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); } void PurgMemEndRead(struct PurgMem *purgObj) @@ -405,7 +393,12 @@ size_t PurgMemGetContentSize(struct PurgMem *purgObj) bool PurgMemAppendModify(struct PurgMem *purgObj, PurgMemModifyFunc func, void *funcPara) { IF_NULL_LOG_ACTION(func, "input func is NULL", return true); - + IF_NULL_LOG_ACTION(purgObj, "input purgObj is NULL", return false); + /* apply modify */ + bool succ = func(purgObj->dataPtr, purgObj->dataSizeInput, funcPara); + if (!succ) { + return false; + } struct PurgMemBuilder *builder = PurgMemBuilderCreate(func, funcPara, NULL); IF_NULL_LOG_ACTION(builder, "PurgMemBuilderCreate fail", return false); @@ -423,5 +416,5 @@ static bool IsPurged_(struct PurgMem *purgObj) HILOG_INFO(LOG_CORE, "%{public}s, has never built, return true", __func__); return true; } - return !UxpteIsPresent(purgObj->uxPageTable, purgObj->dataPtr, purgObj->dataSizeInput); + return USE_UXPT && !UxpteIsPresent(purgObj->uxPageTable, (uint64_t)(purgObj->dataPtr), purgObj->dataSizeInput); } diff --git a/libpurgeablemem/include/pm_ptr_util.h b/libpurgeablemem/common/include/pm_ptr_util.h similarity index 85% rename from libpurgeablemem/include/pm_ptr_util.h rename to libpurgeablemem/common/include/pm_ptr_util.h index e0263d5..8d4ab84 100644 --- a/libpurgeablemem/include/pm_ptr_util.h +++ b/libpurgeablemem/common/include/pm_ptr_util.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef LIB_PURGEABLE_MEM_PM_PTR_UTIL_H -#define LIB_PURGEABLE_MEM_PM_PTR_UTIL_H +#ifndef OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_PTR_UTIL_H +#define OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_PTR_UTIL_H #include "hilog/log.h" @@ -33,4 +33,4 @@ } \ } while (0) -#endif /* LIB_PURGEABLE_MEM_PM_PTR_UTIL_H */ +#endif /* OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_PTR_UTIL_H */ diff --git a/libpurgeablemem/include/pm_state.h b/libpurgeablemem/common/include/pm_state_c.h similarity index 90% rename from libpurgeablemem/include/pm_state.h rename to libpurgeablemem/common/include/pm_state_c.h index 52758b6..07ecd70 100644 --- a/libpurgeablemem/include/pm_state.h +++ b/libpurgeablemem/common/include/pm_state_c.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef LIB_PURGEABLE_MEM_PM_STATE_H -#define LIB_PURGEABLE_MEM_PM_STATE_H +#ifndef OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_STATE_C_H +#define OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_STATE_C_H #ifdef __cplusplus #if __cplusplus @@ -77,4 +77,4 @@ static const char * const PMStateNames[PM_ERR_TYPES] = { #endif /* End of #if __cplusplus */ #endif /* End of #ifdef __cplusplus */ -#endif /* LIB_PURGEABLE_MEM_PM_STATE_H */ +#endif /* OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_STATE_C_H */ diff --git a/libpurgeablemem/include/ux_page_table.h b/libpurgeablemem/common/include/pm_util.h similarity index 57% rename from libpurgeablemem/include/ux_page_table.h rename to libpurgeablemem/common/include/pm_util.h index d4e8873..e0fcf01 100644 --- a/libpurgeablemem/include/ux_page_table.h +++ b/libpurgeablemem/common/include/pm_util.h @@ -13,13 +13,8 @@ * limitations under the License. */ -#ifndef LIB_PURGEABLE_MEM_UX_PAGE_TABLE_H -#define LIB_PURGEABLE_MEM_UX_PAGE_TABLE_H - -#include /* uint64_t */ -#include /* bool */ -#include /* size_t */ -#include "pm_state.h" +#ifndef OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_UTIL_H +#define OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_UTIL_H #ifdef __cplusplus #if __cplusplus @@ -35,31 +30,24 @@ extern "C" { */ #define USE_UXPT false -#if defined(USE_UXPT) && (USE_UXPT == true) +#define MAP_PURGEABLE 0x40 #define MAP_USEREXPTE 0x80 -#else -#define MAP_USEREXPTE 0x0 -#endif + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1 << PAGE_SHIFT) /* - * using uint64_t as uxpte_t to avoid avoid confusion on 32-bit and 64 bit systems. - * Type uxpte_t may be modified to uint32_t in the future, so typedef is used. + * When UXPT is not used, In order not to affect the normal function + * of user programs, this lib will provide normal anon memory. So + * MAP_PURGEABLE is set to 0x0. */ -typedef uint64_t uxpte_t; - -/* user extend page table */ -struct UxPageTable; - -bool UxpteIsEnabled(void); -size_t UxPageTableSize(void); - -PMState InitUxPageTable(struct UxPageTable *upt, void *addr, size_t len); -PMState DeinitUxPageTable(struct UxPageTable *upt); - -void UxpteGet(struct UxPageTable *upt, void *addr, size_t len); -void UxptePut(struct UxPageTable *upt, void *addr, size_t len); -bool UxpteIsPresent(struct UxPageTable *upt, void *addr, size_t len); +#if (USE_UXPT == false) +#undef MAP_PURGEABLE +#define MAP_PURGEABLE 0x0 +#undef MAP_USEREXPTE +#define MAP_USEREXPTE 0x0 +#endif #ifdef __cplusplus #if __cplusplus @@ -67,4 +55,4 @@ bool UxpteIsPresent(struct UxPageTable *upt, void *addr, size_t len); #endif /* End of #if __cplusplus */ #endif /* End of #ifdef __cplusplus */ -#endif /* LIB_PURGEABLE_MEM_UX_PAGE_TABLE_H */ +#endif /* OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_PM_UTIL_H */ diff --git a/libpurgeablemem/common/include/ux_page_table_c.h b/libpurgeablemem/common/include/ux_page_table_c.h new file mode 100644 index 0000000..e98e15a --- /dev/null +++ b/libpurgeablemem/common/include/ux_page_table_c.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifndef OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_UX_PAGE_TABLE_C_H +#define OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_UX_PAGE_TABLE_C_H + +#include /* uint64_t */ +#include /* bool */ +#include /* size_t */ +#include "pm_state_c.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* End of #if __cplusplus */ +#endif /* End of #ifdef __cplusplus */ + +/* user extend page table */ +typedef struct UserExtendPageTable UxPageTableStruct; + +bool UxpteIsEnabled(void); +size_t UxPageTableSize(void); + +PMState InitUxPageTable(UxPageTableStruct *upt, uint64_t addr, size_t len); +PMState DeinitUxPageTable(UxPageTableStruct *upt); + +void UxpteGet(UxPageTableStruct *upt, uint64_t addr, size_t len); +void UxptePut(UxPageTableStruct *upt, uint64_t addr, size_t len); +void UxpteClear(UxPageTableStruct *upt, uint64_t addr, size_t len); +bool UxpteIsPresent(UxPageTableStruct *upt, uint64_t addr, size_t len); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* End of #if __cplusplus */ +#endif /* End of #ifdef __cplusplus */ + +#endif /* OHOS_UTILS_MEMOEY_LIBPURGEABLEMEM_COMMON_INCLUDE_UX_PAGE_TABLE_C_H */ diff --git a/libpurgeablemem/src/ux_page_table.c b/libpurgeablemem/common/src/ux_page_table_c.c similarity index 70% rename from libpurgeablemem/src/ux_page_table.c rename to libpurgeablemem/common/src/ux_page_table_c.c index ad79d2b..fe29f1c 100644 --- a/libpurgeablemem/src/ux_page_table.c +++ b/libpurgeablemem/common/src/ux_page_table_c.c @@ -18,18 +18,25 @@ #include /* sched_yield() */ #include "hilog/log.h" -#include "ux_page_table.h" +#include "pm_util.h" +#include "ux_page_table_c.h" #undef LOG_TAG -#define LOG_TAG "libpurgeablemem: uxpt" +#define LOG_TAG "PurgeableMemC: UPT" #if (USE_UXPT == true) /* (USE_UXPT == true) means using uxpt */ -struct UxPageTable { +/* + * using uint64_t as uxpte_t to avoid avoid confusion on 32-bit and 64 bit systems. + * Type uxpte_t may be modified to uint32_t in the future, so typedef is used. + */ +typedef uint64_t uxpte_t; + +typedef struct UserExtendPageTable { uint64_t dataAddr; size_t dataSize; uxpte_t *uxpte; -}; +} UxPageTableStruct; /* * ------------------------------------------------------------------------- @@ -39,8 +46,6 @@ struct UxPageTable { * -------------------------------------------------------------------------- * | | UXPTE_PER_PAGE_SHIFT | PAGE_SHIFT | */ -static const size_t PAGE_SHIFT = 12; -static const size_t PAGE_SIZE = 1 << PAGE_SHIFT; static const size_t UXPTE_SIZE_SHIFT = 3; static const size_t UXPTE_PER_PAGE_SHIFT = PAGE_SHIFT - UXPTE_SIZE_SHIFT; static const size_t UXPTE_PER_PAGE = 1 << UXPTE_PER_PAGE_SHIFT; @@ -102,16 +107,17 @@ static inline uint64_t RoundDown_(uint64_t val, size_t align) enum UxpteOp { UPT_GET = 0, UPT_PUT = 1, - UPT_IS_PRESENT = 2, + UPT_CLEAR = 2, + UPT_IS_PRESENT = 3, }; static void UxpteAdd_(uxpte_t *pte, size_t incNum); static void UxpteSub_(uxpte_t *pte, size_t decNum); -static void GetUxpteAt_(struct UxPageTable *upt, uint64_t addr); -static void PutUxpteAt_(struct UxPageTable *upt, uint64_t addr); -static bool IsPresentAt_(struct UxPageTable *upt, uint64_t addr); -static PMState UxpteOps_(struct UxPageTable *upt, uint64_t addr, size_t len, enum UxpteOp op); +static void GetUxpteAt_(UxPageTableStruct *upt, uint64_t addr); +static void PutUxpteAt_(UxPageTableStruct *upt, uint64_t addr); +static bool IsPresentAt_(UxPageTableStruct *upt, uint64_t addr); +static PMState UxpteOps_(UxPageTableStruct *upt, uint64_t addr, size_t len, enum UxpteOp op); static uxpte_t *MapUxptePages_(uint64_t dataAddr, size_t dataSize); static int UnmapUxptePages_(uxpte_t *ptes, size_t size); @@ -123,21 +129,22 @@ bool UxpteIsEnabled(void) size_t UxPageTableSize(void) { - return sizeof(struct UxPageTable); + return sizeof(UxPageTableStruct); } -PMState InitUxPageTable(struct UxPageTable *upt, void *addr, size_t len) +PMState InitUxPageTable(UxPageTableStruct *upt, uint64_t addr, size_t len) { - upt->dataAddr = (uint64_t) addr; + upt->dataAddr = addr; upt->dataSize = len; upt->uxpte = MapUxptePages_(upt->dataAddr, upt->dataSize); if (!(upt->uxpte)) { return PM_MMAP_UXPT_FAIL; } + UxpteClear(upt, addr, len); return PM_OK; } -PMState DeinitUxPageTable(struct UxPageTable *upt) +PMState DeinitUxPageTable(UxPageTableStruct *upt) { size_t size = GetUxPageSize_(upt->dataAddr, upt->dataSize); int unmapRet = 0; @@ -154,42 +161,68 @@ PMState DeinitUxPageTable(struct UxPageTable *upt) return PM_OK; } -void UxpteGet(struct UxPageTable *upt, void *addr, size_t len) +void UxpteGet(UxPageTableStruct *upt, uint64_t addr, size_t len) +{ + UxpteOps_(upt, addr, len, UPT_GET); +} + +void UxptePut(UxPageTableStruct *upt, uint64_t addr, size_t len) { - UxpteOps_(upt, (uint64_t)addr, len, UPT_GET); + UxpteOps_(upt, addr, len, UPT_PUT); } -void UxptePut(struct UxPageTable *upt, void *addr, size_t len) +void UxpteClear(UxPageTableStruct *upt, uint64_t addr, size_t len) { - UxpteOps_(upt, (uint64_t)addr, len, UPT_PUT); + UxpteOps_(upt, addr, len, UPT_CLEAR); } -bool UxpteIsPresent(struct UxPageTable *upt, void *addr, size_t len) +bool UxpteIsPresent(UxPageTableStruct *upt, uint64_t addr, size_t len) { - PMState ret = UxpteOps_(upt, (uint64_t)addr, len, UPT_IS_PRESENT); + PMState ret = UxpteOps_(upt, addr, len, UPT_IS_PRESENT); return ret == PM_OK; } -static void UxpteAdd_(uxpte_t *pte, size_t incNum) +static inline uxpte_t UxpteLoad_(uxpte_t *uxpte) { - uxpte_t old = 0, ret = 0; + __sync_synchronize(); + return *uxpte; +} - while (true) { - old = *pte; +static inline bool UxpteCAS_(uxpte_t *uxpte, uxpte_t old, uxpte_t newVal) +{ + return __sync_bool_compare_and_swap(uxpte, old, newVal); +} + +static void UxpteAdd_(uxpte_t *pte, size_t incNum) +{ + uxpte_t old; + do { + old = UxpteLoad_(pte); if (IsUxpteUnderReclaim_(old)) { sched_yield(); continue; } - - ret = __sync_val_compare_and_swap(pte, old, old + incNum); - if (ret == old) - break; - } + } while (!UxpteCAS_(pte, old, old + incNum)); } static void UxpteSub_(uxpte_t *pte, size_t decNum) { - (void)__sync_fetch_and_sub(pte, decNum); + uxpte_t old; + do { + old = UxpteLoad_(pte); + } while (!UxpteCAS_(pte, old, old - decNum)); +} + +static void UxpteClear_(uxpte_t *pte) +{ + uxpte_t old = UxpteLoad_(pte); + if (!old) { + return; /* has been set to zero */ + } + HILOG_ERROR(LOG_CORE, "%{public}s: upte(0x%{public}llx) != 0", __func__, (unsigned long long)old); + do { + old = UxpteLoad_(pte); + } while (!UxpteCAS_(pte, old, 0)); } static inline size_t GetIndexInUxpte_(uint64_t startAddr, uint64_t currAddr) @@ -197,7 +230,7 @@ static inline size_t GetIndexInUxpte_(uint64_t startAddr, uint64_t currAddr) return UxpteOffset_(startAddr) + (VirtPageNo_(currAddr) - VirtPageNo_(startAddr)); } -static void GetUxpteAt_(struct UxPageTable *upt, uint64_t addr) +static void GetUxpteAt_(UxPageTableStruct *upt, uint64_t addr) { size_t index = GetIndexInUxpte_(upt->dataAddr, addr); UxpteAdd_(&(upt->uxpte[index]), UXPTE_REFCNT_ONE); @@ -206,7 +239,7 @@ static void GetUxpteAt_(struct UxPageTable *upt, uint64_t addr) __func__, (unsigned long long)addr, (unsigned long long)(upt->uxpte[index])); } -static void PutUxpteAt_(struct UxPageTable *upt, uint64_t addr) +static void PutUxpteAt_(UxPageTableStruct *upt, uint64_t addr) { size_t index = GetIndexInUxpte_(upt->dataAddr, addr); UxpteSub_(&(upt->uxpte[index]), UXPTE_REFCNT_ONE); @@ -215,7 +248,13 @@ static void PutUxpteAt_(struct UxPageTable *upt, uint64_t addr) __func__, (unsigned long long)addr, (unsigned long long)(upt->uxpte[index])); } -static bool IsPresentAt_(struct UxPageTable *upt, uint64_t addr) +static void ClearUxpteAt_(UxPageTableStruct *upt, uint64_t addr) +{ + size_t index = GetIndexInUxpte_(upt->dataAddr, addr); + UxpteClear_(&(upt->uxpte[index])); +} + +static bool IsPresentAt_(UxPageTableStruct *upt, uint64_t addr) { size_t index = GetIndexInUxpte_(upt->dataAddr, addr); @@ -225,7 +264,7 @@ static bool IsPresentAt_(struct UxPageTable *upt, uint64_t addr) return IsUxptePresent_(upt->uxpte[index]); } -static PMState UxpteOps_(struct UxPageTable *upt, uint64_t addr, size_t len, enum UxpteOp op) +static PMState UxpteOps_(UxPageTableStruct *upt, uint64_t addr, size_t len, enum UxpteOp op) { uint64_t start = RoundDown_(addr, PAGE_SIZE); uint64_t end = RoundUp_(addr + len, PAGE_SIZE); @@ -248,6 +287,10 @@ static PMState UxpteOps_(struct UxPageTable *upt, uint64_t addr, size_t len, enu PutUxpteAt_(upt, off); break; } + case UPT_CLEAR: { + ClearUxpteAt_(upt, off); + break; + } case UPT_IS_PRESENT: { if (!IsPresentAt_(upt, off)) { HILOG_ERROR(LOG_CORE, "%{public}s: addr(0x%{public}llx) not present", __func__, @@ -285,6 +328,10 @@ static int UnmapUxptePages_(uxpte_t *ptes, size_t size) #else /* (USE_UXPT == false), it means does not using uxpt */ +typedef struct UserExtendPageTable { + /* i am empty */ +} UxPageTableStruct; + bool UxpteIsEnabled(void) { return false; @@ -295,21 +342,21 @@ size_t UxPageTableSize(void) return 0; } -PMState InitUxPageTable(struct UxPageTable *upt, void *addr, size_t len) +PMState InitUxPageTable(UxPageTableStruct *upt, uint64_t addr, size_t len) { return PM_OK; } -PMState DeinitUxPageTable(struct UxPageTable *upt) +PMState DeinitUxPageTable(UxPageTableStruct *upt) { return PM_OK; } -void UxpteGet(struct UxPageTable *upt, void *addr, size_t len) {} +void UxpteGet(UxPageTableStruct *upt, uint64_t addr, size_t len) {} -void UxptePut(struct UxPageTable *upt, void *addr, size_t len) {} +void UxptePut(UxPageTableStruct *upt, uint64_t addr, size_t len) {} -bool UxpteIsPresent(struct UxPageTable *upt, void *addr, size_t len) +bool UxpteIsPresent(UxPageTableStruct *upt, uint64_t addr, size_t len) { return true; } diff --git a/libpurgeablemem/test/purgeable_c_test.cpp b/libpurgeablemem/test/purgeable_c_test.cpp index 1802eae..ae6fd3f 100644 --- a/libpurgeablemem/test/purgeable_c_test.cpp +++ b/libpurgeablemem/test/purgeable_c_test.cpp @@ -17,7 +17,7 @@ #include #include "gtest/gtest.h" -#include "purgeable_mem.h" +#include "purgeable_mem_c.h" namespace { using namespace testing; @@ -287,9 +287,8 @@ void ModifyPurgMemByFunc(struct PurgMem *pdata, PurgMemModifyFunc Modfunc, void } std::this_thread::sleep_for(std::chrono::seconds(MODIFY_INTERVAL_SECONDS)); std::cout << __func__ << " before mod data=[" << (char *)PurgMemGetContent(pdata) << "]" << std::endl; - Modfunc(PurgMemGetContent(pdata), PurgMemGetContentSize(pdata), param); - std::cout<< __func__ << " after mod data=[" << (char *)PurgMemGetContent(pdata) << "]" << std::endl; PurgMemAppendModify(pdata, Modfunc, param); + std::cout<< __func__ << " after mod data=[" << (char *)PurgMemGetContent(pdata) << "]" << std::endl; std::cout << __func__ << " data=[" << (char *)PurgMemGetContent(pdata) << "]" << std::endl; PurgMemEndWrite(pdata); -- Gitee