1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.9.2
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for the event buffer.
9 */
10 
11 #include <trcRecorder.h>
12 
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
14 
xTraceEventBufferInitialize(TraceEventBuffer_t * pxTraceEventBuffer,uint32_t uiOptions,uint8_t * puiBuffer,uint32_t uiSize)15 traceResult xTraceEventBufferInitialize(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiOptions,
16 	uint8_t* puiBuffer, uint32_t uiSize)
17 {
18 	/* This should never fail */
19 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
20 
21 	/* This should never fail */
22 	TRC_ASSERT(puiBuffer != (void*)0);
23 
24 	/* This should never fail */
25 	TRC_ASSERT(uiSize != 0u);
26 
27 	pxTraceEventBuffer->uiOptions = uiOptions;
28 	pxTraceEventBuffer->uiHead = 0u;
29 	pxTraceEventBuffer->uiTail = 0u;
30 	pxTraceEventBuffer->uiSize = uiSize;
31 	pxTraceEventBuffer->uiFree = uiSize;
32 	pxTraceEventBuffer->puiBuffer = puiBuffer;
33 	pxTraceEventBuffer->uiSlack = 0u;
34 	pxTraceEventBuffer->uiNextHead = 0u;
35 	pxTraceEventBuffer->uiTimerWraparounds = 0u;
36 
37 	(void)xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT_BUFFER);
38 
39 	return TRC_SUCCESS;
40 }
41 
42 /**
43  * @brief Pops the oldest event from the Event Buffer.
44  *
45  * @param[in] pxTraceEventBuffer Pointer to initialized trace event buffer.
46  *
47  * @retval TRC_FAIL Failure
48  * @retval TRC_SUCCESS Success
49  */
prvTraceEventBufferPop(TraceEventBuffer_t * pxTraceEventBuffer)50 static traceResult prvTraceEventBufferPop(TraceEventBuffer_t *pxTraceEventBuffer)
51 {
52 	uint32_t uiFreeSize = 0u;
53 
54 	/* Get size of event we are freeing */
55 	/* This should never fail */
56 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
57 
58 	pxTraceEventBuffer->uiFree += uiFreeSize;
59 
60 	/* Update tail to point to the new last event */
61 	pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
62 
63 	return TRC_SUCCESS;
64 }
65 
prvTraceEventBufferAllocPop(TraceEventBuffer_t * pxTraceEventBuffer)66 static traceResult prvTraceEventBufferAllocPop(TraceEventBuffer_t *pxTraceEventBuffer)
67 {
68 	uint32_t uiFreeSize = 0u;
69 
70 	/* Check if tail is in, or at the start of the slack area. We do not want to call
71 	 * a free when in the slack area since it would read garbage data and free would
72 	 * become undefined.
73 	 */
74 	if (pxTraceEventBuffer->uiTail >= (pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiSlack))
75 	{
76 		/* Tail was in the slack area, wrap back to the start of the buffer. */
77 		pxTraceEventBuffer->uiTail = 0u;
78 	}
79 	else
80 	{
81 		/* Get size of event we are freeing (this should never fail) */
82 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEventGetSize(((void*)&(pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiTail])), &uiFreeSize) == TRC_SUCCESS); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
83 
84 		/* Update tail to point to the new last event */
85 		pxTraceEventBuffer->uiTail = (pxTraceEventBuffer->uiTail + uiFreeSize) % pxTraceEventBuffer->uiSize;
86 	}
87 
88 	return TRC_SUCCESS;
89 }
90 
xTraceEventBufferAlloc(TraceEventBuffer_t * pxTraceEventBuffer,uint32_t uiSize,void ** ppvData)91 traceResult xTraceEventBufferAlloc(TraceEventBuffer_t *pxTraceEventBuffer, uint32_t uiSize, void **ppvData)
92 {
93 	uint32_t uiFreeSpace;
94 	uint32_t uiHead;
95 	uint32_t uiTail;
96 	uint32_t uiBufferSize;
97 
98 	/* This should never fail */
99 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
100 
101 	/* This should never fail */
102 	TRC_ASSERT(ppvData != (void*)0);
103 
104 	uiBufferSize = pxTraceEventBuffer->uiSize;
105 
106 	TRC_ASSERT(uiBufferSize != 0u);
107 
108 	/* Check if the data size is larger than the buffer */
109 	/* This should never fail */
110 	TRC_ASSERT(uiSize <= uiBufferSize);
111 
112 	/* Handle overwrite buffer allocation, since this kind of allocation modifies
113 	 * both head and tail it should only be used for internal buffers without any
114 	 * flushing calls (Streaming Ringbuffer)
115 	 */
116 	if (pxTraceEventBuffer->uiOptions == TRC_EVENT_BUFFER_OPTION_OVERWRITE)
117 	{
118 		if (pxTraceEventBuffer->uiHead >= pxTraceEventBuffer->uiTail)
119 		{
120 			/* Do we have enough space to directly allocate from the buffer? */
121 			if ((uiBufferSize - pxTraceEventBuffer->uiHead) > uiSize)
122 			{
123 				*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
124 				pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead  + uiSize) % uiBufferSize;
125 			}
126 			/* There wasn't enough space for a direct alloc, handle freeing up
127 			 * space and wrapping. */
128 			else
129 			{
130 				/* Free space until there is enough space for a contiguous
131 				 * allocation */
132 				do
133 				{
134 					(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
135 					uiFreeSpace = pxTraceEventBuffer->uiTail - sizeof(uint32_t);
136 				} while (uiFreeSpace < uiSize);
137 
138 				/* Calculate slack from the wrapping */
139 				pxTraceEventBuffer->uiSlack = uiBufferSize - pxTraceEventBuffer->uiHead;
140 
141 				/* Wrap head */
142 				pxTraceEventBuffer->uiHead = 0u;
143 
144 				/* Allocate data */
145 				*ppvData = pxTraceEventBuffer->puiBuffer;
146 
147 				pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead  + uiSize) % uiBufferSize;
148 			}
149 		}
150 		else
151 		{
152 			uiFreeSpace = pxTraceEventBuffer->uiTail - pxTraceEventBuffer->uiHead - sizeof(uint32_t);
153 
154 			/* Check if we have to free space */
155 			if (uiFreeSpace < uiSize)
156 			{
157 				/* Check if this is a wrapping alloc */
158 				if ((pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiHead) < uiSize)
159 				{
160 					/* To avoid uiHead and uiTail from becoming the same we want to
161 					 * pop any events that would make uiTail equal uiHead before
162 					 * wrapping the head. */
163 					do
164 					{
165 						(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
166 					} while (pxTraceEventBuffer->uiTail == 0u);
167 
168 					pxTraceEventBuffer->uiSlack = pxTraceEventBuffer->uiSize - pxTraceEventBuffer->uiHead;
169 					pxTraceEventBuffer->uiHead = 0u;
170 				}
171 
172 				do
173 				{
174 					(void)prvTraceEventBufferAllocPop(pxTraceEventBuffer);
175 					uiFreeSpace = pxTraceEventBuffer->uiTail - pxTraceEventBuffer->uiHead - sizeof(uint32_t);
176 				} while (uiFreeSpace < uiSize);
177 
178 				if (pxTraceEventBuffer->uiTail == 0u)
179 				{
180 					*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
181 				}
182 			}
183 
184 			/* Alloc data */
185 			*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
186 
187 			pxTraceEventBuffer->uiNextHead = (pxTraceEventBuffer->uiHead + uiSize);
188 		}
189 	}
190 	else
191 	{
192 		/* Since a consumer could potentially update tail (free) during the procedure
193 		 * we have to save it here to avoid problems with it changing during this call.
194 		 */
195 		uiHead = pxTraceEventBuffer->uiHead;
196 		uiTail = pxTraceEventBuffer->uiTail;
197 
198 		if (uiHead >= uiTail)
199 		{
200 			uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
201 
202 			if (uiFreeSpace < uiSize)
203 			{
204 				*ppvData = 0;
205 
206 				return TRC_FAIL;
207 			}
208 
209 			/* Copy data */
210 			if ((uiBufferSize - uiHead) > uiSize)
211 			{
212 				*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
213 
214 				pxTraceEventBuffer->uiNextHead = (uiHead + uiSize) % uiBufferSize;
215 			}
216 			else
217 			{
218 				uiFreeSpace = uiTail;
219 
220 				if (uiFreeSpace < uiSize)
221 				{
222 					*ppvData = 0;
223 
224 					return TRC_FAIL;
225 				}
226 
227 				/* Calculate slack */
228 				pxTraceEventBuffer->uiSlack = uiBufferSize - uiHead;
229 
230 				*ppvData = pxTraceEventBuffer->puiBuffer;
231 
232 				pxTraceEventBuffer->uiNextHead = (uiHead + pxTraceEventBuffer->uiSlack + uiSize) % uiBufferSize;
233 			}
234 		}
235 		else
236 		{
237 			uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
238 
239 			if (uiFreeSpace < uiSize)
240 			{
241 				*ppvData = 0;
242 
243 				return TRC_FAIL;
244 			}
245 
246 			/* Alloc data */
247 			*ppvData = &pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead]; /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
248 
249 			pxTraceEventBuffer->uiNextHead = (uiHead + uiSize);
250 		}
251 	}
252 
253 	return TRC_SUCCESS;
254 }
255 
xTraceEventBufferAllocCommit(TraceEventBuffer_t * pxTraceEventBuffer,const void * pvData,uint32_t uiSize,int32_t * piBytesWritten)256 traceResult xTraceEventBufferAllocCommit(TraceEventBuffer_t *pxTraceEventBuffer, const void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
257 {
258 	(void)pvData;
259 
260 	/* This should never fail */
261 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
262 
263 	/* Advance head location */
264 	pxTraceEventBuffer->uiHead = pxTraceEventBuffer->uiNextHead;
265 
266 	/* Update bytes written */
267 	*piBytesWritten = (int32_t)uiSize;
268 
269 	return TRC_SUCCESS;
270 }
271 
xTraceEventBufferPush(TraceEventBuffer_t * pxTraceEventBuffer,void * pvData,uint32_t uiSize,int32_t * piBytesWritten)272 traceResult xTraceEventBufferPush(TraceEventBuffer_t *pxTraceEventBuffer, void *pvData, uint32_t uiSize, int32_t *piBytesWritten)
273 {
274 	uint32_t uiBufferSize;
275 	uint32_t uiHead;
276 	uint32_t uiTail;
277 	uint32_t uiFreeSpace;
278 
279 	/* This should never fail */
280 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
281 
282 	/* This should never fail */
283 	TRC_ASSERT(pvData != (void*)0);
284 
285 	uiBufferSize = pxTraceEventBuffer->uiSize;
286 
287 	TRC_ASSERT(uiBufferSize != 0u);
288 
289 	/* Check if the data size is larger than the buffer */
290 	/* This should never fail */
291 	TRC_ASSERT(uiSize <= uiBufferSize);
292 
293 	/* Check byte alignment */
294 	/* This should never fail */
295 	TRC_ASSERT((uiSize % 4u) == 0u);
296 
297 	/* Ensure bytes written start at 0 */
298 	/* This should never fail */
299 	TRC_ASSERT(piBytesWritten != (void*)0);
300 
301 	*piBytesWritten = 0;
302 
303 	/* This should never fail */
304 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceTimestampGetWraparounds(&pxTraceEventBuffer->uiTimerWraparounds) == TRC_SUCCESS);
305 
306 	/* In ring buffer mode we cannot provide lock free access since the producer modified
307 	 * the head and tail variables in the same call. This option is only safe when used
308 	 * with an internal buffer (streaming snapshot) which no consumer accesses.
309 	 */
310 	switch (pxTraceEventBuffer->uiOptions)
311 	{
312 		case TRC_EVENT_BUFFER_OPTION_OVERWRITE:
313 			uiHead = pxTraceEventBuffer->uiHead;
314 
315 			/* If there isn't enough space in the buffer pop events until there is */
316 			while (pxTraceEventBuffer->uiFree < uiSize)
317 			{
318 				(void)prvTraceEventBufferPop(pxTraceEventBuffer);
319 			}
320 
321 			/* Copy data */
322 			if ((uiBufferSize - uiHead) > uiSize)
323 			{
324 				TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
325 			}
326 			else
327 			{
328 				TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, (uiBufferSize - uiHead)); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
329 				TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, (void*)(&((uint8_t*)pvData)[(uiBufferSize - uiHead)]), (uiSize - (uiBufferSize - uiHead))); /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/ /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
330 			}
331 
332 			pxTraceEventBuffer->uiFree -= uiSize;
333 
334 			pxTraceEventBuffer->uiHead = (uiHead + uiSize) % uiBufferSize;
335 
336 			*piBytesWritten = (int32_t)uiSize;
337 			break;
338 		case TRC_EVENT_BUFFER_OPTION_SKIP:
339 			/* Since a consumer could potentially update tail (free) during the procedure
340 			 * we have to save it here to avoid problems with the push algorithm.
341 			 */
342 			uiHead = pxTraceEventBuffer->uiHead;
343 			uiTail = pxTraceEventBuffer->uiTail;
344 
345 			if (uiHead >= uiTail)
346 			{
347 				uiFreeSpace = (uiBufferSize - uiHead - sizeof(uint32_t)) + uiTail;
348 
349 				if (uiFreeSpace < uiSize)
350 				{
351 					*piBytesWritten = 0;
352 
353 					return TRC_SUCCESS;
354 				}
355 
356 				/* Copy data */
357 				if ((uiBufferSize - uiHead) > uiSize)
358 				{
359 					TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
360 				}
361 				else
362 				{
363 					TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[uiHead], pvData, (uiBufferSize - uiHead)); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
364 					TRC_MEMCPY(pxTraceEventBuffer->puiBuffer, (void*)(&((uint8_t*)pvData)[(uiBufferSize - uiHead)]), (uiSize - (uiBufferSize - uiHead)));  /*cstat !MISRAC2012-Rule-11.5 Suppress pointer checks*/ /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
365 				}
366 
367 				pxTraceEventBuffer->uiHead = (uiHead + uiSize) % uiBufferSize;
368 			}
369 			else
370 			{
371 				uiFreeSpace = uiTail - uiHead - sizeof(uint32_t);
372 
373 				if (uiFreeSpace < uiSize)
374 				{
375 					*piBytesWritten = 0;
376 
377 					return TRC_SUCCESS;
378 				}
379 
380 				/* Copy data */
381 				TRC_MEMCPY(&pxTraceEventBuffer->puiBuffer[pxTraceEventBuffer->uiHead], pvData, uiSize); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
382 
383 				pxTraceEventBuffer->uiHead = (uiHead + uiSize);
384 			}
385 
386 			*piBytesWritten = (int32_t)uiSize;
387 			break;
388 		default:
389 			return TRC_FAIL;
390 	}
391 
392 	return TRC_SUCCESS;
393 }
394 
xTraceEventBufferTransferAll(TraceEventBuffer_t * pxTraceEventBuffer,int32_t * piBytesWritten)395 traceResult xTraceEventBufferTransferAll(TraceEventBuffer_t* pxTraceEventBuffer, int32_t* piBytesWritten)
396 {
397 	int32_t iBytesWritten = 0;
398 	int32_t iSumBytesWritten = 0;
399 	uint32_t uiHead;
400 	uint32_t uiTail;
401 	uint32_t uiSlack;
402 
403 	/* This should never fail */
404 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
405 
406 	/* This should never fail */
407 	TRC_ASSERT(piBytesWritten != (void*)0);
408 
409 	uiHead = pxTraceEventBuffer->uiHead;
410 	uiTail = pxTraceEventBuffer->uiTail;
411 	uiSlack = pxTraceEventBuffer->uiSlack;
412 
413 	/* Check if core event buffer is empty */
414 	if (uiHead == uiTail)
415 	{
416 		/* Make sure this value is set in case it was passed uninitialized. */
417 		*piBytesWritten = 0;
418 
419 		return TRC_SUCCESS;
420 	}
421 
422 	/* Check if we can do a direct write or if we have to handle wrapping */
423 	if (uiHead > uiTail)
424 	{
425 		/* No wrapping */
426 		(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (uiHead - uiTail), &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
427 	}
428 	else
429 	{
430 		/* Wrapping */
431 
432 		/* Try to write: tail -> end of buffer */
433 		(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], (pxTraceEventBuffer->uiSize - uiTail - uiSlack), &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
434 
435 		/* Did we manage to write all bytes? */
436 		if ((uint32_t)iBytesWritten == (pxTraceEventBuffer->uiSize - uiTail - uiSlack))
437 		{
438 			/* uiTail is moved to start of buffer */
439 			pxTraceEventBuffer->uiTail = 0u;
440 
441 			iSumBytesWritten = iBytesWritten;
442 
443 			/* We zero this here in case it does not get zeroed by the streamport. This isn't really a problem with our
444 			 * streamports, but there has been cases with custom streamport forgetting to set this to 0 if there is no
445 			 * data to write. */
446 			iBytesWritten = 0;
447 
448 			/* Try to write: start of buffer -> head */
449 			(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[0], uiHead, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
450 		}
451 	}
452 
453 	/* Move tail */
454 	pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
455 
456 	iSumBytesWritten += iBytesWritten;
457 
458 	*piBytesWritten = iSumBytesWritten;
459 
460 	return TRC_SUCCESS;
461 }
462 
xTraceEventBufferTransferChunk(TraceEventBuffer_t * pxTraceEventBuffer,uint32_t uiChunkSize,int32_t * piBytesWritten)463 traceResult xTraceEventBufferTransferChunk(TraceEventBuffer_t* pxTraceEventBuffer, uint32_t uiChunkSize, int32_t* piBytesWritten)
464 {
465 	int32_t iBytesWritten = 0;
466 	uint32_t uiHead;
467 	uint32_t uiTail;
468 	uint32_t uiSlack;
469 	uint32_t uiBytesToWrite;
470 
471 	/* This should never fail */
472 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
473 
474 	/* This should never fail */
475 	TRC_ASSERT(piBytesWritten != (void*)0);
476 
477 	uiHead = pxTraceEventBuffer->uiHead;
478 	uiTail = pxTraceEventBuffer->uiTail;
479 	uiSlack = pxTraceEventBuffer->uiSlack;
480 
481 	/* Check if core event buffer is empty */
482 	if (uiHead == uiTail)
483 	{
484 		/* Make sure this value is set in case it was passed uninitialized. */
485 		*piBytesWritten = 0;
486 
487 		return TRC_SUCCESS;
488 	}
489 
490 	/* Check if we can do a direct write or if we have to handle wrapping */
491 	if (uiHead > uiTail)
492 	{
493 		uiBytesToWrite = uiHead - uiTail;
494 		if (uiBytesToWrite > uiChunkSize)
495 		{
496 			uiBytesToWrite = uiChunkSize;
497 		}
498 
499 		(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], uiBytesToWrite, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
500 
501 		pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
502 	}
503 	else
504 	{
505 		uiBytesToWrite = pxTraceEventBuffer->uiSize - uiTail - uiSlack;
506 		if (uiBytesToWrite > uiChunkSize)
507 		{
508 			uiBytesToWrite = uiChunkSize;
509 		}
510 
511 		(void)xTraceStreamPortWriteData(&pxTraceEventBuffer->puiBuffer[uiTail], uiBytesToWrite, &iBytesWritten); /*cstat !MISRAC2004-17.4_b We need to access a specific part of the buffer*/
512 
513 		/* Check if we managed to write until the end or not, if we didn't we
514 		 * add the number of bytes written. If we managed to write the last
515 		 * segment, reset tail to 0. */
516 		if ((uiTail + (uint32_t)iBytesWritten) == (pxTraceEventBuffer->uiSize - uiSlack))
517 		{
518 			pxTraceEventBuffer->uiTail = 0u;
519 		}
520 		else
521 		{
522 			pxTraceEventBuffer->uiTail += (uint32_t)iBytesWritten;
523 		}
524 	}
525 
526 	*piBytesWritten = iBytesWritten;
527 
528 	return TRC_SUCCESS;
529 }
530 
xTraceEventBufferClear(TraceEventBuffer_t * pxTraceEventBuffer)531 traceResult xTraceEventBufferClear(TraceEventBuffer_t* pxTraceEventBuffer)
532 {
533 	/* This should never fail */
534 	TRC_ASSERT(pxTraceEventBuffer != (void*)0);
535 
536 	pxTraceEventBuffer->uiHead = 0u;
537 	pxTraceEventBuffer->uiTail = 0u;
538 	pxTraceEventBuffer->uiFree = pxTraceEventBuffer->uiSize;
539 	pxTraceEventBuffer->uiSlack = 0u;
540 	pxTraceEventBuffer->uiNextHead = 0u;
541 
542 	return TRC_SUCCESS;
543 }
544 
545 #endif
546