未验证 提交 c485583a 编写于 作者: O openharmony_ci 提交者: Gitee

!1727 添加接口:CachedParameterGet

Merge pull request !1727 from cheng_jinsong/0129
...@@ -24,6 +24,7 @@ extern "C" { ...@@ -24,6 +24,7 @@ extern "C" {
#endif #endif
typedef uint32_t ParamHandle; typedef uint32_t ParamHandle;
typedef void *CachedHandle;
typedef struct { typedef struct {
uint8_t updaterMode; uint8_t updaterMode;
...@@ -72,6 +73,27 @@ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len); ...@@ -72,6 +73,27 @@ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len);
long long GetSystemCommitId(void); long long GetSystemCommitId(void);
/**
* 外部接口
* 保存相关的parameter信息,包括workspace,和各层的commit。
*
*/
CachedHandle CachedParameterCreate(const char *name, const char *defValue);
/**
* 外部接口
* 如果获取到value,返回对应的 paramValue的指针,否则返回上面定义的defValue
*
*/
const char *CachedParameterGet(CachedHandle handle);
/**
* 外部接口
* 释放handle内存
*
*/
void CachedParameterDestroy(CachedHandle handle);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "param_manager.h" #include "param_manager.h"
#include "param_trie.h" #include "param_trie.h"
static int ReadParamValue(ParamHandle handle, char *value, uint32_t *length);
static ParamWorkSpace g_paramWorkSpace = {0}; static ParamWorkSpace g_paramWorkSpace = {0};
PARAM_STATIC int WorkSpaceNodeCompare(const HashNode *node1, const HashNode *node2) PARAM_STATIC int WorkSpaceNodeCompare(const HashNode *node1, const HashNode *node2)
{ {
...@@ -329,4 +331,132 @@ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len) ...@@ -329,4 +331,132 @@ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len)
{ {
PARAM_CHECK(len != NULL && handle != 0, return -1, "The value is null"); PARAM_CHECK(len != NULL && handle != 0, return -1, "The value is null");
return ReadParamValue(handle, value, len); return ReadParamValue(handle, value, len);
}
static int ReadParamValue_(ParamNode *entry, uint32_t *commitId, char *value, uint32_t *length)
{
uint32_t id = *commitId;
do {
*commitId = id;
int ret = ParamMemcpy(value, *length, entry->data + entry->keyLength + 1, entry->valueLength);
PARAM_CHECK(ret == 0, return -1, "Failed to copy value");
value[entry->valueLength] = '\0';
*length = entry->valueLength;
id = ReadCommitId(entry);
} while (*commitId != id); // if change,must read
return 0;
}
static int ReadParamValue(ParamHandle handle, char *value, uint32_t *length)
{
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return -1, "Invalid workspace");
PARAM_CHECK(length != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param");
ParamNode *entry = (ParamNode *)GetTrieNodeByHandle(handle);
if (entry == NULL) {
return PARAM_CODE_NOT_FOUND;
}
if (value == NULL) {
*length = entry->valueLength + 1;
return 0;
}
PARAM_CHECK(*length > entry->valueLength, return PARAM_CODE_INVALID_PARAM,
"Invalid value len %u %u", *length, entry->valueLength);
uint32_t commitId = ReadCommitId(entry);
return ReadParamValue_(entry, &commitId, value, length);
}
CachedHandle CachedParameterCreate(const char *name, const char *defValue)
{
PARAM_CHECK(name != NULL && defValue != NULL, return NULL, "Invalid name or default value");
PARAM_WORKSPACE_CHECK(GetParamWorkSpace(), return NULL, "Invalid param workspace");
uint32_t nameLen = strlen(name);
PARAM_CHECK(nameLen < PARAM_NAME_LEN_MAX, return NULL, "Invalid name %s", name);
uint32_t valueLen = strlen(defValue);
if (IS_READY_ONLY(name)) {
PARAM_CHECK(valueLen < PARAM_CONST_VALUE_LEN_MAX, return NULL, "Illegal param value %s", defValue);
} else {
PARAM_CHECK(valueLen < PARAM_VALUE_LEN_MAX, return NULL, "Illegal param value %s length", defValue);
}
int ret = CheckParamPermission(GetParamSecurityLabel(), name, DAC_READ);
PARAM_CHECK(ret == 0, return NULL, "Forbid to access parameter %s", name);
WorkSpace *workspace = GetWorkSpace(name);
PARAM_CHECK(workspace != NULL, return NULL, "Invalid workSpace");
ParamTrieNode *node = FindTrieNode(workspace, name, strlen(name), NULL);
CachedParameter *param = (CachedParameter *)malloc(
sizeof(CachedParameter) + PARAM_ALIGN(nameLen) + 1 + PARAM_VALUE_LEN_MAX);
PARAM_CHECK(param != NULL, return NULL, "Failed to create CachedParameter for %s", name);
ret = ParamStrCpy(param->data, nameLen + 1, name);
PARAM_CHECK(ret == 0, free(param);
return NULL, "Failed to copy name %s", name);
param->workspace = workspace;
param->nameLen = nameLen;
param->paramValue = &param->data[PARAM_ALIGN(nameLen) + 1];
param->bufferLen = PARAM_VALUE_LEN_MAX;
if (node != NULL && node->dataIndex != 0) {
param->dataIndex = node->dataIndex;
ParamNode *entry = (ParamNode *)GetTrieNode(workspace, node->dataIndex);
PARAM_CHECK(entry != NULL, free(param);
return NULL, "Failed to get trie node %s", name);
uint32_t length = param->bufferLen;
param->dataCommitId = ReadCommitId(entry);
ret = ReadParamValue_(entry, &param->dataCommitId, param->paramValue, &length);
PARAM_CHECK(ret == 0, free(param);
return NULL, "Failed to read parameter value %s", name);
} else {
param->dataIndex = 0;
ret = ParamStrCpy(param->paramValue, param->bufferLen, defValue);
PARAM_CHECK(ret == 0, free(param);
return NULL, "Failed to copy name %s", name);
}
param->spaceCommitId = ATOMIC_LOAD_EXPLICIT(&workspace->area->commitId, memory_order_acquire);
PARAM_LOGV("CachedParameterCreate %u %u %lld \n", param->dataIndex, param->dataCommitId, param->spaceCommitId);
return (CachedHandle)param;
}
static const char *CachedParameterCheck(CachedParameter *param)
{
if (param->dataIndex == 0) {
// no change, do not to find
long long spaceCommitId = ATOMIC_LOAD_EXPLICIT(&param->workspace->area->commitId, memory_order_acquire);
if (param->spaceCommitId == spaceCommitId) {
return param->paramValue;
}
param->spaceCommitId = spaceCommitId;
ParamTrieNode *node = FindTrieNode(param->workspace, param->data, param->nameLen, NULL);
if (node != NULL) {
param->dataIndex = node->dataIndex;
} else {
return param->paramValue;
}
}
ParamNode *entry = (ParamNode *)GetTrieNode(param->workspace, param->dataIndex);
PARAM_CHECK(entry != NULL, return param->paramValue, "Failed to get trie node %s", param->data);
uint32_t dataCommitId = ATOMIC_LOAD_EXPLICIT(&entry->commitId, memory_order_acquire);
dataCommitId &= PARAM_FLAGS_COMMITID;
if (param->dataCommitId == dataCommitId) {
return param->paramValue;
}
uint32_t length = param->bufferLen;
param->dataCommitId = dataCommitId;
int ret = ReadParamValue_(entry, &param->dataCommitId, param->paramValue, &length);
PARAM_CHECK(ret == 0, return NULL, "Failed to copy value %s", param->data);
PARAM_LOGI("CachedParameterCheck %u", param->dataCommitId);
return param->paramValue;
}
const char *CachedParameterGet(CachedHandle handle)
{
CachedParameter *param = (CachedParameter *)handle;
PARAM_CHECK(param != NULL, return NULL, "Invalid handle %x", handle);
return CachedParameterCheck(param);
}
void CachedParameterDestroy(CachedHandle handle)
{
if (handle != NULL) {
free(handle);
}
} }
\ No newline at end of file
...@@ -32,6 +32,17 @@ INIT_LOCAL_API int ParamSprintf(char *buffer, size_t buffSize, const char *forma ...@@ -32,6 +32,17 @@ INIT_LOCAL_API int ParamSprintf(char *buffer, size_t buffSize, const char *forma
INIT_LOCAL_API int ParamMemcpy(void *dest, size_t destMax, const void *src, size_t count); INIT_LOCAL_API int ParamMemcpy(void *dest, size_t destMax, const void *src, size_t count);
INIT_LOCAL_API int ParamStrCpy(char *strDest, size_t destMax, const char *strSrc); INIT_LOCAL_API int ParamStrCpy(char *strDest, size_t destMax, const char *strSrc);
typedef struct CachedParameter_ {
struct WorkSpace_ *workspace;
long long spaceCommitId;
uint32_t dataCommitId;
uint32_t dataIndex;
uint32_t bufferLen;
uint32_t nameLen;
char *paramValue;
char data[0];
} CachedParameter;
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -484,31 +484,6 @@ INIT_LOCAL_API uint32_t ReadCommitId(ParamNode *entry) ...@@ -484,31 +484,6 @@ INIT_LOCAL_API uint32_t ReadCommitId(ParamNode *entry)
return commitId & PARAM_FLAGS_COMMITID; return commitId & PARAM_FLAGS_COMMITID;
} }
INIT_LOCAL_API int ReadParamValue(ParamHandle handle, char *value, uint32_t *length)
{
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return -1, "Invalid workspace");
PARAM_CHECK(length != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param");
ParamNode *entry = (ParamNode *)GetTrieNodeByHandle(handle);
if (entry == NULL) {
return PARAM_CODE_NOT_FOUND;
}
if (value == NULL) {
*length = entry->valueLength + 1;
return 0;
}
PARAM_CHECK(*length > entry->valueLength, return PARAM_CODE_INVALID_PARAM,
"Invalid value len %u %u", *length, entry->valueLength);
uint32_t commitId = ReadCommitId(entry);
do {
int ret = ParamMemcpy(value, *length, entry->data + entry->keyLength + 1, entry->valueLength);
PARAM_CHECK(ret == 0, return -1, "Failed to copy value");
value[entry->valueLength] = '\0';
*length = entry->valueLength;
} while (commitId != ReadCommitId(entry));
return 0;
}
INIT_LOCAL_API int ReadParamName(ParamHandle handle, char *name, uint32_t length) INIT_LOCAL_API int ReadParamName(ParamHandle handle, char *name, uint32_t length)
{ {
ParamWorkSpace *paramSpace = GetParamWorkSpace(); ParamWorkSpace *paramSpace = GetParamWorkSpace();
......
...@@ -118,7 +118,6 @@ INIT_LOCAL_API int WritePersistParam(const char *name, const char *value); ...@@ -118,7 +118,6 @@ INIT_LOCAL_API int WritePersistParam(const char *name, const char *value);
INIT_LOCAL_API uint32_t ReadCommitId(ParamNode *entry); INIT_LOCAL_API uint32_t ReadCommitId(ParamNode *entry);
INIT_LOCAL_API int ReadParamName(ParamHandle handle, char *name, uint32_t length); INIT_LOCAL_API int ReadParamName(ParamHandle handle, char *name, uint32_t length);
INIT_LOCAL_API int ReadParamValue(ParamHandle handle, char *value, uint32_t *length);
INIT_LOCAL_API int CheckParameterSet(const char *name, const char *value, INIT_LOCAL_API int CheckParameterSet(const char *name, const char *value,
const ParamSecurityLabel *srcLabel, int *ctrlService); const ParamSecurityLabel *srcLabel, int *ctrlService);
INIT_LOCAL_API ParamHandle GetParamHandle(const WorkSpace *workSpace, uint32_t index, const char *name); INIT_LOCAL_API ParamHandle GetParamHandle(const WorkSpace *workSpace, uint32_t index, const char *name);
......
...@@ -333,6 +333,49 @@ static int32_t BShellParamCmdMemGet(BShellHandle shell, int32_t argc, char *argv ...@@ -333,6 +333,49 @@ static int32_t BShellParamCmdMemGet(BShellHandle shell, int32_t argc, char *argv
return 0; return 0;
} }
#define MAX_TEST 10000
static long long DiffLocalTime(struct timespec *startTime)
{
struct timespec endTime;
clock_gettime(CLOCK_MONOTONIC, &(endTime));
long long diff = (long long)((endTime.tv_sec - startTime->tv_sec) * 1000000); // 1000000 1000ms
if (endTime.tv_nsec > startTime->tv_nsec) {
diff += (endTime.tv_nsec - startTime->tv_nsec) / 1000; // 1000 1ms
} else {
diff -= (startTime->tv_nsec - endTime.tv_nsec) / 1000; // 1000 1ms
}
return diff;
}
static void TestPerformance(const char *testParamName)
{
struct timespec startTime;
CachedHandle cacheHandle = CachedParameterCreate(testParamName, "true");
clock_gettime(CLOCK_MONOTONIC, &(startTime));
const char *value = NULL;
for (int i = 0; i < MAX_TEST; ++i) {
value = CachedParameterGet(cacheHandle);
}
CachedParameterDestroy(cacheHandle);
printf("CachedParameterGet time %lld us value %s \n", DiffLocalTime(&startTime), value);
return;
}
static int32_t BShellParamCmdPerformance(BShellHandle shell, int32_t argc, char *argv[])
{
const char *name = "test.performance.read";
TestPerformance(name);
CachedHandle cacheHandle = CachedParameterCreate(name, "true");
int i = 0;
while (++i < MAX_TEST) {
const char *value = CachedParameterGet(cacheHandle);
printf("CachedParameterGet %s value %s \n", name, value);
usleep(100);
}
CachedParameterDestroy(cacheHandle);
return 0;
}
int32_t BShellCmdRegister(BShellHandle shell, int execMode) int32_t BShellCmdRegister(BShellHandle shell, int execMode)
{ {
if (execMode == 0) { if (execMode == 0) {
...@@ -353,6 +396,7 @@ int32_t BShellCmdRegister(BShellHandle shell, int execMode) ...@@ -353,6 +396,7 @@ int32_t BShellCmdRegister(BShellHandle shell, int execMode)
{"group", BShellParamCmdGroupTest, "group test", "group test [stage]", "group test"}, {"group", BShellParamCmdGroupTest, "group test", "group test [stage]", "group test"},
{"display", BShellParamCmdUdidGet, "display udid", "display udid", "display udid"}, {"display", BShellParamCmdUdidGet, "display udid", "display udid", "display udid"},
{"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"}, {"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
{"test", BShellParamCmdPerformance, "test performance", "test performance", "test performance"},
}; };
for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) { for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
BShellEnvRegisterCmd(GetShellHandle(), &infos[i]); BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
......
...@@ -438,4 +438,30 @@ HWTEST_F(ParamUnitTest, TestGetServiceCtlName, TestSize.Level0) ...@@ -438,4 +438,30 @@ HWTEST_F(ParamUnitTest, TestGetServiceCtlName, TestSize.Level0)
free(serviceInfo); free(serviceInfo);
} }
} }
HWTEST_F(ParamUnitTest, TestParamCache, TestSize.Level0)
{
const char *name = "test.write.1111111.222222";
CachedHandle cacheHandle = CachedParameterCreate(name, "true");
EXPECT_NE(cacheHandle, nullptr);
const char *value = CachedParameterGet(cacheHandle);
EXPECT_EQ(strcmp(value, "true"), 0);
uint32_t dataIndex = 0;
int ret = WriteParam(name, "false", &dataIndex, 0);
EXPECT_EQ(ret, 0);
value = CachedParameterGet(cacheHandle);
EXPECT_EQ(strcmp(value, "false"), 0);
CachedParameterDestroy(cacheHandle);
// cache 2, for parameter exist
CachedHandle cacheHandle3 = CachedParameterCreate(name, "true");
EXPECT_NE(cacheHandle3, nullptr);
value = CachedParameterGet(cacheHandle3);
EXPECT_EQ(strcmp(value, "false"), 0);
ret = WriteParam(name, "2222222", &dataIndex, 0);
EXPECT_EQ(ret, 0);
value = CachedParameterGet(cacheHandle3);
EXPECT_EQ(strcmp(value, "2222222"), 0);
CachedParameterDestroy(cacheHandle3);
} }
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册