/*
 * FreeRTOS Kernel <DEVELOPMENT BRANCH>
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * SPDX-License-Identifier: MIT
 *
 * 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.
 *
 * https://www.FreeRTOS.org
 * https://github.com/FreeRTOS
 *
 */

/* Standard includes. */
#include <stdio.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"

#ifdef __GNUC__
    #include "mmsystem.h"
#else
    #pragma comment(lib, "winmm.lib")
#endif

#define portMAX_INTERRUPTS              ( ( uint32_t ) sizeof( uint32_t ) * 8UL ) /* The number of bits in an uint32_t. */
#define portNO_CRITICAL_NESTING         ( ( uint32_t ) 0 )

/* The priorities at which the various components of the simulation execute. */
#define portDELETE_SELF_THREAD_PRIORITY          THREAD_PRIORITY_TIME_CRITICAL /* Must be highest. */
#define portSIMULATED_INTERRUPTS_THREAD_PRIORITY THREAD_PRIORITY_TIME_CRITICAL
#define portSIMULATED_TIMER_THREAD_PRIORITY      THREAD_PRIORITY_HIGHEST
#define portTASK_THREAD_PRIORITY                 THREAD_PRIORITY_ABOVE_NORMAL

/*
 * Created as a high priority thread, this function uses a timer to simulate
 * a tick interrupt being generated on an embedded target.  In this Windows
 * environment the timer does not achieve anything approaching real time
 * performance though.
 */
static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter );

/*
 * Process all the simulated interrupts - each represented by a bit in
 * ulPendingInterrupts variable.
 */
static void prvProcessSimulatedInterrupts( void );

/*
 * Interrupt handlers used by the kernel itself.  These are executed from the
 * simulated interrupt handler thread.
 */
static uint32_t prvProcessYieldInterrupt( void );
static uint32_t prvProcessTickInterrupt( void );

/*
 * Exiting a critical section will cause the calling task to block on yield
 * event to wait for an interrupt to process if an interrupt was pended while
 * inside the critical section.  This variable protects against a recursive
 * attempt to obtain pvInterruptEventMutex if a critical section is used inside
 * an interrupt handler itself.
 */
volatile BaseType_t xInsideInterrupt = pdFALSE;

/*
 * Called when the process exits to let Windows know the high timer resolution
 * is no longer required.
 */
static BOOL WINAPI prvEndProcess( DWORD dwCtrlType );

/*-----------------------------------------------------------*/

/* The WIN32 simulator runs each task in a thread.  The context switching is
managed by the threads, so the task stack does not have to be managed directly,
although the task stack is still used to hold an xThreadState structure this is
the only thing it will ever hold.  The structure indirectly maps the task handle
to a thread handle. */
typedef struct
{
    /* Handle of the thread that executes the task. */
    void *pvThread;

    /* Event used to make sure the thread does not execute past a yield point
    between the call to SuspendThread() to suspend the thread and the
    asynchronous SuspendThread() operation actually being performed. */
    void *pvYieldEvent;
} ThreadState_t;

/* Simulated interrupts waiting to be processed.  This is a bit mask where each
bit represents one interrupt, so a maximum of 32 interrupts can be simulated. */
static volatile uint32_t ulPendingInterrupts = 0UL;

/* An event used to inform the simulated interrupt processing thread (a high
priority thread that simulated interrupt processing) that an interrupt is
pending. */
static void *pvInterruptEvent = NULL;

/* Mutex used to protect all the simulated interrupt variables that are accessed
by multiple threads. */
static void *pvInterruptEventMutex = NULL;

/* The critical nesting count for the currently executing task.  This is
initialised to a non-zero value so interrupts do not become enabled during
the initialisation phase.  As each task has its own critical nesting value
ulCriticalNesting will get set to zero when the first task runs.  This
initialisation is probably not critical in this simulated environment as the
simulated interrupt handlers do not get created until the FreeRTOS scheduler is
started anyway. */
static volatile uint32_t ulCriticalNesting = 9999UL;

/* Handlers for all the simulated software interrupts.  The first two positions
are used for the Yield and Tick interrupts so are handled slightly differently,
all the other interrupts can be user defined. */
static uint32_t (*ulIsrHandler[ portMAX_INTERRUPTS ])( void ) = { 0 };

