1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci * You may obtain a copy of the License at
6d9f0492fSopenharmony_ci *
7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci *
9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci * limitations under the License.
14d9f0492fSopenharmony_ci */
15d9f0492fSopenharmony_ci
16d9f0492fSopenharmony_ci#ifndef BASE_STARTUP_INIT_SYS_PARAM_H
17d9f0492fSopenharmony_ci#define BASE_STARTUP_INIT_SYS_PARAM_H
18d9f0492fSopenharmony_ci
19d9f0492fSopenharmony_ci#include <stdint.h>
20d9f0492fSopenharmony_ci#ifndef __LITEOS_M__
21d9f0492fSopenharmony_ci#include <pthread.h>
22d9f0492fSopenharmony_ci#endif
23d9f0492fSopenharmony_ci
24d9f0492fSopenharmony_ci#if (defined(PARAM_SUPPORT_STDATOMIC) || defined(__LITEOS_A__))
25d9f0492fSopenharmony_ci#include <stdatomic.h>
26d9f0492fSopenharmony_ci#endif
27d9f0492fSopenharmony_ci
28d9f0492fSopenharmony_ci#ifndef __LITEOS_A__
29d9f0492fSopenharmony_ci#if defined FUTEX_WAIT || defined FUTEX_WAKE
30d9f0492fSopenharmony_ci#include <linux/futex.h>
31d9f0492fSopenharmony_ci#endif
32d9f0492fSopenharmony_ci#endif
33d9f0492fSopenharmony_ci
34d9f0492fSopenharmony_ci#define MEMORY_ORDER_ACQUIRE 2
35d9f0492fSopenharmony_ci
36d9f0492fSopenharmony_ci#ifdef __cplusplus
37d9f0492fSopenharmony_ci#if __cplusplus
38d9f0492fSopenharmony_ciextern "C" {
39d9f0492fSopenharmony_ci#endif
40d9f0492fSopenharmony_ci#endif
41d9f0492fSopenharmony_ci
42d9f0492fSopenharmony_ci#ifdef __LITEOS_M__
43d9f0492fSopenharmony_ci#define ATOMIC_UINT32 uint32_t
44d9f0492fSopenharmony_ci#define ATOMIC_LLONG  long long
45d9f0492fSopenharmony_ci#define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) *(commitId)
46d9f0492fSopenharmony_ci
47d9f0492fSopenharmony_ci#else
48d9f0492fSopenharmony_ci#if (defined(PARAM_SUPPORT_STDATOMIC) || defined(__LITEOS_A__))
49d9f0492fSopenharmony_ci#define ATOMIC_UINT32 atomic_uint
50d9f0492fSopenharmony_ci#define ATOMIC_LLONG atomic_llong
51d9f0492fSopenharmony_ci#define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) atomic_load_explicit((commitId), order)
52d9f0492fSopenharmony_ci
53d9f0492fSopenharmony_ci#else
54d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST
55d9f0492fSopenharmony_ci#define ATOMIC_UINT32 uint32_t
56d9f0492fSopenharmony_ci#define ATOMIC_LLONG int64_t
57d9f0492fSopenharmony_cistatic inline ATOMIC_LLONG param_atomic_uint64_load(ATOMIC_LLONG *ptr, int order)
58d9f0492fSopenharmony_ci{
59d9f0492fSopenharmony_ci    return *((volatile ATOMIC_LLONG *)ptr);
60d9f0492fSopenharmony_ci}
61d9f0492fSopenharmony_ci#define ATOMIC_UINT64_LOAD_EXPLICIT(commitId, order) param_atomic_uint64_load((commitId), order)
62d9f0492fSopenharmony_ci#endif
63d9f0492fSopenharmony_ci#endif
64d9f0492fSopenharmony_ci#endif
65d9f0492fSopenharmony_ci
66d9f0492fSopenharmony_ci#ifdef __LITEOS_M__
67d9f0492fSopenharmony_citypedef struct {
68d9f0492fSopenharmony_ci    uint32_t mutex;
69d9f0492fSopenharmony_ci} ParamRWMutex;
70d9f0492fSopenharmony_ci
71d9f0492fSopenharmony_citypedef struct {
72d9f0492fSopenharmony_ci    uint32_t mutex;
73d9f0492fSopenharmony_ci} ParamMutex;
74d9f0492fSopenharmony_ci#endif
75d9f0492fSopenharmony_ci
76d9f0492fSopenharmony_ci// support mutex
77d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST
78d9f0492fSopenharmony_citypedef struct {
79d9f0492fSopenharmony_ci    pthread_rwlock_t rwlock;
80d9f0492fSopenharmony_ci} ParamRWMutex;
81d9f0492fSopenharmony_ci
82d9f0492fSopenharmony_citypedef struct {
83d9f0492fSopenharmony_ci    pthread_mutex_t mutex;
84d9f0492fSopenharmony_ci} ParamMutex;
85d9f0492fSopenharmony_ci#endif
86d9f0492fSopenharmony_ci
87d9f0492fSopenharmony_ci#ifndef STARTUP_INIT_TEST
88d9f0492fSopenharmony_citypedef struct {
89d9f0492fSopenharmony_ci    int shmid;
90d9f0492fSopenharmony_ci} MemHandle;
91d9f0492fSopenharmony_ci
92d9f0492fSopenharmony_citypedef struct {
93d9f0492fSopenharmony_ci    ATOMIC_LLONG commitId;
94d9f0492fSopenharmony_ci    ATOMIC_LLONG commitPersistId;
95d9f0492fSopenharmony_ci    uint32_t trieNodeCount;
96d9f0492fSopenharmony_ci    uint32_t paramNodeCount;
97d9f0492fSopenharmony_ci    uint32_t securityNodeCount;
98d9f0492fSopenharmony_ci    uint32_t currOffset;
99d9f0492fSopenharmony_ci    uint32_t spaceSizeOffset;
100d9f0492fSopenharmony_ci    uint32_t firstNode;
101d9f0492fSopenharmony_ci    uint32_t dataSize;
102d9f0492fSopenharmony_ci    char data[0];
103d9f0492fSopenharmony_ci} ParamTrieHeader;
104d9f0492fSopenharmony_ci
105d9f0492fSopenharmony_citypedef struct WorkSpace_ {
106d9f0492fSopenharmony_ci    unsigned int flags;
107d9f0492fSopenharmony_ci    MemHandle memHandle;
108d9f0492fSopenharmony_ci    ParamTrieHeader *area;
109d9f0492fSopenharmony_ci    ATOMIC_UINT32 rwSpaceLock;
110d9f0492fSopenharmony_ci    uint32_t spaceSize;
111d9f0492fSopenharmony_ci    uint32_t spaceIndex;
112d9f0492fSopenharmony_ci    ParamRWMutex rwlock;
113d9f0492fSopenharmony_ci    char fileName[0];
114d9f0492fSopenharmony_ci} WorkSpace;
115d9f0492fSopenharmony_ci
116d9f0492fSopenharmony_citypedef struct CachedParameter_ {
117d9f0492fSopenharmony_ci    struct WorkSpace_ *workspace;
118d9f0492fSopenharmony_ci    const char *(*cachedParameterCheck)(struct CachedParameter_ *param, int *changed);
119d9f0492fSopenharmony_ci    long long spaceCommitId;
120d9f0492fSopenharmony_ci    uint32_t dataCommitId;
121d9f0492fSopenharmony_ci    uint32_t dataIndex;
122d9f0492fSopenharmony_ci    uint32_t bufferLen;
123d9f0492fSopenharmony_ci    uint32_t nameLen;
124d9f0492fSopenharmony_ci    char *paramValue;
125d9f0492fSopenharmony_ci    char data[0];
126d9f0492fSopenharmony_ci} CachedParameter;
127d9f0492fSopenharmony_ci
128d9f0492fSopenharmony_citypedef void *CachedHandle;
129d9f0492fSopenharmony_ci#endif
130d9f0492fSopenharmony_ci/**
131d9f0492fSopenharmony_ci * parameter client init
132d9f0492fSopenharmony_ci */
133d9f0492fSopenharmony_civoid InitParameterClient(void);
134d9f0492fSopenharmony_ci
135d9f0492fSopenharmony_ci/**
136d9f0492fSopenharmony_ci * by name and default value,save parameter info in handle。
137d9f0492fSopenharmony_ci *
138d9f0492fSopenharmony_ci */
139d9f0492fSopenharmony_ciCachedHandle CachedParameterCreate(const char *name, const char *defValue);
140d9f0492fSopenharmony_ci
141d9f0492fSopenharmony_ci/**
142d9f0492fSopenharmony_ci * destroy handle
143d9f0492fSopenharmony_ci *
144d9f0492fSopenharmony_ci */
145d9f0492fSopenharmony_civoid CachedParameterDestroy(CachedHandle handle);
146d9f0492fSopenharmony_ci
147d9f0492fSopenharmony_ci/**
148d9f0492fSopenharmony_ci * if name exist,return value else return default value
149d9f0492fSopenharmony_ci *
150d9f0492fSopenharmony_ci */
151d9f0492fSopenharmony_cistatic inline const char *CachedParameterGet(CachedHandle handle)
152d9f0492fSopenharmony_ci{
153d9f0492fSopenharmony_ci    struct CachedParameter_ *param = (struct CachedParameter_ *)handle;
154d9f0492fSopenharmony_ci    if (param == NULL) {
155d9f0492fSopenharmony_ci        return NULL;
156d9f0492fSopenharmony_ci    }
157d9f0492fSopenharmony_ci
158d9f0492fSopenharmony_ci    // no change, do not to find
159d9f0492fSopenharmony_ci    long long spaceCommitId = ATOMIC_UINT64_LOAD_EXPLICIT(&param->workspace->area->commitId, MEMORY_ORDER_ACQUIRE);
160d9f0492fSopenharmony_ci    if (param->spaceCommitId == spaceCommitId) {
161d9f0492fSopenharmony_ci        return param->paramValue;
162d9f0492fSopenharmony_ci    }
163d9f0492fSopenharmony_ci    param->spaceCommitId = spaceCommitId;
164d9f0492fSopenharmony_ci    int changed = 0;
165d9f0492fSopenharmony_ci    if (param->cachedParameterCheck == NULL) {
166d9f0492fSopenharmony_ci        return param->paramValue;
167d9f0492fSopenharmony_ci    }
168d9f0492fSopenharmony_ci    return param->cachedParameterCheck(param, &changed);
169d9f0492fSopenharmony_ci}
170d9f0492fSopenharmony_ci
171d9f0492fSopenharmony_cistatic inline const char *CachedParameterGetChanged(CachedHandle handle, int *changed)
172d9f0492fSopenharmony_ci{
173d9f0492fSopenharmony_ci    struct CachedParameter_ *param = (struct CachedParameter_ *)handle;
174d9f0492fSopenharmony_ci    if (param == NULL) {
175d9f0492fSopenharmony_ci        return NULL;
176d9f0492fSopenharmony_ci    }
177d9f0492fSopenharmony_ci    // no change, do not to find
178d9f0492fSopenharmony_ci    long long spaceCommitId = ATOMIC_UINT64_LOAD_EXPLICIT(&param->workspace->area->commitId, MEMORY_ORDER_ACQUIRE);
179d9f0492fSopenharmony_ci    if (param->spaceCommitId == spaceCommitId) {
180d9f0492fSopenharmony_ci        return param->paramValue;
181d9f0492fSopenharmony_ci    }
182d9f0492fSopenharmony_ci    param->spaceCommitId = spaceCommitId;
183d9f0492fSopenharmony_ci    if ((changed == NULL) || (param->cachedParameterCheck == NULL)) {
184d9f0492fSopenharmony_ci        return param->paramValue;
185d9f0492fSopenharmony_ci    }
186d9f0492fSopenharmony_ci    return param->cachedParameterCheck(param, changed);
187d9f0492fSopenharmony_ci}
188d9f0492fSopenharmony_ci
189d9f0492fSopenharmony_ci#ifdef __cplusplus
190d9f0492fSopenharmony_ci#if __cplusplus
191d9f0492fSopenharmony_ci}
192d9f0492fSopenharmony_ci#endif
193d9f0492fSopenharmony_ci#endif
194d9f0492fSopenharmony_ci#endif