/*
 * FreeRTOS Kernel V10.3.0
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

/**
 * This file exercises the event mechanism whereby more than one task is
 * blocked waiting for the same event.
 *
 * The demo creates five tasks - four 'event' tasks, and a controlling task.
 * The event tasks have various different priorities and all block on reading
 * the same queue.  The controlling task writes data to the queue, then checks
 * to see which of the event tasks read the data from the queue.  The
 * controlling task has the lowest priority of all the tasks so is guaranteed
 * to always get preempted immediately upon writing to the queue.
 *
 * By selectively suspending and resuming the event tasks the controlling task
 * can check that the highest priority task that is blocked on the queue is the
 * task that reads the posted data from the queue.
 *
 * Two of the event tasks share the same priority.  When neither of these tasks
 * are suspended they should alternate - one reading one message from the queue,
 * the other the next message, etc.
 */

/* Standard includes. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

/* Demo program include files. */
#include "mevents.h"
#include "print.h"

/* Demo specific constants. */
#define evtSTACK_SIZE		( ( unsigned portBASE_TYPE ) configMINIMAL_STACK_SIZE )
#define evtNUM_TASKS		( 4 )
#define evtQUEUE_LENGTH		( ( unsigned portBASE_TYPE ) 3 )
#define evtNO_DELAY						0

/* Just indexes used to uniquely identify the tasks.  Note that two tasks are
'highest' priority. */
#define evtHIGHEST_PRIORITY_INDEX_2		3
#define evtHIGHEST_PRIORITY_INDEX_1		2
#define evtMEDIUM_PRIORITY_INDEX		1
#define evtLOWEST_PRIORITY_INDEX		0

/* Each event task increments one of these counters each time it reads data
from the queue. */
static volatile portBASE_TYPE xTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 };

/* Each time the controlling task posts onto the queue it increments the 
expected count of the task that it expected to read the data from the queue 
(i.e. the task with the highest priority that should be blocked on the queue).  

xExpectedTaskCounters are incremented from the controlling task, and 
xTaskCounters are incremented from the individual event tasks - therefore
comparing xTaskCounters to xExpectedTaskCounters shows whether or not the 
correct task was unblocked by the post. */
static portBASE_TYPE xExpectedTaskCounters[ evtNUM_TASKS ] = { 0, 0, 0, 0 };

/* Handles to the four event tasks.  These are required to suspend and resume
the tasks. */
static TaskHandle_t xCreatedTasks[ evtNUM_TASKS ];

/* The single queue onto which the controlling task posts, and the four event
tasks block. */
static QueueHandle_t xQueue;

/* Flag used to indicate whether or not an error has occurred at any time.
An error is either the queue being full when not expected, or an unexpected
task reading data from the queue. */
static portBASE_TYPE xHealthStatus = pdPASS;

/*-----------------------------------------------------------*/

/* Function that implements the event task.  This is created four times. */
static void prvMultiEventTask( void *pvParameters );

/* Function that implements the controlling task. */
static void prvEventControllerTask( void *pvParameters );

/* This is a utility function that posts data to the queue, then compares 
xExpectedTaskCounters with xTaskCounters to ensure everything worked as 
expected.

The event tasks all have higher priorities the controlling task.  Therefore
the controlling task will always get preempted between writhing to the queue
and checking the task counters. 

@param xExpectedTask  The index to the task that the controlling task thinks
                      should be the highest priority task waiting for data, and
					  therefore the task that will unblock.
					  
@param	xIncrement    The number of items that should be written to the queue.
*/
static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement );

/* This is just incremented each cycle of the controlling tasks function so
the main application can ensure the test is still running. */
static portBASE_TYPE xCheckVariable = 0;

/*-----------------------------------------------------------*/