/* Pointer to the TCB of the currently executing task. */
extern void * volatile pxCurrentTCB;

/* Used to ensure nothing is processed during the startup sequence. */
static BaseType_t xPortRunning = pdFALSE;

/*-----------------------------------------------------------*/

static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter )
{
TickType_t xMinimumWindowsBlockTime;
TIMECAPS xTimeCaps;

    /* Set the timer resolution to the maximum possible. */
    if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
    {
        xMinimumWindowsBlockTime = ( TickType_t ) xTimeCaps.wPeriodMin;
        timeBeginPeriod( xTimeCaps.wPeriodMin );

        /* Register an exit handler so the timeBeginPeriod() function can be
        matched with a timeEndPeriod() when the application exits. */
        SetConsoleCtrlHandler( prvEndProcess, TRUE );
    }
    else
    {
        xMinimumWindowsBlockTime = ( TickType_t ) 20;
    }

    /* Just to prevent compiler warnings. */
    ( void ) lpParameter;

    while( xPortRunning == pdTRUE )
    {
        /* Wait until the timer expires and we can access the simulated interrupt
        variables.  *NOTE* this is not a 'real time' way of generating tick
        events as the next wake time should be relative to the previous wake
        time, not the time that Sleep() is called.  It is done this way to
        prevent overruns in this very non real time simulated/emulated
        environment. */
        if( portTICK_PERIOD_MS < xMinimumWindowsBlockTime )
        {
            Sleep( xMinimumWindowsBlockTime );
        }
        else
        {
            Sleep( portTICK_PERIOD_MS );
        }

        if( xPortRunning == pdTRUE )
        {
            configASSERT( xPortRunning );

            /* Can't proceed if in a critical section as pvInterruptEventMutex won't
            be available. */
            WaitForSingleObject( pvInterruptEventMutex, INFINITE );

            /* The timer has expired, generate the simulated tick event. */
            ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );

            /* The interrupt is now pending - notify the simulated interrupt
            handler thread.  Must be outside of a critical section to get here so
            the handler thread can execute immediately pvInterruptEventMutex is
            released. */
            configASSERT( ulCriticalNesting == 0UL );
            SetEvent( pvInterruptEvent );

            /* Give back the mutex so the simulated interrupt handler unblocks
            and can access the interrupt handler variables. */
            ReleaseMutex( pvInterruptEventMutex );
        }
    }


    return 0;
}
/*-----------------------------------------------------------*/

static BOOL WINAPI prvEndProcess( DWORD dwCtrlType )
{
TIMECAPS xTimeCaps;

    ( void ) dwCtrlType;

    if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR )
    {
        /* Match the call to timeBeginPeriod( xTimeCaps.wPeriodMin ) made when
        the process started with a timeEndPeriod() as the process exits. */
        timeEndPeriod( xTimeCaps.wPeriodMin );
    }

    return pdFALSE;
}
/*-----------------------------------------------------------*/

StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
ThreadState_t *pxThreadState = NULL;
int8_t *pcTopOfStack = ( int8_t * ) pxTopOfStack;
const SIZE_T xStackSize = 1024; /* Set the size to a small number which will get rounded up to the minimum possible. */

    /* In this simulated case a stack is not initialised, but instead a thread
    is created that will execute the task being created.  The thread handles
    the context switching itself.  The ThreadState_t object is placed onto
    the stack that was created for the task - so the stack buffer is still
    used, just not in the conventional way.  It will not be used for anything
    other than holding this structure. */
    pxThreadState = ( ThreadState_t * ) ( pcTopOfStack - sizeof( ThreadState_t ) );

    /* Create the event used to prevent the thread from executing past its yield
    point if the SuspendThread() call that suspends the thread does not take
    effect immediately (it is an asynchronous call). */
    pxThreadState->pvYieldEvent = CreateEvent(  NULL,  /* Default security attributes. */
                                                FALSE, /* Auto reset. */
                                                FALSE, /* Start not signalled. */
                                                NULL );/* No name. */

    /* Create the thread itself. */
    pxThreadState->pvThread = CreateThread( NULL, xStackSize, ( LPTHREAD_START_ROUTINE ) pxCode, pvParameters, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, NULL );
    configASSERT( pxThreadState->pvThread ); /* See comment where TerminateThread() is called. */
    SetThreadAffinityMask( pxThreadState->pvThread, 0x01 );
    SetThreadPriorityBoost( pxThreadState->pvThread, TRUE );
    SetThreadPriority( pxThreadState->pvThread, portTASK_THREAD_PRIORITY );

    return ( StackType_t * ) pxThreadState;
}
/*-----------------------------------------------------------*/

