1 /*
2 * Copyright (c) 2020 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 #include "hiview_cache.h"
17 #include "securec.h"
18 #include "ohos_types.h"
19 #include "hiview_util.h"
20
21 static uint16 GetReadCursor(HiviewCache *cache);
22
InitHiviewStaticCache(HiviewCache * cache,HiviewCacheType type,uint8 * buffer,uint16 size)23 boolean InitHiviewStaticCache(HiviewCache *cache, HiviewCacheType type, uint8 *buffer, uint16 size)
24 {
25 if (cache == NULL) {
26 return FALSE;
27 }
28
29 cache->usedSize = 0;
30 cache->wCursor = 0;
31 cache->buffer = buffer;
32 cache->size = size;
33 cache->type = type;
34
35 return TRUE;
36 }
37
InitHiviewCache(HiviewCache * cache,HiviewCacheType type,uint16 size)38 boolean InitHiviewCache(HiviewCache *cache, HiviewCacheType type, uint16 size)
39 {
40 if (cache == NULL) {
41 return FALSE;
42 }
43
44 uint8 *buffer = (uint8 *)HIVIEW_MemAlloc(MEM_POOL_HIVIEW_ID, size);
45 if (buffer == NULL) {
46 return FALSE;
47 }
48
49 cache->usedSize = 0;
50 cache->wCursor = 0;
51 cache->buffer = buffer;
52 cache->size = size;
53 cache->type = type;
54
55 return TRUE;
56 }
57
WriteToCache(HiviewCache * cache,const uint8 * data,uint16 wLen)58 int32 WriteToCache(HiviewCache *cache, const uint8 *data, uint16 wLen)
59 {
60 if (cache == NULL || data == NULL || cache->buffer == NULL) {
61 return -1;
62 }
63
64 uint16 firstLen;
65 uint16 secondLen;
66 uint32 intSave = HIVIEW_IntLock();
67 // cast to uint32 for prevent uint16 overflow
68 if ((uint32)cache->size < (uint32)wLen + (uint32)cache->usedSize) {
69 HIVIEW_IntRestore(intSave);
70 return -1;
71 }
72 // overflow, cast to uint32 for prevent uint16 overflow
73 if ((uint32)cache->wCursor + (uint32)wLen > (uint32)cache->size) {
74 firstLen = cache->size - cache->wCursor;
75 if (firstLen > 0) {
76 if (memcpy_s(cache->buffer + cache->wCursor, firstLen, data, firstLen) == EOK) {
77 cache->wCursor += firstLen;
78 cache->usedSize += firstLen;
79 } else {
80 HIVIEW_IntRestore(intSave);
81 return -1;
82 }
83 }
84 cache->wCursor = 0;
85 secondLen = wLen - firstLen;
86 if (secondLen > 0) {
87 if (memcpy_s(cache->buffer + cache->wCursor, secondLen, data + firstLen, secondLen) == EOK) {
88 cache->wCursor += secondLen;
89 cache->usedSize += secondLen;
90 } else {
91 HIVIEW_IntRestore(intSave);
92 return firstLen;
93 }
94 }
95 } else {
96 if (memcpy_s(cache->buffer + cache->wCursor, wLen, data, wLen) == EOK) {
97 cache->wCursor += wLen;
98 cache->usedSize += wLen;
99 } else {
100 HIVIEW_IntRestore(intSave);
101 return -1;
102 }
103 }
104 HIVIEW_IntRestore(intSave);
105
106 return wLen;
107 }
108
ReadFromCache(HiviewCache * cache,uint8 * data,uint16 rLen)109 int32 ReadFromCache(HiviewCache *cache, uint8 *data, uint16 rLen)
110 {
111 if (cache == NULL || data == NULL || cache->buffer == NULL) {
112 return -1;
113 }
114
115 uint16 firstLen;
116 uint16 secondLen;
117 uint16 rCursor;
118 // This function is the only read operation, so there is no need to lock
119 if (cache->usedSize < rLen) {
120 return -1;
121 }
122 rCursor = GetReadCursor(cache);
123 // overflow, cast to uint32 for prevent uint16 overflow
124 if ((uint32)rCursor + (uint32)rLen > (uint32)cache->size) {
125 firstLen = cache->size - rCursor;
126 if (firstLen > 0) {
127 if (memcpy_s(data, firstLen, cache->buffer + rCursor, firstLen) != EOK) {
128 return -1;
129 }
130 }
131 secondLen = rLen - firstLen;
132 if (secondLen > 0) {
133 if (memcpy_s(data + firstLen, secondLen, cache->buffer, secondLen) != EOK) {
134 return firstLen;
135 }
136 }
137 } else {
138 if (memcpy_s(data, rLen, cache->buffer + rCursor, rLen) != EOK) {
139 return -1;
140 }
141 }
142 uint32 intSave = HIVIEW_IntLock();
143 cache->usedSize -= rLen;
144 HIVIEW_IntRestore(intSave);
145
146 return rLen;
147 }
148
PrereadFromCache(HiviewCache * cache,uint8 * data,uint16 rLen)149 int32 PrereadFromCache(HiviewCache *cache, uint8 *data, uint16 rLen)
150 {
151 if (cache == NULL || data == NULL || cache->buffer == NULL) {
152 return -1;
153 }
154 if (cache->usedSize < rLen) {
155 return -1;
156 }
157
158 uint16 firstLen;
159 uint16 secondLen;
160 uint16 rCursor = GetReadCursor(cache);
161 // overflow, cast to uint32 for prevent uint16 overflow
162 if ((uint32)rCursor + (uint32)rLen > (uint32)cache->size) {
163 firstLen = cache->size - rCursor;
164 if (firstLen > 0) {
165 if (memcpy_s(data, firstLen, cache->buffer + rCursor, firstLen) != EOK) {
166 return -1;
167 }
168 }
169 secondLen = rLen - firstLen;
170 if (secondLen > 0) {
171 if (memcpy_s(data + firstLen, secondLen, cache->buffer, secondLen) != EOK) {
172 return firstLen;
173 }
174 }
175 } else {
176 if (memcpy_s(data, rLen, cache->buffer + rCursor, rLen) != EOK) {
177 return -1;
178 }
179 }
180
181 return rLen;
182 }
183
DiscardCacheData(HiviewCache * cache)184 void DiscardCacheData(HiviewCache *cache)
185 {
186 if (cache == NULL) {
187 return;
188 }
189 cache->wCursor = 0;
190 cache->usedSize = 0;
191 }
192
DestroyCache(HiviewCache * cache)193 void DestroyCache(HiviewCache *cache)
194 {
195 if (cache == NULL) {
196 return;
197 }
198 if (cache->buffer != NULL) {
199 HIVIEW_MemFree(MEM_POOL_HIVIEW_ID, cache->buffer);
200 cache->buffer = NULL;
201 }
202 cache->wCursor = 0;
203 cache->usedSize = 0;
204 cache->size = 0;
205 }
206
GetReadCursor(HiviewCache * cache)207 static uint16 GetReadCursor(HiviewCache *cache)
208 {
209 if (cache == NULL || cache->buffer == NULL) {
210 return 0;
211 }
212
213 uint16 readCursor;
214 uint32 intSave = HIVIEW_IntLock();
215 if (cache->wCursor >= cache->usedSize) {
216 readCursor = cache->wCursor - cache->usedSize;
217 } else {
218 readCursor = cache->size - (cache->usedSize - cache->wCursor);
219 }
220 HIVIEW_IntRestore(intSave);
221 return readCursor;
222 }
223