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