void vStartMultiEventTasks( void )
{
	/* Create the queue to be used for all the communications. */
	xQueue = xQueueCreate( evtQUEUE_LENGTH, ( unsigned portBASE_TYPE ) sizeof( unsigned portBASE_TYPE ) );

	/* Start the controlling task.  This has the idle priority to ensure it is
	always preempted by the event tasks. */
	xTaskCreate( prvEventControllerTask, "EvntCTRL", evtSTACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );

	/* Start the four event tasks.  Note that two have priority 3, one 
	priority 2 and the other priority 1. */
	xTaskCreate( prvMultiEventTask, "Event0", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 0 ] ), 1, &( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] ) );
	xTaskCreate( prvMultiEventTask, "Event1", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 1 ] ), 2, &( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] ) );
	xTaskCreate( prvMultiEventTask, "Event2", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 2 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] ) );
	xTaskCreate( prvMultiEventTask, "Event3", evtSTACK_SIZE, ( void * ) &( xTaskCounters[ 3 ] ), 3, &( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] ) );
}
/*-----------------------------------------------------------*/

static void prvMultiEventTask( void *pvParameters )
{
portBASE_TYPE *pxCounter;
unsigned portBASE_TYPE uxDummy;
const char * const pcTaskStartMsg = "Multi event task started.\r\n";

	/* The variable this task will increment is passed in as a parameter. */
	pxCounter = ( portBASE_TYPE * ) pvParameters;

	vPrintDisplayMessage( &pcTaskStartMsg );

	for( ;; )
	{
		/* Block on the queue. */
		if( xQueueReceive( xQueue, &uxDummy, portMAX_DELAY ) )
		{
			/* We unblocked by reading the queue - so simply increment
			the counter specific to this task instance. */
			( *pxCounter )++;
		}
		else
		{
			xHealthStatus = pdFAIL;
		}
	}
}
/*-----------------------------------------------------------*/