BaseType_t xPortStartScheduler( void )
{
void *pvHandle = NULL;
int32_t lSuccess;
ThreadState_t *pxThreadState = NULL;
SYSTEM_INFO xSystemInfo;

    /* This port runs windows threads with extremely high priority.  All the
    threads execute on the same core - to prevent locking up the host only start
    if the host has multiple cores. */
    GetSystemInfo( &xSystemInfo );
    if( xSystemInfo.dwNumberOfProcessors <= 1 )
    {
        printf( "This version of the FreeRTOS Windows port can only be used on multi-core hosts.\r\n" );
        lSuccess = pdFAIL;
    }
    else
    {
        lSuccess = pdPASS;

        /* The highest priority class is used to [try to] prevent other Windows
        activity interfering with FreeRTOS timing too much. */
        if( SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ) == 0 )
        {
            printf( "SetPriorityClass() failed\r\n" );
        }

        /* Install the interrupt handlers used by the scheduler itself. */
        vPortSetInterruptHandler( portINTERRUPT_YIELD, prvProcessYieldInterrupt );
        vPortSetInterruptHandler( portINTERRUPT_TICK, prvProcessTickInterrupt );

        /* Create the events and mutexes that are used to synchronise all the
        threads. */
        pvInterruptEventMutex = CreateMutex( NULL, FALSE, NULL );
        pvInterruptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

        if( ( pvInterruptEventMutex == NULL ) || ( pvInterruptEvent == NULL ) )
        {
            lSuccess = pdFAIL;
        }

        /* Set the priority of this thread such that it is above the priority of
        the threads that run tasks.  This higher priority is required to ensure
        simulated interrupts take priority over tasks. */
        pvHandle = GetCurrentThread();
        if( pvHandle == NULL )
        {
            lSuccess = pdFAIL;
        }
    }

    if( lSuccess == pdPASS )
    {
        if( SetThreadPriority( pvHandle, portSIMULATED_INTERRUPTS_THREAD_PRIORITY ) == 0 )
        {
            lSuccess = pdFAIL;
        }
        SetThreadPriorityBoost( pvHandle, TRUE );
        SetThreadAffinityMask( pvHandle, 0x01 );
    }

    if( lSuccess == pdPASS )
    {
        /* Start the thread that simulates the timer peripheral to generate
        tick interrupts.  The priority is set below that of the simulated
        interrupt handler so the interrupt event mutex is used for the
        handshake / overrun protection. */
        pvHandle = CreateThread( NULL, 0, prvSimulatedPeripheralTimer, NULL, CREATE_SUSPENDED, NULL );
        if( pvHandle != NULL )
        {
            SetThreadPriority( pvHandle, portSIMULATED_TIMER_THREAD_PRIORITY );
            SetThreadPriorityBoost( pvHandle, TRUE );
            SetThreadAffinityMask( pvHandle, 0x01 );
            ResumeThread( pvHandle );
        }

        /* Start the highest priority task by obtaining its associated thread
        state structure, in which is stored the thread handle. */
        pxThreadState = ( ThreadState_t * ) *( ( size_t * ) pxCurrentTCB );
        ulCriticalNesting = portNO_CRITICAL_NESTING;

        /* Start the first task. */
        ResumeThread( pxThreadState->pvThread );

        /* The scheduler is now running. */
        xPortRunning = pdTRUE;

        /* Handle all simulated interrupts - including yield requests and
        simulated ticks. */
        prvProcessSimulatedInterrupts();
    }

    /* Would not expect to return from prvProcessSimulatedInterrupts(), so should
    not get here. */
    return 0;
}
/*-----------------------------------------------------------*/

static uint32_t prvProcessYieldInterrupt( void )
{
    /* Always return true as this is a yield. */
    return pdTRUE;
}
/*-----------------------------------------------------------*/

static uint32_t prvProcessTickInterrupt( void )
{
uint32_t ulSwitchRequired;

    /* Process the tick itself. */
    configASSERT( xPortRunning );
    ulSwitchRequired = ( uint32_t ) xTaskIncrementTick();

    return ulSwitchRequired;
}
/*-----------------------------------------------------------*/

