/*******************************************************************************
 * Tracealyzer v3.0.2 Recorder Library
 * Percepio AB, www.percepio.com
 *
 * trcKernel.c
 *
 * Functions used by trcKernelHooks.h for storing various kernel events.
 *
 * Terms of Use
 * This software is copyright Percepio AB. The recorder library is free for
 * use together with Percepio products. You may distribute the recorder library
 * in its original form, including modifications in trcHardwarePort.c/.h
 * given that these modification are clearly marked as your own modifications
 * and documented in the initial comment section of these source files.
 * This software is the intellectual property of Percepio AB and may not be
 * sold or in other ways commercially redistributed without explicit written
 * permission by Percepio AB.
 *
 * Disclaimer
 * The trace tool and recorder library is being delivered to you AS IS and
 * Percepio AB makes no warranty as to its use or performance. Percepio AB does
 * not and cannot warrant the performance or results you may obtain by using the
 * software or documentation. Percepio AB make no warranties, express or
 * implied, as to noninfringement of third party rights, merchantability, or
 * fitness for any particular purpose. In no event will Percepio AB, its
 * technology partners, or distributors be liable to you for any consequential,
 * incidental or special damages, including any lost profits or lost savings,
 * even if a representative of Percepio AB has been advised of the possibility
 * of such damages, or for any claim by any third party. Some jurisdictions do
 * not allow the exclusion or limitation of incidental, consequential or special
 * damages, or the exclusion of implied warranties or limitations on how long an
 * implied warranty may last, so the above limitations may not apply to you.
 *
 * Tabs are used for indent in this file (1 tab = 4 spaces)
 *
 * Copyright Percepio AB, 2014.
 * www.percepio.com
 ******************************************************************************/

#include "trcKernel.h"

#if (USE_TRACEALYZER_RECORDER == 1)

#include <stdint.h>

/* Internal variables */
int8_t nISRactive = 0;
objectHandleType handle_of_last_logged_task = 0;
uint8_t inExcludedTask = 0;

#if (INCLUDE_MEMMANG_EVENTS == 1) && (TRACE_SCHEDULING_ONLY == 0)
 /* Current heap usage. Always updated. */
 static uint32_t heapMemUsage = 0;
#endif

#if (TRACE_SCHEDULING_ONLY == 0)
static uint32_t prvTraceGetParam(uint32_t, uint32_t);
#endif

#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1

static int readyEventsEnabled = 1;

void vTraceSetReadyEventsEnabled(int status)
{
	readyEventsEnabled = status;
}

/*******************************************************************************
 * vTraceStoreTaskReady
 *
 * This function stores a ready state for the task handle sent in as parameter.
 ******************************************************************************/
void vTraceStoreTaskReady(objectHandleType handle)
{
	uint16_t dts3;
	TREvent* tr;
	uint8_t hnd8;

	TRACE_SR_ALLOC_CRITICAL_SECTION();

	if (handle == 0)
	{
		/*  On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad
		placement of the trace macro. In that case, the events are ignored. */
		return;
	}
	
	if (! readyEventsEnabled)
	{
		/* When creating tasks, ready events are also created. If creating 
		a "hidden" (not traced) task, we must therefore disable recording 
		of ready events to avoid an undesired ready event... */
		return;
	}

	TRACE_ASSERT(handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );

	if (recorder_busy)
	{
	 /***********************************************************************
	 * This should never occur, as the tick- and kernel call ISR is on lowest
	 * interrupt priority and always are disabled during the critical sections
	 * of the recorder.
	 ***********************************************************************/

	 vTraceError("Recorder busy - high priority ISR using syscall? (1)");
	 return;
	}

	trcCRITICAL_SECTION_BEGIN();
	if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
	{
		if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))
		{
			dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
			hnd8 = prvTraceGet8BitHandle(handle);
			tr = (TREvent*)xTraceNextFreeEventBufferSlot();
			if (tr != NULL)
			{
				tr->type = DIV_TASK_READY;
				tr->dts = dts3;
				tr->objHandle = hnd8;
				prvTraceUpdateCounters();
			}
		}
	}
	trcCRITICAL_SECTION_END();
}
#endif

