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 strings.
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 #include <trcTypes.h>
18 
19 #ifndef TRC_SEND_NAME_ONLY_ON_DELETE
20 #define TRC_SEND_NAME_ONLY_ON_DELETE 0
21 #endif
22 
23 traceResult prvTraceObjectSendNameEvent(void* pvObject, const char* szName);
24 
xTraceObjectRegisterInternal(uint32_t uiEventCode,void * pvObject,const char * szName,TraceUnsignedBaseType_t uxStateCount,TraceUnsignedBaseType_t uxStates[],TraceUnsignedBaseType_t uxOptions,TraceObjectHandle_t * pxObjectHandle)25 traceResult xTraceObjectRegisterInternal(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxStateCount, TraceUnsignedBaseType_t uxStates[], TraceUnsignedBaseType_t uxOptions, TraceObjectHandle_t* pxObjectHandle)
26 {
27 	TraceEntryHandle_t xEntryHandle;
28 	TraceEventHandle_t xEventHandle = 0;
29 	TraceUnsignedBaseType_t i;
30 
31 	TRACE_ALLOC_CRITICAL_SECTION();
32 
33 	/* This should never fail */
34 	TRC_ASSERT(pxObjectHandle != 0);
35 
36 	/* This should never fail */
37 	TRC_ASSERT(uxStateCount <= (TRC_ENTRY_TABLE_STATE_COUNT));
38 
39 	TRACE_ENTER_CRITICAL_SECTION();
40 
41 	if (pvObject != 0)
42 	{
43 		/* An address was supplied */
44 		if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
45 		{
46 			TRACE_EXIT_CRITICAL_SECTION();
47 
48 			return TRC_FAIL;
49 		}
50 	}
51 	else
52 	{
53 		/* No address was supplied */
54 		if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
55 		{
56 			TRACE_EXIT_CRITICAL_SECTION();
57 
58 			return TRC_FAIL;
59 		}
60 
61 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress(xEntryHandle, &pvObject) == TRC_SUCCESS);
62 	}
63 
64 	for (i = 0; i < uxStateCount; i++)
65 	{
66 		/* This should never fail */
67 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, i, uxStates[i]) == TRC_SUCCESS);
68 	}
69 
70 	/* This should never fail */
71 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions(xEntryHandle, uxOptions) == TRC_SUCCESS);
72 
73 	*pxObjectHandle = (TraceObjectHandle_t)xEntryHandle;
74 
75 	TRACE_EXIT_CRITICAL_SECTION();
76 
77 	if (szName != 0 && szName[0] != 0)
78 	{
79 		/* Not a null or empty string */
80 		/* This will set the symbol and create an event for it */
81 		/* This should never fail */
82 		TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName) == TRC_SUCCESS);
83 	}
84 
85 	/* Send the create event, if possible */
86 	/*We need to check this */
87 	if (xTraceEventBegin(uiEventCode, sizeof(void*) + uxStateCount * sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS)
88 	{
89 		xTraceEventAddPointer(xEventHandle, pvObject);
90 		for (i = 0; i < uxStateCount; i++)
91 		{
92 			xTraceEventAddUnsignedBaseType(xEventHandle, uxStates[i]);
93 		}
94 		xTraceEventEnd(xEventHandle);
95 	}
96 
97 	return TRC_SUCCESS;
98 }
99 
xTraceObjectRegister(uint32_t uiEventCode,void * pvObject,const char * szName,TraceUnsignedBaseType_t uxState,TraceObjectHandle_t * pxObjectHandle)100 traceResult xTraceObjectRegister(uint32_t uiEventCode, void *pvObject, const char* szName, TraceUnsignedBaseType_t uxState, TraceObjectHandle_t *pxObjectHandle)
101 {
102 	return xTraceObjectRegisterInternal(uiEventCode, pvObject, szName, 1, &uxState, 0, pxObjectHandle);
103 }
104 
xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle,uint32_t uiEventCode,TraceUnsignedBaseType_t uxState)105 traceResult xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle, uint32_t uiEventCode, TraceUnsignedBaseType_t uxState)
106 {
107 	void* pvObject = 0;
108 	const char *szName = 0;
109 	TraceEventHandle_t xEventHandle = 0;
110 
111 	/* If asserts are disabled this variable will not get used, this stops warnings. */
112 	(void)szName;
113 
114 	/* This should never fail */
115 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS);
116 
117 	/* This should never fail */
118 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetSymbol((TraceEntryHandle_t)xObjectHandle, &szName) == TRC_SUCCESS);
119 
120 #if (TRC_SEND_NAME_ONLY_ON_DELETE == 1)
121 	/* Send name event because this is a delete */
122 	/* This should never fail */
123 	TRC_ASSERT(prvTraceObjectSendNameEvent(pvObject, szName) == TRC_SUCCESS);
124 #endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 1) */
125 
126 	/* Send the delete event, if possible */
127 	if (xTraceEventBegin(uiEventCode, sizeof(void*) + sizeof(TraceUnsignedBaseType_t), &xEventHandle) == TRC_SUCCESS)
128 	{
129 		xTraceEventAddPointer(xEventHandle, pvObject);
130 		xTraceEventAddUnsignedBaseType(xEventHandle, uxState);
131 		xTraceEventEnd(xEventHandle);
132 	}
133 
134 	return xTraceEntryDelete(xObjectHandle);
135 }
136 
xTraceObjectSetName(TraceObjectHandle_t xObjectHandle,const char * szName)137 traceResult xTraceObjectSetName(TraceObjectHandle_t xObjectHandle, const char* szName)
138 {
139 	void* pvObject = 0;
140 
141     /* If asserts are disabled this variable will not get used, this stops warnings. */
142 	(void)pvObject;
143 
144 	if (szName == 0)
145 	{
146 		szName = "";
147 	}
148 
149 	/* This should never fail */
150 	TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS);
151 
152 #if (TRC_SEND_NAME_ONLY_ON_DELETE == 0)
153 	/* Send name event now since we don't do it on delete events */
154 	/* This should never fail */
155 	TRC_ASSERT_ALWAYS_EVALUATE(prvTraceObjectSendNameEvent(pvObject, szName) == TRC_SUCCESS);
156 #endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 0) */
157 
158 	return xTraceEntrySetSymbol((TraceEntryHandle_t)xObjectHandle, szName);
159 }
160 
xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode,void * pvObject,const char * szName,TraceUnsignedBaseType_t uxState)161 traceResult xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState)
162 {
163 	TraceObjectHandle_t xObjectHandle;
164 
165 	return xTraceObjectRegister(uiEventCode, pvObject, szName, uxState, &xObjectHandle);
166 }
167 
xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode,void * pvObject,TraceUnsignedBaseType_t uxState)168 traceResult xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState)
169 {
170 	TraceEntryHandle_t xEntryHandle;
171 	traceResult xResult;
172 
173 	TRACE_ALLOC_CRITICAL_SECTION();
174 
175 	TRACE_ENTER_CRITICAL_SECTION();
176 
177 	if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
178 	{
179 		TRACE_EXIT_CRITICAL_SECTION();
180 
181 		return TRC_FAIL;
182 	}
183 
184 	xResult = xTraceObjectUnregister((TraceObjectHandle_t)xEntryHandle, uiEventCode, uxState);
185 
186 	TRACE_EXIT_CRITICAL_SECTION();
187 
188 	return xResult;
189 }
190 
xTraceObjectSetNameWithoutHandle(void * pvObject,const char * szName)191 traceResult xTraceObjectSetNameWithoutHandle(void* pvObject, const char* szName)
192 {
193 	TraceEntryHandle_t xEntryHandle;
194 	traceResult xResult;
195 
196 	TRACE_ALLOC_CRITICAL_SECTION();
197 
198 	TRACE_ENTER_CRITICAL_SECTION();
199 
200 	if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
201 	{
202 		/* No previous entry found. Create one. */
203 		if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
204 		{
205 			TRACE_EXIT_CRITICAL_SECTION();
206 
207 			return TRC_FAIL;
208 		}
209 	}
210 
211 	xResult = xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName);
212 
213 	TRACE_EXIT_CRITICAL_SECTION();
214 
215 	return xResult;
216 }
217 
xTraceObjectSetSpecificStateWithoutHandle(void * pvObject,uint32_t uiIndex,TraceUnsignedBaseType_t uxState)218 traceResult xTraceObjectSetSpecificStateWithoutHandle(void* pvObject, uint32_t uiIndex, TraceUnsignedBaseType_t uxState)
219 {
220 	TraceEntryHandle_t xEntryHandle;
221 	traceResult xResult;
222 
223 	TRACE_ALLOC_CRITICAL_SECTION();
224 
225 	TRACE_ENTER_CRITICAL_SECTION();
226 
227 	if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
228 	{
229 		TRACE_EXIT_CRITICAL_SECTION();
230 
231 		return TRC_FAIL;
232 	}
233 
234 	xResult = xTraceObjectSetSpecificState((TraceObjectHandle_t)xEntryHandle, uiIndex, uxState);
235 
236 	TRACE_EXIT_CRITICAL_SECTION();
237 
238 	return xResult;
239 }
240 
xTraceObjectSetOptionsWithoutHandle(void * pvObject,uint32_t uiMask)241 traceResult xTraceObjectSetOptionsWithoutHandle(void* pvObject, uint32_t uiMask)
242 {
243 	TraceEntryHandle_t xEntryHandle;
244 	traceResult xResult;
245 
246 	TRACE_ALLOC_CRITICAL_SECTION();
247 
248 	TRACE_ENTER_CRITICAL_SECTION();
249 
250 	if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
251 	{
252 		/* No previous entry found. Create one. */
253 		if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
254 		{
255 			TRACE_EXIT_CRITICAL_SECTION();
256 
257 			return TRC_FAIL;
258 		}
259 	}
260 
261 	xResult = xTraceObjectSetOptions((TraceObjectHandle_t)xEntryHandle, uiMask);
262 
263 	TRACE_EXIT_CRITICAL_SECTION();
264 
265 	return xResult;
266 }
267 
prvTraceObjectSendNameEvent(void * pvObject,const char * szName)268 traceResult prvTraceObjectSendNameEvent(void* pvObject, const char* szName)
269 {
270 	uint32_t i = 0, uiLength = 0, uiValue = 0;
271 	TraceEventHandle_t xEventHandle = 0;
272 
273 	for (i = 0; (szName[i] != 0) && (i < (TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE)); i++) {}
274 
275 	uiLength = i;
276 
277 	if (xTraceEventBegin(PSF_EVENT_OBJ_NAME, sizeof(void*) + uiLength, &xEventHandle) == TRC_SUCCESS)
278 	{
279 		xTraceEventAddPointer(xEventHandle, pvObject);
280 		xTraceEventAddData(xEventHandle, (void*)szName, uiLength);
281 
282 		/* Check if we can truncate */
283 		xTraceEventPayloadRemaining(xEventHandle, &uiValue);
284 		if (uiValue > 0)
285 		{
286 			xTraceEventAdd8(xEventHandle, 0);
287 		}
288 
289 		xTraceEventEnd(xEventHandle);
290 	}
291 
292 	return TRC_SUCCESS;
293 }
294 
295 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
296 
297 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
298