static void prvProcessSimulatedInterrupts( void )
{
uint32_t ulSwitchRequired, i;
ThreadState_t *pxThreadState;
void *pvObjectList[ 2 ];
CONTEXT xContext;
DWORD xWinApiResult;
const DWORD xTimeoutMilliseconds = 1000;

    /* Going to block on the mutex that ensured exclusive access to the simulated
    interrupt objects, and the event that signals that a simulated interrupt
    should be processed. */
    pvObjectList[ 0 ] = pvInterruptEventMutex;
    pvObjectList[ 1 ] = pvInterruptEvent;

    /* Create a pending tick to ensure the first task is started as soon as
    this thread pends. */
    ulPendingInterrupts |= ( 1 << portINTERRUPT_TICK );
    SetEvent( pvInterruptEvent );

    while( xPortRunning == pdTRUE )
    {
        xInsideInterrupt = pdFALSE;

        /* Wait with timeout so that we can exit from this loop when
         * the scheduler is stopped by calling vPortEndScheduler. */
        xWinApiResult = WaitForMultipleObjects( sizeof( pvObjectList ) / sizeof( void * ), pvObjectList, TRUE, xTimeoutMilliseconds );

        if( xWinApiResult != WAIT_TIMEOUT )
        {
            /* Cannot be in a critical section to get here.  Tasks that exit a
            critical section will block on a yield mutex to wait for an interrupt to
            process if an interrupt was set pending while the task was inside the
            critical section.  xInsideInterrupt prevents interrupts that contain
            critical sections from doing the same. */
            xInsideInterrupt = pdTRUE;

            /* Used to indicate whether the simulated interrupt processing has
            necessitated a context switch to another task/thread. */
            ulSwitchRequired = pdFALSE;

            /* For each interrupt we are interested in processing, each of which is
            represented by a bit in the 32bit ulPendingInterrupts variable. */
            for( i = 0; i < portMAX_INTERRUPTS; i++ )
            {
                /* Is the simulated interrupt pending? */
                if( ( ulPendingInterrupts & ( 1UL << i ) ) != 0 )
                {
                    /* Is a handler installed? */
                    if( ulIsrHandler[ i ] != NULL )
                    {
                        /* Run the actual handler.  Handlers return pdTRUE if they
                        necessitate a context switch. */
                        if( ulIsrHandler[ i ]() != pdFALSE )
                        {
                            /* A bit mask is used purely to help debugging. */
                            ulSwitchRequired |= ( 1 << i );
                        }
                    }

                    /* Clear the interrupt pending bit. */
                    ulPendingInterrupts &= ~( 1UL << i );
                }
            }

            if( ulSwitchRequired != pdFALSE )
            {
                void *pvOldCurrentTCB;

                pvOldCurrentTCB = pxCurrentTCB;

                /* Select the next task to run. */
                vTaskSwitchContext();

                /* If the task selected to enter the running state is not the task
                that is already in the running state. */
                if( pvOldCurrentTCB != pxCurrentTCB )
                {
                    /* Suspend the old thread.  In the cases where the (simulated)
                    interrupt is asynchronous (tick event swapping a task out rather
                    than a task blocking or yielding) it doesn't matter if the
                    'suspend' operation doesn't take effect immediately - if it
                    doesn't it would just be like the interrupt occurring slightly
                    later.  In cases where the yield was caused by a task blocking
                    or yielding then the task will block on a yield event after the
                    yield operation in case the 'suspend' operation doesn't take
                    effect immediately.  */
                    pxThreadState = ( ThreadState_t *) *( ( size_t * ) pvOldCurrentTCB );
                    SuspendThread( pxThreadState->pvThread );

                    /* Ensure the thread is actually suspended by performing a
                    synchronous operation that can only complete when the thread is
                    actually suspended.  The below code asks for dummy register
                    data.  Experimentation shows that these two lines don't appear
                    to do anything now, but according to
                    https://devblogs.microsoft.com/oldnewthing/20150205-00/?p=44743
                    they do - so as they do not harm (slight run-time hit). */
                    xContext.ContextFlags = CONTEXT_INTEGER;
                    ( void ) GetThreadContext( pxThreadState->pvThread, &xContext );

                    /* Obtain the state of the task now selected to enter the
                    Running state. */
                    pxThreadState = ( ThreadState_t * ) ( *( size_t *) pxCurrentTCB );

                    /* pxThreadState->pvThread can be NULL if the task deleted
                    itself - but a deleted task should never be resumed here. */
                    configASSERT( pxThreadState->pvThread != NULL );
                    ResumeThread( pxThreadState->pvThread );
                }
            }

            /* If the thread that is about to be resumed stopped running
            because it yielded then it will wait on an event when it resumed
            (to ensure it does not continue running after the call to
            SuspendThread() above as SuspendThread() is asynchronous).
            Signal the event to ensure the thread can proceed now it is
            valid for it to do so.  Signaling the event is benign in the case that
            the task was switched out asynchronously by an interrupt as the event
            is reset before the task blocks on it. */
            pxThreadState = ( ThreadState_t * ) ( *( size_t *) pxCurrentTCB );
            SetEvent( pxThreadState->pvYieldEvent );
            ReleaseMutex( pvInterruptEventMutex );
        }
    }
}
/*-----------------------------------------------------------*/