/*******************************************************************************
 * vTraceStoreLowPower
 *
 * This function stores a low power state.
 ******************************************************************************/
void vTraceStoreLowPower(uint32_t flag)
{
	uint16_t dts;
	LPEvent* lp;
	TRACE_SR_ALLOC_CRITICAL_SECTION();

	TRACE_ASSERT(flag <= 1, "vTraceStoreLowPower: Invalid flag value", );

	if (recorder_busy)
	{
		/***********************************************************************
		* This should never occur, as the tick- and kernel call ISR is on lowest
		* interrupt priority and always are disabled during the critical sections
		* of the recorder.
		***********************************************************************/

		vTraceError("Recorder busy - high priority ISR using syscall? (1)");
		return;
	}

	trcCRITICAL_SECTION_BEGIN();
	if (RecorderDataPtr->recorderActive)
	{
		dts = (uint16_t)prvTraceGetDTS(0xFFFF);
		lp = (LPEvent*)xTraceNextFreeEventBufferSlot();
		if (lp != NULL)
		{
			lp->type = LOW_POWER_BEGIN + ( uint8_t ) flag; /* BEGIN or END depending on flag */
			lp->dts = dts;
			prvTraceUpdateCounters();
		}
	}
	trcCRITICAL_SECTION_END();
}

/*******************************************************************************
 * vTraceStoreMemMangEvent
 *
 * This function stores malloc and free events. Each call requires two records,
 * for size and address respectively. The event code parameter (ecode) is applied
 * to the first record (size) and the following address record gets event
 * code "ecode + 1", so make sure this is respected in the event code table.
 * Note: On "free" calls, the signed_size parameter should be negative.
 ******************************************************************************/
#if (INCLUDE_MEMMANG_EVENTS == 1)
void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size)
{	
#if (TRACE_SCHEDULING_ONLY == 0)
	uint8_t dts1;
	MemEventSize * ms;
	MemEventAddr * ma;
	uint16_t size_low;
	uint16_t addr_low;
	uint8_t addr_high;
	uint32_t size;
	TRACE_SR_ALLOC_CRITICAL_SECTION();

	if (RecorderDataPtr == NULL) // This happens in vTraceInitTraceData, if using dynamic allocation...
		return;
	
	if (signed_size < 0)
		size = (uint32_t)(- signed_size);
	else
		size = (uint32_t)(signed_size);

	trcCRITICAL_SECTION_BEGIN();
	
	heapMemUsage += signed_size;
	
	if (RecorderDataPtr->recorderActive)
	{
		/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
		if (nISRactive || !inExcludedTask)
		{
			dts1 = (uint8_t)prvTraceGetDTS(0xFF);
			size_low = (uint16_t)prvTraceGetParam(0xFFFF, size);
			ms = (MemEventSize *)xTraceNextFreeEventBufferSlot();

			if (ms != NULL)
			{
				ms->dts = dts1;
				ms->type = NULL_EVENT; /* Updated when all events are written */
				ms->size = size_low;
				prvTraceUpdateCounters();

				/* Storing a second record with address (signals "failed" if null) */
				#if (HEAP_SIZE_BELOW_16M)
				    /* If the heap address range is within 16 MB, i.e., the upper 8 bits
					of addresses are constant, this optimization avoids storing an extra
					event record by ignoring the upper 8 bit of the address */
					addr_low = address & 0xFFFF;          
					addr_high = (address >> 16) & 0xFF;
				#else
				    /* The whole 32 bit address is stored using a second event record
					for the upper 16 bit */
					addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address);
					addr_high = 0;
				#endif

				ma = (MemEventAddr *) xTraceNextFreeEventBufferSlot();
				if (ma != NULL)
				{
					ma->addr_low = addr_low;
					ma->addr_high = addr_high;
					ma->type = ( ( uint8_t) ecode ) + 1; /* Note this! */
					ms->type = (uint8_t)ecode;
					prvTraceUpdateCounters();					
					RecorderDataPtr->heapMemUsage = heapMemUsage;
				}
			}
		}
	}
	trcCRITICAL_SECTION_END();
