/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#ifndef INCLUDE_ECXX_PLATFORM_SPECIFIC_ATOMIC_GUARD_H
#error "this file cannot be included directly"
#endif
#undef INCLUDE_ECXX_PLATFORM_SPECIFIC_ATOMIC_GUARD_H


#ifndef ECXX_PLATFORM_NODEMCU_ATOMIC_GUARD_H
#define ECXX_PLATFORM_NODEMCU_ATOMIC_GUARD_H


#include <eCxx/CTL/UninstantiableUncopyable.h>


namespace eCxx {


//
// A simple atomic guard
//
class AtomicGuard : public Uncopyable {
    public:
        inline AtomicGuard() __ECXX_ATTR_ALWAYS_INLINE
        {
            __asm__ __volatile__ (
                "rsil %0, 15 \n\t"
                : "=a"(_state)
                :
                : "memory"
            );
        }

        inline ~AtomicGuard() __ECXX_ATTR_ALWAYS_INLINE
        {
            __asm__ __volatile__ (
                "wsr %0, ps \n\t"
                "isync      \n\t"
                :
                : "a"(_state)
                : "memory"
            );
        }

    private:
        uint32_t _state;
};


} // namespace eCxx


#endif