void vPortDeleteThread( void *pvTaskToDelete )
{
ThreadState_t *pxThreadState;
uint32_t ulErrorCode;

    /* Remove compiler warnings if configASSERT() is not defined. */
    ( void ) ulErrorCode;

    /* Find the handle of the thread being deleted. */
    pxThreadState = ( ThreadState_t * ) ( *( size_t *) pvTaskToDelete );

    /* Check that the thread is still valid, it might have been closed by
    vPortCloseRunningThread() - which will be the case if the task associated
    with the thread originally deleted itself rather than being deleted by a
    different task. */
    if( pxThreadState->pvThread != NULL )
    {
        WaitForSingleObject( pvInterruptEventMutex, INFINITE );

        /* !!! This is not a nice way to terminate a thread, and will eventually
        result in resources being depleted if tasks frequently delete other
        tasks (rather than deleting themselves) as the task stacks will not be
        freed. */
        ulErrorCode = TerminateThread( pxThreadState->pvThread, 0 );
        configASSERT( ulErrorCode );

        ulErrorCode = CloseHandle( pxThreadState->pvThread );
        configASSERT( ulErrorCode );

        ReleaseMutex( pvInterruptEventMutex );
    }
}
/*-----------------------------------------------------------*/

void vPortCloseRunningThread( void *pvTaskToDelete, volatile BaseType_t *pxPendYield )
{
ThreadState_t *pxThreadState;
void *pvThread;
uint32_t ulErrorCode;

    /* Remove compiler warnings if configASSERT() is not defined. */
    ( void ) ulErrorCode;

    /* Find the handle of the thread being deleted. */
    pxThreadState = ( ThreadState_t * ) ( *( size_t *) pvTaskToDelete );
    pvThread = pxThreadState->pvThread;

    /* Raise the Windows priority of the thread to ensure the FreeRTOS scheduler
    does not run and swap it out before it is closed.  If that were to happen
    the thread would never run again and effectively be a thread handle and
    memory leak. */
    SetThreadPriority( pvThread, portDELETE_SELF_THREAD_PRIORITY );

    /* This function will not return, therefore a yield is set as pending to
    ensure a context switch occurs away from this thread on the next tick. */
    *pxPendYield = pdTRUE;

    /* Mark the thread associated with this task as invalid so
    vPortDeleteThread() does not try to terminate it. */
    pxThreadState->pvThread = NULL;

    /* Close the thread. */
    ulErrorCode = CloseHandle( pvThread );
    configASSERT( ulErrorCode );

    /* This is called from a critical section, which must be exited before the
    thread stops. */
    taskEXIT_CRITICAL();
    CloseHandle( pxThreadState->pvYieldEvent );
    ExitThread( 0 );
}
/*-----------------------------------------------------------*/

void vPortEndScheduler( void )
{
    xPortRunning = pdFALSE;
}
/*-----------------------------------------------------------*/