#endif /* TRACE_SCHEDULING_ONLY */
}
#endif

/*******************************************************************************
 * vTraceStoreKernelCall
 *
 * This is the main integration point for storing kernel calls, and
 * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes).
 ******************************************************************************/
void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
{
#if (TRACE_SCHEDULING_ONLY == 0)
	KernelCall * kse;
	uint16_t dts1;
	uint8_t hnd8;
	TRACE_SR_ALLOC_CRITICAL_SECTION();

	TRACE_ASSERT(ecode < 0xFF, "vTraceStoreKernelCall: ecode >= 0xFF", );
	TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", );
	TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCall: Invalid value for objectNumber", );

	if (recorder_busy)
	{
		/*************************************************************************
		* This may occur if a high-priority ISR is illegally using a system call,
		* or creates a user event.
		* Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls
		* or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).
		*************************************************************************/

		vTraceError("Recorder busy - high priority ISR using syscall? (2)");
		return;
	}

	if (handle_of_last_logged_task == 0)
	{
		return;
	}

	trcCRITICAL_SECTION_BEGIN();
	if (RecorderDataPtr->recorderActive)
	{
		/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
		if (nISRactive || !inExcludedTask)
		{
			/* Check if the referenced object or the event code is excluded */
			if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
			{
				dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
				hnd8 = prvTraceGet8BitHandle(objectNumber);
				kse = (KernelCall*) xTraceNextFreeEventBufferSlot();
				if (kse != NULL)
				{
					kse->dts = dts1;
					kse->type = (uint8_t)ecode;
					kse->objHandle = hnd8;
					prvTraceUpdateCounters();
				}
			}
		}
	}
	trcCRITICAL_SECTION_END();
#endif /* TRACE_SCHEDULING_ONLY */
}

/*******************************************************************************
 * vTraceStoreKernelCallWithParam
 *
 * Used for storing kernel calls with a handle and a numeric parameter. If the
 * numeric parameter does not fit in one byte, and extra XPS event is inserted
 * before the kernel call event containing the three upper bytes.
 ******************************************************************************/
void vTraceStoreKernelCallWithParam(uint32_t evtcode,
									traceObjectClass objectClass,
									uint32_t objectNumber,
									uint32_t param)
{
#if (TRACE_SCHEDULING_ONLY == 0)
	KernelCallWithParamAndHandle * kse;
	uint8_t dts2;
	uint8_t hnd8;
	uint8_t p8;
	TRACE_SR_ALLOC_CRITICAL_SECTION();

	TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCall: evtcode >= 0xFF", );
	TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", );
	TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCallWithParam: Invalid value for objectNumber", );

	if (recorder_busy)
	{
		/*************************************************************************
		* This may occur if a high-priority ISR is illegally using a system call,
		* or creates a user event.
		* Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls
		* or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).
		*************************************************************************/

		vTraceError("Recorder busy - high priority ISR using syscall? (3)");
		return;
	}

	trcCRITICAL_SECTION_BEGIN();
	if (RecorderDataPtr->recorderActive && handle_of_last_logged_task && (! inExcludedTask || nISRactive))
	{
		/* Check if the referenced object or the event code is excluded */
		if (!uiTraceIsObjectExcluded(objectClass, (objectHandleType)objectNumber) &&
			!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
		{
			dts2 = (uint8_t)prvTraceGetDTS(0xFF);
			p8 = (uint8_t) prvTraceGetParam(0xFF, param);
			hnd8 = prvTraceGet8BitHandle((objectHandleType)objectNumber);
			kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();
			if (kse != NULL)
			{
				kse->dts = dts2;
				kse->type = (uint8_t)evtcode;
				kse->objHandle = hnd8;
				kse->param = p8;
				prvTraceUpdateCounters();
			}
		}
	}
	trcCRITICAL_SECTION_END();
#endif /* TRACE_SCHEDULING_ONLY */
}

#if (TRACE_SCHEDULING_ONLY == 0)

/*******************************************************************************
 * prvTraceGetParam
 *
 * Used for storing extra bytes for kernel calls with numeric parameters.
 *
 * May only be called within a critical section!
 ******************************************************************************/
static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
{
	XPSEvent* xps;

	TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF,
		"prvTraceGetParam: Invalid value for param_max", param);

	if (param <= param_max)
	{
		return param;
	}
	else
	{
		xps = (XPSEvent*) xTraceNextFreeEventBufferSlot();
		if (xps != NULL)
		{
			xps->type = DIV_XPS;
			xps->xps_8 = (param & (0xFF00 & ~param_max)) >> 8;
			xps->xps_16 = (param & (0xFFFF0000 & ~param_max)) >> 16;
			prvTraceUpdateCounters();
		}

		return param & param_max;
	}
}
#endif

