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(&param->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(&param->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