void vPortGenerateSimulatedInterrupt( uint32_t ulInterruptNumber )
{
ThreadState_t *pxThreadState = ( ThreadState_t *) *( ( size_t * ) pxCurrentTCB );

    configASSERT( xPortRunning );

    if( ( ulInterruptNumber < portMAX_INTERRUPTS ) && ( pvInterruptEventMutex != NULL ) )
    {
        WaitForSingleObject( pvInterruptEventMutex, INFINITE );
        ulPendingInterrupts |= ( 1 << ulInterruptNumber );

        /* The simulated interrupt is now held pending, but don't actually
        process it yet if this call is within a critical section.  It is
        possible for this to be in a critical section as calls to wait for
        mutexes are accumulative.  If in a critical section then the event
        will get set when the critical section nesting count is wound back
        down to zero. */
        if( ulCriticalNesting == portNO_CRITICAL_NESTING )
        {
            SetEvent( pvInterruptEvent );

            /* Going to wait for an event - make sure the event is not already
            signaled. */
            ResetEvent( pxThreadState->pvYieldEvent );
        }

        ReleaseMutex( pvInterruptEventMutex );
        if( ulCriticalNesting == portNO_CRITICAL_NESTING )
        {
            /* An interrupt was pended so ensure to block to allow it to
            execute.  In most cases the (simulated) interrupt will have
            executed before the next line is reached - so this is just to make
            sure. */
            WaitForSingleObject( pxThreadState->pvYieldEvent, INFINITE );
        }
    }
}
/*-----------------------------------------------------------*/

void vPortSetInterruptHandler( uint32_t ulInterruptNumber, uint32_t (*pvHandler)( void ) )
{
    if( ulInterruptNumber < portMAX_INTERRUPTS )
    {
        if( pvInterruptEventMutex != NULL )
        {
            WaitForSingleObject( pvInterruptEventMutex, INFINITE );
            ulIsrHandler[ ulInterruptNumber ] = pvHandler;
            ReleaseMutex( pvInterruptEventMutex );
        }
        else
        {
            ulIsrHandler[ ulInterruptNumber ] = pvHandler;
        }
    }
}
/*-----------------------------------------------------------*/

void vPortEnterCritical( void )
{
    if( xPortRunning == pdTRUE )
    {
        /* The interrupt event mutex is held for the entire critical section,
        effectively disabling (simulated) interrupts. */
        WaitForSingleObject( pvInterruptEventMutex, INFINITE );
    }

    ulCriticalNesting++;
}
/*-----------------------------------------------------------*/

void vPortExitCritical( void )
{
int32_t lMutexNeedsReleasing;

    /* The interrupt event mutex should already be held by this thread as it was
    obtained on entry to the critical section. */
    lMutexNeedsReleasing = pdTRUE;

    if( ulCriticalNesting > portNO_CRITICAL_NESTING )
    {
        ulCriticalNesting--;

        /* Don't need to wait for any pending interrupts to execute if the
        critical section was exited from inside an interrupt. */
        if( ( ulCriticalNesting == portNO_CRITICAL_NESTING ) && ( xInsideInterrupt == pdFALSE ) )
        {
            /* Were any interrupts set to pending while interrupts were
            (simulated) disabled? */
            if( ulPendingInterrupts != 0UL )
            {
                ThreadState_t *pxThreadState = ( ThreadState_t *) *( ( size_t * ) pxCurrentTCB );

                configASSERT( xPortRunning );

                /* The interrupt won't actually executed until
                pvInterruptEventMutex is released as it waits on both
                pvInterruptEventMutex and pvInterruptEvent.
                pvInterruptEvent is only set when the simulated
                interrupt is pended if the interrupt is pended
                from outside a critical section - hence it is set
                here. */
                SetEvent( pvInterruptEvent );
                /* The calling task is going to wait for an event to ensure the
                interrupt that is pending executes immediately after the
                critical section is exited - so make sure the event is not
                already signaled. */
                ResetEvent( pxThreadState->pvYieldEvent );

                /* Mutex will be released now so the (simulated) interrupt can
                execute, so does not require releasing on function exit. */
                lMutexNeedsReleasing = pdFALSE;
                ReleaseMutex( pvInterruptEventMutex );
                WaitForSingleObject( pxThreadState->pvYieldEvent, INFINITE );
            }
        }
    }

    if( pvInterruptEventMutex != NULL )
    {
        if( lMutexNeedsReleasing == pdTRUE )
        {
            configASSERT( xPortRunning );
            ReleaseMutex( pvInterruptEventMutex );
        }
    }
}
/*-----------------------------------------------------------*/
