/*
 * FreeRTOS Kernel V10.3.1
 * 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
 *
 */

/**
 * @file atomic.h
 * @brief FreeRTOS atomic operation support.
 *
 * This file implements atomic functions by disabling interrupts globally.
 * Implementations with architecture specific atomic instructions can be
 * provided under each compiler directory.
 */

#ifndef ATOMIC_H
    #define ATOMIC_H

    #ifndef INC_FREERTOS_H
        #error "include FreeRTOS.h must appear in source files before include atomic.h"
    #endif

/* Standard includes. */
    #include <stdint.h>

    #ifdef __cplusplus
        extern "C" {
    #endif

/*
 * Port specific definitions -- entering/exiting critical section.
 * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
 *
 * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
 * ATOMIC_ENTER_CRITICAL().
 *
 */
    #if defined( portSET_INTERRUPT_MASK_FROM_ISR )

/* Nested interrupt scheme is supported in this port. */
        #define ATOMIC_ENTER_CRITICAL() \
    UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()

        #define ATOMIC_EXIT_CRITICAL() \
    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )

    #else

/* Nested interrupt scheme is NOT supported in this port. */
        #define ATOMIC_ENTER_CRITICAL()    portENTER_CRITICAL()
        #define ATOMIC_EXIT_CRITICAL()     portEXIT_CRITICAL()

    #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */

/*
 * Port specific definition -- "always inline".
 * Inline is compiler specific, and may not always get inlined depending on your
 * optimization level.  Also, inline is considered as performance optimization
 * for atomic.  Thus, if portFORCE_INLINE is not provided by portmacro.h,
 * instead of resulting error, simply define it away.
 */
    #ifndef portFORCE_INLINE
        #define portFORCE_INLINE
    #endif

    #define ATOMIC_COMPARE_AND_SWAP_SUCCESS    0x1U /**< Compare and swap succeeded, swapped. */
    #define ATOMIC_COMPARE_AND_SWAP_FAILURE    0x0U /**< Compare and swap failed, did not swap. */

/*----------------------------- Swap && CAS ------------------------------*/

/**
 * Atomic compare-and-swap
 *
 * @brief Performs an atomic compare-and-swap operation on the specified values.
 *
 * @param[in, out] pulDestination  Pointer to memory location from where value is
 *                               to be loaded and checked.
 * @param[in] ulExchange         If condition meets, write this value to memory.
 * @param[in] ulComparand        Swap condition.
 *
 * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
 *
 * @note This function only swaps *pulDestination with ulExchange, if previous
 *       *pulDestination value equals ulComparand.
 */
    static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
                                                                uint32_t ulExchange,
                                                                uint32_t ulComparand )
    {
        uint32_t ulReturnValue;

        ATOMIC_ENTER_CRITICAL();
        {
            if( *pulDestination == ulComparand )
            {
                *pulDestination = ulExchange;
                ulReturnValue   = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
            }
            else
            {
                ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
            }
        }
        ATOMIC_EXIT_CRITICAL();

        return ulReturnValue;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic swap (pointers)
 *
 * @brief Atomically sets the address pointed to by *ppvDestination to the value
 *        of *pvExchange.
 *
 * @param[in, out] ppvDestination  Pointer to memory location from where a pointer
 *                                 value is to be loaded and written back to.
 * @param[in] pvExchange           Pointer value to be written to *ppvDestination.
 *
 * @return The initial value of *ppvDestination.
 */
    static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
                                                            void * pvExchange )
    {
        void * pReturnValue;

        ATOMIC_ENTER_CRITICAL();
        {
            pReturnValue    = *ppvDestination;
            *ppvDestination = pvExchange;
        }
        ATOMIC_EXIT_CRITICAL();

        return pReturnValue;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic compare-and-swap (pointers)
 *
 * @brief Performs an atomic compare-and-swap operation on the specified pointer
 *        values.
 *
 * @param[in, out] ppvDestination  Pointer to memory location from where a pointer
 *                                 value is to be loaded and checked.
 * @param[in] pvExchange           If condition meets, write this value to memory.
 * @param[in] pvComparand          Swap condition.
 *
 * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
 *
 * @note This function only swaps *ppvDestination with pvExchange, if previous
 *       *ppvDestination value equals pvComparand.
 */
    static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
                                                                        void * pvExchange,
                                                                        void * pvComparand )
    {
        uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;

        ATOMIC_ENTER_CRITICAL();
        {
            if( *ppvDestination == pvComparand )
            {
                *ppvDestination = pvExchange;
                ulReturnValue   = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
            }
        }
        ATOMIC_EXIT_CRITICAL();

        return ulReturnValue;
    }