/*******************************************************************************
 * vTraceStoreKernelCallWithNumericParamOnly
 *
 * Used for storing kernel calls with numeric parameters only. This is
 * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.
 ******************************************************************************/
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
{
#if (TRACE_SCHEDULING_ONLY == 0)
	KernelCallWithParam16 * kse;
	uint8_t dts6;
	uint16_t restParam;
	TRACE_SR_ALLOC_CRITICAL_SECTION();

	restParam = 0;

	TRACE_ASSERT(evtcode < 0xFF,
		"vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );

	if (recorder_busy)
	{
		/*************************************************************************
		* This may occur if a high-priority ISR is illegally using a system call,
		* or creates a user event.
		* Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls
		* or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).
		*************************************************************************/

		vTraceError("Recorder busy - high priority ISR using syscall? (4)");
		return;
	}

	trcCRITICAL_SECTION_BEGIN();
	if (RecorderDataPtr->recorderActive && handle_of_last_logged_task
		&& (! inExcludedTask || nISRactive))
	{
		/* Check if the event code is excluded */
		if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
		{
			dts6 = (uint8_t)prvTraceGetDTS(0xFF);
			restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
			kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
			if (kse != NULL)
			{
				kse->dts = dts6;
				kse->type = (uint8_t)evtcode;
				kse->param = restParam;
				prvTraceUpdateCounters();
			}
		}
	}
	trcCRITICAL_SECTION_END();
#endif /* TRACE_SCHEDULING_ONLY */
}

/*******************************************************************************
 * vTraceStoreTaskswitch
 * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.
 * At this point interrupts are assumed to be disabled!
 ******************************************************************************/
void vTraceStoreTaskswitch(objectHandleType task_handle)
{
	uint16_t dts3;
	TSEvent* ts;
	int8_t skipEvent;
	uint8_t hnd8;
	TRACE_SR_ALLOC_CRITICAL_SECTION();

	skipEvent = 0;

	TRACE_ASSERT(task_handle <= NTask,
		"vTraceStoreTaskswitch: Invalid value for task_handle", );

	/***************************************************************************
	This is used to detect if a high-priority ISRs is illegally using the
	recorder ISR trace functions (vTraceStoreISRBegin and ...End) while the
	recorder is busy with a task-level event or lower priority ISR event.

	If this is detected, it triggers a call to vTraceError with the error
	"Illegal call to vTraceStoreISRBegin/End". If you get this error, it means
	that the macro trcCRITICAL_SECTION_BEGIN does not disable this ISR, as required.

	Note: Setting recorder_busy is normally handled in our macros
	trcCRITICAL_SECTION_BEGIN and _END, but is needed explicitly in this
	function since critical sections should not be used in the context switch
	event...)
	***************************************************************************/

	/* Skip the event if the task has been excluded, using vTraceExcludeTask */
	if (TRACE_GET_TASK_FLAG_ISEXCLUDED(task_handle))
	{
		skipEvent = 1;
		inExcludedTask = 1;
	}
	else
	{
		inExcludedTask = 0;
	}

	trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY();

	/* Skip the event if the same task is scheduled */
	if (task_handle == handle_of_last_logged_task)
	{
		skipEvent = 1;
	}

	if (!RecorderDataPtr->recorderActive)
	{
		skipEvent = 1;
	}

	/* If this event should be logged, log it! */
	if (skipEvent == 0)
	{
		dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
		handle_of_last_logged_task = task_handle;
		hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task);
		ts = (TSEvent*)xTraceNextFreeEventBufferSlot();

		if (ts != NULL)
		{
			if (uiTraceGetObjectState(TRACE_CLASS_TASK,
				handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE)
			{
				ts->type = TS_TASK_RESUME;
			}
			else
			{
				ts->type = TS_TASK_BEGIN;
			}

			ts->dts = dts3;
			ts->objHandle = hnd8;

			vTraceSetObjectState(TRACE_CLASS_TASK,
									handle_of_last_logged_task,
									TASK_STATE_INSTANCE_ACTIVE);

			prvTraceUpdateCounters();
		}
	}

	trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY();
}

/*******************************************************************************
 * vTraceStoreNameCloseEvent
 *
 * Updates the symbol table with the name of this object from the dynamic
 * objects table and stores a "close" event, holding the mapping between handle
 * and name (a symbol table handle). The stored name-handle mapping is thus the
 * "old" one, valid up until this point.
 ******************************************************************************/
#if (INCLUDE_OBJECT_DELETE == 1)
void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,
										traceObjectClass objectclass)
{
	ObjCloseNameEvent * ce;
	const char * name;
	traceLabel idx;

	TRACE_ASSERT(objectclass < TRACE_NCLASSES,
		"vTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", );
	TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
		"vTraceStoreObjectNameOnCloseEvent: Invalid value for handle", );

	if (RecorderDataPtr->recorderActive)
	{
		uint8_t hnd8 = prvTraceGet8BitHandle(handle);
		name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
		idx = prvTraceOpenSymbol(name, 0);

		// Interrupt disable not necessary, already done in trcHooks.h macro
		ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();
		if (ce != NULL)
		{
			ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;
			ce->objHandle = hnd8;
			ce->symbolIndex = idx;
			prvTraceUpdateCounters();
		}
	}
}

