1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.6.6
3 * Copyright 2021 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for heaps.
9 */
10 
11 #include <trcRecorder.h>
12 
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1)
14 
15 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
16 
17 #if (TRC_USE_HEAPS == 1)
18 
xTraceHeapCreate(const char * szName,TraceUnsignedBaseType_t uxCurrent,TraceUnsignedBaseType_t uxHighWaterMark,TraceUnsignedBaseType_t uxMax,TraceHeapHandle_t * pxHeapHandle)19 traceResult xTraceHeapCreate(const char *szName, TraceUnsignedBaseType_t uxCurrent, TraceUnsignedBaseType_t uxHighWaterMark, TraceUnsignedBaseType_t uxMax, TraceHeapHandle_t *pxHeapHandle)
20 {
21 	TraceUnsignedBaseType_t uxStates[3];
22 
23 	uxStates[TRC_HEAP_STATE_INDEX_CURRENT] = uxCurrent;
24 	uxStates[TRC_HEAP_STATE_INDEX_HIGHWATERMARK] = uxHighWaterMark;
25 	uxStates[TRC_HEAP_STATE_INDEX_MAX] = uxMax;
26 
27 	return xTraceObjectRegisterInternal(PSF_EVENT_HEAP_CREATE, 0, szName, 3, uxStates, TRC_ENTRY_OPTION_HEAP, (TraceObjectHandle_t*)pxHeapHandle);
28 }
29 
xTraceHeapAlloc(TraceHeapHandle_t xHeapHandle,void * pvAddress,TraceUnsignedBaseType_t uxSize)30 traceResult xTraceHeapAlloc(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize)
31 {
32 	TraceUnsignedBaseType_t uxCurrent, uxHighWaterMark;
33 	TraceEventHandle_t xEventHandle = 0;
34 
35 	if (xHeapHandle == 0)
36 	{
37 		/* This can happen */
38 		return TRC_FAIL;
39 	}
40 
41 	/* If the address is null we assume this was a failed alloc attempt */
42 	if (pvAddress != 0)
43 	{
44 		/* This should never fail */
45 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent) == TRC_SUCCESS);
46 
47 		/* This should never fail */
48 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, &uxHighWaterMark) == TRC_SUCCESS);
49 
50 		uxCurrent += uxSize;
51 
52 		if (uxCurrent > uxHighWaterMark)
53 		{
54 			uxHighWaterMark = uxCurrent;
55 			/* This should never fail */
56 			TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_HIGHWATERMARK, uxHighWaterMark) == TRC_SUCCESS);
57 		}
58 
59 		/* This should never fail */
60 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent) == TRC_SUCCESS);
61 	}
62 
63 	/* We need to check this */
64 	if (xTraceEventBegin(pvAddress != 0 ? PSF_EVENT_MALLOC : PSF_EVENT_MALLOC_FAILED, sizeof(void*) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS)
65 	{
66 		xTraceEventAddPointer(xEventHandle, pvAddress);
67 		xTraceEventAddUnsignedBaseType(xEventHandle, uxSize);
68 		xTraceEventEnd(xEventHandle);
69 	}
70 
71 	return TRC_SUCCESS;
72 }
73 
xTraceHeapFree(TraceHeapHandle_t xHeapHandle,void * pvAddress,TraceUnsignedBaseType_t uxSize)74 traceResult xTraceHeapFree(TraceHeapHandle_t xHeapHandle, void *pvAddress, TraceUnsignedBaseType_t uxSize)
75 {
76 	TraceUnsignedBaseType_t uxCurrent;
77 	TraceEventHandle_t xEventHandle = 0;
78 
79 	if (xHeapHandle == 0)
80 	{
81 		/* This can happen */
82 		return TRC_FAIL;
83 	}
84 
85 	/* If the address is null we assume this was a failed alloc attempt */
86 	if (pvAddress != 0)
87 	{
88 		/* This should never fail */
89 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, &uxCurrent) == TRC_SUCCESS);
90 
91 		uxCurrent -= uxSize;
92 
93 		/* This should never fail */
94 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xHeapHandle, TRC_HEAP_STATE_INDEX_CURRENT, uxCurrent) == TRC_SUCCESS);
95 	}
96 
97 	/* We need to check this */
98 	if (xTraceEventBegin(pvAddress != 0 ? PSF_EVENT_FREE : PSF_EVENT_FREE_FAILED, sizeof(void*) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS)
99 	{
100 		xTraceEventAddPointer(xEventHandle, pvAddress);
101 		xTraceEventAddUnsignedBaseType(xEventHandle, uxSize);
102 		xTraceEventEnd(xEventHandle);
103 	}
104 
105 	return TRC_SUCCESS;
106 }
107 
108 #endif /* (TRC_USE_HEAPS == 1) */
109 
110 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
111 
112 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
113