• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "los_cir_buf_pri.h"
33 
34 
LOS_CirBufUsedSize(CirBuf * cirbufCB)35 UINT32 LOS_CirBufUsedSize(CirBuf *cirbufCB)
36 {
37     UINT32 size;
38     UINT32 intSave;
39 
40     LOS_SpinLockSave(&cirbufCB->lock, &intSave);
41     size = cirbufCB->size - cirbufCB->remain;
42     LOS_SpinUnlockRestore(&cirbufCB->lock, intSave);
43 
44     return size;
45 }
46 
47 /*
48  *                    startIdx
49  *                    |
50  *    0 0 0 0 0 0 0 0 X X X X X X X X 0 0 0 0 0 0
51  *                                    |
52  *                                  endIdx
53  */
OsCirBufWriteLinear(CirBuf * cirbufCB,const CHAR * buf,UINT32 size)54 STATIC UINT32 OsCirBufWriteLinear(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
55 {
56     UINT32 cpSize;
57     errno_t err;
58 
59     cpSize = (cirbufCB->remain < size) ? cirbufCB->remain : size;
60 
61     if (cpSize == 0) {
62         return 0;
63     }
64 
65     err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, cirbufCB->remain, buf, cpSize);
66     if (err != EOK) {
67         return 0;
68     }
69 
70     cirbufCB->remain -= cpSize;
71     cirbufCB->endIdx += cpSize;
72 
73     return cpSize;
74 }
75 
OsCirBufWriteLoop(CirBuf * cirbufCB,const CHAR * buf,UINT32 size)76 STATIC UINT32 OsCirBufWriteLoop(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
77 {
78     UINT32 right, cpSize;
79     errno_t err;
80 
81     right = cirbufCB->size - cirbufCB->endIdx;
82     cpSize = (right < size) ? right : size;
83 
84     err = memcpy_s(cirbufCB->fifo + cirbufCB->endIdx, right, buf, cpSize);
85     if (err != EOK) {
86         return 0;
87     }
88 
89     cirbufCB->remain -= cpSize;
90     cirbufCB->endIdx += cpSize;
91     if (cirbufCB->endIdx == cirbufCB->size) {
92         cirbufCB->endIdx = 0;
93     }
94 
95     if (cpSize == size) {
96         return size;
97     } else {
98         cpSize += OsCirBufWriteLinear(cirbufCB, buf + cpSize, size - cpSize);
99     }
100 
101     return cpSize;
102 }
103 
LOS_CirBufWrite(CirBuf * cirbufCB,const CHAR * buf,UINT32 size)104 UINT32 LOS_CirBufWrite(CirBuf *cirbufCB, const CHAR *buf, UINT32 size)
105 {
106     UINT32 cpSize;
107 
108     if ((cirbufCB == NULL) || (buf == NULL) || (size == 0)) {
109         return 0;
110     }
111 
112     if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == 0))  {
113         return 0;
114     }
115 
116     if (cirbufCB->startIdx <= cirbufCB->endIdx) {
117         cpSize = OsCirBufWriteLoop(cirbufCB, buf, size);
118     } else {
119         cpSize = OsCirBufWriteLinear(cirbufCB, buf, size);
120     }
121 
122     return cpSize;
123 }
124 
OsCirBufReadLinear(CirBuf * cirbufCB,CHAR * buf,UINT32 size)125 STATIC UINT32 OsCirBufReadLinear(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
126 {
127     UINT32 cpSize, remain;
128     errno_t err;
129 
130     remain = cirbufCB->endIdx - cirbufCB->startIdx;
131     cpSize = (remain < size) ? remain : size;
132 
133     if (cpSize == 0) {
134         return 0;
135     }
136 
137     err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize);
138     if (err != EOK) {
139         return 0;
140     }
141 
142     cirbufCB->remain += cpSize;
143     cirbufCB->startIdx += cpSize;
144 
145     return cpSize;
146 }
147 
OsCirBufReadLoop(CirBuf * cirbufCB,CHAR * buf,UINT32 size)148 STATIC UINT32 OsCirBufReadLoop(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
149 {
150     UINT32 right, cpSize;
151     errno_t err;
152 
153     right = cirbufCB->size - cirbufCB->startIdx;
154     cpSize = (right < size) ? right : size;
155 
156     err = memcpy_s(buf, size, cirbufCB->fifo + cirbufCB->startIdx, cpSize);
157     if (err != EOK) {
158         return 0;
159     }
160 
161     cirbufCB->remain += cpSize;
162     cirbufCB->startIdx += cpSize;
163     if (cirbufCB->startIdx == cirbufCB->size) {
164         cirbufCB->startIdx = 0;
165     }
166 
167     if (cpSize < size) {
168         cpSize += OsCirBufReadLinear(cirbufCB, buf + cpSize, size - cpSize);
169     }
170 
171     return cpSize;
172 }
173 
LOS_CirBufRead(CirBuf * cirbufCB,CHAR * buf,UINT32 size)174 UINT32 LOS_CirBufRead(CirBuf *cirbufCB, CHAR *buf, UINT32 size)
175 {
176     UINT32 cpSize;
177 
178     if ((cirbufCB == NULL) || (buf == NULL) || (size == 0)) {
179         return 0;
180     }
181 
182     if ((cirbufCB->fifo == NULL) || (cirbufCB->remain == cirbufCB->size)) {
183         return 0;
184     }
185 
186     if (cirbufCB->startIdx >= cirbufCB->endIdx) {
187         cpSize = OsCirBufReadLoop(cirbufCB, buf, size);
188     } else {
189         cpSize = OsCirBufReadLinear(cirbufCB, buf, size);
190     }
191 
192     return cpSize;
193 }
194 
LOS_CirBufInit(CirBuf * cirbufCB,CHAR * fifo,UINT32 size)195 UINT32 LOS_CirBufInit(CirBuf *cirbufCB, CHAR *fifo, UINT32 size)
196 {
197     if ((cirbufCB == NULL) || (fifo == NULL)) {
198         return LOS_NOK;
199     }
200 
201     (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf));
202     LOS_SpinInit(&cirbufCB->lock);
203     cirbufCB->size = size;
204     cirbufCB->remain = size;
205     cirbufCB->status = CBUF_USED;
206     cirbufCB->fifo = fifo;
207 
208     return LOS_OK;
209 }
210 
LOS_CirBufDeinit(CirBuf * cirbufCB)211 VOID LOS_CirBufDeinit(CirBuf *cirbufCB)
212 {
213     (VOID)memset_s(cirbufCB, sizeof(CirBuf), 0, sizeof(CirBuf));
214 }
215 
216