static void prvEventControllerTask( void *pvParameters )
{
const char * const pcTaskStartMsg = "Multi event controller task started.\r\n";
portBASE_TYPE xDummy = 0;

	/* Just to stop warnings. */
	( void ) pvParameters;

	vPrintDisplayMessage( &pcTaskStartMsg );

	for( ;; )
	{
		/* All tasks are blocked on the queue.  When a message is posted one of
		the two tasks that share the highest priority should unblock to read
		the queue.  The next message written should unblock the other task with
		the same high priority, and so on in order.   No other task should 
		unblock to read data as they have lower priorities. */

		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_2, 1 );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );

		/* For the rest of these tests we don't need the second 'highest' 
		priority task - so it is suspended. */
		vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] );



		/* Now suspend the other highest priority task.  The medium priority 
		task will then be the task with the highest priority that remains 
		blocked on the queue. */
		vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		
		/* This time, when we post onto the queue we will expect the medium
		priority task to unblock and preempt us. */
		prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 );

		/* Now try resuming the highest priority task while the scheduler is
		suspended.  The task should start executing as soon as the scheduler
		is resumed - therefore when we post to the queue again, the highest
		priority task should again preempt us. */
		vTaskSuspendAll();
			vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		xTaskResumeAll();
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		
		/* Now we are going to suspend the high and medium priority tasks.  The
		low priority task should then preempt us.  Again the task suspension is 
		done with the whole scheduler suspended just for test purposes. */
		vTaskSuspendAll();
			vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
			vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		xTaskResumeAll();
		prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 );
		
		/* Do the same basic test another few times - selectively suspending
		and resuming tasks and each time calling prvCheckTaskCounters() passing
		to the function the number of the task we expected to be unblocked by 
		the	post. */

		vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );
		
		vTaskSuspendAll(); /* Just for test. */
			vTaskSuspendAll(); /* Just for test. */
				vTaskSuspendAll(); /* Just for even more test. */
					vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
				xTaskResumeAll();
			xTaskResumeAll();
		xTaskResumeAll();
		prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, 1 );
		
		vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		prvCheckTaskCounters( evtMEDIUM_PRIORITY_INDEX, 1 );
		
		vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		prvCheckTaskCounters( evtHIGHEST_PRIORITY_INDEX_1, 1 );

		/* Now a slight change, first suspend all tasks. */
		vTaskSuspend( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
		vTaskSuspend( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
		
		/* Now when we resume the low priority task and write to the queue 3 
		times.  We expect the low priority task to service the queue three
		times. */
		vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
		prvCheckTaskCounters( evtLOWEST_PRIORITY_INDEX, evtQUEUE_LENGTH );
		
		/* Again suspend all tasks (only the low priority task is not suspended
		already). */
		vTaskSuspend( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
		
		/* This time we are going to suspend the scheduler, resume the low
		priority task, then resume the high priority task.  In this state we
		will write to the queue three times.  When the scheduler is resumed
		we expect the high priority task to service all three messages. */
		vTaskSuspendAll();
		{
			vTaskResume( xCreatedTasks[ evtLOWEST_PRIORITY_INDEX ] );
			vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_1 ] );
			
			for( xDummy = 0; xDummy < evtQUEUE_LENGTH; xDummy++ )
			{
				if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE )
				{
					xHealthStatus = pdFAIL;
				}
			}			
			
			/* The queue should not have been serviced yet!.  The scheduler
			is still suspended. */
			if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
			{
				xHealthStatus = pdFAIL;
			}
		}
		xTaskResumeAll();

		/* We should have been preempted by resuming the scheduler - so by the
		time we are running again we expect the high priority task to have 
		removed three items from the queue. */
		xExpectedTaskCounters[ evtHIGHEST_PRIORITY_INDEX_1 ] += evtQUEUE_LENGTH;
		if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
		{
			xHealthStatus = pdFAIL;
		}
		
		/* The medium priority and second high priority tasks are still 
		suspended.  Make sure to resume them before starting again. */
		vTaskResume( xCreatedTasks[ evtMEDIUM_PRIORITY_INDEX ] );
		vTaskResume( xCreatedTasks[ evtHIGHEST_PRIORITY_INDEX_2 ] );

		/* Just keep incrementing to show the task is still executing. */
		xCheckVariable++;
	}
}
/*-----------------------------------------------------------*/

static void prvCheckTaskCounters( portBASE_TYPE xExpectedTask, portBASE_TYPE xIncrement )
{
portBASE_TYPE xDummy = 0;

	/* Write to the queue the requested number of times.  The data written is
	not important. */
	for( xDummy = 0; xDummy < xIncrement; xDummy++ )
	{
		if( xQueueSend( xQueue, &xDummy, evtNO_DELAY ) != pdTRUE )
		{
			/* Did not expect to ever find the queue full. */
			xHealthStatus = pdFAIL;
		}
	}

	/* All the tasks blocked on the queue have a priority higher than the 
	controlling task.  Writing to the queue will therefore have caused this
	task to be preempted.  By the time this line executes the event task will
	have executed and incremented its counter.  Increment the expected counter
	to the same value. */
	( xExpectedTaskCounters[ xExpectedTask ] ) += xIncrement;

	/* Check the actual counts and expected counts really are the same. */
	if( memcmp( ( void * ) xExpectedTaskCounters, ( void * ) xTaskCounters, sizeof( xExpectedTaskCounters ) ) )
	{
		/* The counters were not the same.  This means a task we did not expect
		to unblock actually did unblock. */
		xHealthStatus = pdFAIL;
	}
}
/*-----------------------------------------------------------*/

portBASE_TYPE xAreMultiEventTasksStillRunning( void )
{
static portBASE_TYPE xPreviousCheckVariable = 0;

	/* Called externally to periodically check that this test is still
	operational. */

	if( xPreviousCheckVariable == xCheckVariable )
	{
		xHealthStatus = pdFAIL;
	}
	
	xPreviousCheckVariable = xCheckVariable;
	
	return xHealthStatus;	
}