void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
											 traceObjectClass objectclass)
{
	ObjClosePropEvent * pe;

	TRACE_ASSERT(objectclass < TRACE_NCLASSES,
		"vTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", );
	TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
		"vTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", );

	if (RecorderDataPtr->recorderActive)
	{
		// Interrupt disable not necessary, already done in trcHooks.h macro
		pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();
		if (pe != NULL)
		{
			if (objectclass == TRACE_CLASS_TASK)
			{
				pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
			}
			else
			{
				pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
			}
			pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
			prvTraceUpdateCounters();
		}
	}
}
#endif

void vTraceSetPriorityProperty(uint8_t objectclass, objectHandleType id, uint8_t value)
{
	TRACE_ASSERT(objectclass < TRACE_NCLASSES,
		"vTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", );
	TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
		"vTraceSetPriorityProperty: Invalid value for id", );

	TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
}

uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, objectHandleType id)
{
	TRACE_ASSERT(objectclass < TRACE_NCLASSES,
		"uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
	TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
		"uiTraceGetPriorityProperty: Invalid value for id", 0);

	return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
}

void vTraceSetObjectState(uint8_t objectclass, objectHandleType id, uint8_t value)
{
	TRACE_ASSERT(objectclass < TRACE_NCLASSES,
		"vTraceSetObjectState: objectclass >= TRACE_NCLASSES", );
	TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
		"vTraceSetObjectState: Invalid value for id", );

	TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
}

uint8_t uiTraceGetObjectState(uint8_t objectclass, objectHandleType id)
{
	TRACE_ASSERT(objectclass < TRACE_NCLASSES,
		"uiTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);
	TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass],
		"uiTraceGetObjectState: Invalid value for id", 0);

	return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
}

void vTraceSetTaskInstanceFinished(objectHandleType handle)
{
	TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK],
		"vTraceSetTaskInstanceFinished: Invalid value for handle", );

#if (USE_IMPLICIT_IFE_RULES == 1)
	TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
#endif
}

#endif