/*----------------------------- Arithmetic ------------------------------*/

/**
 * Atomic add
 *
 * @brief Atomically adds count to the value of the specified pointer points to.
 *
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 *                         loaded and written back to.
 * @param[in] ulCount      Value to be added to *pulAddend.
 *
 * @return previous *pulAddend value.
 */
    static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
                                                     uint32_t ulCount )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent   = *pulAddend;
            *pulAddend += ulCount;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic subtract
 *
 * @brief Atomically subtracts count from the value of the specified pointer
 *        pointers to.
 *
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 *                         loaded and written back to.
 * @param[in] ulCount      Value to be subtract from *pulAddend.
 *
 * @return previous *pulAddend value.
 */
    static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
                                                          uint32_t ulCount )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent   = *pulAddend;
            *pulAddend -= ulCount;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic increment
 *
 * @brief Atomically increments the value of the specified pointer points to.
 *
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 *                         loaded and written back to.
 *
 * @return *pulAddend value before increment.
 */
    static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent   = *pulAddend;
            *pulAddend += 1;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic decrement
 *
 * @brief Atomically decrements the value of the specified pointer points to
 *
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 *                         loaded and written back to.
 *
 * @return *pulAddend value before decrement.
 */
    static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent   = *pulAddend;
            *pulAddend -= 1;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }

/*----------------------------- Bitwise Logical ------------------------------*/

/**
 * Atomic OR
 *
 * @brief Performs an atomic OR operation on the specified values.
 *
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 *                                to be loaded and written back to.
 * @param [in] ulValue            Value to be ORed with *pulDestination.
 *
 * @return The original value of *pulDestination.
 */
    static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
                                                    uint32_t ulValue )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent        = *pulDestination;
            *pulDestination |= ulValue;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic AND
 *
 * @brief Performs an atomic AND operation on the specified values.
 *
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 *                                to be loaded and written back to.
 * @param [in] ulValue            Value to be ANDed with *pulDestination.
 *
 * @return The original value of *pulDestination.
 */
    static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
                                                     uint32_t ulValue )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent        = *pulDestination;
            *pulDestination &= ulValue;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic NAND
 *
 * @brief Performs an atomic NAND operation on the specified values.
 *
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 *                                to be loaded and written back to.
 * @param [in] ulValue            Value to be NANDed with *pulDestination.
 *
 * @return The original value of *pulDestination.
 */
    static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
                                                      uint32_t ulValue )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent       = *pulDestination;
            *pulDestination = ~( ulCurrent & ulValue );
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }
/*-----------------------------------------------------------*/

/**
 * Atomic XOR
 *
 * @brief Performs an atomic XOR operation on the specified values.
 *
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 *                                to be loaded and written back to.
 * @param [in] ulValue            Value to be XORed with *pulDestination.
 *
 * @return The original value of *pulDestination.
 */
    static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
                                                     uint32_t ulValue )
    {
        uint32_t ulCurrent;

        ATOMIC_ENTER_CRITICAL();
        {
            ulCurrent        = *pulDestination;
            *pulDestination ^= ulValue;
        }
        ATOMIC_EXIT_CRITICAL();

        return ulCurrent;
    }

    #ifdef __cplusplus
        }
    #endif

#endif /* ATOMIC_H */
